summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoriroul <iroul@iroul-VirtualBox.(none)>2014-04-04 07:35:14 -0700
committeriroul <iroul@iroul-VirtualBox.(none)>2014-04-04 07:35:14 -0700
commitafd34f2893a06a3aecf17e8e83b1df6ed2ae91a2 (patch)
tree851102abc55d91a1b76e63e9e89f9a7733da95b5 /src
parentc4b028ad53f7b362a864de24828d7cc39ff67b0a (diff)
downloadfqterm-afd34f2893a06a3aecf17e8e83b1df6ed2ae91a2.tar.xz
move to my github.
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt13
-rw-r--r--src/common/CMakeLists.txt36
-rw-r--r--src/common/common.cpp53
-rw-r--r--src/common/common.h64
-rw-r--r--src/common/fqterm.h350
-rw-r--r--src/common/fqterm_config.cpp181
-rw-r--r--src/common/fqterm_config.h61
-rw-r--r--src/common/fqterm_exif_extractor.cpp647
-rw-r--r--src/common/fqterm_exif_extractor.h126
-rw-r--r--src/common/fqterm_filedialog.cpp157
-rw-r--r--src/common/fqterm_filedialog.h49
-rw-r--r--src/common/fqterm_font.cpp261
-rw-r--r--src/common/fqterm_font.h34
-rw-r--r--src/common/fqterm_param.cpp274
-rw-r--r--src/common/fqterm_param.h221
-rw-r--r--src/common/fqterm_path.cpp601
-rw-r--r--src/common/fqterm_path.h46
-rw-r--r--src/common/fqterm_shortcuthelper.cpp298
-rw-r--r--src/common/fqterm_shortcuthelper.h175
-rw-r--r--src/common/fqterm_sound.cpp733
-rw-r--r--src/common/fqterm_sound.h79
-rw-r--r--src/common/fqterm_trace.cpp328
-rw-r--r--src/common/fqterm_trace.h331
-rw-r--r--src/fqterm/3rdparty/dotnetstyle.cpp1274
-rw-r--r--src/fqterm/3rdparty/dotnetstyle.h77
-rw-r--r--src/fqterm/3rdparty/qxtglobal.h207
-rw-r--r--src/fqterm/3rdparty/qxtglobalshortcut.cpp193
-rw-r--r--src/fqterm/3rdparty/qxtglobalshortcut.h58
-rw-r--r--src/fqterm/3rdparty/qxtglobalshortcut_mac.cpp262
-rw-r--r--src/fqterm/3rdparty/qxtglobalshortcut_p.h63
-rw-r--r--src/fqterm/3rdparty/qxtglobalshortcut_win.cpp214
-rw-r--r--src/fqterm/3rdparty/qxtglobalshortcut_x11.cpp115
-rw-r--r--src/fqterm/3rdparty/uaocodec.cpp15761
-rw-r--r--src/fqterm/3rdparty/uaocodec.h69
-rw-r--r--src/fqterm/CMakeLists.txt83
-rw-r--r--src/fqterm/fqterm.rcbin0 -> 330 bytes
-rw-r--r--src/fqterm/fqterm_app.cpp38
-rw-r--r--src/fqterm/fqterm_app.h41
-rw-r--r--src/fqterm/fqterm_autoupdate.cpp178
-rw-r--r--src/fqterm/fqterm_autoupdate.h61
-rw-r--r--src/fqterm/fqterm_frame.cpp2162
-rw-r--r--src/fqterm/fqterm_frame.h326
-rw-r--r--src/fqterm/fqterm_python.cpp826
-rw-r--r--src/fqterm/fqterm_python.h51
-rw-r--r--src/fqterm/fqterm_screen.cpp1868
-rw-r--r--src/fqterm/fqterm_screen.h281
-rw-r--r--src/fqterm/fqterm_scriptengine.cpp488
-rw-r--r--src/fqterm/fqterm_scriptengine.h147
-rw-r--r--src/fqterm/fqterm_window.cpp2531
-rw-r--r--src/fqterm/fqterm_window.h345
-rw-r--r--src/fqterm/fqterm_wndmgr.cpp381
-rw-r--r--src/fqterm/fqterm_wndmgr.h115
-rw-r--r--src/fqterm/main.cpp135
-rw-r--r--src/protocol/CMakeLists.txt65
-rw-r--r--src/protocol/fqterm_socket.cpp672
-rw-r--r--src/protocol/fqterm_socket.h196
-rw-r--r--src/protocol/fqterm_ssh_socket.cpp352
-rw-r--r--src/protocol/fqterm_ssh_socket.h131
-rw-r--r--src/protocol/internal/crc32.cpp84
-rw-r--r--src/protocol/internal/crc32.h37
-rw-r--r--src/protocol/internal/fqterm_serialization.h54
-rw-r--r--src/protocol/internal/fqterm_ssh1_packet.cpp148
-rw-r--r--src/protocol/internal/fqterm_ssh1_packet.h40
-rw-r--r--src/protocol/internal/fqterm_ssh2_kex.cpp394
-rw-r--r--src/protocol/internal/fqterm_ssh2_kex.h105
-rw-r--r--src/protocol/internal/fqterm_ssh2_packet.cpp267
-rw-r--r--src/protocol/internal/fqterm_ssh2_packet.h51
-rw-r--r--src/protocol/internal/fqterm_ssh_auth.cpp223
-rw-r--r--src/protocol/internal/fqterm_ssh_auth.h112
-rw-r--r--src/protocol/internal/fqterm_ssh_buffer.cpp302
-rw-r--r--src/protocol/internal/fqterm_ssh_buffer.h83
-rw-r--r--src/protocol/internal/fqterm_ssh_channel.cpp439
-rw-r--r--src/protocol/internal/fqterm_ssh_channel.h130
-rw-r--r--src/protocol/internal/fqterm_ssh_cipher.h58
-rw-r--r--src/protocol/internal/fqterm_ssh_const.h146
-rw-r--r--src/protocol/internal/fqterm_ssh_des.cpp180
-rw-r--r--src/protocol/internal/fqterm_ssh_des.h74
-rw-r--r--src/protocol/internal/fqterm_ssh_hash.h47
-rw-r--r--src/protocol/internal/fqterm_ssh_kex.cpp210
-rw-r--r--src/protocol/internal/fqterm_ssh_kex.h100
-rw-r--r--src/protocol/internal/fqterm_ssh_mac.cpp53
-rw-r--r--src/protocol/internal/fqterm_ssh_mac.h54
-rw-r--r--src/protocol/internal/fqterm_ssh_md5.cpp36
-rw-r--r--src/protocol/internal/fqterm_ssh_md5.h50
-rw-r--r--src/protocol/internal/fqterm_ssh_packet.cpp242
-rw-r--r--src/protocol/internal/fqterm_ssh_packet.h148
-rw-r--r--src/protocol/internal/fqterm_ssh_pubkey.h37
-rw-r--r--src/protocol/internal/fqterm_ssh_rsa.cpp67
-rw-r--r--src/protocol/internal/fqterm_ssh_rsa.h41
-rw-r--r--src/protocol/internal/fqterm_ssh_types.h43
-rw-r--r--src/terminal/CMakeLists.txt46
-rw-r--r--src/terminal/fqterm_buffer.cpp998
-rw-r--r--src/terminal/fqterm_buffer.h297
-rw-r--r--src/terminal/fqterm_session.cpp1648
-rw-r--r--src/terminal/fqterm_session.h344
-rw-r--r--src/terminal/fqterm_text_line.cpp541
-rw-r--r--src/terminal/fqterm_text_line.h159
-rw-r--r--src/terminal/internal/fqterm_decode.cpp1279
-rw-r--r--src/terminal/internal/fqterm_decode.h194
-rw-r--r--src/terminal/internal/fqterm_telnet.cpp1041
-rw-r--r--src/terminal/internal/fqterm_telnet.h195
-rw-r--r--src/terminal/internal/fqterm_zmodem.cpp3056
-rw-r--r--src/terminal/internal/fqterm_zmodem.h623
-rw-r--r--src/ui/CMakeLists.txt122
-rw-r--r--src/ui/aboutdialog.cpp71
-rw-r--r--src/ui/aboutdialog.h39
-rw-r--r--src/ui/aboutdialog.ui175
-rw-r--r--src/ui/addrdialog.cpp396
-rw-r--r--src/ui/addrdialog.h87
-rw-r--r--src/ui/addrdialog.ui1211
-rw-r--r--src/ui/articledialog.cpp105
-rw-r--r--src/ui/articledialog.h52
-rw-r--r--src/ui/articledialog.ui132
-rw-r--r--src/ui/defineescape.cpp51
-rw-r--r--src/ui/defineescape.h44
-rw-r--r--src/ui/defineescape.ui68
-rw-r--r--src/ui/fqterm_canvas.cpp537
-rw-r--r--src/ui/fqterm_canvas.h105
-rw-r--r--src/ui/fqterm_time_label.cpp50
-rw-r--r--src/ui/fqterm_time_label.h44
-rw-r--r--src/ui/fqterm_tool_button.cpp41
-rw-r--r--src/ui/fqterm_tool_button.h46
-rw-r--r--src/ui/imageviewer.cpp1749
-rw-r--r--src/ui/imageviewer.h336
-rw-r--r--src/ui/iplookup.cpp56
-rw-r--r--src/ui/iplookup.h43
-rw-r--r--src/ui/iplookup.ui76
-rw-r--r--src/ui/keydialog.cpp285
-rw-r--r--src/ui/keydialog.h63
-rw-r--r--src/ui/keydialog.ui665
-rw-r--r--src/ui/msgdialog.cpp43
-rw-r--r--src/ui/msgdialog.h35
-rw-r--r--src/ui/msgdialog.ui86
-rw-r--r--src/ui/osdmessage.cpp210
-rw-r--r--src/ui/osdmessage.h69
-rw-r--r--src/ui/overlayWidget.cpp84
-rw-r--r--src/ui/overlayWidget.h51
-rw-r--r--src/ui/pictureflow.cpp1201
-rw-r--r--src/ui/pictureflow.h198
-rw-r--r--src/ui/popupMessage.cpp316
-rw-r--r--src/ui/popupMessage.h116
-rw-r--r--src/ui/popwidget.cpp177
-rw-r--r--src/ui/popwidget.h70
-rw-r--r--src/ui/prefdialog.cpp332
-rw-r--r--src/ui/prefdialog.h66
-rw-r--r--src/ui/prefdialog.ui644
-rw-r--r--src/ui/progressBar.cpp100
-rw-r--r--src/ui/progressBar.h71
-rw-r--r--src/ui/quickdialog.cpp258
-rw-r--r--src/ui/quickdialog.h73
-rw-r--r--src/ui/quickdialog.ui211
-rw-r--r--src/ui/schemadialog.cpp323
-rw-r--r--src/ui/schemadialog.h80
-rw-r--r--src/ui/schemadialog.ui539
-rw-r--r--src/ui/shortcutdialog.cpp176
-rw-r--r--src/ui/shortcutdialog.h61
-rw-r--r--src/ui/sitemanager.cpp412
-rw-r--r--src/ui/sitemanager.h104
-rw-r--r--src/ui/sitemanager.ui593
-rw-r--r--src/ui/soundconf.cpp178
-rw-r--r--src/ui/soundconf.h57
-rw-r--r--src/ui/soundconf.ui162
-rw-r--r--src/ui/sshlogin.ui75
-rw-r--r--src/ui/sshlogindialog.cpp80
-rw-r--r--src/ui/sshlogindialog.h45
-rw-r--r--src/ui/statusBar.cpp530
-rw-r--r--src/ui/statusBar.h148
-rw-r--r--src/ui/zmodemdialog.cpp73
-rw-r--r--src/ui/zmodemdialog.h51
-rw-r--r--src/ui/zmodemdialog.ui105
-rw-r--r--src/unite/CMakeLists.txt46
-rw-r--r--src/unite/fqterm_mini_server.cpp71
-rw-r--r--src/unite/fqterm_mini_server.h69
-rw-r--r--src/unite/internal/article.cpp19
-rw-r--r--src/unite/internal/article.h28
-rw-r--r--src/unite/internal/board.cpp19
-rw-r--r--src/unite/internal/board.h28
-rw-r--r--src/unite/internal/session.cpp138
-rw-r--r--src/unite/internal/session.h77
-rw-r--r--src/unite/internal/state.cpp676
-rw-r--r--src/unite/internal/state.h219
-rw-r--r--src/unite/internal/statebuilder.cpp32
-rw-r--r--src/unite/internal/statebuilder.h16
-rw-r--r--src/unite/internal/unite.h35
-rw-r--r--src/unite/internal/user.cpp19
-rw-r--r--src/unite/internal/user.h35
-rw-r--r--src/utilities/CMakeLists.txt33
-rw-r--r--src/utilities/fqterm_convert.cpp3485
-rw-r--r--src/utilities/fqterm_convert.h44
-rw-r--r--src/utilities/fqterm_http.cpp264
-rw-r--r--src/utilities/fqterm_http.h83
-rw-r--r--src/utilities/fqterm_ip_location.cpp265
-rw-r--r--src/utilities/fqterm_ip_location.h73
-rw-r--r--src/utilities/fqwcwidth.cpp468
-rw-r--r--src/utilities/fqwcwidth.h60
195 files changed, 70514 insertions, 0 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..e8aedb4
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,13 @@
+add_subdirectory(common)
+
+add_subdirectory(protocol)
+
+add_subdirectory(ui)
+
+add_subdirectory(terminal)
+
+add_subdirectory(utilities)
+
+add_subdirectory(unite)
+
+add_subdirectory(fqterm)
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
new file mode 100644
index 0000000..d3f0c09
--- /dev/null
+++ b/src/common/CMakeLists.txt
@@ -0,0 +1,36 @@
+set(fqterm_common_SRCS
+ common.h
+ common.cpp
+ fqterm.h
+ fqterm_trace.h
+ fqterm_trace.cpp
+ fqterm_config.h
+ fqterm_config.cpp
+ fqterm_sound.h
+ fqterm_sound.cpp
+ fqterm_param.h
+ fqterm_param.cpp
+ fqterm_path.h
+ fqterm_path.cpp
+ fqterm_font.h
+ fqterm_font.cpp
+ fqterm_exif_extractor.h
+ fqterm_exif_extractor.cpp
+ fqterm_filedialog.h
+ fqterm_filedialog.cpp
+ fqterm_shortcuthelper.h
+ fqterm_shortcuthelper.cpp
+)
+
+qt4_automoc(${fqterm_common_SRCS})
+
+include_directories(
+ ${QT_INCLUDE_DIR}
+ ${QT_QTCORE_INCLUDE_DIR}
+ ${QT_QTGUI_INCLUDE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+add_library(fqterm_common
+ ${fqterm_common_SRCS}
+)
diff --git a/src/common/common.cpp b/src/common/common.cpp
new file mode 100644
index 0000000..ec08bef
--- /dev/null
+++ b/src/common/common.cpp
@@ -0,0 +1,53 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <stdlib.h>
+
+#include <QString>
+#include <QProcess>
+#include <QStringList>
+#include "common.h"
+
+namespace FQTerm {
+
+void runProgram(const QString &cmd, const QString& arg, bool bg) {
+ if (bg) {
+ QProcess::startDetached(cmd, QStringList(arg));
+ } else {
+ QProcess::execute(cmd, QStringList(arg));
+ }
+
+ return;
+ /*
+#if defined(WIN32)
+ QString strCmd = "\"\"" + cmd + "\" \"" + arg + "\"\"";
+#else
+ QString strCmd = "'" + cmd + "' '" + arg + "'";
+#endif
+#if !defined(WIN32)
+ if (bg) {
+ strCmd += " &";
+ }
+#endif
+ system(strCmd.toLocal8Bit());
+ */
+}
+
+} // namespace FQTerm
diff --git a/src/common/common.h b/src/common/common.h
new file mode 100644
index 0000000..5720ddc
--- /dev/null
+++ b/src/common/common.h
@@ -0,0 +1,64 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_COMMON_H
+#define FQTERM_COMMON_H
+
+#if defined(WIN32)
+#define OS_NEW_LINE "\r\n"
+#elif defined(__APPLE__)
+#define OS_NEW_LINE "\r"
+#else
+#define OS_NEW_LINE "\n"
+#endif
+
+class QString;
+
+namespace FQTerm {
+
+enum Directions {
+ kHome = 0,
+ kEnd = 1,
+ kPageUp = 2,
+ kPageDown = 3,
+ kUp = 4,
+ kDown = 5,
+ kLeft = 6,
+ kRight = 7
+};
+
+const char * const kDirections[] = {
+ // 4
+ "\x1b[1~", // 0 HOME
+ "\x1b[4~", // 1 END
+ "\x1b[5~", // 2 PAGE UP
+ "\x1b[6~", // 3 PAGE DOWN
+ // 3
+ "\x1b[A", // 4 UP
+ "\x1b[B", // 5 DOWN
+ "\x1b[D", // 6 LEFT
+ "\x1b[C" // 7 RIGHT
+};
+
+void runProgram(const QString &cmd, const QString& arg = "", bool bg = true);
+
+} // namespace FQTerm
+
+#endif // FQTERM_COMMON_H
diff --git a/src/common/fqterm.h b/src/common/fqterm.h
new file mode 100644
index 0000000..515cedc
--- /dev/null
+++ b/src/common/fqterm.h
@@ -0,0 +1,350 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_GLOBAL_H
+#define FQTERM_GLOBAL_H
+
+#ifndef BUFSIZE
+#define BUFSIZE (1024)
+#endif
+
+#include <QTextCodec>
+#include <QString>
+#include "fqterm_trace.h"
+
+namespace FQTerm {
+
+#if defined(WIN32) && (_MSC_VER >= 1400)
+ //Using vc2005 or +
+#define fq_strdup _strdup
+#else
+#define fq_strdup strdup
+#endif
+
+#ifdef FOUND_PYTHON
+//#define HAVE_PYTHON
+#endif //FOUND_PYTHON
+
+#define USE_GLOBAL_HOTKEY
+
+//code convert
+enum EncodingID {FQTERM_ENCODING_GBK = 0, FQTERM_ENCODING_BIG5 = 1,
+ FQTERM_ENCODING_UTF8 = 2, FQTERM_ENCODING_HKSCS = 3,
+ FQTERM_ENCODING_UAO = 4};
+
+#if QT_VERSION >= 0X040700
+#define GBK_CODECS_NAME "GB18030"
+#else
+#define GBK_CODECS_NAME "GBK"
+#endif
+
+#define G2U(s) ( QTextCodec::codecForName(GBK_CODECS_NAME)->toUnicode(s) )
+#define U2G(s) ( QTextCodec::codecForName(GBK_CODECS_NAME)->fromUnicode(s) )
+#define B2U(s) ( QTextCodec::codecForName("Big5")->toUnicode(s) )
+#define U2B(s) ( QTextCodec::codecForName("Big5")->fromUnicode(s) )
+#define H2U(s) ( QTextCodec::codecForName("Big5-HKSCS")->toUnicode(s) )
+#define U2H(s) ( QTextCodec::codecForName("Big5-HKSCS")->fromUnicode(s) )
+#define U2U8(s) ( s.toUtf8() )
+#define U82U(s) ( QString::fromUtf8(s) )
+#define A2U(s) (QTextCodec::codecForName("UAO")->toUnicode(s) )
+#define U2A(s) ( QTextCodec::codecForName("UAO")->fromUnicode(s) )
+
+inline QByteArray unicode2encoding(const QString &text, int encoding) {
+ switch(encoding)
+ {
+ case FQTERM_ENCODING_GBK:
+ return(U2G(text));
+ case FQTERM_ENCODING_BIG5:
+ return(U2B(text));
+ case FQTERM_ENCODING_UTF8:
+ return(U2U8(text));
+ case FQTERM_ENCODING_HKSCS:
+ return (U2H(text));
+ case FQTERM_ENCODING_UAO:
+ return (U2A(text));
+ }
+
+ return "";
+}
+
+inline QString encoding2unicode(const QByteArray &text, int encoding) {
+ switch(encoding)
+ {
+ case FQTERM_ENCODING_GBK:
+ return(G2U(text));
+ case FQTERM_ENCODING_BIG5:
+ return(B2U(text));
+ case FQTERM_ENCODING_UTF8:
+ return(U82U(text));
+ case FQTERM_ENCODING_HKSCS:
+ return (H2U(text));
+ case FQTERM_ENCODING_UAO:
+ return (A2U(text));
+ }
+
+ return "";
+}
+
+#define FQTERM_CTRL(c) ((c)&0x1f)
+
+// every character has a 16-bit description
+// low 8 for colors
+// hight 8 for attributes
+#define COLORMASK 0x00ff
+#define ATTRMASK 0xff00
+
+// color 8-bit
+// bit 0-2 foreground
+// 0 black
+// 1 red
+// 2 green
+// 3 yellow
+// 4 blue
+// 5 magenta
+// 6 cyan
+// 7 white
+// bit 3 highlight foreground
+// 0 no
+// 1 highlight
+// bit 4-6 background
+// 0 black
+// 1 red
+// 2 green
+// 3 yellow
+// 4 blue
+// 5 magenta
+// 6 cyan
+// 7 white
+// bit 7 highlight background (unused)
+// 0 no
+// 1 highlight
+
+#define FGMASK 0x0f
+#define BGMASK 0xf0
+#define FG_HIGHLIGHT_MASK 0x08
+#define BG_HIGHLIGHT_MASK 0x80
+
+//set color
+#define SETFG(c) ( (c) & FGMASK )
+#define SETBG(c) ( ( (c) << 4 ) & BGMASK )
+#define SET_FG_HIGHLIGHT(c) ( ( (c) << 3 ) & FG_HIGHLIGHT_MASK )
+#define SET_BG_HIGHLIGHT(c) ( ( (c) << 7 ) & BG_HIGHLIGHT_MASK )
+
+//get color
+#define GETFG(c) ( (c) & FGMASK )
+#define GETBG(c) ( ( (c) & BGMASK ) >> 4 )
+
+#define GET_FG_HIGHLIGHT(c) ( ( (c) & FG_HIGHLIGHT_MASK ) >> 3 )
+#define GET_BG_HIGHLIGHT(c) ( ( (c) & BG_HIGHLIGHT_MASK ) >> 7 )
+
+//#define GET_INVERSE_COLOR(c) ( SETFG( (7 - (c & 0x7)) | (c & 0x08) ) | SETBG(15-GETBG(c)) )
+#define GET_INVERSE_COLOR(c) ( SETFG(15-GETFG(c)) | SETBG(15-GETBG(c)) )
+
+// mask for attr
+#define BRIGHTMASK 0x01
+#define DIMMASK 0x02
+#define UNDERLINEMASK 0x08
+#define BLINKMASK 0x10
+#define RAPIDBLINKMASK 0x20
+#define REVERSEMASK 0x40
+#define INVISIBLEMASK 0x80
+
+//set attributes
+#define SETBRIGHT(a) ( (a) | BRIGHTMASK )
+#define SETDIM(a) ( (a) | DIMMASK )
+#define SETUNDERLINE(a) ( (a) | UNDERLINEMASK )
+#define SETBLINK(a) ( (a) | BLINKMASK )
+#define SETRAPIDBLINK(a) ( (a) | RAPIDBLINKMASK )
+#define SETREVERSE(a) ( (a) | REVERSEMASK )
+#define SETINVISIBLE(a) ( (a) | INVISIBLEMASK )
+
+//get attributes
+#define GETBRIGHT(a) ( (a) & BRIGHTMASK )
+#define GETDIM(a) ( (a) & DIMMASK )
+#define GETUNDERLINE(a) ( (a) & UNDERLINEMASK )
+#define GETBLINK(a) ( (a) & BLINKMASK )
+#define GETRAPIDBLINK(a) ( (a) & RAPIDBLINKMASK )
+#define GETREVERSE(a) ( (a) & REVERSEMASK )
+#define GETINVISIBLE(a) ( (a) & INVISIBLEMASK )
+
+//default color
+#define NO_COLOR ( SETFG(7) | SETBG(0) )
+//default attribute
+#define NO_ATTR 0x04
+
+// other definations
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define DAE_FINISH 10001
+#define DAE_TIMEOUT 10002
+
+#define PYE_ERROR 10003
+#define PYE_FINISH 10004
+
+// some keys
+#define CHAR_NUL 0x00 // ^@
+#define CHAR_ENQ 0x05 // ^E
+#define CHAR_BELL 0x07 // ^G
+#define CHAR_BS 0x08 // ^H
+#define CHAR_TAB 0x09 // ^I
+#define CHAR_LF 0x0a // ^J
+#define CHAR_VT 0x0b // ^K
+#define CHAR_FF 0x0c // ^L
+#define CHAR_CR 0x0d // ^M
+#define CHAR_SO 0x0e // ^N
+#define CHAR_SI 0x0f // ^O
+#define CHAR_CAN 0x18 // ^X
+#define CHAR_ESC 0x1b // ^[
+#define CHAR_DEL 0x7f // DEL
+
+#define CHAR_NORMAL -1
+
+const char ANSWERBACK_MESSAGE[] = "This is fqterm.";
+
+// telnet state
+#define TSRESOLVING 30
+#define TSHOSTFOUND 31
+#define TSHOSTNOTFOUND 32
+#define TSCONNECTING 33
+#define TSHOSTCONNECTED 34
+#define TSPROXYCONNECTED 35
+#define TSPROXYAUTH 36
+#define TSPROXYFAIL 38
+#define TSREFUSED 39
+#define TSREADERROR 40
+#define TSCLOSED 41
+#define TSCLOSEFINISH 42
+#define TSCONNECTVIAPROXY 43
+#define TSEGETHOSTBYNAME 44
+#define TSEINIWINSOCK 45
+#define TSERROR 46
+#define TSPROXYERROR 47
+#define TSWRITED 48
+
+// zmodem types
+#define RcvByteCount 0 /* value is # bytes received */
+#define SndByteCount 1 /* value is # bytes sent */
+#define RcvTimeout 2 /* receiver did not respond, aborting */
+#define SndTimeout 3 /* value is # of consecutive send timeouts */
+#define RmtCancel 4 /* remote end has cancelled */
+#define ProtocolErr 5 /* protocol error has occurred, val=hdr */
+#define RemoteMessage 6 /* message from remote end */
+#define DataErr 7 /* data error, val=error count */
+#define FileErr 8 /* error writing file, val=errno */
+#define FileBegin 9 /* file transfer begins, str=name */
+#define FileEnd 10 /* file transfer ends, str=name */
+#define FileSkip 11 /* file being skipped, str=name */
+
+
+// proxy type
+#define NOPROXY 0
+#define WINGATE 1
+#define SOCKS4 2
+#define SOCKS5 3
+#define HTTP 4
+
+// UI ID
+#define ID_FILE_CONNECT 0x00
+#define ID_FILE_DISCONNECT 0x01
+#define ID_FILE_ADDRESS 0x02
+#define ID_FILE_QUICK 0x03
+#define ID_FILE_EXIT 0x04
+
+#define ID_EDIT_COPY 0x10
+#define ID_EDIT_PASTE 0x11
+#define ID_EDIT_COLOR 0x12
+#define ID_EDIT_RECT 0x13
+#define ID_EDIT_AUTO 0x14
+#define ID_EDIT_WW 0x15
+
+#define ID_EDIT_ESC_NO 0x17
+#define ID_EDIT_ESC_ESC 0x18
+#define ID_EDIT_ESC_U 0x19
+#define ID_EDIT_ESC_CUS 0x1a
+
+#define ID_EDIT_CODEC_GBK 0x1b
+#define ID_EDIT_CODEC_BIG5 0x1c
+
+
+#define ID_VIEW_FONT 0x20
+#define ID_VIEW_COLOR 0x21
+#define ID_VIEW_REFRESH 0x22
+#define ID_VIEW_LANG 0x23
+#define ID_VIEW_FULL 0x24
+#define ID_VIEW_BOSS 0x25
+#define ID_VIEW_SCROLL_HIDE 0x26
+#define ID_VIEW_SCROLL_LEFT 0x27
+#define ID_VIEW_SCROLL_RIGHT 0x28
+#define ID_VIEW_SWITCH 0x29
+#define ID_VIEW_STATUS 0x3a
+
+#define ID_OPTION_CURRENT 0x30
+#define ID_OPTION_DEFAULT 0x31
+#define ID_OPTION_PREF 0x32
+
+#define ID_SPEC_ANTI 0x40
+#define ID_SPEC_AUTO 0x41
+#define ID_SPEC_MESSAGE 0x42
+#define ID_SPEC_BEEP 0x43
+#define ID_SPEC_MOUSE 0x44
+#define ID_SPEC_ARTICLE 0x45
+
+#define ID_SCRIPT_RUN 0x50
+#define ID_SCRIPT_STOP 0x51
+
+#define ID_HELP_ABOUT 0x60
+#define ID_HELP_HOMEPAGE 0x61
+
+//for open last addr
+#define LAST_ADDRESS_INDEX -321
+
+//script function names:
+#define SFN_ANTI_IDLE "antiIdle"
+#define SFN_ON_BELL "onBell"
+#define SFN_AUTO_REPLY "autoReply"
+#define SFN_DATA_EVENT "dataEvent"
+#define SFN_KEY_EVENT "keyEvent"
+#define SFN_MOUSE_EVENT "mouseEvent"
+#define SFN_DETECT_MENU "detectMenu"
+
+//script key event type
+#define SKET_KEY_PRESS 0
+
+//script mouse event type
+#define SMET_UNKOWN -1
+#define SMET_MOUSE_PRESS 0
+#define SMET_MOUSE_RELEASE 1
+#define SMET_MOUSE_MOVE 2
+#define SMET_MOUSE_DBCLICK 3
+#define SMET_WHEEL 4
+
+//script button state & key modifier
+#define SBS_LEFT_BUTTON 0x01
+#define SBS_RIGHT_BUTTON 0x02
+#define SBS_MID_BUTTON 0x04
+#define SBS_ALT 0x08
+#define SBS_CTRL 0x10
+#define SBS_SHIFT 0x20
+
+} // namespace FQTerm
+
+#endif // FQTERM_GLOBAL_H
diff --git a/src/common/fqterm_config.cpp b/src/common/fqterm_config.cpp
new file mode 100644
index 0000000..19e0db4
--- /dev/null
+++ b/src/common/fqterm_config.cpp
@@ -0,0 +1,181 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QTextStream>
+#include <QFile>
+#include <QString>
+#include <QTextCodec>
+
+#include "fqterm_trace.h"
+#include "fqterm_config.h"
+
+namespace FQTerm {
+
+FQTermConfig::FQTermConfig(const QString &szFileName) {
+ load(szFileName);
+}
+
+FQTermConfig::~FQTermConfig(){
+
+}
+
+bool FQTermConfig::save(const QString &szFileName) {
+ QFile file(szFileName);
+ if (!file.open(QIODevice::WriteOnly)) {
+ FQ_TRACE("config", 0) << "Failed to open the file for writing: "
+ << szFileName;
+ return false;
+ }
+
+ QTextStream os;
+ os.setDevice(&file);
+ saveToStream(os);
+ // os.unsetDevice();
+ file.close();
+
+
+ return true;
+}
+
+bool FQTermConfig::loadFromStream(QTextStream &is) {
+ QString strLine, strSection;
+
+ data.clear();
+
+ is.setCodec(QTextCodec::codecForName("UTF-8"));
+
+ while (!is.atEnd()) {
+ strLine = is.readLine().trimmed();
+ if (strLine.isEmpty() || strLine[0] == '#') {
+ continue;
+ }
+
+ if (strLine.left(1) == "[" && strLine.right(1) == "]") {
+ strSection = strLine.mid(1, strLine.length() - 2);
+ addSection(strSection);
+ } else {
+ QString strValue = strLine.section('=', 1).trimmed();
+ setItemValue(strSection, strLine.section('=', 0, 0).trimmed(),
+ strValue.isNull() ? QString(""): strValue);
+ }
+ }
+ return true;
+}
+
+bool FQTermConfig::saveToStream(QTextStream &os) {
+ QString strLine, strSection;
+ Section::iterator iStr;
+
+ os.setCodec(QTextCodec::codecForName("UTF-8"));
+
+ for (StrSecMap::iterator iSec = data.begin(); iSec != data.end(); ++iSec) {
+ os << '[' << iSec.key() << "]\n";
+ for (iStr = iSec.value().begin(); iStr != iSec.value().end(); ++iStr) {
+ os << iStr.key() << '=' << iStr.value() << '\n';
+ }
+ os << '\n';
+ }
+ return true;
+}
+
+
+bool FQTermConfig::addSection(const QString &szSection) {
+ if (hasSection(szSection)) {
+ return false;
+ }
+ Section sec;
+ data[szSection] = sec;
+ return true;
+}
+
+bool FQTermConfig::hasSection(const QString &szSection) const
+{
+ return data.find(szSection) != data.end();
+}
+
+bool FQTermConfig::setItemValue(const QString &szSection, const QString
+ &szItemName, const QString &szItemValue) {
+ if (!hasSection(szSection))
+ if (!addSection(szSection)) {
+ return false;
+ }
+
+ data[szSection][szItemName] = szItemValue;
+ return true;
+}
+
+QString FQTermConfig::getItemValue(const QString &szSection,
+ const QString &szItemName) const {
+ if (hasSection(szSection))
+ if (data[szSection].find(szItemName) != data[szSection].end())
+ if (!data[szSection][szItemName].isEmpty()) {
+ return data[szSection][szItemName];
+ }
+ return "";
+}
+
+bool FQTermConfig::renameSection(const QString &szSection, const QString
+ &szNewName) {
+ if (hasSection(szNewName) || !hasSection(szSection)) {
+ return false;
+ }
+
+ if (!addSection(szNewName)) {
+ return false;
+ }
+ data[szNewName] = data[szSection];
+
+ return deleteSection(szSection);
+}
+
+bool FQTermConfig::deleteSection(const QString &szSection) {
+ if (hasSection(szSection)) {
+ data.remove(szSection);
+ return true;
+ }
+ return false;
+}
+
+bool FQTermConfig::deleteItem(const QString &szSection, const QString
+ &szItemName) {
+ if (hasSection(szSection))
+ if (data[szSection].find(szItemName) != data[szSection].end()) {
+ data[szSection].remove(szItemName);
+ return true;
+ }
+ return false;
+}
+
+bool FQTermConfig::load(const QString &filename) {
+ QFile file(filename);
+ if (!file.open(QIODevice::ReadOnly)) {
+ FQ_TRACE("config", 0) << "Failed to open the file for reading "
+ << filename;
+ return false;
+ }
+ QTextStream is;
+ is.setDevice(&file);
+ loadFromStream(is);
+ //is.unsetDevice();
+ file.close();
+ return true;
+}
+
+} // namespace FQTerm
diff --git a/src/common/fqterm_config.h b/src/common/fqterm_config.h
new file mode 100644
index 0000000..2f88602
--- /dev/null
+++ b/src/common/fqterm_config.h
@@ -0,0 +1,61 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_CFG_H
+#define FQTERM_CFG_H
+
+#include <QTextStream>
+#include <QMap>
+#include <QObject>
+
+namespace FQTerm {
+typedef QMap<QString, QString> Section;
+typedef QMap<QString, Section> StrSecMap;
+
+class FQTermConfig {
+ private:
+ StrSecMap data;
+ bool loadFromStream(QTextStream &);
+ bool saveToStream(QTextStream &);
+
+ bool addSection(const QString &sectionName);
+ public:
+ FQTermConfig(const QString &fileName);
+ ~FQTermConfig();
+
+ bool load(const QString &filename);
+ bool save(const QString &fileName);
+
+ bool setItemValue(const QString &sectionName, const QString &itemName,
+ const QString &itemValue);
+
+ QString getItemValue(const QString &sectionName,
+ const QString &itemName) const;
+
+ bool deleteItem(const QString &sectionName, const QString &itemName);
+ bool deleteSection(const QString &sectionName);
+
+ bool renameSection(const QString &sectionName, const QString &newName);
+ bool hasSection(const QString &sectionName) const;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_CFG_H
diff --git a/src/common/fqterm_exif_extractor.cpp b/src/common/fqterm_exif_extractor.cpp
new file mode 100644
index 0000000..05d318e
--- /dev/null
+++ b/src/common/fqterm_exif_extractor.cpp
@@ -0,0 +1,647 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_exif_extractor.h"
+
+namespace FQTerm {
+
+const ExifExtractor::uint16 ExifExtractor::IFD0Tag[16] = {0x010e, 0x010f, 0x0110, 0x0112, 0x011a,
+ 0x011b, 0x0128, 0x0131, 0x0132, 0x013e,
+ 0x013f, 0x0211, 0x0213, 0x0214, 0x8298, 0x8769
+};
+
+const char ExifExtractor::IFD0TagName[16][30] = { "ImageDescription", "Make", "Model", "Orientation",
+ "XResolution", "YResolution", "ResolutionUnit", "Software",
+ "DateTime", "WhitePoint", "PrimaryChromaticities", "YCbCrCoefficients",
+ "YCbCrPositioning", "ReferenceBlackWhite", "Copyright", "ExifOffset"
+};
+
+const ExifExtractor::uint16 ExifExtractor::SubIFDTag[38] = {0x829a,0x829d,0x8822,0x8827,0x9000,0x9003,0x9004,0x9101,0x9102,0x9201,0x9202,0x9203,0x9204,
+ 0x9205,0x9206,0x9207,0x9208,0x9209,0x920a,0x927c,0x9286,0x9290,0x9291,0x9292,0xa000,0xa001,
+ 0xa002,0xa003,0xa004,0xa005,0xa20e,0xa20f,0xa210,0xa215,0xa217,0xa300,0xa301,0xa302};
+
+const char ExifExtractor::SubIFDTagName[38][30] = {"ExposureTime","FNumber","ExposureProgram","ISOSpeedRatings","ExifVersion","DateTimeOriginal","DateTimeDigitized",
+ "ComponentsConfiguration","CompressedBitsPerPixel","ShutterSpeedValue","ApertureValue","BrightnessValue","ExposureBiasValue",
+ "MaxApertureValue","SubjectDistance","MeteringMode","LightSource","Flash","FocalLength","MakerNote","UserComment","SubsecTime",
+ "SubsecTimeOriginal","SubsecTimeDigitized","FlashPixVersion","ColorSpace","ExifImageWidth","ExifImageHeight","RelatedSoundFile",
+ "ExifInteroperabilityOffset","FocalPlaneXResolution","FocalPlaneYResolution","FocalPlaneResolutionUnit","ExposureIndex",
+ "SensingMethod","FileSource","SceneType","CFAPattern"};
+
+const char ExifExtractor::exifHeaderStandard[6] = {'E', 'x', 'i', 'f', '\0', '\0'};
+
+ExifExtractor::ExifExtractor()
+{
+ exifFile_ = NULL;
+ reset();
+}
+
+ExifExtractor::~ExifExtractor()
+{
+ reset();
+}
+
+std::string ExifExtractor::extractExifInfo(std::string fileName) {
+ return extractExifInfo(fopen(fileName.c_str(), "rb"));
+}
+
+std::string ExifExtractor::extractExifInfo(FILE* file) {
+ reset();
+ exifFile_ = file;
+ if (!exifFile_ || !isReadable() || !checkEndian()) {
+ return exifInformation_;
+ }
+ if (!readIFD0())
+ return exifInformation_;
+ readSubIFD();
+ postRead();
+ std::map<std::string, std::string>::iterator ii;
+ for (ii = exifKeyValuePairs_.begin();
+ ii != exifKeyValuePairs_.end();
+ ++ii) {
+ if ((*ii).first == "UserComment") {
+ continue;
+ }
+ exifInformation_ += (*ii).first + " : " + (*ii).second + "\n";
+ }
+ fclose(exifFile_);
+ exifFile_ = NULL;
+ return exifInformation_;
+}
+std::string ExifExtractor::info() {
+ return exifInformation_;
+}
+
+std::string ExifExtractor::operator[]( const std::string& key ) {
+ std::map<std::string, std::string>::iterator ii;
+ if ((ii = exifKeyValuePairs_.find(key)) != exifKeyValuePairs_.end()) {
+ return (*ii).second;
+ }
+ return "";
+}
+
+void ExifExtractor::postRead() {
+ std::map<std::string, std::string>::iterator ii;
+ if ((ii = exifKeyValuePairs_.find("Orientation")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() < 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ switch((*ii).second[0]) {
+ case '1': (*ii).second = "1st row - 1st col : top - left side"; break;
+ case '2': (*ii).second = "1st row - 1st col : top - right side"; break;
+ case '3': (*ii).second = "1st row - 1st col : bottom - right side"; break;
+ case '4': (*ii).second = "1st row - 1st col : bottom - left side"; break;
+ case '5': (*ii).second = "1st row - 1st col : left side - top"; break;
+ case '6': (*ii).second = "1st row - 1st col : right side - top"; break;
+ case '7': (*ii).second = "1st row - 1st col : right side - bottom"; break;
+ case '8': (*ii).second = "1st row - 1st col : left side - bottom"; break;
+ default: exifKeyValuePairs_.erase(ii); break;
+
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("ResolutionUnit")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() < 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ switch((*ii).second[0]) {
+ case '1': (*ii).second = "no-unit"; break;
+ case '2': (*ii).second = "inch"; break;
+ case '3': (*ii).second = "centimeter"; break;
+ default: (*ii).second = "inch"; break;
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("DateTime")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() < 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ for (size_t i = 0; i < (*ii).second.length() && i < 11; ++i) {
+ if ((*ii).second[i] == ':'){
+ (*ii).second[i] = '.';
+ }
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("DateTimeOriginal")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() < 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ for (size_t i = 0; i < (*ii).second.length() && i < 11; ++i) {
+ if ((*ii).second[i] == ':'){
+ (*ii).second[i] = '.';
+ }
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("DateTimeDigitized")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() < 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ for (size_t i = 0; i < (*ii).second.length() && i < 11; ++i) {
+ if ((*ii).second[i] == ':'){
+ (*ii).second[i] = '.';
+ }
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("YCbCrPositioning")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() < 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ switch((*ii).second[0]) {
+ case '1': (*ii).second = "The center of pixel array"; break;
+ case '2': (*ii).second = "The datum point"; break;
+ default: exifKeyValuePairs_.erase(ii); break;
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("MeteringMode")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() < 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ uint16 value = 123;
+ sscanf((*ii).second.c_str(), "%hu", &value);
+ switch(value) {
+ case 0: (*ii).second = "Unknown"; break;
+ case 1: (*ii).second = "Average"; break;
+ case 2: (*ii).second = "CenterWeightedAverage"; break;
+ case 3: (*ii).second = "Spot"; break;
+ case 4: (*ii).second = "Multi-spot"; break;
+ case 5: (*ii).second = "Pattern"; break;
+ case '6': (*ii).second = "Partial"; break;
+ case 255: (*ii).second = "Other"; break;
+ default: exifKeyValuePairs_.erase(ii); break;
+
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("LightSource")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() < 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ uint16 value = 123;
+ sscanf((*ii).second.c_str(), "%hu", &value);
+ switch(value) {
+ case 0: (*ii).second = "unknown"; break;
+ case 1: (*ii).second = "daylight"; break;
+ case 2: (*ii).second = "fluorescent"; break;
+ case 3: (*ii).second = "tungsten"; break;
+ case 10: (*ii).second = "flash"; break;
+ case 17: (*ii).second = "standard light A"; break;
+ case 18: (*ii).second = "standard light B"; break;
+ case 19: (*ii).second = "standard light C"; break;
+ case 20: (*ii).second = "D55"; break;
+ case 21: (*ii).second = "D65"; break;
+ case 22: (*ii).second = "D75"; break;
+ case 255: (*ii).second = "other"; break;
+ default: exifKeyValuePairs_.erase(ii); break;
+
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("Flash")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() < 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ uint16 value = 123;
+ sscanf((*ii).second.c_str(), "%hu", &value);
+ value &= 0x07;
+ switch(value) {
+ case 0: (*ii).second = "Flash did not fire"; break;
+ case 1: (*ii).second = "Flash fired"; break;
+ case 5: (*ii).second = "Flash fired but strobe return light not detected"; break;
+ case 7: (*ii).second = "Flash fired and strobe return light detected"; break;
+ default: exifKeyValuePairs_.erase(ii); break;
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("ColorSpace")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() < 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ switch((*ii).second[0]) {
+ case '1': (*ii).second = "sRGB color space"; break;
+ case '6': (*ii).second = "Uncalibrated"; break;
+ default: exifKeyValuePairs_.erase(ii); break;
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("FocalPlaneResolutionUnit")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() < 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ switch((*ii).second[0]) {
+ case '1': (*ii).second = "no-unit"; break;
+ case '2': (*ii).second = "inch"; break;
+ case '3': (*ii).second = "centimeter"; break;
+ default: exifKeyValuePairs_.erase(ii); break;
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("SensingMethod")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() < 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ switch((*ii).second[0]) {
+ case '2': (*ii).second = "1 chip color area sensor"; break;
+ default: (*ii).second = "other"; break;
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("ExifVersion")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() != 4) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ (*ii).second = 'V' + (*ii).second.substr(0, 2) + '.' + (*ii).second.substr(2);
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("ComponentsConfiguration")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() != 4) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ static const char CCName[7][10] = {"", "[Y]", "[Cb]", "[Cr]", "[Red]", "[Green]", "[Blue]"};
+ std::string cc;
+ for(int i = 0; i < 4; ++i) {
+ int index = (*ii).second[i];
+ if (index < 0 || index >= 7) {
+ index = 0;
+ }
+ cc += CCName[index];
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("ExifVersion")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() != 4) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ (*ii).second = 'V' + (*ii).second.substr(0, 2) + '.' + (*ii).second.substr(2);
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("MakerNote")) != exifKeyValuePairs_.end()) {
+ exifKeyValuePairs_.erase(ii);
+ }
+ if ((ii = exifKeyValuePairs_.find("CFAPattern")) != exifKeyValuePairs_.end()) {
+ exifKeyValuePairs_.erase(ii);
+ }
+ if ((ii = exifKeyValuePairs_.find("UserComment")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() < 8) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ //Leave it to higher level which can deal with encoding.
+ //"\0x41\0x53\0x43\0x49\0x49\0x00\0x00\0x00"//ASCII
+ //"\0x4a\0x49\0x53\0x00\0x00\0x00\0x00\0x00"//JIS
+ //"\0x55\0x4e\0x49\0x43\0x4f\0x44\0x45\0x00"//Unicode
+ //"\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00"//Undefined
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("FlashPixVersion")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() != 4) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ (*ii).second = 'V' + (*ii).second.substr(0, 2) + '.' + (*ii).second.substr(2);
+ }
+ }
+ //FileSource
+ if ((ii = exifKeyValuePairs_.find("FileSource")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() != 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ if ((*ii).second[0] == '\003') {
+ (*ii).second = "Digital still camera";
+ } else {
+ exifKeyValuePairs_.erase(ii);
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("SceneType")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() != 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ if ((*ii).second[0] == '\001') {
+ (*ii).second = "Directly photographed";
+ } else {
+ exifKeyValuePairs_.erase(ii);
+ }
+ }
+ }
+
+}
+
+std::string ExifExtractor::readInfo() {
+ uint32 count;
+ uint32 offset;
+ uint16 shortValue;
+ uint32 longValue;
+ uint32 urationalp;
+ uint32 urationalc;
+ uint32 urationalgcd;
+ int32 rationalp;
+ int32 rationalc;
+ int32 rationalgcd;
+ int32 sign;
+ DATATYPE dataType;
+ char* buffer;
+ std::string ret = "";
+
+ if (!read(&shortValue, 2,1) || shortValue == 0 || shortValue > MAXGUARD) {
+ return ret;
+ }
+ dataType = (DATATYPE)shortValue;
+
+ if (!read(&count, 4,1)) {
+ return ret;
+ }
+
+ switch(dataType) {
+ case UNDEFINED:
+ buffer = new char[count + 1];
+
+ if (count < 4) {
+ if (!read(buffer, 1, count)) {
+ return ret;
+ }
+ } else {
+ if (!read(&offset, 4, 1)) {
+ return ret;
+ }
+ seek(12 + offset, SEEK_SET);
+ memset(buffer, 0, count + 1);
+ read(buffer, 1, count);
+ }
+ ret = std::string(buffer, count);
+ delete []buffer;
+ break;
+ case ASCIISTRING:
+ if (!read(&offset, 4, 1)) {
+ break;
+ }
+ seek(12 + offset, SEEK_SET);
+ buffer = new char[count + 1];
+ memset(buffer, 0, count + 1);
+ read(buffer, 1, count);
+ ret = buffer;
+ delete []buffer;
+ break;
+ case UNSIGNEDINT16:
+ if (!read(&shortValue, 2, 1)) {
+ break;
+ }
+ buffer = new char[256];
+ sprintf(buffer, "%hu", shortValue);
+ ret = buffer;
+ delete []buffer;
+ break;
+ case UNSIGNEDINT32:
+ if (!read(&longValue, 4, 1)) {
+ break;
+ }
+ buffer = new char[256];
+ sprintf(buffer, "%u", longValue);
+ ret = buffer;
+ delete []buffer;
+
+ break;
+ case UNSIGNEDRATIONAL:
+ if (!read(&offset, 4, 1)) {
+ break;
+ }
+ seek(12 + offset, SEEK_SET);
+ if (!read(&urationalc, 4, 1)) {
+ break;
+ }
+ if (!read(&urationalp, 4, 1)) {
+ break;
+ }
+ urationalgcd = gcd(urationalp, urationalc);
+ if (urationalgcd == 0) urationalgcd = 1;
+ buffer = new char[256];
+ sprintf(buffer, "%u/%u", urationalc / urationalgcd, urationalp / urationalgcd);
+ ret = buffer;
+ delete []buffer;
+ break;
+ case RATIONAL:
+ if (!read(&offset, 4, 1)) {
+ break;
+ }
+ sign = 1;
+ seek(12 + offset, SEEK_SET);
+ if (!read(&rationalc, 4, 1)) {
+ break;
+ }
+ if (rationalc < 0) {
+ sign *= -1;
+ rationalc = -rationalc;
+ }
+ if (!read(&rationalp, 4, 1)) {
+ break;
+ }
+ if (rationalp < 0) {
+ sign *= -1;
+ rationalp = -rationalp;
+ }
+ rationalgcd = gcd(rationalp, rationalc);
+ if (rationalgcd == 0) rationalgcd = 1;
+ buffer = new char[256];
+ sprintf(buffer, "%d/%d", sign * rationalc / rationalgcd, rationalp / rationalgcd);
+ ret = buffer;
+ delete []buffer;
+ break;
+ default:
+ break;
+ }
+ return ret;
+}
+
+bool ExifExtractor::analyzeIFD0TagInfo() {
+ bool res = true;
+ uint16 tag;
+ if (!read(&tag, 2, 1))
+ res = false;
+ int index;
+ for (index = 0; index < 16; ++index) {
+ if (IFD0Tag[index] == tag) {
+ break;
+ }
+ }
+ if (index == 16) {
+ res = false;
+ }
+ long pos = ftell(exifFile_) + 10;
+
+ if (res) {
+ std::string info = readInfo();
+ if (info != "")
+ exifKeyValuePairs_[IFD0TagName[index]] = info;
+ }
+
+ seek(pos, SEEK_SET);
+ return res;
+}
+
+bool ExifExtractor::analyzeSubIFDTagInfo() {
+ bool res = true;
+ uint16 tag;
+ if (!read(&tag, 2, 1))
+ res = false;
+ int index;
+ for (index = 0; index < 38; ++index) {
+ if (SubIFDTag[index] == tag) {
+ break;
+ }
+ }
+ if (index == 38) {
+ res = false;
+ }
+ long pos = ftell(exifFile_) + 10;
+
+ if (res) {
+ std::string info = readInfo();
+ if (info != "")
+ exifKeyValuePairs_[SubIFDTagName[index]] = info;
+ }
+
+ seek(pos, SEEK_SET);
+ return res;
+}
+
+bool ExifExtractor::readIFD0() {
+ seek(16, SEEK_SET);
+ if (!read(&ifdOffset_, 4, 1)) {
+ return false;
+ }
+ seek(ifdOffset_ + 12, SEEK_SET);
+ uint16 entryCount = 0;
+ if (!read(&entryCount, 2, 1)) {
+ return false;
+ }
+ int app1Entry = entryCount;
+ while (app1Entry >= 0) {
+ analyzeIFD0TagInfo();
+ app1Entry--;
+ }
+ return true;
+}
+
+bool ExifExtractor::readSubIFD() {
+ std::map<std::string, std::string>::iterator ii;
+ if ((ii = exifKeyValuePairs_.find("ExifOffset")) == exifKeyValuePairs_.end()) {
+ return false;
+ }
+ uint32 exifOffset = 0;
+ sscanf((*ii).second.c_str(), "%u", &exifOffset);
+ seek(12 + exifOffset, SEEK_SET);
+
+ uint16 entryCount = 0;
+ if (!read(&entryCount, 2, 1)) {
+ return false;
+ }
+ int app1Entry = entryCount;
+ while (app1Entry >= 0) {
+ analyzeSubIFDTagInfo();
+ app1Entry--;
+ }
+ return true;
+}
+
+bool ExifExtractor::isReadable() {
+ rewind();
+ unsigned char soi[2];
+ if (!read(soi, 2, 1))
+ return false;
+ if (soi[0] != 0xFF || soi[1] != 0xD8) {
+ return false;
+ }
+ unsigned char app1[2];
+ if (!read(app1, 2, 1))
+ return false;
+ if (app1[0] != 0xFF || app1[1] != 0xE1) {
+ return false;
+ }
+ seek(2, SEEK_CUR);
+ char exifHeader[6];
+ if (!read(exifHeader, 1, 6)) {
+ return false;
+ }
+ for (int i = 0; i < 6; ++i) {
+ if (exifHeader[i] != exifHeaderStandard[i])
+ return false;
+ }
+ return true;
+}
+
+bool ExifExtractor::checkEndian() {
+ toggle_ = false;
+ seek(12, SEEK_SET);
+ uint16 endian = 0;
+ if (!read(&endian, 2, 1)) {
+ return false;
+ }
+ if (endian == 0x4949) {
+ //II
+ toggle_ = false;
+ }
+ else if (endian == 0x4d4d) {
+ //MM
+ toggle_ = true;
+ }
+ return true;
+}
+
+void ExifExtractor::toggleEndian( void* buf, size_t s ) {
+ char* buffer = (char*)buf;
+ if (!toggle_) {
+ return;
+ }
+ for (size_t i = 0; i < s / 2; ++i) {
+ char tmp;
+ tmp = buffer[i];
+ buffer[i] = buffer[s - i - 1];
+ buffer[s - i - 1] = tmp;
+ }
+}
+
+void ExifExtractor::reset() {
+ toggle_ = false;
+ exifKeyValuePairs_.clear();
+ if (exifFile_) {
+ fclose(exifFile_);
+ exifFile_ = NULL;
+ }
+ ifdOffset_ = 0;
+ exifInformation_.clear();
+}
+
+bool ExifExtractor::read( void* buffer, size_t elementSize, size_t count ) {
+ for (size_t i = 0; i < count; ++i) {
+ if (fread((char*)buffer + i * elementSize, elementSize, 1, exifFile_) != 1)
+ return false;
+ toggleEndian((char*)buffer + i * elementSize, elementSize);
+ }
+ return true;
+}
+
+void ExifExtractor::seek( long offset, int origin ) {
+ fseek(exifFile_, offset, origin);
+}
+
+void ExifExtractor::rewind() {
+ ::rewind(exifFile_);
+}
+} //namespace FQTerm
diff --git a/src/common/fqterm_exif_extractor.h b/src/common/fqterm_exif_extractor.h
new file mode 100644
index 0000000..7f05798
--- /dev/null
+++ b/src/common/fqterm_exif_extractor.h
@@ -0,0 +1,126 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_EXIF_EXTRACTOR
+#define FQTERM_EXIF_EXTRACTOR
+
+//#include <QtGlobal>
+
+#include "fqterm_trace.h"
+
+#include <iostream>
+#include <vector>
+#include <stdio.h>
+#include <stdlib.h>
+#include <algorithm>
+#include <map>
+#include <string>
+//using namespace std;
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#include <cstdint>
+#endif
+
+namespace FQTerm {
+
+class ExifExtractor
+{
+public:
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ typedef std::uint32_t uint32;
+ typedef std::uint16_t uint16;
+ typedef std::int32_t int32;
+ typedef std::int16_t int16;
+#elif defined(QT_VERSION)
+ typedef quint32 uint32;
+ typedef quint16 uint16;
+ typedef qint32 int32;
+ typedef qint16 int16;
+#else
+ typedef unsigned int uint32;
+ typedef unsigned short int uint16;
+ typedef short int int16;
+ typedef int int32;
+#endif
+
+ enum DATATYPE {ZEORGARD = 0, UNSIGNEDCHAR = 1, ASCIISTRING = 2, UNSIGNEDINT16 = 3, UNSIGNEDINT32 = 4,
+ UNSIGNEDRATIONAL = 5, SIGNEDCHAR = 6, UNDEFINED = 7, SIGNEDSHORT = 8, SIGNEDLONG = 9, RATIONAL = 10,
+ SIGNEDFLOAT = 11, DOUBLEFLOAT = 12, MAXGUARD = 13};
+
+
+ ExifExtractor();
+ ~ExifExtractor();
+ std::string extractExifInfo(std::string fileName);
+ std::string extractExifInfo(FILE* file);
+
+ std::string info();
+
+ std::string operator[](const std::string& key);
+
+private:
+ void postRead();
+
+ std::string readInfo();
+ bool analyzeIFD0TagInfo();
+
+ bool analyzeSubIFDTagInfo();
+
+ bool readIFD0();
+ bool readSubIFD();
+ bool isReadable();
+ bool checkEndian();
+ void toggleEndian(void* buf, size_t s);
+
+ void reset();
+
+ bool read(void* buffer, size_t elementSize, size_t count);
+
+ void seek(long offset, int origin);
+
+ void rewind();
+
+ template<class T>
+ T gcd(T a, T b) {
+ if (a == 0 || b == 0)
+ return a + b;
+ return gcd(b, a % b);
+ }
+
+
+ bool toggle_;
+ std::map<std::string, std::string> exifKeyValuePairs_;
+ FILE* exifFile_;
+ uint32 ifdOffset_;
+ uint32 subIfdOffset_;
+
+ static const uint16 IFD0Tag[16];
+ static const char IFD0TagName[16][30];
+ static const uint16 SubIFDTag[38];
+ static const char SubIFDTagName[38][30];
+ static const char exifHeaderStandard[6];
+
+ std::string exifInformation_;
+};
+
+
+
+} //namespace FQTerm
+
+#endif
diff --git a/src/common/fqterm_filedialog.cpp b/src/common/fqterm_filedialog.cpp
new file mode 100644
index 0000000..958fff9
--- /dev/null
+++ b/src/common/fqterm_filedialog.cpp
@@ -0,0 +1,157 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_filedialog.h"
+#include "fqterm_trace.h"
+#include "fqterm_path.h"
+#include "fqterm_config.h"
+
+/*
+ * Constructs a articleDialog as a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'.
+ *
+ * The dialog will by default be modeless, unless you set 'modal' to
+ * TRUE to construct a modal dialog.
+ */
+
+namespace FQTerm {
+
+FQTermFileDialog::FQTermFileDialog(FQTermConfig *config, QWidget *parent, Qt::WFlags fl)
+ : QFileDialog(parent, fl) {
+
+ configDir = getPath(USER_CONFIG) + "/";
+ userConfig = configDir + "fqterm.cfg";
+ strSection = "previous";
+ strSave = "save";
+ strOpen = "open";
+ config_ = config;
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+FQTermFileDialog::~FQTermFileDialog() {
+ // no need to delete child widgets, Qt does it all for us
+}
+
+
+
+QString FQTermFileDialog::getSaveName(const QString &fileToSave, const QString &hints, QWidget *widget) {
+ QString saveFile;
+ QString strPrevSave, saveName;
+ QFileDialog fileDialog(widget);
+
+ if (config_->load(userConfig)) {
+ strPrevSave = config_->getItemValue(strSection, strSave);
+ }
+
+ QString strTmp(fileToSave);
+#if !defined(Q_OS_WIN32) || !defined(_OS_WIN32_)
+ if (strTmp.toLocal8Bit().contains("/")) {
+ strTmp.replace(QString("/"), QString("_"));
+ }
+#endif
+
+ if (strPrevSave.isEmpty()) {
+ saveFile = configDir + strTmp;
+ } else {
+ saveFile = strPrevSave + "/" + strTmp;
+ }
+
+ QString realHints = (hints.isEmpty() ? "*" : hints);
+ saveName = fileDialog.getSaveFileName(widget,
+ tr("Save As..."),
+ saveFile, realHints);
+
+ QFileInfo fi(saveName);
+
+ if (!saveName.isEmpty()) {
+ config_->setItemValue(strSection, strSave, fi.absolutePath());
+ config_->save(userConfig);
+ }
+
+ return saveName;
+}
+
+QString FQTermFileDialog::getOpenName(const QString &title, const QString &hints, QWidget *widget) {
+ QString strPrevOpen;
+ QString openName;
+ QFileDialog fileDialog(widget);
+
+ strPrevOpen = (config_->load(userConfig) ? config_->getItemValue(strSection, strOpen) : "./");
+
+ QString realHints = (hints.isEmpty() ? "*" : hints);
+ QString realTitle = (title.isEmpty() ? "Choose a file to open" : title);
+ openName = fileDialog.getOpenFileName(widget, realTitle, strPrevOpen, realHints);
+
+ if (!openName.isEmpty()) {
+ config_->setItemValue(strSection, strOpen, QFileInfo(openName).absolutePath());
+ config_->save(userConfig);
+ }
+
+ return openName;
+}
+
+QStringList FQTermFileDialog::getOpenNames(const QString &title, const QString &hints, QWidget *widget) {
+ QString openDir, strPrevOpen;
+ QStringList openNames;
+ QFileDialog fileDialog(widget);
+
+ strPrevOpen = (config_->load(userConfig) ? config_->getItemValue(strSection, strOpen) : "./");
+
+ QString realHints = (hints.isEmpty() ? "*" : hints);
+ QString realTitle = (title.isEmpty() ? "Choose files to open" : title);
+ openNames = fileDialog.getOpenFileNames(widget, realTitle, strPrevOpen, realHints);
+
+ if (!openNames.isEmpty() && !openNames.at(0).isEmpty()) {
+ openDir = QFileInfo(openNames.at(0)).absolutePath();
+ config_->setItemValue(strSection, strOpen, openDir);
+ config_->save(userConfig);
+ }
+
+ return openNames;
+}
+
+QString FQTermFileDialog::getExistingDirectory(const QString &title, const QString &hints, QWidget *widget) {
+
+ QString strPrevOpen;
+ QFileDialog fileDialog(widget);
+
+ if (hints.isEmpty()) {
+ strPrevOpen = (config_->load(userConfig) ? config_->getItemValue(strSection, strOpen) : "./");
+ } else {
+ strPrevOpen = hints;
+ }
+
+ QString realTitle = (title.isEmpty() ? "Open a directory" : title);
+ QString dir = fileDialog.getExistingDirectory(widget,
+ realTitle,
+ strPrevOpen,
+ QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
+
+ if (!dir.isEmpty()) {
+ config_->setItemValue(strSection, strOpen, QFileInfo(dir).absolutePath());
+ config_->save(userConfig);
+ }
+
+ return dir;
+}
+
+} // namespace FQTerm
diff --git a/src/common/fqterm_filedialog.h b/src/common/fqterm_filedialog.h
new file mode 100644
index 0000000..5248ffd
--- /dev/null
+++ b/src/common/fqterm_filedialog.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_FILEDIALOG_H
+#define FQTERM_FILEDIALOG_H
+
+#include <QFileDialog>
+#include <QMessageBox>
+
+namespace FQTerm {
+
+class FQTermConfig;
+
+class FQTermFileDialog: public QFileDialog {
+public:
+ FQTermFileDialog(FQTermConfig *config, QWidget *parent_ = 0, Qt::WFlags fl = 0);
+ ~FQTermFileDialog();
+
+ QString getSaveName(const QString &filename, const QString &hints, QWidget *widget = 0);
+ QString getOpenName(const QString &title, const QString &hints, QWidget *widget = 0);
+ QStringList getOpenNames(const QString &title, const QString &hints, QWidget *widget = 0);
+ QString getExistingDirectory(const QString &title, const QString &hints, QWidget *widget = 0);
+
+private:
+ QString strSection, strSave, strOpen;
+ FQTermConfig *config_;
+ QString configDir, userConfig;
+};
+
+} // name space FQTerm
+
+#endif // FQTERM_FILEEDIALOG_H
diff --git a/src/common/fqterm_font.cpp b/src/common/fqterm_font.cpp
new file mode 100644
index 0000000..f2dcfbd
--- /dev/null
+++ b/src/common/fqterm_font.cpp
@@ -0,0 +1,261 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <list>
+#include <set>
+#include <utility>
+#include <map>
+
+#include <QFontDatabase>
+#include <QFontInfo>
+#include <QFile>
+#include <QTextStream>
+#include <QTextCodec>
+#include <QLocale>
+
+#include "fqterm_trace.h"
+#include "fqterm_font.h"
+#include "fqterm_path.h"
+#include "fqterm_config.h"
+
+using namespace std;
+
+namespace FQTerm {
+
+namespace Font {
+
+enum Language{US_ENGLISH = 0,
+ SIMPLIFIED_CHINESE,
+ LANGUAGE_COUNT };
+
+QString getLanguageName(Language lang) {
+ switch (lang){
+ case US_ENGLISH:
+ return "en_US";
+ case SIMPLIFIED_CHINESE:
+ return "zh_CN";
+ default:
+ return "C";
+ }
+}
+
+Language getLanguageByName(QString langName) {
+ if (langName == "zh_CN") {
+ return SIMPLIFIED_CHINESE;
+ }
+ if (langName == "en_US") {
+ return US_ENGLISH;
+ }
+ return LANGUAGE_COUNT;
+}
+
+} // namespace Language
+
+typedef set<Font::Language> LanguageSet;
+typedef map<QString, pair<QString, LanguageSet> > FontLanguagesList;
+
+typedef map<QString, map<Font::Language, QStringList> > FontSets;
+
+// This function will be called only once.
+static const FontSets &getPreferedFontSets() {
+ static FontSets font_sets;
+ const QString &res_path = getPath(RESOURCE);
+
+ QString filename = res_path + "default_font.conf";
+
+ if (!QFile::exists(filename)) {
+ filename = res_path + "/dict/" + "default_font.conf";
+ }
+
+
+ QFile file(filename);
+ if (!file.open(QIODevice::ReadOnly)) {
+ FQ_TRACE("font", 0) << "Failed to open the default font configurations file:"
+ << filename;
+ return font_sets;
+ }
+
+ QTextStream is;
+ is.setDevice(&file);
+ is.setCodec(QTextCodec::codecForName("UTF-8"));
+
+#if defined(WIN32)
+ QString expected_section = "Windows";
+#elif defined(__APPLE__)
+ QString expected_section = "Apple";
+#else
+ QString expected_section = "Linux";
+#endif
+
+ QString line;
+
+ QString current_section;
+ while (!is.atEnd()) {
+ line = is.readLine().trimmed();
+ if (line.isEmpty() || line[0] == '#') {
+ continue;
+ }
+
+ if (line.left(1) == "[" && line.right(1) == "]") {
+ current_section = line.mid(1, line.length() - 2);
+ continue;
+ }
+
+ if (current_section == expected_section) {
+ QString en_font = line.section('=', 0, 0).trimmed().toLower();
+ QString fonts_for_lang = line.section('=', 1).trimmed();
+
+ map<Font::Language, QStringList> &font_set = font_sets[en_font];
+
+ QString lang = fonts_for_lang.section(":", 0, 0).trimmed();
+ QString fonts = fonts_for_lang.section(":", 1).trimmed();
+
+ QStringList font_list = fonts.split(",", QString::SkipEmptyParts);
+
+ for (int i = 0; i < font_list.size(); ++i) {
+ font_list[i] = font_list[i].trimmed();
+ }
+
+ font_set[Font::getLanguageByName(lang)] = font_list;
+ }
+ }
+
+ return font_sets;
+}
+
+#if 0
+//Not used
+static int outputAllSystemFonts(const QStringList &fonts) {
+ if (isAllowedCategory("font", 9)) {
+ for (int i = 0; i < fonts.size(); ++i) {
+ FQ_TRACE("font", 9) << "Found a font: "
+ << (QFontInfo(QFont(fonts.at(i))).fixedPitch() ?
+ "fixed-pitch " : "variable-pitch ")
+ << fonts.at(i);
+ }
+ }
+ return 0;
+}
+#endif
+
+static QStringList &getSystemFontFamilies() {
+ static QStringList list = QFontDatabase().families();
+ // static int tmp = outputAllSystemFonts(list);
+
+ return list;
+}
+
+static FontSets &getUserConfigFontSets() {
+ static FontSets font_sets = getPreferedFontSets();
+ return font_sets;
+}
+
+static QString getEnglishFontFamily() {
+ static const QStringList &families = getSystemFontFamilies();
+ static const FontSets &font_sets = getUserConfigFontSets();
+ static QString en_font_name;
+
+ if (!en_font_name.isEmpty()) {
+ return en_font_name;
+ }
+
+ FontSets::const_iterator it = font_sets.find("default");
+ if (it != font_sets.end()) {
+ map<Font::Language, QStringList>::const_iterator itt
+ = it->second.find(Font::US_ENGLISH);
+ if (itt != it->second.end()) {
+ for (int i = 0; i < itt->second.size(); ++i) {
+ const QString &font = itt->second[i];
+ if (families.contains(font)) {
+ en_font_name = font;
+ break;
+ }
+ }
+ }
+ }
+
+ return en_font_name;
+}
+
+
+static QString getFontFamilyForLang(Font::Language lang) {
+ static const QStringList &families = getSystemFontFamilies();
+ static const FontSets &font_sets = getUserConfigFontSets();
+
+ const QString en_font_name = getEnglishFontFamily();
+
+ if (lang == Font::US_ENGLISH) {
+ return en_font_name;
+ }
+
+ FontSets::const_iterator it = font_sets.find(en_font_name.toLower());
+ if (it != font_sets.end()) {
+ map<Font::Language, QStringList>::const_iterator itt
+ = it->second.find(lang);
+ if (itt != it->second.end()) {
+ for (int i = 0; i < itt->second.size(); ++i) {
+ const QString &font = itt->second[i];
+ if (families.contains(font)) {
+ return font;
+ } else {
+ FQ_TRACE("font", 5) << "Font " << font << " for "
+ << en_font_name << " not found.";
+ }
+ }
+ }
+ } else {
+ FQ_TRACE("font", 3) << "NO fontset for " << en_font_name << " found.";
+ }
+
+ return en_font_name;
+}
+
+QString getDefaultFontFamilyForLanguage(bool isEnglish) {
+ Font::Language lang = isEnglish ? Font::US_ENGLISH : Font::SIMPLIFIED_CHINESE;
+
+ static map<Font::Language, QString> langs_fonts_list;
+
+ map<Font::Language, QString>::iterator it = langs_fonts_list.find(lang);
+ if (it == langs_fonts_list.end()) {
+ langs_fonts_list.insert(
+ make_pair(lang, getFontFamilyForLang(lang)));
+ it = langs_fonts_list.find(lang);
+
+ FQ_TRACE("font", 3) << "Defaut font for "
+ << Font::getLanguageName(lang)
+ << " is: "
+ << it->second
+ << " (" << it->second.size() << ")";
+ }
+
+ return it->second;
+}
+
+#if 0
+//Not used.
+static Font::Language getCurrentSystemLanguage() {
+ if (QLocale::system().language() == QLocale::Chinese) {
+ return Font::SIMPLIFIED_CHINESE;
+ }
+
+ return Font::US_ENGLISH;
+}
+#endif
+} // namespace FQTerm
diff --git a/src/common/fqterm_font.h b/src/common/fqterm_font.h
new file mode 100644
index 0000000..7d28ffb
--- /dev/null
+++ b/src/common/fqterm_font.h
@@ -0,0 +1,34 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_FONT_H
+#define FQTERM_FONT_H
+
+#include <QString>
+
+#include "fqterm_param.h"
+
+namespace FQTerm {
+
+QString getDefaultFontFamilyForLanguage(bool isEnglish);
+
+} // namespace FQTerm
+
+#endif // FQTERM_FONT_H
diff --git a/src/common/fqterm_param.cpp b/src/common/fqterm_param.cpp
new file mode 100644
index 0000000..9490bdd
--- /dev/null
+++ b/src/common/fqterm_param.cpp
@@ -0,0 +1,274 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_param.h"
+#include "fqterm_font.h"
+
+namespace FQTerm {
+
+FQTermParam::FQTermParam() {
+ name_ = "NEW SMTH";
+ hostAddress_ = "newsmth.net";
+ port_ = 23;
+ hostType_ = 0; // 0--BBS 1--*NIX
+ isAutoLogin_ = false;
+ preLoginCommand_ = "";
+ userName_ = "";
+ password_ = "";
+ postLoginCommand_ = "";
+ // Display
+ serverEncodingID_ = 0;
+ isFontAutoFit_ = 1;
+ isAlwaysHighlight_ = 0;
+ isAnsiColor_ = 1;
+
+ englishFontName_ = getDefaultFontFamilyForLanguage(true);
+ englishFontSize_ = 14;
+ otherFontName_ = getDefaultFontFamilyForLanguage(false);
+ otherFontSize_ = 14;
+ alignMode_ = 0;
+ charSpacing_ = 0;
+ lineSpacing_ = 0;
+ //charRatio_ = 0;
+
+ backgroundColor_ = QColor(0, 0, 0);
+ foregroundColor_ = QColor(198, 195, 198);
+ schemaFileName_ = "";
+ // Terminal
+ virtualTermType_ = "vt102";
+ keyboardType_ = 0;
+ backspaceType_ = 0;
+ numColumns_ = 80;
+ numRows_ = 24;
+ numScrollLines_ = 240;
+ cursorType_ = 1; // 0--Block 1--Underline 2--I Type
+ escapeString_ = "^[^[[";
+ // Connection
+ proxyType_ = 0; // 0--None 1--Wingate 2--SOCKS4 3--SOCKS5 4--HTTP
+ proxyHostName_ = "";
+ proxyPort_ = 0;
+ isAuthentation_ = false;
+ proxyUserName_ = "";
+ proxyPassword_ = "";
+ protocolType_ = 0; // 0--Telnet 1--SSH1 2--SSH2
+ sshUserName_ = "";
+ sshPassword_ = "";
+ // Misc
+ maxIdleSeconds_ = 120;
+ replyKeyCombination_ = "^Z";
+ antiIdleMessage_ = "^@";
+ isAntiIdle_ = true;
+ isAutoReply_ = false;
+ autoReplyMessage_ = "(FQTerm) Sorry, I am not around";
+ isAutoReconnect_ = false;
+ reconnectInterval_ = 3;
+ retryTimes_ = 0;
+ isAutoCloseWin_ = false;
+ isAutoLoadScript_ = false;
+ enableZmodem_ = true;
+ autoLoadedScriptFileName_ = "";
+ isBeep_ = true;
+ isBuzz_ = false;
+
+ // Mouse
+ isSupportMouse_ = true;
+ // Mouse
+ menuType_ = 2;
+ menuColor_ = QColor(0, 65, 132);
+
+ isColorCopy_ = false;
+ isRectSelect_ = false;
+ isAutoCopy_ = true;
+ isAutoWrap_ = false;
+}
+
+FQTermParam::FQTermParam(const FQTermParam &param) {
+ copy(param);
+}
+
+FQTermParam::~FQTermParam(){}
+
+FQTermParam &FQTermParam::operator = (const FQTermParam &param) {
+ if (this == &param)
+ return *this;
+ copy(param);
+ return *this;
+}
+
+void FQTermParam::copy(const FQTermParam& param) {
+ name_ = param.name_;
+ hostAddress_ = param.hostAddress_;
+ port_ = param.port_;
+ hostType_ = param.hostType_; // 0--BBS 1--*NIX
+ isAutoLogin_ = param.isAutoLogin_;
+ preLoginCommand_ = param.preLoginCommand_;
+ userName_ = param.userName_;
+ password_ = param.password_;
+ postLoginCommand_ = param.postLoginCommand_;
+ // Display
+ serverEncodingID_ = param.serverEncodingID_;
+ isFontAutoFit_ = param.isFontAutoFit_;
+ isAlwaysHighlight_ = param.isAlwaysHighlight_;
+ isAnsiColor_ = param.isAnsiColor_;
+ englishFontName_ = param.englishFontName_;
+ englishFontSize_ = param.englishFontSize_;
+ otherFontName_ = param.otherFontName_;
+ otherFontSize_ = param.otherFontSize_;
+ alignMode_ = param.alignMode_;
+ charSpacing_ = param.charSpacing_;
+ lineSpacing_ = param.lineSpacing_;
+ //charRatio_ = param.charRatio_;
+ backgroundColor_ = param.backgroundColor_;
+ foregroundColor_ = param.foregroundColor_;
+ schemaFileName_ = param.schemaFileName_;
+ // Terminal
+ virtualTermType_ = param.virtualTermType_;
+ keyboardType_ = param.keyboardType_;
+ backspaceType_ = param.backspaceType_;
+ numColumns_ = param.numColumns_;
+ numRows_ = param.numRows_;
+ numScrollLines_ = param.numScrollLines_;
+ cursorType_ = param.cursorType_; // 0--Block 1--Underline 2--I Type
+ escapeString_ = param.escapeString_; // 0--ESC ESC 1--Ctrl+u
+ // Connection
+ proxyType_ = param.proxyType_;
+ // 0--None 1--Wingate 2--SOCKS4 3--SOCKS5 4--HTTP
+ proxyHostName_ = param.proxyHostName_;
+ proxyPort_ = param.proxyPort_;
+ isAuthentation_ = param.isAuthentation_;
+ proxyUserName_ = param.proxyUserName_;
+ proxyPassword_ = param.proxyPassword_;
+ protocolType_ = param.protocolType_; // 0--Telnet 1--SSH1 2--SSH2
+ sshUserName_ = param.sshUserName_;
+ sshPassword_ = param.sshPassword_;
+ // Misc
+ maxIdleSeconds_ = param.maxIdleSeconds_;
+ replyKeyCombination_ = param.replyKeyCombination_;
+ antiIdleMessage_ = param.antiIdleMessage_;
+ isAntiIdle_ = param.isAntiIdle_;
+ isAutoReply_ = param.isAutoReply_;
+ autoReplyMessage_ = param.autoReplyMessage_;
+ isAutoReconnect_ = param.isAutoReconnect_;
+ reconnectInterval_ = param.reconnectInterval_;
+ retryTimes_ = param.retryTimes_;
+ isAutoCloseWin_ = param.isAutoCloseWin_;
+ isAutoLoadScript_ = param.isAutoLoadScript_;
+ enableZmodem_ = param.enableZmodem_;
+ autoLoadedScriptFileName_ = param.autoLoadedScriptFileName_;
+ isBeep_ = param.isBeep_;
+ isBuzz_ = param.isBuzz_;
+
+ isSupportMouse_ = param.isSupportMouse_;
+ // Mouse
+ menuType_ = param.menuType_;
+ menuColor_ = param.menuColor_;
+
+ isColorCopy_ = param.isColorCopy_;
+ isRectSelect_ = param.isRectSelect_;
+ isAutoCopy_ = param.isAutoCopy_;
+ isAutoWrap_ = param.isAutoWrap_;
+}
+
+bool FQTermParam::operator==(const FQTermParam& param)
+{
+ if (name_ != param.name_) return false;
+ if (hostAddress_ != param.hostAddress_) return false;
+ if (port_ != param.port_) return false;
+ if (hostType_ != param.hostType_) return false;
+ if (isAutoLogin_ != param.isAutoLogin_) return false;
+ if (preLoginCommand_ != param.preLoginCommand_) return false;
+ if (userName_ != param.userName_) return false;
+ if (password_ != param.password_) return false;
+ if (postLoginCommand_ != param.postLoginCommand_) return false;
+ if (serverEncodingID_ != param.serverEncodingID_) return false;
+ if (isFontAutoFit_ != param.isFontAutoFit_) return false;
+ if (isAlwaysHighlight_ != param.isAlwaysHighlight_) return false;
+ if (isAnsiColor_ != param.isAnsiColor_) return false;
+ if (englishFontName_ != param.englishFontName_) return false;
+ if (englishFontSize_ != param.englishFontSize_) return false;
+ if (otherFontName_ != param.otherFontName_) return false;
+ if (otherFontSize_ != param.otherFontSize_) return false;
+ if (alignMode_ != param.alignMode_) return false;
+ if (charSpacing_ != param.charSpacing_) return false;
+ if (lineSpacing_ != param.lineSpacing_) return false;
+ if (backgroundColor_ != param.backgroundColor_) return false;
+ if (foregroundColor_ != param.foregroundColor_) return false;
+ if (schemaFileName_ != param.schemaFileName_) return false;
+ if (virtualTermType_ != param.virtualTermType_) return false;
+ if (keyboardType_ != param.keyboardType_) return false;
+ if (backspaceType_ != param.backspaceType_) return false;
+ if (numColumns_ != param.numColumns_) return false;
+ if (numRows_ != param.numRows_) return false;
+ if (numScrollLines_ != param.numScrollLines_) return false;
+ if (cursorType_ != param.cursorType_) return false;
+ if (escapeString_ != param.escapeString_) return false;
+ if (proxyType_ != param.proxyType_) return false;
+ if (proxyHostName_ != param.proxyHostName_) return false;
+ if (proxyPort_ != param.proxyPort_) return false;
+ if (isAuthentation_ != param.isAuthentation_) return false;
+ if (proxyUserName_ != param.proxyUserName_) return false;
+ if (proxyPassword_ != param.proxyPassword_) return false;
+ if (protocolType_ != param.protocolType_) return false;
+ if (sshUserName_ != param.sshUserName_) return false;
+ if (sshPassword_ != param.sshPassword_) return false;
+ if (maxIdleSeconds_ != param.maxIdleSeconds_) return false;
+ if (replyKeyCombination_ != param.replyKeyCombination_) return false;
+ if (antiIdleMessage_ != param.antiIdleMessage_) return false;
+ if (isAntiIdle_ != param.isAntiIdle_) return false;
+ if (isAutoReply_ != param.isAutoReply_) return false;
+ if (autoReplyMessage_ != param.autoReplyMessage_) return false;
+ if (isAutoReconnect_ != param.isAutoReconnect_) return false;
+ if (reconnectInterval_ != param.reconnectInterval_) return false;
+ if (retryTimes_ != param.retryTimes_) return false;
+ if (isAutoCloseWin_ != param.isAutoCloseWin_) return false;
+ if (isAutoLoadScript_ != param.isAutoLoadScript_) return false;
+ if (enableZmodem_ != param.enableZmodem_) return false;
+ if (isBuzz_ != param.isBuzz_) return false;
+ if (isBeep_ != param.isBeep_) return false;
+ if (isSupportMouse_ != param.isSupportMouse_) return false;
+ if (autoLoadedScriptFileName_ != param.autoLoadedScriptFileName_) return false;
+ if (menuType_ != param.menuType_) return false;
+ if (isColorCopy_ != param.isColorCopy_) return false;
+ if (isRectSelect_ != param.isRectSelect_) return false;
+ if (isAutoCopy_ != param.isAutoCopy_) return false;
+ if (isAutoWrap_ != param.isAutoWrap_) return false;
+ return true;
+}
+
+QString FQTermParam::getLanguageName(bool isEnglish, bool translate /* = true */)
+{
+ if (isEnglish) {
+ return QString(translate ? QObject::tr("&English") : "English");
+ }
+ return QString(translate ? QObject::tr("&Non-English") : "Non-English");
+}
+
+const FQTermParam& FQTermParam::getFQBBSParam() {
+ static bool inited = false;
+ static FQTermParam param;
+ if (!inited) {
+ param.name_ = "FQTermHelp";
+ param.hostAddress_ = "127.0.0.1";
+ param.port_ = 35172;
+ param.serverEncodingID_ = 2;
+ }
+ return param;
+}
+} // namespace FQTerm
diff --git a/src/common/fqterm_param.h b/src/common/fqterm_param.h
new file mode 100644
index 0000000..ef44f59
--- /dev/null
+++ b/src/common/fqterm_param.h
@@ -0,0 +1,221 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_PARAM_H
+#define FQTERM_PARAM_H
+
+#include <QString>
+#include <QColor>
+
+namespace FQTerm {
+
+
+//The FQTerm Pref also contains global settings.
+//TODO: move all global settings into FQTermPref.
+struct FQTermPref {
+ static FQTermPref* getInstance()
+ {
+ //Though Singleton, I didn't define a ctor and make it private
+ //Why?
+ //I'm lazy.
+ static FQTermPref* pThis = new FQTermPref();
+ return pThis;
+ }
+ int displayOffset_;
+ int vsetting_;
+ int imeEncodingID_; // 0--GBK 1--BIG5
+ int widthToWrapWord_;
+ // bool bSmartWW;
+ bool isWheelSupported_;
+ bool openWarnOnClose_;
+ bool openTabBlinking_;
+ bool replyENQ_;
+ // bool bLogMsg;
+ QString httpBrowser_;
+ int openBeep_;
+ QString beepSoundFileName_;
+ int beepMethodID_;
+ QString beepPlayerName_;
+ bool openUrlCheck_;
+ // bool bAutoCopy;
+ bool openAntiAlias_;
+ bool openMinimizeToTray_;
+ bool needClearZmodemPoolOnClose_;
+ bool useStyleSheet_;
+ QString styleSheetFile_;
+ QString zmodemDir_;
+ QString poolDir_;
+ QString imageViewerName_;
+ QString externalEditor_;
+ QString externalEditorArg_;
+ QString searchEngine_;
+ //global settings
+ bool isBossColor_;
+ bool isAnsciiEnhance_;
+ QString escapeString_;
+ int termScrollBarPosition_; // 0--hide 1--LEFT 2--RIGHT
+ bool runServer_;
+};
+
+
+class FQTermParam {
+ public:
+ FQTermParam();
+ FQTermParam(const FQTermParam &);
+ ~FQTermParam();
+
+ FQTermParam &operator = (const FQTermParam &);
+
+ bool operator==(const FQTermParam &);
+
+ static const FQTermParam& getFQBBSParam();
+ static QString getLanguageName(bool isEnglish, bool translate = true);
+ // General
+ // Name
+ QString name_;
+ // Address
+ QString hostAddress_;
+ // Port
+ quint16 port_;
+ // Host Type
+ int hostType_; // 0--BBS 1--*NIX
+ // Auto Login
+ bool isAutoLogin_;
+ // Pre Login
+ QString preLoginCommand_;
+ // User Name
+ QString userName_;
+ // Password
+ QString password_;
+ // Post Login
+ QString postLoginCommand_;
+
+ // Display
+ // {FQTERM_ENCODING_GBK = 0, FQTERM_ENCODING_BIG5 = 1, FQTERM_ENCODING_UTF8 = 2, FQTERM_ENCODING_HKSCS = 3, FQTERM_ENCODING_UAO = 4};
+ int serverEncodingID_;
+
+ // 0 - keep column/row, adjust font
+ // 1 - keep font, adjust column/row
+ // 2 - keep column/row/font
+ int isFontAutoFit_;
+ // Always Highlight
+ bool isAlwaysHighlight_;
+ // ANSI Color
+ bool isAnsiColor_;
+ // Font Name
+ QString englishFontName_;
+ QString otherFontName_;
+ // Font Size
+ int englishFontSize_;
+ int otherFontSize_;
+
+ int alignMode_; //how to align english char/chinese char in vertical direction 0 -- vcenter, 1 -- bottom 2 -- top
+ int charSpacing_; //additional char spacing for English char.
+ int lineSpacing_; //additional line spacing
+ //int charRatio_; //height of english char / width of english char
+ // Background Color
+ QColor backgroundColor_;
+ // Foreground Color
+ QColor foregroundColor_;
+ // Schema File
+ QString schemaFileName_;
+
+ // Terminal
+ // Terminal Type
+ QString virtualTermType_;
+ // Key Type
+ int keyboardType_; // 0--BBS 1--XTERM 2--VT100
+ // Columns & Rows
+ int numColumns_, numRows_;
+ // Scroll Lines
+ int numScrollLines_;
+ // Curor Type
+ int cursorType_; // 0--Block 1--Underline 2--I Type
+ // the esacpe string
+ QString escapeString_;
+
+ //Keyboard
+ int backspaceType_; //0--^H 1--^?(127)
+
+
+ // Connection
+ // Proxy Type
+ int proxyType_; // 0--None 1--Wingate 2--SOCKS4 3--SOCKS5 4--HTTP
+ // Address
+ QString proxyHostName_;
+ // Port
+ quint16 proxyPort_;
+ // Authentation
+ bool isAuthentation_;
+ // User Name
+ QString proxyUserName_;
+ // Password
+ QString proxyPassword_;
+ // Protocol
+ int protocolType_; // 0--Telnet 1--SSH1 2--SSH2 3--Local
+ // User Name
+ QString sshUserName_;
+ // Password
+ QString sshPassword_;
+ // Misc
+ // Max Idle Time %s
+ int maxIdleSeconds_;
+ QString replyKeyCombination_;
+ // Send When Idle
+ QString antiIdleMessage_;
+ bool isAntiIdle_;
+ // wether autoreply
+ bool isAutoReply_;
+ // Auto Reply Messages
+ QString autoReplyMessage_;
+ // Reconnect When Disconnected By Host
+ bool isAutoReconnect_;
+ // Reconnect Interval (s)
+ int reconnectInterval_;
+ // Retry times
+ int retryTimes_; // -1 -- infinite
+ // Close Window When Disconnected By Host
+ bool isAutoCloseWin_;
+
+ bool isBeep_;
+ bool isBuzz_;
+
+ // Mouse
+ bool isSupportMouse_;
+ int menuType_; // 0--underline 1--reverse 2--color
+ QColor menuColor_;
+ // Script
+ bool isAutoLoadScript_;
+ QString autoLoadedScriptFileName_;
+ // Zmodem
+ bool enableZmodem_;
+
+ bool isColorCopy_;
+ bool isRectSelect_;
+ bool isAutoCopy_;
+ bool isAutoWrap_;
+
+ private:
+ void copy(const FQTermParam& parm);
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_PARAM_H
diff --git a/src/common/fqterm_path.cpp b/src/common/fqterm_path.cpp
new file mode 100644
index 0000000..88ee385
--- /dev/null
+++ b/src/common/fqterm_path.cpp
@@ -0,0 +1,601 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifdef WIN32
+#include <windows.h>
+#include <shlobj.h>
+#endif // WIN32
+
+#include <QApplication>
+#include <QFile>
+#include <QDir>
+#include <QFont>
+
+#include "fqterm_config.h"
+#include "fqterm_trace.h"
+#include "fqterm_param.h"
+#include "fqterm_path.h"
+#include "fqterm_font.h"
+
+namespace FQTerm {
+
+static QString getUserDataDir();
+static QString getInstallPrefix();
+static QString getResourceDir(const QString &prefix);
+
+const QString &getPath(PathCategory category) {
+ static QString null_dir = "";
+ static QString user_config = getUserDataDir();
+ static QString prefix = getInstallPrefix();
+ static QString resource = getResourceDir(prefix);
+
+ switch (category) {
+ case RESOURCE:
+ return resource;
+ break;
+ case USER_CONFIG:
+ return user_config;
+ break;
+ }
+ return null_dir;
+}
+
+void clearDir(const QString &path) {
+ QDir dir(path);
+ if (dir.exists()) {
+ const QFileInfoList list = dir.entryInfoList();
+ //QFileInfoListIterator it( *list );
+ //QFileInfo *fi;
+ foreach(QFileInfo fi, list) {
+ if (fi.isFile()) {
+ dir.remove(fi.fileName());
+ }
+ }
+ }
+}
+
+bool checkPath(const QString &path) {
+ QDir dir(path);
+ if (!dir.exists()) {
+ if (!dir.mkpath(path)) {
+ FQ_TRACE("path", 0) << "Failed to create directory " << path;
+ return false;
+ }
+ }
+ return true;
+}
+
+bool checkFile(const QString &src, const QString &dst) {
+ if (QFile(dst).exists()) {
+ return true;
+ }
+
+ if (!QFile::copy(src, dst)) {
+ FQ_TRACE("path", 0) << "Failed to copy a file from " << src
+ << " to " << dst;
+ return false;
+ }
+
+ FQ_TRACE("path", 5) << "A file copied from " << src
+ << " to " << dst;
+
+ if (!QFile::setPermissions(dst, QFile::ReadOwner | QFile::WriteOwner)) {
+ FQ_TRACE("path", 0) << "Failed to change access attributs of "<< dst
+ << " to make only the owner have rights to "
+ << "read/write it.";
+ return false;
+ }
+
+ return true;
+}
+
+bool iniSettings() {
+ if (!checkPath(getPath(USER_CONFIG))) {
+ return false;
+ }
+
+ if (!checkFile(getPath(RESOURCE) + "userconf/fqterm.cfg.orig",
+ getPath(USER_CONFIG) + "fqterm.cfg")) {
+ return false;
+ }
+
+ if (!checkFile(getPath(RESOURCE) + "userconf/address.cfg.orig",
+ getPath(USER_CONFIG) + "address.cfg")) {
+ return false;
+ }
+
+ if (!checkFile(getPath(RESOURCE) + "userconf/language.cfg.orig",
+ getPath(USER_CONFIG) + "language.cfg")) {
+ return false;
+ }
+
+ //Copy schema files
+ if (checkPath(getPath(USER_CONFIG) + "schema")) {
+ checkFile(getPath(RESOURCE) + "schema/default.schema",
+ getPath(USER_CONFIG) + "schema/default.schema");
+
+ checkFile(getPath(RESOURCE) + "schema/Linux.schema",
+ getPath(USER_CONFIG) + "schema/Linux.schema");
+
+ checkFile(getPath(RESOURCE) + "schema/Softness.schema",
+ getPath(USER_CONFIG) + "schema/Softness.schema");
+
+ checkFile(getPath(RESOURCE) + "schema/VIM.schema",
+ getPath(USER_CONFIG) + "schema/VIM.schema");
+
+ checkFile(getPath(RESOURCE) + "schema/XTerm.schema",
+ getPath(USER_CONFIG) + "schema/XTerm.schema");
+ }
+
+
+ //read settings from fqterm.cfg
+ FQTermConfig *conf = new FQTermConfig(getPath(USER_CONFIG) + "fqterm.cfg");
+
+ //set font
+ QString family = (conf->getItemValue("global", "font"));
+
+ QString pointsize = conf->getItemValue("global", "pointsize");
+ QString pixelsize = conf->getItemValue("global", "pixelsize");
+ if (!family.isEmpty()) {
+ QFont font(family);
+ if (pointsize.toInt() > 0) {
+ font.setPointSize(pointsize.toInt());
+ }
+ if (pixelsize.toInt() > 0) {
+ font.setPixelSize(pixelsize.toInt());
+ }
+ QString openAntiAlias_ = conf->getItemValue("global", "antialias");
+ if (openAntiAlias_ != "0") {
+ font.setStyleStrategy(QFont::PreferAntialias);
+ }
+ qApp->setFont(font);
+ }
+
+ // zmodem and pool directory
+ QString pathZmodem = conf->getItemValue("preference", "zmodem");
+ if (pathZmodem.isEmpty()) {
+ pathZmodem = getPath(USER_CONFIG) + "zmodem";
+ }
+
+ if (!checkPath(pathZmodem)) {
+ return false;
+ }
+
+ QString pathPool = conf->getItemValue("preference", "pool");
+
+ if (pathPool.isEmpty()) {
+ pathPool = getPath(USER_CONFIG) + "pool/";
+ }
+
+ if (pathPool.right(1) != "/") {
+ pathPool.append('/');
+ }
+
+ QString pathCache = pathPool + "shadow-cache/";
+
+ if (!checkPath(pathPool) || !checkPath(pathCache)) {
+ return false;
+ }
+
+ delete conf;
+ return true;
+}
+
+void checkHelpExists(FQTermConfig* pConf) {
+ QString strTmp = pConf->getItemValue("bbs list", "num");
+ int bbsCount = strTmp.toInt();
+
+ QString strSection;
+
+ for (int i = 0; i < bbsCount; i++) {
+ strSection.sprintf("bbs %d", i);
+ strTmp = pConf->getItemValue(strSection, "name");
+ if (strTmp == "FQTermHelp")
+ return;
+ }
+ pConf->setItemValue("bbs list", "num", QString("%1").arg(bbsCount + 1));
+ saveAddress(pConf, bbsCount, FQTermParam::getFQBBSParam());
+ pConf->save(getPath(USER_CONFIG) + "address.cfg");
+}
+
+void loadNameList(FQTermConfig *pConf, QStringList &listName) {
+ QString strTmp = pConf->getItemValue("bbs list", "num");
+
+ QString strSection;
+
+ for (int i = 0; i < strTmp.toInt(); i++) {
+ strSection.sprintf("bbs %d", i);
+ listName.append(pConf->getItemValue(strSection, "name"));
+ }
+}
+
+bool loadAddress(FQTermConfig *pConf, int n, FQTermParam &param) {
+ QString strTmp, strSection;
+ if (n < 0) {
+ strSection = "default";
+ } else {
+ strSection.sprintf("bbs %d", n);
+ }
+
+ if (!pConf->hasSection(strSection))
+ return false;
+
+ // check if larger than existence
+ strTmp = pConf->getItemValue("bbs list", "num");
+ if (n >= strTmp.toInt()) {
+ return false;
+ }
+ param.name_ = pConf->getItemValue(strSection, "name");
+ param.hostAddress_ = pConf->getItemValue(strSection, "addr");
+ strTmp = pConf->getItemValue(strSection, "port");
+ param.port_ = strTmp.toUShort();
+ strTmp = pConf->getItemValue(strSection, "hosttype");
+ param.hostType_ = strTmp.toInt();
+ strTmp = pConf->getItemValue(strSection, "autologin");
+ param.isAutoLogin_ = (strTmp != "0");
+ param.preLoginCommand_ = pConf->getItemValue(strSection, "prelogin");
+ param.userName_ = pConf->getItemValue(strSection, "user");
+ param.password_ = pConf->getItemValue(strSection, "password");
+ param.postLoginCommand_ = pConf->getItemValue(strSection, "postlogin");
+
+ strTmp = pConf->getItemValue(strSection, "bbscode");
+ param.serverEncodingID_ = strTmp.toInt();
+ strTmp = pConf->getItemValue(strSection, "autofont");
+ if (strTmp == "0") {
+ param.isFontAutoFit_ = 0;
+ } else if (strTmp == "2") {
+ param.isFontAutoFit_ = 2;
+ } else {
+ param.isFontAutoFit_ = 1;
+ }
+ strTmp = pConf->getItemValue(strSection, "alwayshighlight");
+ param.isAlwaysHighlight_ = (strTmp != "0");
+ strTmp = pConf->getItemValue(strSection, "ansicolor");
+ param.isAnsiColor_ = (strTmp != "0");
+ QString language;
+ QString font_name;
+ QString font_size;
+ language = FQTermParam::getLanguageName(true, false);
+ font_name = pConf->getItemValue(strSection, language + "fontname");
+ font_size = pConf->getItemValue(strSection, language + "fontsize");
+ if (!font_name.isEmpty()) {
+ param.englishFontName_ = font_name;
+ }
+ if (!font_size.isEmpty()) {
+ param.englishFontSize_ = font_size.toInt();
+ }
+ //FIXME: Should be removed in next release!!!!! (Since 0.9.7)
+ if (font_name.isEmpty()) {
+ language = FQTermParam::getLanguageName(true);
+ font_name = pConf->getItemValue(strSection, language + "fontname");
+ if (!font_name.isEmpty()) {
+ param.englishFontName_ = font_name;
+ }
+ }
+
+ language = FQTermParam::getLanguageName(false, false);
+ font_name = pConf->getItemValue(strSection, language + "fontname");
+ font_size = pConf->getItemValue(strSection, language + "fontsize");
+ if (!font_name.isEmpty()) {
+ param.otherFontName_ = font_name;
+ }
+ if (!font_size.isEmpty()) {
+ param.otherFontSize_ = font_size.toInt();
+ }
+
+ //FIXME: Should be removed in next release!!!!!
+ if (font_name.isEmpty()) {
+ language = FQTermParam::getLanguageName(false);
+ font_name = pConf->getItemValue(strSection, language + "fontname");
+ if (!font_name.isEmpty()) {
+ param.englishFontName_ = font_name;
+ }
+ }
+
+ param.foregroundColor_.setNamedColor(pConf->getItemValue(strSection, "fgcolor"));
+ param.backgroundColor_.setNamedColor(pConf->getItemValue(strSection, "bgcolor"));
+ param.schemaFileName_ = pConf->getItemValue(strSection, "schemafile");
+
+ param.virtualTermType_ = pConf->getItemValue(strSection, "termtype");
+ strTmp = pConf->getItemValue(strSection, "keytype");
+ param.keyboardType_ = strTmp.toInt();
+ strTmp = pConf->getItemValue(strSection, "backspacetype");
+ param.backspaceType_ = strTmp.toInt();
+ strTmp = pConf->getItemValue(strSection, "column");
+ param.numColumns_ = strTmp.toInt();
+ strTmp = pConf->getItemValue(strSection, "row");
+ param.numRows_ = strTmp.toInt();
+ strTmp = pConf->getItemValue(strSection, "scroll");
+ param.numScrollLines_ = strTmp.toInt();
+ strTmp = pConf->getItemValue(strSection, "cursor");
+ param.cursorType_ = strTmp.toInt();
+ param.escapeString_ = pConf->getItemValue(strSection, "escape");
+
+ strTmp = pConf->getItemValue(strSection, "proxytype");
+ param.proxyType_ = strTmp.toInt();
+ strTmp = pConf->getItemValue(strSection, "proxyauth");
+ param.isAuthentation_ = (strTmp != "0");
+ param.proxyHostName_ = pConf->getItemValue(strSection, "proxyaddr");
+ strTmp = pConf->getItemValue(strSection, "proxyport");
+ param.proxyPort_ = strTmp.toInt();
+ param.proxyUserName_ = pConf->getItemValue(strSection, "proxyuser");
+ param.proxyPassword_ = pConf->getItemValue(strSection, "proxypassword");
+ strTmp = pConf->getItemValue(strSection, "protocol");
+ param.protocolType_ = strTmp.toInt();
+ param.sshUserName_ = pConf->getItemValue(strSection, "sshuser");
+ param.sshPassword_ = pConf->getItemValue(strSection, "sshpassword");
+
+ strTmp = pConf->getItemValue(strSection, "maxidle");
+ param.maxIdleSeconds_ = strTmp.toInt();
+ param.replyKeyCombination_ = pConf->getItemValue(strSection, "replykey");
+ if (param.replyKeyCombination_.isNull()) {
+ Q_ASSERT(false);
+ }
+
+ param.antiIdleMessage_ = pConf->getItemValue(strSection, "antiidlestring");
+ strTmp = pConf->getItemValue(strSection, "isantiidle");
+ param.isAntiIdle_ = (strTmp != "0");
+ param.autoReplyMessage_ = pConf->getItemValue(strSection, "autoreply");
+ strTmp = pConf->getItemValue(strSection, "bautoreply");
+ param.isAutoReply_ = (strTmp != "0");
+
+ strTmp = pConf->getItemValue(strSection, "reconnect");
+ param.isAutoReconnect_ = (strTmp != "0");
+ strTmp = pConf->getItemValue(strSection, "interval");
+ param.reconnectInterval_ = strTmp.toInt();
+ strTmp = pConf->getItemValue(strSection, "retrytimes");
+ param.retryTimes_ = strTmp.toInt();
+
+ strTmp = pConf->getItemValue(strSection, "autoclosewin");
+ param.isAutoCloseWin_ = (strTmp == "1");
+
+ strTmp = pConf->getItemValue(strSection, "alignmode");
+ param.alignMode_ = strTmp.toInt();
+
+
+ strTmp = pConf->getItemValue(strSection, "charspacing");
+ param.charSpacing_ = strTmp.toInt();
+
+ strTmp = pConf->getItemValue(strSection, "linespacing");
+ param.lineSpacing_ = strTmp.toInt();
+
+ strTmp = pConf->getItemValue(strSection, "loadscript");
+ param.isAutoLoadScript_ = (strTmp != "0");
+ param.autoLoadedScriptFileName_ = pConf->getItemValue(strSection, "scriptfile");
+
+ strTmp = pConf->getItemValue(strSection, "enablezmodem");
+ param.enableZmodem_ = (strTmp != "0");
+
+ strTmp = pConf->getItemValue(strSection, "isbeep");
+ param.isBeep_ = (strTmp != "0");
+
+ strTmp = pConf->getItemValue(strSection, "isbuzz");
+ param.isBuzz_ = (strTmp != "0");
+
+ strTmp = pConf->getItemValue(strSection, "ismouse");
+ param.isSupportMouse_ = (strTmp != "0");
+
+ strTmp = pConf->getItemValue(strSection, "menutype");
+ param.menuType_ = strTmp.toInt();
+ param.menuColor_.setNamedColor(pConf->getItemValue(strSection, "menucolor"));
+
+ param.isColorCopy_ = (pConf->getItemValue(strSection, "colorcopy") != "0");
+ param.isAutoCopy_ = (pConf->getItemValue(strSection, "autocopy") != "0");
+ param.isRectSelect_ = (pConf->getItemValue(strSection, "rectselect") != "0");
+ param.isAutoWrap_ = (pConf->getItemValue(strSection, "autowrap" ) == "1");
+
+ return true;
+}
+
+void saveAddress(FQTermConfig *pConf, int n, const FQTermParam &param) {
+ QString strTmp, strSection;
+ if (n < 0) {
+ strSection = "default";
+ } else {
+ strSection.sprintf("bbs %d", n);
+ }
+
+ pConf->setItemValue(strSection, "name", param.name_);
+ pConf->setItemValue(strSection, "addr", param.hostAddress_);
+ strTmp.setNum(param.port_);
+ pConf->setItemValue(strSection, "port", strTmp);
+ strTmp.setNum(param.hostType_);
+ pConf->setItemValue(strSection, "hosttype", strTmp);
+ pConf->setItemValue(strSection, "autologin", param.isAutoLogin_ ? "1" : "0");
+ pConf->setItemValue(strSection, "prelogin", param.preLoginCommand_);
+ pConf->setItemValue(strSection, "user", param.userName_);
+ pConf->setItemValue(strSection, "password", param.password_);
+ pConf->setItemValue(strSection, "postlogin", param.postLoginCommand_);
+
+ strTmp.setNum(param.serverEncodingID_);
+ pConf->setItemValue(strSection, "bbscode", strTmp);
+ pConf->setItemValue(strSection, "autofont", strTmp.setNum(param.isFontAutoFit_));
+ pConf->setItemValue(strSection, "alwayshighlight", param.isAlwaysHighlight_ ?
+ "1" : "0");
+ pConf->setItemValue(strSection, "ansicolor", param.isAnsiColor_ ? "1" : "0");
+
+ pConf->setItemValue(strSection, FQTermParam::getLanguageName(true, false) + "fontname", param.englishFontName_);
+ strTmp.setNum(param.englishFontSize_);
+ pConf->setItemValue(strSection, FQTermParam::getLanguageName(true, false) + "fontsize", strTmp);
+
+ pConf->setItemValue(strSection, FQTermParam::getLanguageName(false, false) + "fontname", param.otherFontName_);
+ strTmp.setNum(param.otherFontSize_);
+ pConf->setItemValue(strSection, FQTermParam::getLanguageName(false, false) + "fontsize", strTmp);
+
+ pConf->setItemValue(strSection, "alignmode", strTmp.setNum(param.alignMode_));
+ pConf->setItemValue(strSection, "charspacing", strTmp.setNum(param.charSpacing_));
+ pConf->setItemValue(strSection, "linespacing", strTmp.setNum(param.lineSpacing_));
+
+ pConf->setItemValue(strSection, "bgcolor", param.backgroundColor_.name());
+ pConf->setItemValue(strSection, "fgcolor", param.foregroundColor_.name());
+
+ pConf->setItemValue(strSection, "schemafile", param.schemaFileName_);
+
+ pConf->setItemValue(strSection, "termtype", param.virtualTermType_);
+ strTmp.setNum(param.keyboardType_);
+ pConf->setItemValue(strSection, "keytype", strTmp);
+ strTmp.setNum(param.backspaceType_);
+ pConf->setItemValue(strSection, "backspacetype", strTmp);
+ strTmp.setNum(param.numColumns_);
+ pConf->setItemValue(strSection, "column", strTmp);
+ strTmp.setNum(param.numRows_);
+ pConf->setItemValue(strSection, "row", strTmp);
+ strTmp.setNum(param.numScrollLines_);
+ pConf->setItemValue(strSection, "scroll", strTmp);
+ strTmp.setNum(param.cursorType_);
+ pConf->setItemValue(strSection, "cursor", strTmp);
+ pConf->setItemValue(strSection, "escape", param.escapeString_);
+
+ strTmp.setNum(param.proxyType_);
+ pConf->setItemValue(strSection, "proxytype", strTmp);
+ pConf->setItemValue(strSection, "proxyauth", param.isAuthentation_ ? "1" : "0");
+ pConf->setItemValue(strSection, "proxyaddr", param.proxyHostName_);
+ strTmp.setNum(param.proxyPort_);
+ pConf->setItemValue(strSection, "proxyport", strTmp);
+ pConf->setItemValue(strSection, "proxyuser", param.proxyUserName_);
+ pConf->setItemValue(strSection, "proxypassword", param.proxyPassword_);
+ strTmp.setNum(param.protocolType_);
+ pConf->setItemValue(strSection, "protocol", strTmp);
+ pConf->setItemValue(strSection, "sshuser", param.sshUserName_);
+ pConf->setItemValue(strSection, "sshpassword", param.sshPassword_);
+
+ strTmp.setNum(param.maxIdleSeconds_);
+ pConf->setItemValue(strSection, "maxidle", strTmp);
+ pConf->setItemValue(strSection, "replykey", param.replyKeyCombination_);
+ pConf->setItemValue(strSection, "antiidlestring", param.antiIdleMessage_);
+ pConf->setItemValue(strSection, "isantiidle", param.isAntiIdle_?"1" : "0");
+ pConf->setItemValue(strSection, "bautoreply", param.isAutoReply_ ? "1" : "0");
+ pConf->setItemValue(strSection, "autoreply", param.autoReplyMessage_);
+ pConf->setItemValue(strSection, "reconnect", param.isAutoReconnect_? "1" : "0");
+ strTmp.setNum(param.reconnectInterval_);
+ pConf->setItemValue(strSection, "interval", strTmp);
+ strTmp.setNum(param.retryTimes_);
+ pConf->setItemValue(strSection, "retrytimes", strTmp);
+ pConf->setItemValue(strSection, "autoclosewin", param.isAutoCloseWin_? "1" : "0");
+
+ pConf->setItemValue(strSection, "loadscript", param.isAutoLoadScript_ ? "1" : "0");
+ pConf->setItemValue(strSection, "scriptfile", param.autoLoadedScriptFileName_);
+
+ pConf->setItemValue(strSection, "enablezmodem", param.enableZmodem_? "1" : "0");
+
+ pConf->setItemValue(strSection, "isbeep", param.isBeep_? "1" : "0");
+ pConf->setItemValue(strSection, "isbuzz", param.isBuzz_? "1" : "0");
+ pConf->setItemValue(strSection, "ismouse", param.isSupportMouse_? "1" : "0");
+
+ strTmp.setNum(param.menuType_);
+ pConf->setItemValue(strSection, "menutype", strTmp);
+ pConf->setItemValue(strSection, "menucolor", param.menuColor_.name());
+
+ pConf->setItemValue(strSection, "colorcopy", param.isColorCopy_? "1" : "0");
+ pConf->setItemValue(strSection, "autocopy", param.isAutoCopy_? "1" : "0");
+ pConf->setItemValue(strSection, "rectselect", param.isRectSelect_? "1" : "0");
+ pConf->setItemValue(strSection, "autowrap", param.isAutoWrap_?"1":"0");
+
+}
+
+static QString getResourceDir(const QString &prefix) {
+ QString res;
+
+ std::string fqterm_resource;
+
+ char *p = NULL;
+ if ((p = getenv("FQTERM_RESOURCE")) != NULL)
+ fqterm_resource = p;
+
+ if (fqterm_resource.size() == 0) {
+#if defined(WIN32)
+ res = prefix;
+#elif defined(__APPLE__)
+ res = prefix + "../Resources/";
+#else
+ res = prefix + "share/FQTerm/";
+#endif
+ } else {
+ res = QString::fromLocal8Bit(fqterm_resource.c_str());
+ }
+
+ if (res[res.size() - 1] != '/')
+ res += '/';
+
+ return res;
+}
+
+static QString getInstallPrefix() {
+ QString res;
+
+ std::string fqterm_prefix;
+
+ char *p = NULL;
+ if ((p = getenv("FQTERM_PREFIX")) != NULL)
+ fqterm_prefix = p;
+
+ if (fqterm_prefix.size() == 0) {
+ res = QCoreApplication::applicationDirPath() + "/";
+ } else {
+ res = QString::fromLocal8Bit(fqterm_prefix.c_str());
+ }
+
+ if (res[res.size() - 1] != '/')
+ res += '/';
+
+ return res;
+}
+
+static QString getUserDataDir() {
+ char *evnDataDir = NULL;
+ if ((evnDataDir = getenv("FQTERM_DATADIR")) != NULL) {
+ std::string fqterm_data = evnDataDir;
+ if (fqterm_data[fqterm_data.size() - 1] != '/'
+#ifdef WIN32
+ || fqterm_data[fqterm_data.size() - 1] != '\\'
+#endif
+ )
+ fqterm_data += '/';
+ if (fqterm_data.length() != 0) {
+ return QString::fromLocal8Bit(fqterm_data.c_str());
+ }
+ }
+
+#ifdef WIN32
+ char buffer[MAX_PATH];
+ SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, buffer);
+ std::string dir(buffer);
+
+ if (dir[dir.size() - 1] != '\\') {
+ dir += '\\';
+ }
+ return QString::fromLocal8Bit(dir.c_str()) + "FQTerm/";
+#else
+ char *p = NULL;
+
+ std::string home;
+ if ((p = getenv("HOME")) != NULL)
+ home = p;
+ if (home.size() == 0)
+ home = "/root/";
+
+ if (home[home.size() - 1] != '/')
+ home += '/';
+
+ return QString::fromLocal8Bit(home.c_str()) + ".fqterm/";
+#endif
+}
+
+} // namespace FQTerm
diff --git a/src/common/fqterm_path.h b/src/common/fqterm_path.h
new file mode 100644
index 0000000..08611be
--- /dev/null
+++ b/src/common/fqterm_path.h
@@ -0,0 +1,46 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_PATH_H
+#define FQTERM_PATH_H
+
+class QString;
+class QStringList;
+
+class FQTermConfig;
+class FQTermParam;
+
+namespace FQTerm {
+
+enum PathCategory {RESOURCE, USER_CONFIG};
+
+const QString &getPath(PathCategory category);
+
+bool iniSettings();
+
+void checkHelpExists(FQTermConfig*);
+void loadNameList(FQTermConfig *, QStringList &);
+bool loadAddress(FQTermConfig *, int, FQTermParam &);
+void saveAddress(FQTermConfig *, int, const FQTermParam &);
+
+void clearDir(const QString &path);
+} // namespace FQTerm
+
+#endif // FQTERM_PATH_H
diff --git a/src/common/fqterm_shortcuthelper.cpp b/src/common/fqterm_shortcuthelper.cpp
new file mode 100644
index 0000000..8c18643
--- /dev/null
+++ b/src/common/fqterm_shortcuthelper.cpp
@@ -0,0 +1,298 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+#include "fqterm_shortcuthelper.h"
+#include "fqterm_config.h"
+#include "fqterm_path.h"
+
+#include <QWidget>
+#include <QAction>
+#include <QPixmap>
+namespace FQTerm
+{
+
+FQTermShortcutHelper::FQTermShortcutHelper(FQTermConfig* config, QWidget* actionParent) :
+ config_(config),
+ actionParent_(actionParent)
+{
+ initShortcutDescriptionTable();
+}
+
+QString FQTermShortcutHelper::getShortcutText(int shortcut)
+{
+ if (!config_)
+ return "";
+ QString result = getShortcutConfig(shortcut);
+ if (result == "")
+ result = getShortcutDefaultText(shortcut);
+ else if (result == "Undefined")
+ result = "";
+ return result;
+}
+
+void FQTermShortcutHelper::initShortcutDescriptionTable()
+{
+ initShortcutDescriptionTableEntry(CONNECT, "connect", tr(""), tr("Connect Host"), "connect");
+ initShortcutDescriptionTableEntry(CASCADEWINDOWS, "cascadewindows", tr(""), tr("Cascade Windows"));
+ initShortcutDescriptionTableEntry(TILEWINDOWS, "tilewindows", tr(""), tr("Tils Windows"));
+ initShortcutDescriptionTableEntry(DISCONNECT, "disconnect", tr(""), tr("Disconnect Host"), "disconnect");
+ initShortcutDescriptionTableEntry(ADDRESSBOOK, "addressbook", tr("F2"), tr("Address Book"), "address_book");
+ initShortcutDescriptionTableEntry(QUICKLOGIN, "quicklogin", tr("F3"), tr("Quick Login"), "quick_login");
+#if defined(__APPLE__)
+ initShortcutDescriptionTableEntry(COPY, "copy", tr("Ctrl+C"), tr("Copy"), "copy");
+ initShortcutDescriptionTableEntry(PASTE, "paste", tr("Ctrl+V"), tr("Paste"), "paste");
+#else
+ initShortcutDescriptionTableEntry(COPY, "copy", tr("Ctrl+Ins"), tr("Copy"), "copy");
+ initShortcutDescriptionTableEntry(PASTE, "paste", tr("Shift+Insert"), tr("Paste"), "paste");
+#endif
+ initShortcutDescriptionTableEntry(COPYWITHCOLOR, "copywithcolor", tr(""), tr("Copy With Color"), "copy_with_color");
+ getAction(COPYWITHCOLOR)->setCheckable(true);
+ initShortcutDescriptionTableEntry(RECTANGLESELECTION, "rectangleselection", tr(""), tr("Rectangle Selection"), "rectangle_selection");
+ getAction(RECTANGLESELECTION)->setCheckable(true);
+ initShortcutDescriptionTableEntry(AUTOCOPYSELECTION, "autocopyselection", tr(""), tr("Auto Copy Selection"));
+ getAction(AUTOCOPYSELECTION)->setCheckable(true);
+ initShortcutDescriptionTableEntry(PASTEWORDWRAP, "pastewordwrap", tr(""), tr("Paste With Word Wrap"));
+ getAction(PASTEWORDWRAP)->setCheckable(true);
+ initShortcutDescriptionTableEntry(ENGLISHFONT, "englishfont", tr(""), tr("Set English Font"));
+ initShortcutDescriptionTableEntry(OTHERFONT, "nonenglishfont", tr(""), tr("Set Other Font"));
+ initShortcutDescriptionTableEntry(COLORSETTING, "colorsetting", tr(""), tr("Color Setting"), "ansi_color");
+ initShortcutDescriptionTableEntry(REFRESHSCREEN, "refreshscreen", tr(""), tr("Refresh Screen"), "refresh");
+ initShortcutDescriptionTableEntry(ANSICOLOR, "ansicolor", tr(""), tr("Toggle Ansi Color"), "toggle_ansi_color");
+ getAction(ANSICOLOR)->setCheckable(true);
+ initShortcutDescriptionTableEntry(UIFONT, "uifont", tr(""), tr("Set UI Font"));
+ initShortcutDescriptionTableEntry(FULLSCREEN, "fullscreen", tr("F6"), tr("Toggle Full Screen"));
+ getAction(FULLSCREEN)->setCheckable(true);
+ initShortcutDescriptionTableEntry(BOSSCOLOR, "bosscolor", tr("F12"), tr("Toggle Boss Color"));
+ getAction(BOSSCOLOR)->setCheckable(true);
+ initShortcutDescriptionTableEntry(SWITCHBAR, "switchbar", tr(""), tr("Toggle Switch Bar"));
+ getAction(SWITCHBAR)->setCheckable(true);
+ initShortcutDescriptionTableEntry(CURRENTSETTING, "currentsetting", tr(""), tr("Current Session Setting"), "preferences");
+ initShortcutDescriptionTableEntry(SEARCHIT, "googleit", tr("Ctrl+Alt+G"), tr("Google selected words"));
+ initShortcutDescriptionTableEntry(WEIBOSHARE, "shareit", tr("Alt+`"), tr("Share selected text and highlighted URL to weibo"));
+ initShortcutDescriptionTableEntry(EXTERNALEDITOR, "externaleditor", tr("Ctrl+Alt+E"), tr("Invoke external editor"));
+ initShortcutDescriptionTableEntry(FASTPOST, "fastpost", tr("Ctrl+Alt+F"), tr("Fast post from clipboard"));
+ initShortcutDescriptionTableEntry(DEFAULTSETTING, "defaultsetting", tr(""), tr("Default Setting"));
+ initShortcutDescriptionTableEntry(PREFERENCE, "preference", tr(""), tr("Preference"), "preferences");
+ initShortcutDescriptionTableEntry(EDITSCHEMA, "schema", tr(""), tr("Edit Schema"));
+ initShortcutDescriptionTableEntry(SHORTCUTSETTING, "shortcut", tr(""), tr("Shorcut Setting"));
+ initShortcutDescriptionTableEntry(COPYARTICLE, "copyarticle", tr("F9"), tr("Copy Article"), "get_article_fulltext");
+ initShortcutDescriptionTableEntry(ANTIIDLE, "antiidle", tr(""), tr("Toggle Anti Idle"), "anti_idle");
+ getAction(ANTIIDLE)->setCheckable(true);
+ initShortcutDescriptionTableEntry(AUTOREPLY, "autoreply", tr(""), tr("Toggle Auto Reply"), "auto_reply");
+ getAction(AUTOREPLY)->setCheckable(true);
+ initShortcutDescriptionTableEntry(VIEWMESSAGE, "viewmessage", tr("F10"), tr("View Messages"), "view_messages");
+ initShortcutDescriptionTableEntry(IPLOOKUP, "iplookup", tr(""), tr("IP Lookup"));
+ initShortcutDescriptionTableEntry(BEEP, "beep", tr(""), tr("Toggle Beep"), "beep");
+ getAction(BEEP)->setCheckable(true);
+ initShortcutDescriptionTableEntry(MOUSESUPPORT, "mousesupport", tr(""), tr("Toggle Mouse Support"), "mouse");
+ getAction(MOUSESUPPORT)->setCheckable(true);
+ initShortcutDescriptionTableEntry(IMAGEVIEWER, "imageviewer", tr(""), tr("Image Viewer"), "image_viewer");
+ initShortcutDescriptionTableEntry(RUNSCRIPT, "runscript", tr("F7"), tr("Run Script"));
+ initShortcutDescriptionTableEntry(STOPSCRIPT, "stop", tr("F8"), tr("Stop Script"));
+#ifdef HAVE_PYTHON
+ initShortcutDescriptionTableEntry(RUNPYTHONSCRIPT, "runpythonscript", tr("Ctrl+F1"), tr("Run Python Script"));
+#endif //HAVE_PYTHON
+ initShortcutDescriptionTableEntry(ABOUT, "about", tr("Shift+F1"), tr("About"));
+ initShortcutDescriptionTableEntry(HOMEPAGE, "homepage", tr(""), tr("Homepage"));
+ initShortcutDescriptionTableEntry(EXIT, "exit", tr(""), tr("Exit FQTerm"));
+ initShortcutDescriptionTableEntry(COLORCTL_NO, "colorctlno", tr(""), tr("Set Color Ctrl to None"));
+ getAction(COLORCTL_NO)->setCheckable(true);
+ initShortcutDescriptionTableEntry(COLORCTL_SMTH, "colorctlsmth", tr(""), tr("Set Color Ctrl to **["));
+ getAction(COLORCTL_SMTH)->setCheckable(true);
+ initShortcutDescriptionTableEntry(COLORCTL_PTT, "colorctlptt", tr(""), tr("Set Color Ctrl to ^u["));
+ getAction(COLORCTL_PTT)->setCheckable(true);
+ initShortcutDescriptionTableEntry(COLORCTL_OLD_CUSTOM, "colorctloldcustom", tr(""), tr("Set Color Ctrl to old custom"));
+ getAction(COLORCTL_OLD_CUSTOM)->setCheckable(true);
+ initShortcutDescriptionTableEntry(COLORCTL_CUSTOM, "colorctlcustom", tr(""), tr("Set Color Ctrl to custom"));
+ getAction(COLORCTL_CUSTOM)->setCheckable(false);
+ initShortcutDescriptionTableEntry(AUTORECONNECT, "autoreconnect", tr(""), tr("Toggle Auto Reconnect"), "auto_reconnect");
+ getAction(AUTORECONNECT)->setCheckable(true);
+ initShortcutDescriptionTableEntry(SCROLLBAR_LEFT, "scrollbarleft", tr(""), tr("Set Scrollbar to Left"));
+ getAction(SCROLLBAR_LEFT)->setCheckable(true);
+ initShortcutDescriptionTableEntry(SCROLLBAR_RIGHT, "scrollbarright", tr(""), tr("Set Scrollbar to Right"));
+ getAction(SCROLLBAR_RIGHT)->setCheckable(true);
+ initShortcutDescriptionTableEntry(SCROLLBAR_HIDDEN, "scrollbarhidden", tr(""), tr("Set Scrollbar Hidden"));
+ getAction(SCROLLBAR_HIDDEN)->setCheckable(true);
+ initShortcutDescriptionTableEntry(SEARCH_GOOGLE, "searchgoogle", tr(""), tr("Use Google"));
+ getAction(SEARCH_GOOGLE)->setCheckable(true);
+ initShortcutDescriptionTableEntry(SEARCH_BAIDU, "searchbaidu", tr(""), tr("Use Baidu"));
+ getAction(SEARCH_BAIDU)->setCheckable(true);
+ initShortcutDescriptionTableEntry(SEARCH_BING, "searchbing", tr(""), tr("Use Bing"));
+ getAction(SEARCH_BING)->setCheckable(true);
+ initShortcutDescriptionTableEntry(SEARCH_YAHOO, "searchyahoo", tr(""), tr("Use Yahoo!"));
+ getAction(SEARCH_YAHOO)->setCheckable(true);
+ initShortcutDescriptionTableEntry(SEARCH_CUSTOM, "searchcustom", tr(""), tr("Use Customized SE"));
+ getAction(SEARCH_CUSTOM)->setCheckable(true);
+ initShortcutDescriptionTableEntry(LANGUAGE_ENGLISH, "languageenglish", tr(""), tr("Choose UI Language: English"));
+ getAction(LANGUAGE_ENGLISH)->setCheckable(true);
+ initShortcutDescriptionTableEntry(SAVESETTING, "savesetting", tr(""), tr("Save Current Session Setting"), "save_setting");
+
+#if defined(__APPLE__)
+ QString opt(tr("Ctrl"));
+#else
+ QString opt(tr("Alt"));
+#endif
+
+ initShortcutDescriptionTableEntry(NEXTWINDOW, "nextwindow", opt + tr("+Right"), tr("Next Window"));
+ initShortcutDescriptionTableEntry(PREVWINDOW, "prevwindow", opt + tr("+Left"), tr("Prev Window"));
+
+ initShortcutDescriptionTableEntry(GLOBAL_SHOW_FQTERM, "showfqterm", tr("Ctrl+Alt+Q"), tr("Show FQTerm"));
+ //index, key, default shortcut, descritption
+
+ retranslateActions();
+}
+
+void FQTermShortcutHelper::retranslateAction(int shortcut, const QString& text)
+{
+ if (getAction(shortcut))
+ getAction(shortcut)->setText(text);
+}
+
+void FQTermShortcutHelper::retranslateActions() {
+ retranslateAction(CONNECT, tr("&Connect"));
+ retranslateAction(DISCONNECT, tr("&Disconnect"));
+ retranslateAction(ADDRESSBOOK, tr("&Address book"));
+ retranslateAction(QUICKLOGIN, tr("&Quick login"));
+ retranslateAction(COPY, tr("&Copy"));
+ retranslateAction(PASTE, tr("&Paste"));
+ retranslateAction(COPYWITHCOLOR, tr("C&opy with color"));
+ retranslateAction(RECTANGLESELECTION, tr("&Rectangle select"));
+ retranslateAction(AUTOCOPYSELECTION, tr("Auto copy &select"));
+ retranslateAction(PASTEWORDWRAP, tr("P&aste with wordwrap"));
+ retranslateAction(ENGLISHFONT, tr("&English Font"));
+ retranslateAction(OTHERFONT, tr("O&ther Font"));
+ retranslateAction(COLORSETTING, tr("&Color Setting"));
+ retranslateAction(ANSICOLOR, tr("&Use ANSI Color"));
+ retranslateAction(REFRESHSCREEN, tr("&Refresh"));
+ retranslateAction(UIFONT, tr("U&I font"));
+ retranslateAction(FULLSCREEN, tr("Fullscree&n"));
+ retranslateAction(BOSSCOLOR, tr("B&oss Color"));
+ retranslateAction(SWITCHBAR, tr("S&witch Bar"));
+ retranslateAction(SEARCHIT, tr("&Search It"));
+ retranslateAction(WEIBOSHARE, tr("Sha&re It"));
+ retranslateAction(EXTERNALEDITOR, tr("E&xternal Editor"));
+ retranslateAction(FASTPOST, tr("&Fast Post"));
+ retranslateAction(CURRENTSETTING, tr("&Setting for current session"));
+ retranslateAction(DEFAULTSETTING, tr("&Default setting"));
+ retranslateAction(PREFERENCE, tr("&Preferences..."));
+ retranslateAction(SHORTCUTSETTING, tr("Short&cut Setting"));
+ retranslateAction(EDITSCHEMA, tr("&Edit Schema"));
+ retranslateAction(COPYARTICLE, tr("&Copy article"));
+ retranslateAction(ANTIIDLE, tr("Anti &idle"));
+ retranslateAction(AUTOREPLY, tr("Auto &reply"));
+ retranslateAction(VIEWMESSAGE, tr("&View messages"));
+ retranslateAction(IPLOOKUP, tr("I&P Lookup"));
+ retranslateAction(BEEP, tr("&Beep"));
+ retranslateAction(MOUSESUPPORT, tr("&Mouse support"));
+ retranslateAction(IMAGEVIEWER, tr("Ima&ge viewer"));
+ retranslateAction(RUNSCRIPT, tr("&Run..."));
+ retranslateAction(STOPSCRIPT, tr("&Stop"));
+ retranslateAction(RUNPYTHONSCRIPT, tr("Run &Python..."));
+ retranslateAction(ABOUT, tr("About &FQTerm"));
+ retranslateAction(HOMEPAGE, tr("FQTerm's &Homepage"));
+ retranslateAction(CASCADEWINDOWS, tr("&Cascade"));
+ retranslateAction(TILEWINDOWS, tr("&Tile"));
+ retranslateAction(EXIT, tr("&Exit"));
+ retranslateAction(COLORCTL_NO, tr("&None"));
+ retranslateAction(COLORCTL_SMTH, tr("&ESC ESC ["));
+ retranslateAction(COLORCTL_PTT, tr("Ctrl+&U["));
+ retranslateAction(COLORCTL_CUSTOM, tr("&Custom..."));
+ retranslateAction(AUTORECONNECT, tr("Reconnect When Disconnected By Host"));
+ retranslateAction(NEXTWINDOW, tr("Next Window"));
+ retranslateAction(PREVWINDOW, tr("Prev Window"));
+ retranslateAction(LANGUAGE_ENGLISH, tr("&English"));
+ retranslateAction(SCROLLBAR_HIDDEN, tr("&Hide"));
+ retranslateAction(SCROLLBAR_RIGHT, tr("&Right"));
+ retranslateAction(SCROLLBAR_LEFT, tr("&Left"));
+ retranslateAction(SEARCH_GOOGLE, tr("&Google"));
+ retranslateAction(SEARCH_BAIDU, tr("&Baidu"));
+ retranslateAction(SEARCH_BING, tr("&Bing"));
+ retranslateAction(SEARCH_YAHOO, tr("&Yahoo!"));
+ retranslateAction(SEARCH_CUSTOM, tr("&Custom"));
+ retranslateAction(SAVESETTING, tr("Save Settin&g"));
+}
+
+
+void FQTermShortcutHelper::resetAllShortcutText()
+{
+ for (int i = FQTERM_APPLICATION_SHORTCUT_START + 1; i < FQTERM_APPLICATION_SHORTCUT_END; ++i)
+ {
+ resetShortcutText(i);
+ }
+}
+
+void FQTermShortcutHelper::resetShortcutText(int shortcut)
+{
+ if (!config_)
+ return;
+ setShortcutText(shortcut, getShortcutDefaultText(shortcut));
+}
+
+void FQTermShortcutHelper::setShortcutText(int shortcut, const QString& text)
+{
+ if (!config_)
+ return;
+ QString val = text.trimmed();
+ if (val == "")
+ val = "Undefined";
+ setShortcutConfig(shortcut, val);
+ if (getAction(shortcut))
+ getAction(shortcut)->setShortcut(val);
+}
+
+FQTermShortcutHelper::~FQTermShortcutHelper()
+{
+}
+
+QString FQTermShortcutHelper::getShortcutConfig(int shortcut)
+{
+ return config_->getItemValue(getShortcutSection(), getShortcutKey(shortcut));
+}
+
+void FQTermShortcutHelper::setShortcutConfig(int shortcut, const QString& text)
+{
+ config_->setItemValue(getShortcutSection(), getShortcutKey(shortcut), text);
+}
+
+void FQTermShortcutHelper::initShortcutDescriptionTableEntry(int index, const QString& key, const QString& defaultshortcuttext, const QString& description, const QString& actionSkin) {
+ shortcutDescriptionTable_[index] = ShortcutDescriptionEntry(key, defaultshortcuttext, description);
+ shortcutDescriptionTable_[index].action_ = new QAction(actionParent_);
+ if (actionParent_) {
+ actionParent_->addAction(shortcutDescriptionTable_[index].action_);
+ }
+ shortcutDescriptionTable_[index].action_->setShortcut(getShortcutText(index));
+ if (actionSkin != QString::null)
+ shortcutDescriptionTable_[index].action_->setIcon(QPixmap(getPath(RESOURCE) + "pic/" + actionSkin + ".png"));
+}
+
+
+FQTermShortcutHelper::ShortcutDescriptionEntry::ShortcutDescriptionEntry(const QString& key /*= QString("")*/,
+ const QString& defaultshortcuttext /*= QString("")*/,
+ const QString& description /*= QString("")*/) :
+ key_(key),
+ defaultshortcuttext_(defaultshortcuttext),
+ description_(description),
+ action_(NULL) {}
+
+FQTermShortcutHelper::ShortcutDescriptionEntry::~ShortcutDescriptionEntry() {
+ delete action_;
+}
+}//namespace FQTerm
+
+#include "fqterm_shortcuthelper.moc" \ No newline at end of file
diff --git a/src/common/fqterm_shortcuthelper.h b/src/common/fqterm_shortcuthelper.h
new file mode 100644
index 0000000..7e77df7
--- /dev/null
+++ b/src/common/fqterm_shortcuthelper.h
@@ -0,0 +1,175 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef __FQTERM_SHORTCUTHELPER__
+#define __FQTERM_SHORTCUTHELPER__
+
+#include "fqterm.h"
+#include <QObject>
+#include <QString>
+#include <QMap>
+
+class QWidget;
+class QAction;
+namespace FQTerm
+{
+class FQTermConfig;
+
+
+#define FQTERM_ADDACTION(WIDGET, NAME, RECEIVER, FUNCTION) \
+ do{ \
+ QAction *action = getAction((FQTermShortcutHelper::NAME));\
+ QObject::disconnect(action, SIGNAL(triggered()), (RECEIVER), SLOT(FUNCTION())); \
+ FQ_VERIFY(connect(action, SIGNAL(triggered()), (RECEIVER), SLOT(FUNCTION()))); \
+ (WIDGET)->addAction(action);\
+ } while(0)
+
+
+
+class FQTermShortcutHelper : public QObject
+{
+ Q_OBJECT;
+public:
+ enum FQTERM_SHORTCUT
+ {
+ FQTERM_APPLICATION_SHORTCUT_START = 0,
+ CONNECT,
+ DISCONNECT,
+ ADDRESSBOOK, //F2
+ QUICKLOGIN, //F3
+ COPY, //Ctrl+Ins under lin & win, Ctrl+C under mac
+ PASTE, //Shift+Insert under lin & win, Ctrl+V under mac
+ COPYWITHCOLOR,
+ RECTANGLESELECTION,
+ AUTOCOPYSELECTION,
+ PASTEWORDWRAP,
+ ENGLISHFONT,
+ OTHERFONT,
+ COLORSETTING,
+ ANSICOLOR,
+ REFRESHSCREEN, //F5
+ UIFONT,
+ FULLSCREEN, //F6
+ BOSSCOLOR, //F12
+ SWITCHBAR,
+ SEARCHIT, //Ctrl+Alt+G
+ WEIBOSHARE,
+ EXTERNALEDITOR, //Ctrl+Alt+E
+ FASTPOST, //Ctrl+Alt+F
+ CURRENTSETTING,
+ DEFAULTSETTING,
+ SAVESETTING,
+ PREFERENCE,
+ SHORTCUTSETTING,
+ EDITSCHEMA,
+ COPYARTICLE, //F9
+ ANTIIDLE,
+ AUTOREPLY,
+ VIEWMESSAGE, //F10
+ IPLOOKUP,
+ BEEP,
+ MOUSESUPPORT,
+ IMAGEVIEWER,
+ RUNSCRIPT, //F7
+ STOPSCRIPT, //F8
+ RUNPYTHONSCRIPT, //Ctrl+F1
+ ABOUT, //F1
+ HOMEPAGE,
+ CASCADEWINDOWS,
+ TILEWINDOWS,
+ EXIT,
+ COLORCTL_NO,
+ COLORCTL_SMTH,
+ COLORCTL_PTT,
+ COLORCTL_OLD_CUSTOM,
+ COLORCTL_CUSTOM,
+ AUTORECONNECT,
+ SCROLLBAR_LEFT,
+ SCROLLBAR_RIGHT,
+ SCROLLBAR_HIDDEN,
+ SEARCH_GOOGLE,
+ SEARCH_BAIDU,
+ SEARCH_BING,
+ SEARCH_YAHOO,
+ SEARCH_CUSTOM,
+ LANGUAGE_ENGLISH,
+ NEXTWINDOW,
+ PREVWINDOW,
+ GLOBAL_SHOW_FQTERM,
+ FQTERM_APPLICATION_SHORTCUT_END,
+ };
+
+
+public:
+ FQTermShortcutHelper(FQTermConfig* config, QWidget* actionParent);
+ ~FQTermShortcutHelper();
+
+private:
+ struct ShortcutDescriptionEntry
+ {
+ ShortcutDescriptionEntry(const QString& key = QString(""), const QString& defaultshortcuttext = QString(""), const QString& description = QString(""));
+ ~ShortcutDescriptionEntry();
+ QString key_;
+ QString defaultshortcuttext_;
+ QString description_;
+ QAction* action_;
+ };
+ void initShortcutDescriptionTable();
+ FQTermConfig* config_;
+ QWidget* actionParent_;
+ QMap<int, ShortcutDescriptionEntry> shortcutDescriptionTable_;
+ void initShortcutDescriptionTableEntry(int index, const QString& key, const QString& defaultshortcuttext, const QString& description, const QString& actionSkin = QString::null);
+
+public:
+
+ QString getShortcutText(int shortcut) ;
+ QString getShortcutDescription(int shortcut) {
+ return shortcutDescriptionTable_[shortcut].description_;
+ }
+ QString getShortcutDefaultText(int shortcut) {
+ return shortcutDescriptionTable_[shortcut].defaultshortcuttext_;
+ }
+ void setShortcutText(int shortcut, const QString& text);
+ void resetShortcutText(int shortcut);
+ void resetAllShortcutText();
+
+ QAction* getAction(int shortcut) {
+ return shortcutDescriptionTable_[shortcut].action_;
+ }
+ void retranslateActions();
+private:
+ //These functions are used to save shortcut
+ QString getShortcutSection() {
+ return QString("shortcutsettings");
+ }
+ QString getShortcutKey(int shortcut) {
+ return shortcutDescriptionTable_[shortcut].key_;
+ }
+
+ QString getShortcutConfig(int shortcut);
+ void setShortcutConfig(int shortcut, const QString& text);
+ void retranslateAction(int shortcut, const QString& text);
+};
+
+
+}//namespace FQTerm
+
+
+#endif
diff --git a/src/common/fqterm_sound.cpp b/src/common/fqterm_sound.cpp
new file mode 100644
index 0000000..96bcc83
--- /dev/null
+++ b/src/common/fqterm_sound.cpp
@@ -0,0 +1,733 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QSound>
+#include <QFile>
+#include <QMessageBox>
+#include <stdio.h>
+#include <stdlib.h>
+
+/*******************************************************/
+/********** OSS code is from OpenSound System **********/
+/*******************************************************/
+#ifdef AUDIO_OSS
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#if defined(_OS_FREEBSD_) || defined(_OS_LINUX_)
+#include <sys/soundcard.h>
+#define FQ_AUDIO_DEV "/dev/dsp"
+#else
+#include <machine/soundcard.h>
+#define FQ_AUDIO_DEV "/dev/audio"
+#endif
+
+#define WAVE_FORMAT_PCM 0x0001
+#define WAVE_FORMAT_ADPCM 0x0002
+#define WAVE_FORMAT_ALAW 0x0006
+#define WAVE_FORMAT_MULAW 0x0007
+#define WAVE_FORMAT_IMA_ADPCM 0x0011
+
+#ifndef AFMT_S32_LE
+#define AFMT_S32_LE 0x00001000 /* Little endian signed 32-bit */
+#endif
+
+typedef struct {
+ int coeff1, coeff2;
+} adpcm_coeff;
+
+#endif /* AUDIO_OSS */
+
+/* 2008.07.06, ecore.cn@gmail.com, alsa sound for FQTerm ... */
+#ifdef AUDIO_ALSA
+#include <alsa/asoundlib.h>
+#include <stdint.h>
+typedef struct tag_FQ_WAVE_FILE_HEADER {
+ uint32_t rid; /* RIFF ID */
+ uint32_t rsz; /* RIFF SIZE */
+ uint32_t wid; /* WAVE ID */
+}
+FQWFH;
+
+typedef struct tag_FQ_WAVE_FORMAT_HEADER {
+ uint32_t fid; /* FORMAT ID */
+ uint32_t fsz; /* FORMAT SIZE */
+ uint16_t aid; /* AUDIO ID */
+ uint16_t ach; /* AUDIO CHANNELS */
+ uint32_t asr; /* AUDIO SAMPLE RATE */
+ uint32_t abr; /* AUDIO BYTE RATE */
+ uint16_t aba; /* AUDIO BLOCK ALIGNMENT */
+ uint16_t abps; /* AUDIO BITS PER SAMPLE */
+}
+FQWMH;
+
+typedef struct tag_FQ_WAVE_DATA_HEADER {
+ uint32_t did; /* DATA ID */
+ uint32_t dsz; /* DATA SIZE */
+}
+FQWDH;
+
+#endif /* AUDIO_ALSA */
+
+#include "common.h"
+#include "fqterm_sound.h"
+
+namespace FQTerm {
+
+FQTermSound::FQTermSound(const QString &filename, QObject *parent,
+ const char *name)
+ : QThread(parent), soundFile_(filename) {
+ connect(this, SIGNAL(finished()), SLOT(deleteInstance()));
+ connect(this, SIGNAL(terminated()), SLOT(deleteInstance()));
+}
+
+FQTermSound::~FQTermSound() {
+}
+
+void FQTermSound::deleteInstance() {
+ FQ_TRACE("sound", 3) << "sound instance [" << (void*)this << "] is to be deleted!";
+ delete this;
+}
+
+void FQTermSound::run() {
+ if (QFile::exists(soundFile_)) {
+#if !defined(AUDIO_OSS) && !defined(AUDIO_ALSA)
+ QSound::play(soundFile_);
+#else
+ this->play();
+#endif
+ }
+}
+
+void FQTermExternalSound::setPlayer(const QString &playername) {
+ playerName_ = playername;
+}
+
+void FQTermExternalSound::play() {
+ if (QFile::exists(soundFile_)) {
+ runProgram(playerName_, soundFile_, false);
+ }
+}
+
+/*******************************************************/
+/********** OSS code is from OpenSound System **********/
+/*******************************************************/
+#ifdef AUDIO_OSS
+static int le_int (unsigned char *p, int l) {
+
+ int i, val;
+ val = 0;
+
+ for (i = l - 1; i >= 0; i--) {
+ val = (val << 8) | p[i];
+ }
+
+ return val;
+}
+
+static int setupDevice(int audiofd, int channels, int bits, int speed) {
+
+ int tmp;
+
+ tmp = bits;
+ if (ioctl(audiofd, SNDCTL_DSP_SETFMT, &tmp) == -1) {
+ return 0;
+ }
+
+ if (tmp != bits) {
+ return 0;
+ }
+
+ tmp = channels;
+ if (ioctl(audiofd, SNDCTL_DSP_CHANNELS, &tmp) == -1) {
+ return 0;
+ }
+
+ if (tmp != channels) {
+ return 0;
+ }
+
+ tmp = speed;
+ if (ioctl(audiofd, SNDCTL_DSP_SPEED, &tmp) == -1) {
+ return 0;
+ }
+
+ return 1;
+}
+
+static void dumpData(int audiofd, int soundfd, int filesize) {
+
+ int bsize, l;
+ unsigned char buf[1024];
+ bsize = sizeof(buf);
+
+ while (filesize) {
+
+ l = bsize;
+
+ if (l > filesize) {
+ l = filesize;
+ }
+
+ if ((l = read(soundfd, buf, l)) <= 0) {
+ return;
+ }
+
+ if (write(audiofd, buf, l) == -1) {
+ return;
+ }
+
+ filesize -= l;
+ }
+}
+
+static void dumpData24 (int audiofd, int soundfd, int filesize) {
+
+ int bsize, i, l;
+ unsigned char buf[1024];
+ int outbuf[1024], outlen=0;
+ int sample_s32;
+ bsize = sizeof(buf);
+
+ filesize -= filesize % 3;
+
+ while(filesize >= 3) {
+
+ l = bsize - bsize % 3;
+ if (l > filesize) {
+ l = filesize;
+ }
+
+ if(l < 3) {
+ break;
+ }
+
+ if ((l = read(soundfd, buf, l)) <= 0) {
+ return;
+ }
+
+ outlen=0;
+
+ for(i=0; i<l; i+= 3) {
+
+ unsigned int *u32 = (unsigned int *)&sample_s32; /* Alias */
+
+ /* Read the litle endian input samples */
+ *u32 = (buf[i] << 8) | (buf[i+1] << 16) | (buf[i+2]<<24);
+ outbuf[outlen++]=sample_s32;
+
+ }
+
+ if (write(audiofd, outbuf, outlen*sizeof(int)) == -1) {
+ return;
+ }
+
+ filesize -= l;
+ }
+}
+
+static void playAdpcmWave(int audiofd, int soundfd, unsigned char *hdr, int l) {
+
+ int i, n, dataleft, x;
+
+ adpcm_coeff coeff[32];
+ static int AdaptionTable[] = { 230, 230, 230, 230, 307, 409, 512, 614,
+ 768, 614, 512, 409, 307, 230, 230, 230
+ };
+
+ unsigned char buf[4096];
+
+ int channels = 1;
+ int bits = 8;
+ int speed = 11025;
+ int p = 12, max, outp;
+ int nBlockAlign, wSamplesPerBlock, wNumCoeff;
+ int fmt = -1;
+ int nib;
+
+ unsigned char outbuf[64 * 1024];
+
+ while (p < l - 16 && memcmp(&hdr[p], "data", 4) != 0) {
+
+ n = le_int(&hdr[p + 4], 4);
+ if (memcmp(&hdr[p], "fmt ", 4) == 0) {
+
+ fmt = le_int(&hdr[p + 8], 2);
+ channels = le_int(&hdr[p + 10], 2);
+ speed = le_int(&hdr[p + 12], 4);
+ nBlockAlign = le_int(&hdr[p + 20], 2);
+ bits = AFMT_S16_LE;
+ wSamplesPerBlock = le_int(&hdr[p + 26], 2);
+ wNumCoeff = le_int(&hdr[p + 28], 2);
+
+ x = p + 30;
+
+ for (i = 0; i < wNumCoeff; i++) {
+
+ coeff[i].coeff1 = (short)le_int(&hdr[x], 2);
+ x += 2;
+ coeff[i].coeff2 = (short)le_int(&hdr[x], 2);
+ x += 2;
+ }
+ }
+
+ p += n + 8;
+ }
+
+ if (p < l - 16 && memcmp(&hdr[p], "data", 4) == 0) {
+
+ dataleft = n = le_int(&hdr[p + 4], 4);
+ p += 8;
+
+ if (lseek(soundfd, p, SEEK_SET) == -1) {
+ return;
+ }
+
+ if (fmt != WAVE_FORMAT_ADPCM) {
+ return;
+ }
+
+ if (!setupDevice(audiofd, channels, bits, speed)) {
+ return;
+ }
+
+#define OUT_SAMPLE(s) { \
+ if (s>32767)s=32767;else if(s<-32768)s=-32768; \
+ outbuf[outp++] = (unsigned char)(s & 0xff); \
+ outbuf[outp++] = (unsigned char)((s>>8) & 0xff); \
+ n+=2; \
+ if (outp>=max){write(audiofd, outbuf, outp);outp=0;}\
+ }
+
+#define GETNIBBLE \
+ ((nib==0) ? \
+ (buf[x + nib++] >> 4) & 0x0f : \
+ buf[x++ + --nib] & 0x0f \
+ )
+
+ max = 1024;
+ outp = 0;
+
+ while (dataleft > nBlockAlign &&
+ read(soundfd, buf, nBlockAlign) == nBlockAlign) {
+
+ int predictor[2], delta[2], samp1[2], samp2[2];
+ int x = 0;
+ dataleft -= nBlockAlign;
+
+ nib = 0;
+ n = 0;
+
+ for (i = 0; i < channels; i++) {
+ predictor[i] = buf[x];
+ x++;
+ }
+
+ for (i = 0; i < channels; i++) {
+ delta[i] = (short)le_int(&buf[x], 2);
+ x += 2;
+ }
+
+ for (i = 0; i < channels; i++) {
+ samp1[i] = (short)le_int(&buf[x], 2);
+ x += 2;
+ OUT_SAMPLE(samp1[i]);
+ }
+
+ for (i = 0; i < channels; i++) {
+ samp2[i] = (short)le_int(&buf[x], 2);
+ x += 2;
+ OUT_SAMPLE(samp2[i]);
+ }
+
+ while (n < (wSamplesPerBlock * 2 * channels)) {
+
+ for (i = 0; i < channels; i++) {
+
+ int pred, new_pred, error_delta, i_delta;
+
+ pred = ((samp1[i] * coeff[predictor[i]].coeff1)
+ + (samp2[i] * coeff[predictor[i]].coeff2)) / 256;
+ i_delta = error_delta = GETNIBBLE;
+
+ if (i_delta & 0x08) {
+ i_delta -= 0x10; /* Convert to signed */
+ }
+
+ new_pred = pred + (delta[i] * i_delta);
+ OUT_SAMPLE(new_pred);
+
+ delta[i] = delta[i] * AdaptionTable[error_delta] / 256;
+ if (delta[i] < 16) {
+ delta[i] = 16;
+ }
+
+ samp2[i] = samp1[i];
+ samp1[i] = new_pred;
+ }
+ }
+ }
+ }
+
+ if (outp > 0) {
+ write (audiofd, outbuf, outp /*(outp+3) & ~3 */ );
+ }
+}
+
+static void playWave(int audiofd, int soundfd, unsigned char *hdr, int l) {
+
+ int filelen;
+ int n;
+ int channels = 1;
+ int bits = 8;
+ int file_bits = 8;
+ int speed = 11025;
+ int p = 12;
+ int fmt = -1;
+
+ filelen = le_int(&hdr[4], 4);
+
+ while(p < l - 16 && memcmp(&hdr[p], "data", 4) != 0) {
+
+ n = le_int(&hdr[p + 4], 4);
+
+ if (memcmp(&hdr[p], "fmt ", 4) == 0) {
+
+ fmt = le_int(&hdr[p + 8], 2);
+ channels = le_int(&hdr[p + 10], 2);
+ speed = le_int(&hdr[p + 12], 4);
+ bits = le_int(&hdr[p + 22], 2);
+
+ if (fmt == WAVE_FORMAT_ADPCM) {
+ playAdpcmWave(audiofd, soundfd, hdr, l);
+ return;
+ }
+
+ p += n + 8;
+ } else {
+ break;
+ }
+ }
+
+ if (p < l - 16 && memcmp(&hdr[p], "data", 4) == 0) {
+
+ n = le_int(&hdr[p + 4], 4);
+ p += 8;
+
+ if (lseek(soundfd, p, SEEK_SET) == -1) {
+ return;
+ }
+
+ if (fmt != WAVE_FORMAT_PCM) {
+ switch (fmt) {
+ case WAVE_FORMAT_ALAW:
+ bits = AFMT_A_LAW;
+ break;
+ case WAVE_FORMAT_MULAW:
+ bits = AFMT_MU_LAW;
+ break;
+ case WAVE_FORMAT_IMA_ADPCM:
+ bits = AFMT_IMA_ADPCM;
+ break;
+ default:
+ return;
+ }
+ }
+
+ file_bits = bits;
+
+ if (bits == 32) {
+ bits = AFMT_S32_LE;
+ } else if (bits == 24) {
+ bits = AFMT_S32_LE;
+ }
+
+ if (!setupDevice(audiofd, channels, bits, speed)) {
+ return;
+ }
+
+ if (file_bits != 24) {
+ dumpData (audiofd, soundfd, n);
+ } else {
+ dumpData24 (audiofd, soundfd, n);
+ }
+ }
+}
+#endif /* AUDIO_OSS */
+
+void FQTermSystemSound::play() {
+
+#ifdef AUDIO_OSS
+ int audio_fd = -1;
+ if ((audio_fd = open(FQ_AUDIO_DEV, O_WRONLY, 0)) == -1) {
+ FQ_TRACE("sound", 0) << "Error opening device: " << FQ_AUDIO_DEV;
+ return;
+ }
+
+ int sound_fd = -1;
+ QFile soundFile(soundFile_);
+
+ if (soundFile.open(QFile::ReadOnly)) {
+ sound_fd = soundFile.handle();
+ } else {
+ FQ_TRACE("sound", 0) << "Error opening file: " << soundFile_;
+ close(audio_fd);
+ return;
+ }
+
+ int l;
+ unsigned char sound_buf[1024];
+
+ if ((l = read(sound_fd, sound_buf, sizeof(sound_buf))) == -1) {
+ FQ_TRACE("sound", 0) << "Error reading file into buffer." << soundFile_;
+ soundFile.close();
+ close(audio_fd);
+ return;
+ }
+
+ if (l == 0) {
+ FQ_TRACE("sound", 0) << "Empty file: " << soundFile_;
+ soundFile.close();
+ close(audio_fd);
+ return;
+ }
+
+ lseek(sound_fd, 0, SEEK_SET); /* Start from the beginning */
+
+ if (l > 16 &&
+ memcmp(&sound_buf[0], "RIFF", 4) == 0 && memcmp(&sound_buf[8], "WAVE", 4) == 0) {
+
+ playWave(audio_fd, sound_fd, sound_buf, l);
+ } else {
+ FQ_TRACE("sound", 0) << "We play WAVE files only: " << soundFile_;
+ }
+
+ soundFile.close();
+ close(audio_fd);
+
+#undef OUTSAMPLE
+#undef GETNIBBLE
+#endif /* AUDIO_OSS */
+
+/* 2008.07.06, ecore.cn@gmail.com, alsa sound for FQTerm ... */
+#ifdef AUDIO_ALSA
+ FILE *fp;
+ FQWFH wfh;
+ FQWMH wmh;
+ FQWDH wdh;
+ int endian, sz, len, count, ret;
+ unsigned int val;
+ snd_pcm_t *handle;
+ snd_pcm_hw_params_t *hwparams;
+ snd_pcm_sw_params_t *swparams;
+ snd_pcm_format_t format;
+ snd_pcm_uframes_t csz, vsz;
+ void *data;
+
+#define WAVE_UINT16(_x) (endian? ( \
+ (((_x) & 0x00FF) << 8) | \
+ (((_x) & 0xFF00) >> 8)): \
+ (_x))
+
+#define WAVE_UINT32(_x) (endian? ( \
+ (((_x) & 0x000000FF) << 24) | \
+ (((_x) & 0x0000FF00) << 8) | \
+ (((_x) & 0x00FF0000) >> 8) | \
+ (((_x) & 0xFF000000) >> 24)): \
+ (_x))
+
+ do {
+ if ((fp = fopen(this->soundFile_.toLocal8Bit(), "r")) == NULL) {
+ continue;
+ }
+
+ if (fread(&wfh, sizeof(FQWFH), 1, fp) != 1) {
+ continue;
+ }
+
+ switch (wfh.rid) {
+ case 0x52494646:
+ endian = 1; /* Big-Endian */
+ break;
+ case 0x46464952:
+ endian = 0; /* Small-Endian */
+ break;
+ default:
+ continue;
+ }
+
+ if (WAVE_UINT32(wfh.wid) != 0x45564157) { /* "WAVE" */
+ continue;
+ }
+
+ if (fread(&wmh, sizeof(FQWMH), 1, fp) != 1) {
+ continue;
+ }
+
+ if (WAVE_UINT32(wmh.fid) != 0x20746d66) { /* "FMT " */
+ continue;
+ }
+
+ if (WAVE_UINT32(wmh.fsz) != 16 || WAVE_UINT16(wmh.aid) != 1) { /* PCM */
+ continue;
+ }
+
+ if (fread(&wdh, sizeof(FQWDH), 1, fp) != 1) {
+ continue;
+ }
+
+ if (WAVE_UINT32(wdh.did) != 0x61746164) { /* "DATA" */
+ continue;
+ }
+
+ if (snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0) < 0) {
+ continue;
+ }
+
+ snd_pcm_hw_params_alloca(&hwparams);
+ snd_pcm_sw_params_alloca(&swparams);
+
+ if (snd_pcm_hw_params_any(handle, hwparams) < 0) {
+ continue;
+ }
+
+ if (snd_pcm_hw_params_set_access(handle, hwparams,
+ SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
+ continue;
+ }
+
+ switch(WAVE_UINT16(wmh.abps)) {
+ case 8:
+ format = SND_PCM_FORMAT_U8;
+ break;
+ case 16:
+ format = SND_PCM_FORMAT_S16_LE;
+ break;
+ case 24:
+ switch (WAVE_UINT16(wmh.aba) / WAVE_UINT16(wmh.ach)) {
+ case 3:
+ format = SND_PCM_FORMAT_S24_3LE;
+ break;
+ case 4:
+ format = SND_PCM_FORMAT_S24_LE;
+ break;
+ default:
+ continue;
+ }
+
+ break;
+ case 32:
+ format = SND_PCM_FORMAT_S32_LE;
+ break;
+ default:
+ continue;
+ }
+
+ if (snd_pcm_hw_params_set_format(handle, hwparams, format) < 0) {
+ continue;
+ }
+
+ if (snd_pcm_hw_params_set_channels(handle, hwparams,
+ WAVE_UINT16(wmh.ach)) < 0) {
+ continue;
+ }
+
+ val = WAVE_UINT32(wmh.asr);
+
+ if (snd_pcm_hw_params_set_rate_near(handle, hwparams, &val, NULL) < 0) {
+ continue;
+ }
+
+ if (snd_pcm_hw_params(handle, hwparams) < 0) {
+ continue;
+ }
+
+ snd_pcm_hw_params_get_period_size(hwparams, &csz, NULL);
+ snd_pcm_hw_params_get_buffer_size(hwparams, &vsz);
+
+ if (csz == vsz) {
+ continue;
+ }
+
+ snd_pcm_sw_params_current(handle, swparams);
+
+ if (snd_pcm_sw_params_set_avail_min(handle, swparams, csz) < 0) {
+ continue;
+ }
+
+ if (snd_pcm_sw_params_set_start_threshold(handle, swparams, vsz) < 0) {
+ continue;
+ }
+
+ if (snd_pcm_sw_params_set_stop_threshold(handle, swparams, vsz) < 0) {
+ continue;
+ }
+
+ if (snd_pcm_sw_params(handle, swparams) < 0) {
+ continue;
+ }
+
+ sz = csz * snd_pcm_format_physical_width(format)
+ * WAVE_UINT16(wmh.ach) / 8;
+
+ if ((data = malloc(sz)) == NULL) {
+ continue;
+ }
+
+ len = WAVE_UINT32(wdh.dsz);
+
+ while (len > 0) {
+ count = (len < sz)? len: sz;
+
+ ret = fread(data, 1, count, fp);
+
+ len -= ret;
+
+ if (ret != count) {
+ continue;
+ }
+
+ count = ret * csz / sz;
+
+ ret = snd_pcm_writei(handle, data, count);
+
+ if (ret == -EAGAIN || (ret >= 0 && ret < count)) {
+ snd_pcm_wait(handle, 200);
+ }
+ }
+
+ free(data);
+
+ snd_pcm_drain(handle);
+ snd_pcm_close(handle);
+
+ fclose(fp);
+ }
+ while (0);
+
+#undef WAVE_UINT16
+#undef WAVE_UINT32
+#endif /* AUDIO_ALSA */
+}
+
+} // namespace FQTerm
+
+#include "fqterm_sound.moc"
diff --git a/src/common/fqterm_sound.h b/src/common/fqterm_sound.h
new file mode 100644
index 0000000..ab18645
--- /dev/null
+++ b/src/common/fqterm_sound.h
@@ -0,0 +1,79 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SOUND_H
+#define FQTERM_SOUND_H
+
+#include <QObject>
+#include <QString>
+#include <QThread>
+
+#include "fqterm.h"
+
+namespace FQTerm {
+// By using QThread, we avoid blocking the main app.
+// FIXME: However, whichever play method we use (ext|int),
+// there are some WAVE files we can't play...
+
+class FQTermSound: public QThread {
+ Q_OBJECT;
+
+ public:
+ FQTermSound(const QString &filename, QObject *parent = 0,
+ const char *name = 0);
+
+ ~FQTermSound();
+
+ public slots:
+ void deleteInstance();
+
+ protected:
+ QString soundFile_;
+ virtual void play() = 0;
+ void run();
+};
+
+class FQTermSystemSound: public FQTermSound {
+ public:
+ FQTermSystemSound(const QString &filename, QObject *parent = 0,
+ const char *name = 0)
+ : FQTermSound(filename, parent, name) {
+ }
+
+ protected:
+ void play();
+};
+
+class FQTermExternalSound: public FQTermSound {
+ public:
+ FQTermExternalSound(const QString &playername, const QString &filename,
+ QObject *parent = 0, const char *name = 0)
+ : FQTermSound(filename, parent, name), playerName_(playername) {
+ }
+
+ protected:
+ QString playerName_;
+ void play();
+ void setPlayer(const QString &playername);
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SOUND_H
diff --git a/src/common/fqterm_trace.cpp b/src/common/fqterm_trace.cpp
new file mode 100644
index 0000000..867b7ad
--- /dev/null
+++ b/src/common/fqterm_trace.cpp
@@ -0,0 +1,328 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <string>
+
+#ifdef WIN32
+#include <hash_set>
+#else
+#include <set>
+#endif
+
+#include "fqterm_trace.h"
+
+namespace FQTerm {
+
+int *getDefaultMaxTraceLevel() {
+ static int max_trace_level = 10;
+ return &max_trace_level;
+}
+
+int getMaxTraceLevel() {
+ return *getDefaultMaxTraceLevel();
+}
+
+void setMaxTraceLevel(int max_trace_level) {
+ *getDefaultMaxTraceLevel() = max_trace_level;
+ FQ_TRACE("info", 0) << "The upper bound of maximum trace level is "
+ << FQTERM_MAX_TRACE_LEVEL;
+ FQ_TRACE("info", 0) << "The maximum trace level is set to "
+ << max_trace_level;
+}
+
+#ifdef WIN32
+typedef stdext::hash_set<std::string> CategorySet;
+#else
+typedef std::set<std::string> CategorySet;
+#endif
+
+CategorySet *getAllowedCategories() {
+ static CategorySet *allowed_categories
+ = new CategorySet;
+ return allowed_categories;
+}
+
+int isAllowedCategory(const char *category, int trace_level) {
+ if (trace_level <= 0) return true;
+
+ const CategorySet &categories = *getAllowedCategories();
+ if (categories.empty()
+ || categories.find(category) != categories.end()) {
+ return true;
+ }
+ return false;
+}
+
+void addAllowedCategory(const char *category) {
+ CategorySet &categories = *getAllowedCategories();
+
+ categories.insert(category);
+
+ FQ_TRACE("info", 0) << "Allow category: " << category;
+}
+
+// Event name from event type id (updated to Qt4.3.0).
+static const char *kEventName[] = {
+ "QEvent::None", // 0
+ "QEvent::Timer", // 1
+ "QEvent::MouseButtonPress", // 2
+ "QEvent::MouseButtonRelease", // 3
+ "QEvent::MouseButtonDblClick", // 4
+ "QEvent::MouseMove", // 5
+ "QEvent::KeyPress", // 6
+ "QEvent::KeyRelease", // 7
+ "QEvent::FocusIn", // 8
+ "QEvent::FocusOut", // 9
+ "QEvent::Enter", // 10
+ "QEvent::Leave", // 11
+ "QEvent::Paint", // 12
+ "QEvent::Move", // 13
+ "QEvent::Resize", // 14
+ "None", // 15
+ "None", // 16
+ "QEvent::Show", // 17
+ "QEvent::Hide", // 18
+ "QEvent::Close", // 19
+ "None", // 20
+ "QEvent::ParentChange", // 21
+ "None", // 22
+ "None", // 23
+ "QEvent::WindowActivate", // 24
+ "QEvent::WindowDeactivate", // 25
+ "QEvent::ShowToParent", // 26
+ "QEvent::HideToParent", // 27
+ "None", // 28
+ "None", // 29
+ "None", // 30
+ "QEvent::Wheel", // 31
+ "None", // 32
+ "QEvent::WindowTitleChange", // 33
+ "QEvent::WindowIconChange", // 34
+ "QEvent::ApplicationWindowIconChange", // 35
+ "QEvent::ApplicationFontChange", // 36
+ "QEvent::ApplicationLayoutDirectionChange", // 37
+ "QEvent::ApplicationPaletteChange", // 38
+ "QEvent::PaletteChange", // 39
+ "QEvent::Clipboard", // 40
+ "None", // 41
+ "None", // 42
+ "QEvent::MetaCall", // 43
+ "None", // 44
+ "None", // 45
+ "None", // 46
+ "None", // 47
+ "None", // 48
+ "None", // 49
+ "QEvent::SockAct", // 50
+ "QEvent::ShortcutOverride", // 51
+ "QEvent::DeferredDelete", // 52
+ "None", // 53
+ "None", // 54
+ "None", // 55
+ "None", // 56
+ "None", // 57
+ "None", // 58
+ "None", // 59
+ "QEvent::DragEnter", // 60
+ "QEvent::DragMove", // 61
+ "QEvent::DragLeave", // 62
+ "QEvent::Drop", // 63
+ "None", // 64
+ "None", // 65
+ "None", // 66
+ "None", // 67
+ "QEvent::ChildAdded", // 68
+ "QEvent::ChildPolished", // 69
+ "None", // 70
+ "QEvent::ChildRemoved", // 71
+ "None", // 72
+ "None", // 73
+ "QEvent::PolishRequest", // 74
+ "QEvent::Polish", // 75
+ "QEvent::LayoutRequest", // 76
+ "QEvent::UpdateRequest", // 77
+ "QEvent::UpdateLater", // 78
+ "None", // 79
+ "None", // 80
+ "None", // 81
+ "QEvent::ContextMenu", // 82
+ "QEvent::InputMethod", // 83
+ "None", // 84
+ "None", // 85
+ "QEvent::AccessibilityPrepare", // 86
+ "QEvent::TabletMove", // 87
+ "QEvent::LocaleChange", // 88
+ "QEvent::LanguageChange", // 89
+ "QEvent::LayoutDirectionChange", // 90
+ "None", // 91
+ "QEvent::TabletPress", // 92
+ "QEvent::TabletRelease", // 93
+ "None", // 94
+ "None", // 95
+ "QEvent::IconDrag", // 96
+ "QEvent::FontChange", // 97
+ "QEvent::EnabledChange", // 98
+ "QEvent::ActivationChange", // 99
+ "QEvent::StyleChange", // 100
+ "QEvent::IconTextChange", // 101
+ "QEvent::ModifiedChange", // 102
+ "QEvent::WindowBlocked", // 103
+ "QEvent::WindowUnblocked", // 104
+ "QEvent::WindowStateChange", // 105
+ "None", // 106
+ "None", // 107
+ "None", // 108
+ "QEvent::MouseTrackingChange", // 109
+ "QEvent::ToolTip", // 110
+ "QEvent::WhatsThis", // 111
+ "QEvent::StatusTip", // 112
+ "QEvent::ActionChanged", // 113
+ "QEvent::ActionAdded", // 114
+ "QEvent::ActionRemoved", // 115
+ "QEvent::FileOpen", // 116
+ "QEvent::Shortcut", // 117
+ "QEvent::WhatsThisClicked", // 118
+ "QEvent::AccessibilityHelp", // 119
+ "QEvent::ToolBarChange", // 120
+ "QEvent::ApplicationActivate", // 121
+ "QEvent::ApplicationDeactivate", // 122
+ "QEvent::QueryWhatsThis", // 123
+ "QEvent::EnterWhatsThisMode", // 124
+ "QEvent::LeaveWhatsThisMode", // 125
+ "QEvent::ZOrderChange", // 126
+ "QEvent::HoverEnter", // 127
+ "QEvent::HoverLeave", // 128
+ "QEvent::HoverMove", // 129
+ "QEvent::AccessibilityDescription", // 130
+ "QEvent::ParentAboutToChange", // 131
+ "QEvent::WinEventAct", // 132
+ "None", // 133
+ "None", // 134
+ "None", // 135
+ "None", // 136
+ "None", // 137
+ "None", // 138
+ "None", // 139
+ "None", // 140
+ "None", // 141
+ "None", // 142
+ "None", // 143
+ "None", // 144
+ "None", // 145
+ "None", // 146
+ "None", // 147
+ "None", // 148
+ "None", // 149
+ "QEvent::EnterEditFocus", // 150
+ "QEvent::LeaveEditFocus", // 151
+ "None", // 152
+ "QEvent::MenubarUpdated", // 153
+ "None", // 154
+ "QEvent::GraphicsSceneMouseMove", // 155
+ "QEvent::GraphicsSceneMousePress", // 156
+ "QEvent::GraphicsSceneMouseRelease", // 157
+ "QEvent::GraphicsSceneMouseDoubleClick", // 158
+ "QEvent::GraphicsSceneContextMenu", // 159
+ "QEvent::GraphicsSceneHoverEnter", // 160
+ "QEvent::GraphicsSceneHoverMove", // 161
+ "QEvent::GraphicsSceneHoverLeave", // 162
+ "QEvent::GraphicsSceneHelp", // 163
+ "QEvent::GraphicsSceneDragEnter", // 164
+ "QEvent::GraphicsSceneDragMove", // 165
+ "QEvent::GraphicsSceneDragLeave", // 166
+ "QEvent::GraphicsSceneDrop", // 167
+ "QEvent::GraphicsSceneWheel", // 168
+ "QEvent::KeyboardLayoutChange", // 169
+ "QEvent::DynamicPropertyChange", // 170
+ "QEvent::TabletEnterProximity", // 171
+ "QEvent::TabletLeaveProximity", // 172
+ // "QEvent::User", // 1000
+ // "QEvent::MaxUser", // 65535
+};
+
+const char *getEventName(unsigned int type) {
+ if (type > 1000) {
+ return "User defined event";
+ }
+
+ if (type > 172) {
+ return "None";
+ }
+
+ return kEventName[type];
+}
+
+} // namespace FQTerm
+
+#ifdef WIN32
+/*
+ * Number of micro-seconds between the beginning of the Windows epoch
+ * (Jan. 1, 1601) and the Unix epoch (Jan. 1, 1970).
+ *
+ * This assumes all Win32 compilers have 64-bit support.
+ */
+
+#include <Windows.h>
+
+#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) || defined(__WATCOMC__)
+ #define DELTA_EPOCH_IN_USEC 11644473600000000Ui64
+#else
+ #define DELTA_EPOCH_IN_USEC 11644473600000000ULL
+#endif
+
+static unsigned long long filetime_to_unix_epoch (const FILETIME *ft)
+{
+ unsigned long long res = (unsigned long long) ft->dwHighDateTime << 32;
+
+ res |= ft->dwLowDateTime;
+ res /= 10; /* from 100 nano-sec periods to usec */
+ res -= DELTA_EPOCH_IN_USEC; /* from Win epoch to Unix epoch */
+ return (res);
+}
+
+int gettimeofday (struct timeval *tv, int unused)
+{
+ FILETIME ft;
+ unsigned long long tim;
+
+ GetSystemTimeAsFileTime (&ft);
+ tim = filetime_to_unix_epoch (&ft);
+ tv->tv_sec = (long) (tim / 1000000L);
+ tv->tv_usec = (long) (tim % 1000000L);
+ return (0);
+}
+#else
+
+#include <sys/time.h>
+#include <time.h>
+
+#endif
+
+namespace FQTerm {
+
+long long getTraceTime() {
+ struct timeval t;
+ gettimeofday(&t, 0);
+ long long sec = t.tv_sec;
+ long long usec = t.tv_usec;
+ return sec * 1000 + usec/1000;
+}
+
+} // namespace FQTerm
diff --git a/src/common/fqterm_trace.h b/src/common/fqterm_trace.h
new file mode 100644
index 0000000..287a8a8
--- /dev/null
+++ b/src/common/fqterm_trace.h
@@ -0,0 +1,331 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_TRACE_H
+#define FQTERM_TRACE_H
+
+#include <cassert>
+#ifndef WIN32
+#include <unistd.h>
+#endif // WIN32
+
+#include <QtDebug>
+#include <QFileInfo>
+
+namespace FQTerm {
+
+// define NO_FQTERM_TRACE to avoid all trace output.
+// #define NO_FQTERM_TRACE
+
+// define NO_FQTERM_TRACE_FILE_LINE_NUM to avoid file line number in trace
+// output.
+
+// define NO_FQTERM_TRACE_FUNCTION_NAME to avoid function name in trace output.
+// define integer FQTERM_MAX_TRACE_LEVEL to determine the maximize outputed
+// trace level.
+//#define NO_FQTERM_TRACE
+#if defined(NDEBUG)
+#define FQTERM_MAX_TRACE_LEVEL 1
+#endif
+
+#ifndef FQTERM_MAX_TRACE_LEVEL
+#define FQTERM_MAX_TRACE_LEVEL 20
+#endif // FQTERM_MAX_TRACE_LEVEL
+
+int getMaxTraceLevel();
+
+void setMaxTraceLevel(int max_trace_level);
+
+long long getTraceTime();
+
+int isAllowedCategory(const char *category, int trace_level);
+
+void addAllowedCategory(const char *category);
+
+static void soft_break() {
+#if defined(WIN32)
+ __asm int 03h;
+#else
+ pause();
+#endif
+}
+
+template<int trace_level>
+class FQTermTrace {
+ public:
+ FQTermTrace(const char *category, const char *file_name, int line_num, const char *func_name)
+ : category_(category),
+ is_dummy_(!isAllowedCategory(category, trace_level)),
+ trace_output_((trace_level <= FQTERM_MAX_TRACE_LEVEL
+ && trace_level <= getMaxTraceLevel())
+ ? new QDebug(qDebug().nospace())
+ : NULL),
+ dump_string_(false) {
+
+ if (is_dummy_) return;
+
+#ifdef NO_FQTERM_TRACE_FILE_LINE_NUM
+#ifdef NO_FQTERM_TRACE_FUNCTION_NAME
+ return;
+#endif // NO_FQTERM_TRACE_FUNCTION_NAME
+#endif // NO_FQTERM_TRACE_FILE_LINE_NUM
+
+ (*this) << "[" << category_ << " " << trace_level << " ";
+
+#ifndef NO_FQTERM_TRACE_FILE_LINE_NUM
+ (*this) << QFileInfo(file_name).fileName().toAscii().constData()
+ << ": " << line_num;
+#endif // NO_FQTERM_TRACE_FILE_LINE_NUM
+
+#ifndef NO_FQTERM_TRACE_FUNCTION_NAME
+#ifndef NO_FQTERM_TRACE_FILE_LINE_NUM
+ (*this) << ", ";
+#endif // NO_FQTERM_TRACE_FILE_LINE_NUM
+ (*this) << func_name;
+#endif // NO_FQTERM_TRACE_FUNCTION_NAME
+
+ (*this) << "] ";
+ }
+
+ ~FQTermTrace() {
+ if (is_dummy_) return;
+
+ if (trace_level <= FQTERM_MAX_TRACE_LEVEL && trace_level <= getMaxTraceLevel()) {
+ delete trace_output_;
+
+ if (trace_level < 0) {
+ soft_break();
+ assert(false);
+ qFatal("Fatal error occured!\n");
+ }
+ }
+ }
+
+ template<class T>
+ FQTermTrace &operator << (const T &t) {
+ if (is_dummy_) return *this;
+
+ if (trace_level <= FQTERM_MAX_TRACE_LEVEL && trace_level <= getMaxTraceLevel()) {
+ *trace_output_ << t;
+ }
+ return *this;
+ }
+
+ FQTermTrace &operator << (const std::string &t) {
+ return output_raw_string(t);
+ }
+
+ FQTermTrace &operator << (const char *t) {
+ return output_raw_string(t);
+ }
+
+ FQTermTrace &operator << (void (*setter)(FQTermTrace<trace_level> &)) {
+ (*setter)(*this);
+ return *this;
+ }
+
+ private:
+ FQTermTrace &output_raw_string(const std::string &t) {
+ if (is_dummy_) return *this;
+
+ if (trace_level <= FQTERM_MAX_TRACE_LEVEL && trace_level <= getMaxTraceLevel()) {
+ if (!dump_string_) {
+ for (std::string::size_type i = 0; i < t.size(); ++i) {
+ *trace_output_ << t[i];
+ }
+ } else {
+ for (std::string::size_type i = 0; i < t.size(); ++i) {
+ unsigned char a = t[i];
+ unsigned char b = a / 0x10;
+ unsigned char c = a % 0x10;
+ char h = (char) (b < 10 ? '0' + b : 'A' + b - 10);
+ char l = (char) (c < 10 ? '0' + c : 'A' + c - 10);
+
+ *trace_output_ << h << l << ' ';
+ }
+ }
+ }
+ return *this;
+ }
+
+ private:
+ const char *category_;
+ bool is_dummy_;
+ QDebug *trace_output_;
+
+ public:
+ bool dump_string_; // whether we print string in hex mode.
+
+};
+
+template<int trace_level>
+class FQTermDummyTrace {
+ public:
+ template<class T>
+ FQTermDummyTrace &operator << (const T &) {
+ return *this;
+ }
+
+ FQTermDummyTrace &operator << (void (*setter)(FQTermTrace<trace_level> &)) {
+ return *this;
+ }
+};
+
+template<int trace_level>
+void dumpHexString(FQTermTrace<trace_level> &tracer) {
+ tracer.dump_string_ = true;
+}
+
+template<int trace_level>
+void dumpNormalString(FQTermTrace<trace_level> &tracer) {
+ tracer.dump_string_ = false;
+}
+
+template<int trace_level>
+class FQTermScopeTrace {
+ public:
+ FQTermScopeTrace(const char *category, const char *file_name, int line_num,
+ const char *func_name, const char *scope_name)
+ : category_(category),
+ is_dummy_(!isAllowedCategory(category, trace_level)),
+ file_name_(file_name),
+ line_num_(line_num),
+ func_name_(func_name),
+ scope_name_(scope_name) {
+ if (is_dummy_) return;
+ FQTermTrace<trace_level>(category_, file_name_, line_num_, func_name_)
+ << "Entering " << scope_name_;
+ }
+
+ ~FQTermScopeTrace() {
+ if (is_dummy_) return;
+ FQTermTrace<trace_level>(category_, file_name_, line_num_, func_name_)
+ << "Leaving " << scope_name_;
+ }
+
+ private:
+ const char *category_;
+ bool is_dummy_;
+
+ const char *file_name_;
+ const int line_num_;
+ const char *func_name_;
+ const char *scope_name_;
+};
+
+template<int trace_level>
+class FQTermTimerTrace {
+ public:
+ FQTermTimerTrace(const char *category, const char *file_name, int line_num,
+ const char *func_name, const char *msg)
+ : category_(category),
+ is_dummy_(!isAllowedCategory(category, trace_level)),
+ file_name_(file_name),
+ line_num_(line_num),
+ func_name_(func_name),
+ msg_(msg),
+ start_time(is_dummy_? 0: getTraceTime()) {
+ }
+
+ ~FQTermTimerTrace() {
+ if (is_dummy_) return;
+
+ long long total_time = getTraceTime() - start_time;
+
+ long long num_sec = total_time / 1000;
+ long long num_ms = total_time % 1000;
+
+ FQTermTrace<trace_level>(category_, file_name_, line_num_, func_name_)
+ << msg_ << num_sec << "s" << num_ms << "ms";
+ }
+
+ private:
+ const char *category_;
+ bool is_dummy_;
+
+ const char *file_name_;
+ const int line_num_;
+ const char *func_name_;
+ const char *msg_;
+
+ long long start_time; // in millisecond.
+};
+
+// Some macros work in both debug & release version.
+#define FQ_FATAL(file, line, func) \
+ do {FQTerm::soft_break(); qFatal("%s", (QString(file) + ": %1 " + QString(func)).arg(line).toUtf8().constData());} while(false)
+
+#define FQ_VERIFY(expr) do { \
+ if(!(expr)) { \
+ FQ_FATAL(__FILE__, __LINE__, __FUNCTION__); \
+ } \
+ } while(false)
+
+
+
+#ifdef NO_FQTERM_TRACE
+
+#define FQ_TRACE(category, trace_level) FQTermDummyTrace<trace_level>()
+#define FQ_SCOPE_TRACE(category, trace_level, scope_name) do {} while (false)
+#define FQ_FUNC_TRACE(category, trace_level) do {} while(false)
+
+#define FQ_ASSERT(expr) do {} while(false)
+
+#define FQ_SCOPE_TIMER(category, trace_level, msg) do {} while(false)
+#define FQ_FUNC_TIMER(category, trace_level) do {} while(false)
+
+
+#else // NO_FQTERM_TRACE
+
+#define FQ_TRACE(category, trace_level) \
+ FQTermTrace<trace_level>(category, __FILE__, __LINE__, __FUNCTION__)
+
+#define FQ_SCOPE_TRACE_PRIVATE(file, line, func, category, trace_level, scope_name) \
+ FQTermScopeTrace<trace_level> file##line##func(category, file, line, func, scope_name);
+
+#define FQ_SCOPE_TRACE(category, trace_level, scope_name) \
+ FQ_SCOPE_TRACE_PRIVATE(__FILE__, __LINE__, __FUNCTION__, category, trace_level, scope_name)
+
+#define FQ_FUNC_TRACE(category, trace_level) \
+ FQ_SCOPE_TRACE_PRIVATE(__FILE__, __LINE__, __FUNCTION__, category, trace_level, "function")
+
+
+#define FQ_ASSERT(expr) \
+ do {if(!(expr)) {FQ_TRACE("assert", -1) << "assertion failed." << #expr;}} while(false)
+
+
+#define FQ_SCOPE_TIMER_PRIVATE(file, line, func, category, trace_level, msg) \
+ FQTermTimerTrace<trace_level> file##line##func(category, file, line, func, msg);
+
+#define FQ_SCOPE_TIMER(category, trace_level, msg) \
+ FQ_SCOPE_TIMER_PRIVATE(__FILE__, __LINE__, __FUNCTION__, category, trace_level, msg)
+
+#define FQ_FUNC_TIMER(category, trace_level) \
+ FQ_SCOPE_TIMER_PRIVATE(__FILE__, __LINE__, __FUNCTION__, category, trace_level, "The function runs for ")
+
+
+#endif // NO_FQTERM_TRACE
+
+
+const char *getEventName(unsigned int type);
+
+} // namespace FQTerm
+
+#endif // FQTERM_TRACE_H
diff --git a/src/fqterm/3rdparty/dotnetstyle.cpp b/src/fqterm/3rdparty/dotnetstyle.cpp
new file mode 100644
index 0000000..d016ff2
--- /dev/null
+++ b/src/fqterm/3rdparty/dotnetstyle.cpp
@@ -0,0 +1,1274 @@
+/****************************************************************************
+**
+** Copyright (C) 2007-2007 Trolltech ASA. All rights reserved.
+**
+** This file is part of the DotNetStyle project on Trolltech Labs.
+**
+** This file may be used under the terms of the GNU General Public
+** License version 2.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of
+** this file. Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+** http://www.trolltech.com/products/qt/opensource.html
+**
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://www.trolltech.com/products/qt/licensing.html or contact the
+** sales department at sales@trolltech.com.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#ifdef USE_DOTNET_STYLE
+#include "dotnetstyle.h"
+#include <QStyleOption>
+#include <QPainter>
+#include <QMainWindow>
+#include <QDockWidget>
+#include <QDialogButtonBox>
+#include <QToolBar>
+#include <QDialog>
+#include <QLineEdit>
+#include <QComboBox>
+#include <QLibrary>
+#include <QStatusBar>
+#include <QApplication>
+#include <qt_windows.h>
+
+typedef bool (WINAPI *PtrIsAppThemed)();
+typedef HRESULT (WINAPI *PtrGetCurrentThemeName)(OUT LPWSTR pszThemeFileName, int cchMaxNameChars, OUT OPTIONAL LPWSTR pszColorBuff, int cchMaxColorChars, OUT OPTIONAL LPWSTR pszSizeBuff, int cchMaxSizeChars);
+
+static PtrIsAppThemed pIsAppThemed = 0;
+static PtrGetCurrentThemeName pGetCurrentThemeName = 0;
+
+static const int windowsItemFrame = 2; // menu item frame width
+static const int windowsSepHeight = 9; // separator item height
+static const int windowsItemHMargin = 3; // menu item hor text margin
+static const int windowsItemVMargin = 2; // menu item ver text margin
+static const int windowsArrowHMargin = 6; // arrow horizontal margin
+static const int windowsRightBorder = 15; // right border on windows
+
+class DotNetStylePrivate
+{
+public:
+ DotNetStylePrivate()
+ {
+ QLibrary themeLib("uxtheme");
+ themeLib.load();
+ if (themeLib.isLoaded()) { //resolve uxtheme functions
+ pIsAppThemed = (PtrIsAppThemed)themeLib.resolve("IsAppThemed");
+ pGetCurrentThemeName = (PtrGetCurrentThemeName)themeLib.resolve("GetCurrentThemeName");
+ }
+ }
+ ~DotNetStylePrivate()
+ {}
+
+ enum InternalPalette {
+ Blue,
+ Silver,
+ Olive,
+ System,
+ Classic
+ };
+
+ void init();
+ QColor gradientDarkColor(const QStyleOption *option) const;
+ QColor gradientLightColor(const QStyleOption *option) const;
+ QColor highlightOutlineColor(const QStyleOption *option, bool act) const;
+ QColor shadowColor(const QStyleOption *option) const;
+ QBrush highlightBrush(const QStyleOption *option, bool act) const;
+ QBrush highlightMenuCheckBrush(const QStyleOption *option, bool act) const;
+ QLinearGradient toolbarGradient(const QStyleOption *option, QRect rect, Qt::Orientation orientaion) const;
+ QLinearGradient menuGradient(const QStyleOption *option, QRect rect, Qt::Orientation orientaion) const;
+ void updatePalette();
+
+ QColor menuSeparatorColor;
+ QColor menuBackgroundColor;
+ QColor menuFrameColor;
+ InternalPalette internalPalette; //internal color theme
+ DotNetStyle::ColorTheme theme; //external color theme
+ QPalette currentPal; //used to detect system palette changes
+ };
+
+
+
+inline QColor DotNetStylePrivate::gradientDarkColor(const QStyleOption *option) const {
+ QColor color = option->palette.background().color();
+ switch (internalPalette) {
+ case Olive:
+ color = QColor(217, 217, 167);
+ break;
+ case Blue:
+ color = QColor(158, 190, 245);
+ break;
+ case Silver:
+ color = QColor(216, 216, 229);
+ break;
+ default:
+ break;
+ }
+ return color;
+}
+
+inline QColor DotNetStylePrivate::gradientLightColor(const QStyleOption *option) const {
+ QColor color = option->palette.background().color().lighter(106);
+ switch (internalPalette) {
+ case Olive:
+ color = QColor(241, 240, 227);
+ break;
+ case Blue:
+ color = QColor(196, 217, 249);
+ break;
+ case Silver:
+ color = QColor(242, 242, 247);
+ break;
+ case Classic:
+ color = option->palette.light().color().lighter(106);
+ default:
+ break;
+ }
+ return color;
+}
+
+inline QColor DotNetStylePrivate::shadowColor(const QStyleOption *option) const {
+ QColor color;
+ switch (internalPalette) {
+ case Blue:
+ color = QColor(59, 97, 156);
+ break;
+ case Silver:
+ color = QColor(124, 124, 148);
+ break;
+ case Olive:
+ color = QColor(96, 128, 88);
+ break;
+ case Classic:
+ color = option->palette.background().color();
+ break;
+ default:
+ color = option->palette.dark().color();
+ break;
+ }
+ return color;
+}
+
+inline QColor DotNetStylePrivate::highlightOutlineColor(const QStyleOption *option, bool act = false) const {
+ QColor color;
+ switch (internalPalette) {
+ case Blue:
+ color = QColor(0, 0, 128);
+ break;
+ case Silver:
+ color = QColor(75, 75, 111);
+ break;
+ case Olive:
+ color = QColor(63, 93, 56);
+ break;
+ default:
+ if (act)
+ return option->palette.highlight().color().darker(110);
+ else
+ return option->palette.highlight().color().lighter(110);
+ break;
+ }
+ return color;
+}
+
+QBrush DotNetStylePrivate::highlightBrush(const QStyleOption *option, bool act) const {
+ QBrush brush;
+ QColor highlight;
+ switch (internalPalette) {
+ case Silver:
+ case Olive:
+ case Blue:
+ if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ brush = QColor(255, 238, 194);
+ } else {
+ QLinearGradient gradient(option->rect.topLeft(), option->rect.bottomLeft());
+ if (act) {
+ gradient.setColorAt(0, QColor(254, 149, 82));
+ gradient.setColorAt(1, QColor(255, 211, 142));
+ } else {
+ gradient.setColorAt(0, QColor(255, 252, 200));
+ gradient.setColorAt(1, QColor(255, 208, 145));
+ }
+ brush = gradient;
+ }
+ break;
+ default:
+ highlight = option->palette.highlight().color().lighter(120);
+ if (act)
+ highlight.setHsv(highlight.hue(), 70, 220);
+ else
+ highlight.setHsv(highlight.hue(), 40, 230);
+ brush = QBrush(highlight);
+ break;
+ }
+ return brush;
+}
+
+QBrush DotNetStylePrivate::highlightMenuCheckBrush(const QStyleOption *option, bool act) const {
+ QBrush brush;
+ QColor highlight;
+
+ switch (internalPalette) {
+ case Silver:
+ case Olive:
+ case Blue:
+ if (act)
+ brush = QColor(254, 128, 62);
+ else
+ brush = QColor(255, 192, 111);
+ break;
+ default:
+ highlight = option->palette.highlight().color().lighter(120);
+ if (act)
+ highlight.setHsv(highlight.hue(), 120, 180);
+ else {
+ highlight.setHsv(highlight.hue(), 30, 230);
+ }
+ highlight.setAlpha(170);
+ brush = highlight;
+ break;
+ }
+ return brush;
+}
+
+QLinearGradient DotNetStylePrivate::toolbarGradient(const QStyleOption *option, QRect rect, Qt::Orientation orientation= Qt::Vertical) const {
+ QLinearGradient gradient(rect.topLeft(), orientation == Qt::Vertical ? rect.topRight() : rect.bottomLeft());
+ QColor start, stop;
+ switch (internalPalette)
+ {
+ case Blue:
+ start = QColor(220, 235, 254);
+ stop = QColor(129, 169, 226);
+ gradient.setColorAt(0.3, start);
+ break;
+ case Silver:
+ start = QColor(242, 242, 249);
+ stop = QColor(153, 151, 181);
+ gradient.setColorAt(0.3, start);
+ break;
+ case Olive:
+ start = QColor(241, 245, 217);
+ stop = QColor(183, 198, 145);
+ gradient.setColorAt(0.0, start);
+ break;
+ default:
+ start = option->palette.light().color();
+ if (internalPalette == Classic)
+ start = start.lighter(130);
+ start.setAlpha(180);
+ stop = option->palette.button().color();
+ stop.setHsv(stop.hue(), qMin(stop.saturation()*2, 255), (stop.value()*2)/3);
+ stop.setAlpha(128);
+ if (internalPalette == Classic)
+ stop.setAlpha(0);
+ gradient.setColorAt(0.3, start);
+ break;
+ }
+ gradient.setColorAt(1, stop);
+ return gradient;
+}
+
+
+QLinearGradient DotNetStylePrivate::menuGradient(const QStyleOption *option, QRect rect, Qt::Orientation orientaion = Qt::Horizontal) const {
+
+ QColor start, stop;
+ QLinearGradient grad;
+ if (orientaion == Qt::Vertical) {
+ grad.setStart(rect.left(), rect.top());
+ grad.setFinalStop(rect.left(), rect.bottom());
+ } else {
+ grad.setStart(QPoint(rect.left(), 0));
+ grad.setFinalStop(QPoint(rect.left() + 24, 0));
+ }
+ switch (internalPalette)
+ {
+ case Blue:
+ start = QColor(220, 235, 254);
+ stop = QColor(129, 169, 226);
+ grad.setColorAt(0.3, start);
+ break;
+ case Olive:
+ start = QColor(246, 248, 224);
+ stop = QColor(186, 201, 148);
+ grad.setColorAt(0.0, start);
+ break;
+ case Silver:
+ start = QColor(215, 215, 226);
+ stop = QColor(138, 137, 166);
+ grad.setColorAt(0.4, start);
+ break;
+ default:
+ start = option->palette.brush(QPalette::Active, QPalette::Base).color();
+ stop = gradientDarkColor(option);
+ stop.setHsv(stop.hue(), qMin((int)(stop.saturation()*1.2), 255), (5*stop.value()/7));
+ if (internalPalette == Classic)
+ stop.setAlpha(120);
+ grad.setColorAt(0, start);
+ break;
+ }
+ grad.setColorAt(1, stop);
+ return grad;
+}
+
+
+
+/*!
+ \class DotNetStyle qtdotnetstyle.h
+ \brief The DotNetStyle class provides an alternative, modern look for Qt applications on Windows.
+
+ The GUI look is very similar to the style introduced in
+ Visual Studio 2005, Office 2003 as well as in .NET Windows
+ Forms (when the RenderMode is set to "Professional"
+ instead of "System"). It gives applications a modern
+ gradient appearance for tool bars and menus while
+ retaining the native look and feel for other widgets.
+
+ The style supports different color themes, which may be specified in
+ the constructor. The default is \c Standard color theme.
+
+ This is the textedit example running with the Standard style:
+ \img dotnetstyle.png
+
+ This is the textedit example running with the Office style:
+ \img dotnetstyle2.png
+
+ \sa QStyle, QWindowsVistaStyle, QWindowsXPStyle
+*/
+
+
+/*!
+ \enum DotNetStyle::ColorTheme
+
+ This enum describes the different color schemes supported by the style.
+
+ \value Standard Use gradients based on the operating system palette.
+ \value Office Use Microsoft Office 2003 style gradients.
+*/
+
+/*!
+ Constructs a DotNetStyle object which uses the default color
+ theme (\c Office).
+*/
+DotNetStyle::DotNetStyle()
+: QWindowsVistaStyle(), d(new DotNetStylePrivate())
+{
+ d->theme = Office;
+}
+
+
+/*!
+ Constructs a DotNetStyle object which uses the color theme \a
+ colortheme.
+*/
+DotNetStyle::DotNetStyle(ColorTheme colortheme)
+ : QWindowsVistaStyle(), d(new DotNetStylePrivate())
+{
+ d->theme = colortheme;
+}
+
+
+/*!
+ Destroys the DotNetStyle object.
+*/
+DotNetStyle::~DotNetStyle()
+{
+ delete d;
+}
+
+
+/*!
+ \reimp
+ */
+void DotNetStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const
+{
+ QColor gradientDark = d->gradientDarkColor(option);
+ QColor gradientLight = d->gradientLightColor(option);
+ QColor shadow = d->shadowColor(option);
+
+ QRect rect = option->rect;
+ switch (element) {
+ case PE_IndicatorDockWidgetResizeHandle:
+ break;
+ case PE_PanelLineEdit:
+ if (widget && qobject_cast<QToolBar*>(widget->parentWidget())) {
+ QRect rect = option->rect.adjusted(2, 1, -2, -2);
+ painter->save();
+ bool active = option->state & State_Active &&
+ ((option->state & State_MouseOver)
+ || (option->state & State_HasFocus));
+ QBrush editBrush = option->palette.brush(QPalette::Base);
+ painter->setPen(QPen(editBrush.color()));
+ painter->fillRect(rect, editBrush);
+
+ QRect re = option->rect ;
+ if (active) {
+ painter->setPen(d->highlightOutlineColor(option));
+ painter->drawRect(rect);
+ }
+ painter->restore();
+ } else {
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ QWindowsVistaStyle::drawPrimitive(element, option, painter, widget);
+ else
+ QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
+ }
+ case PE_PanelButtonTool:
+ {
+ QStyleOption opt2 = *option;
+ if (widget)
+ if(QDockWidget *dw = qobject_cast<QDockWidget *>(widget->parentWidget())) {
+ if (!dw->isFloating())
+ opt2.palette.setBrush(QPalette::Button, Qt::transparent);
+ }
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ QWindowsVistaStyle::drawPrimitive(element, &opt2, painter, widget);
+ else
+ QWindowsXPStyle::drawPrimitive(element, &opt2, painter, widget);
+ }
+ break;
+ case PE_FrameMenu:
+ {
+ QPen pen = painter->pen();
+ QBrush brush = painter->brush();
+ if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar*>(option))
+ {
+ Qt::Orientation orientation =(toolbar->toolBarArea == Qt::RightToolBarArea ||
+ toolbar->toolBarArea == Qt::LeftToolBarArea) ?
+ Qt::Vertical : Qt::Horizontal;
+ painter->setBrush(d->toolbarGradient(toolbar, toolbar->rect, orientation));
+ } else {
+ painter->setBrush(d->menuBackgroundColor);
+ }
+ painter->setPen(d->menuFrameColor);
+ painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
+ painter->setPen(pen);
+ painter->setBrush(brush);
+ }
+ break;
+ case PE_Widget:
+ if (const QMainWindow *mw = qobject_cast<const QMainWindow *>(widget)) {
+ if (d->currentPal != qApp->palette()) //workaround for style polish on theme color change
+ {
+ d->currentPal = qApp->palette();
+ d->updatePalette();
+ }
+ painter->save();
+ QPoint begin = widget->geometry().topRight();
+ QPoint end = widget->geometry().topLeft() + QPoint(0, widget->geometry().height()/2);
+ begin = widget->mapFromGlobal(begin);
+ end = widget->mapFromGlobal(end);
+ QLinearGradient menubargradient(begin, end);
+ menubargradient.setColorAt(0, gradientLight);
+ if (d->internalPalette == DotNetStylePrivate::System)
+ menubargradient.setColorAt(0.3, gradientDark);
+ else
+ menubargradient.setColorAt(0.8, gradientDark);
+ menubargradient.setColorAt(1, gradientDark);
+ QRect windowRect = option->rect;
+ if (QStatusBar *statusBar = mw->findChild<QStatusBar*>()) {
+ windowRect.adjust(0, 0, 0, -statusBar->height());
+ painter->setPen(option->palette.background().color().lighter(106));
+ painter->drawLine(windowRect.bottomLeft() + QPoint(0, 1),
+ windowRect.bottomRight() + QPoint(0, 1));
+ }
+ painter->fillRect(windowRect, menubargradient);
+ painter->restore();
+ }
+ break;
+ case PE_IndicatorToolBarSeparator:
+ {
+ QRect rect = option->rect;
+ shadow.setAlpha(180);
+ painter->setPen(shadow);
+ const int margin = 3;
+ if (option->state & State_Horizontal) {
+ const int offset = rect.width()/2;
+ painter->drawLine(rect.bottomLeft().x() + offset,
+ rect.bottomLeft().y() - margin,
+ rect.topLeft().x() + offset,
+ rect.topLeft().y() + margin);
+ painter->setPen(QPen(option->palette.background().color().light(110)));
+ painter->drawLine(rect.bottomLeft().x() + offset + 1,
+ rect.bottomLeft().y() - margin,
+ rect.topLeft().x() + offset + 1,
+ rect.topLeft().y() + margin);
+ } else { //Draw vertical separator
+ const int offset = rect.height()/2;
+ painter->setPen(QPen(option->palette.background().color().dark(110)));
+ painter->drawLine(rect.topLeft().x() + margin ,
+ rect.topLeft().y() + offset,
+ rect.topRight().x() - margin,
+ rect.topRight().y() + offset);
+ painter->setPen(QPen(option->palette.background().color().light(110)));
+ painter->drawLine(rect.topLeft().x() + margin ,
+ rect.topLeft().y() + offset + 1,
+ rect.topRight().x() - margin,
+ rect.topRight().y() + offset + 1);
+ }
+ }
+ break;
+ case PE_IndicatorToolBarHandle:
+ painter->save();
+ {
+ QColor gripColor = shadow;
+ if (d->internalPalette != DotNetStylePrivate::System)
+ gripColor = shadow.darker(120);
+ if (option->state & State_Horizontal) {
+ for (int i = rect.height()/5; i <= 4*(rect.height()/5) ; i+=4) {
+ int y = rect.topLeft().y() + i + 1;
+ int x1 = rect.topLeft().x() + 3;
+ painter->fillRect(x1 + 1, y, 2, 2, Qt::white);
+ painter->fillRect(x1, y - 1, 2, 2, gripColor);
+ }
+ }
+ else { //vertical toolbar
+ for (int i = rect.width()/5; i <= 4*(rect.width()/5) ; i+=4) {
+ int x = rect.topLeft().x() + i + 1;
+ int y1 = rect.topLeft().y() + 3;
+ painter->fillRect(x , y1 + 1, 2, 2, Qt::white);
+ painter->fillRect(x - 1, y1, 2, 2, gripColor);
+ }
+ }
+ }
+ painter->restore();
+ break;
+ case PE_PanelMenuBar:
+ break;
+ default:
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ QWindowsVistaStyle::drawPrimitive(element, option, painter, widget);
+ else
+ QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
+ break;
+ }
+}
+
+/*!
+ \reimp
+ */
+void DotNetStyle::drawControl(ControlElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const
+{
+
+ QColor gradientDark = d->gradientDarkColor(option);
+ QColor gradientLight = d->gradientLightColor(option);
+ QColor shadow = d->shadowColor(option);
+ QRect rect = option->rect;
+
+ switch (element) {
+#ifndef QT_NO_MENU
+ case CE_MenuItem:
+ painter->save();
+ if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ int x, y, w, h;
+ QStyleOptionMenuItem mbiCopy = *menuitem;
+ painter->fillRect(rect, d->menuBackgroundColor);
+ painter->fillRect(QRect(0, rect.top(), 25, rect.bottom()), d->menuGradient(option, rect));
+ menuitem->rect.getRect(&x, &y, &w, &h);
+
+ int tab = menuitem->tabWidth;
+ bool dis = !(menuitem->state & State_Enabled);
+ bool checked = menuitem->checkType != QStyleOptionMenuItem::NotCheckable
+ ? menuitem->checked : false;
+ bool act = menuitem->state & State_Selected;
+
+ // windows always has a check column, regardless whether we have an icon or not
+ int checkcol = qMax(menuitem->maxIconWidth, 20);
+ if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) {
+ int yoff = y-1 + h / 2;
+ painter->setPen(d->menuSeparatorColor);
+ painter->drawLine(x + 32, yoff, x + w + 6, yoff);
+ painter->restore();
+ return;
+ }
+
+ QRect vCheckRect = visualRect(option->direction, menuitem->rect,
+ QRect(menuitem->rect.x(), menuitem->rect.y(), checkcol, menuitem->rect.height()));
+ vCheckRect.adjust(2, 0, 0, 0);
+
+ if (act) {
+ painter->setPen(d->highlightOutlineColor(option));
+ painter->setBrush(d->highlightBrush(option, false));
+ painter->drawRect(option->rect.adjusted(0, 0, -2, -2));
+ }
+
+ if (!menuitem->icon.isNull()) {
+ QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
+ if (act && !dis)
+ mode = QIcon::Active;
+ QPixmap pixmap;
+ if (checked)
+ pixmap = menuitem->icon.pixmap(pixelMetric(PM_SmallIconSize), mode, QIcon::On);
+ else
+ pixmap = menuitem->icon.pixmap(pixelMetric(PM_SmallIconSize), mode);
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ QRect pmr(0, 0, pixw, pixh);
+ pmr.moveCenter(vCheckRect.center());
+ painter->setPen(menuitem->palette.text().color());
+ painter->drawPixmap(pmr.topLeft(), pixmap);
+ } else if (checked) {
+ painter->save();
+ painter->setPen(d->highlightOutlineColor(option, act));
+ painter->setBrush(d->highlightMenuCheckBrush(option, act));
+ painter->drawRect(vCheckRect.adjusted(-1, 1, 0, -3));
+ painter->restore();
+
+ QStyleOptionMenuItem newMi = *menuitem;
+ newMi.state = State_None;
+ if (!dis)
+ newMi.state |= State_Enabled;
+ if (act)
+ newMi.state |= State_On;
+ newMi.rect = visualRect(option->direction, menuitem->rect,
+ QRect(menuitem->rect.x() + windowsItemFrame, menuitem->rect.y() + windowsItemFrame,
+ checkcol - 2 * windowsItemFrame, menuitem->rect.height() - 2*windowsItemFrame));
+ drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, painter, widget);
+ }
+ painter->setPen(menuitem->palette.buttonText().color());
+
+ QColor discol;
+ if (dis) {
+ discol = menuitem->palette.text().color();
+ painter->setPen(discol);
+ }
+
+ int xm = windowsItemFrame + checkcol + windowsItemHMargin;
+ int xpos = menuitem->rect.x() + xm;
+ QRect textRect(xpos + 5, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
+ QRect vTextRect = visualRect(option->direction, menuitem->rect, textRect);
+ QString s = menuitem->text;
+
+ if (!s.isEmpty()) { // draw text
+ painter->save();
+ int t = s.indexOf(QLatin1Char('\t'));
+ int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+ if (!styleHint(SH_UnderlineShortcut, menuitem, widget))
+ text_flags |= Qt::TextHideMnemonic;
+ text_flags |= Qt::AlignLeft;
+ if (t >= 0) {
+ QRect vShortcutRect = visualRect(option->direction, menuitem->rect,
+ QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom())));
+ if (dis && !act) {
+ painter->setPen(discol);
+ }
+ painter->drawText(vShortcutRect, text_flags, s.mid(t + 1));
+ s = s.left(t);
+ }
+ QFont font = menuitem->font;
+ if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
+ font.setBold(true);
+ painter->setFont(font);
+ if (dis && !act) {
+ painter->setPen(discol);
+ }
+ painter->drawText(vTextRect, text_flags, s.left(t));
+ painter->restore();
+ }
+ if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
+ int dim = (h - 2 * windowsItemFrame) / 2;
+ PrimitiveElement arrow;
+ arrow = (option->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
+ xpos = x + w - windowsArrowHMargin - windowsItemFrame - dim;
+ QRect vSubMenuRect = visualRect(option->direction, menuitem->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim));
+ QStyleOptionMenuItem newMI = *menuitem;
+ newMI.rect = vSubMenuRect;
+ newMI.state = dis ? State_None : State_Enabled;
+ drawPrimitive(arrow, &newMI, painter, widget);
+ }
+ }
+ painter->restore();
+ break;
+#endif // QT_NO_MENU
+
+ case CE_MenuEmptyArea:
+ {
+ painter->fillRect(option->rect, option->palette.base());
+ QLinearGradient grad(QPoint(rect.left() , 0), QPoint(rect.left() + 23, 0));
+ grad.setColorAt(0, gradientLight.light(110));
+ grad.setColorAt(1, gradientDark);
+ painter->fillRect(QRect(0, rect.top() + 2, 23, rect.bottom() - 3), grad);
+ }
+ break;
+ case CE_MenuBarItem:
+ if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ QRect rect(QPoint(0, 0), widget->window()->size());
+ {
+ if (widget->window())
+ drawPrimitive(PE_Widget, option, painter, widget);
+ }
+ if (option->state & (QStyle::State_Sunken | QStyle::State_Selected))
+ {
+ QColor highlight = shadow;
+ painter->setPen(d->menuFrameColor);
+ if (option->state & QStyle::State_Sunken) {
+
+ if (d->internalPalette == DotNetStylePrivate::System)
+ painter->setBrush(Qt::white);
+ else
+ painter->setBrush(d->menuGradient(option, option->rect, Qt::Vertical));
+
+ painter->drawRect(option->rect.adjusted(0, 2, -1, 0));
+ //draw shadow behind:
+ QColor shade = Qt::black;
+ shade.setAlpha(50);
+ painter->setBrush(shade);
+ painter->setPen(Qt::transparent);
+ QRect shadowRect(option->rect.topRight() + QPoint(0, 4), option->rect.bottomRight() + QPoint(1,0));
+ painter->drawRect(shadowRect);
+ }
+ else {
+ painter->setPen(d->highlightOutlineColor(option));
+ painter->setBrush(d->highlightBrush(option, false));
+ painter->drawRect(option->rect.adjusted(0, 2, -2, -2));
+ }
+ }
+ QStyleOptionMenuItem mbiCopy = *mbi;
+ QPalette pal = mbi->palette;
+ pal.setBrush(QPalette::All, QPalette::ButtonText, mbi->palette.text());
+ mbiCopy.palette = pal;
+ QCommonStyle::drawControl(element, &mbiCopy, painter, widget);
+ }
+ break;
+ case CE_MenuBarEmptyArea:
+ if (widget->window())
+ drawPrimitive(PE_Widget, option, painter, widget);
+ break;
+ case CE_DockWidgetTitle:
+ if (const QDockWidget *dockWidget = qobject_cast<const QDockWidget *>(widget)) {
+ painter->save();
+ if (d->internalPalette == DotNetStylePrivate::System) {
+ painter->setBrush(option->palette.dark().color().light(130));
+ painter->setPen(option->palette.dark().color());
+ } else if (d->internalPalette == DotNetStylePrivate::Classic) {
+ painter->setBrush(option->palette.background().color().dark(108));
+ painter->setPen(option->palette.dark().color());
+ } else {
+ painter->setBrush(d->toolbarGradient(option, option->rect, Qt::Horizontal));
+ QColor color = d->gradientDarkColor(option).darker(120);
+ painter->setPen(color);
+ }
+ painter->drawRect(rect.adjusted(0, 2, -1, -3));
+
+ if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) {
+ QRect titleRect = option->rect.adjusted(6, 2, 0, 0);
+ int buttonMargin = 4;
+ int mw = pixelMetric(QStyle::PM_DockWidgetTitleMargin, dwOpt, widget);
+ if (dwOpt->closable) {
+ QPixmap pm = standardIcon(QStyle::SP_TitleBarCloseButton, dwOpt, widget).pixmap(10, 10);
+ titleRect.adjust(0, 0, -pm.size().width() - mw - buttonMargin, 0);
+ }
+ if (dwOpt->floatable) {
+ QPixmap pm = standardIcon(QStyle::SP_TitleBarMaxButton, dwOpt, widget).pixmap(10, 10);
+ titleRect.adjust(0, 0, -pm.size().width() - mw - buttonMargin, 0);
+ }
+ titleRect = visualRect(option->direction, option->rect, titleRect);
+
+ if (!dwOpt->title.isEmpty()) {
+ QString titleText = painter->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, titleRect.width());
+ drawItemText(painter, titleRect,
+ Qt::AlignLeft | Qt::AlignVCenter, dwOpt->palette,
+ dwOpt->state & State_Enabled, titleText,
+ QPalette::WindowText);
+ }
+ painter->restore();
+ }
+ break;
+ }
+ case CE_ToolBar:
+ if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar*>(option)) {
+ painter->save();
+ rect.adjust(1, 0, 0, 0);
+
+ if (const QToolBar *tb = qobject_cast<const QToolBar *>(widget)) {
+ if (option->direction == Qt::LeftToRight)
+ rect.setRight(tb->childrenRect().right() + 2);
+ else
+ rect.setLeft(tb->childrenRect().left() - 2);
+ }
+ Qt::Orientation gradientOrientation =(toolbar->toolBarArea == Qt::RightToolBarArea ||
+ toolbar->toolBarArea == Qt::LeftToolBarArea) ? Qt::Vertical : Qt::Horizontal;
+ QLinearGradient gradient = d->toolbarGradient(toolbar, rect, gradientOrientation);
+ painter->setBrush(gradient);
+ painter->setPen(Qt::NoPen);
+
+ bool roundEdges = true;
+ if (widget && widget->parentWidget()) {
+ if (const QToolBar *tb = qobject_cast<const QToolBar *>(widget)) {
+ if (!(tb->childrenRect().width() + 32 < widget->parentWidget()->geometry().width())) {
+ roundEdges = false;
+ rect.adjust(-1, 0, 0, 0);
+ }
+ }
+ }
+ if (roundEdges) {
+ rect = rect.adjusted(1, 1, -1, 0);
+ QRegion region = rect;
+ region -= QRect(rect.left(), rect.bottom(), 2, 1);
+ region -= QRect(rect.right() - 1, rect.bottom(), 2, 1);
+ region -= QRect(rect.left(), rect.bottom() - 1, 1, 1);
+ region -= QRect(rect.right(), rect.bottom() - 1, 1, 1);
+ region -= QRect(rect.left(), rect.top(), 2, 1);
+ region -= QRect(rect.right() - 1, rect.top(), 2, 1);
+ region -= QRect(rect.left(), rect.top() + 1, 1, 1);
+ region -= QRect(rect.right(), rect.top() + 1, 1, 1);
+ painter->setClipRegion(region);
+
+ painter->fillRect(rect, gradient);
+
+ painter->setPen(QPen(shadow, 0));
+ painter->drawLine(rect.bottomLeft() + QPoint(3,0), rect.bottomRight() - QPoint(2,0));
+ painter->drawPoint(rect.bottomRight() - QPoint(1, 1));
+ QColor alphashadow = shadow;
+ alphashadow.setAlpha(128);
+ painter->setPen(QPen(alphashadow, 0));
+ painter->drawLine(rect.topRight() + QPoint(0, 2), rect.bottomRight() - QPoint(0, 2));
+ } else {
+ painter->fillRect(rect, gradient);
+ }
+ painter->restore();
+ }
+ break;
+ default:
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ QWindowsVistaStyle::drawControl(element, option, painter, widget);
+ else
+ QWindowsXPStyle::drawControl(element, option, painter, widget);
+ break;
+ }
+}
+
+/*!
+ \reimp
+ */
+void DotNetStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const
+{
+ switch (control) {
+ case CC_ComboBox:
+ if (widget && qobject_cast<QToolBar *>(widget->parentWidget())) {
+ QColor highlightedOutlineColor = d->highlightOutlineColor(option);
+ if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option))
+ {
+ bool active = cmb->state & State_Active &&
+ ((cmb->state & State_MouseOver)
+ || (cmb->state & State_On)
+ || (cmb->state & State_HasFocus));
+ QRect editRect = QWindowsStyle::subControlRect(CC_ComboBox, cmb, SC_ComboBoxEditField, widget).adjusted(0, 0, 3, 1);
+ QRect rect = option->rect.adjusted(1, 1, -3, -2);
+ editRect.setLeft(rect.left());
+
+ if (cmb->subControls & SC_ComboBoxEditField) {
+ painter->save();
+ QBrush editBrush = cmb->palette.brush(QPalette::Base);
+ painter->setPen(QPen(editBrush.color()));
+ painter->drawRect(rect);
+ painter->fillRect(editRect, editBrush);
+
+ if (active) {
+ QColor highlight = highlightedOutlineColor;
+ painter->setPen(highlight);
+ painter->drawRect(rect);
+ }
+ painter->restore();
+ }
+
+ if (cmb->subControls & SC_ComboBoxArrow) {
+ State flags = State_None;
+
+ QRect ar = QWindowsStyle::subControlRect(CC_ComboBox, cmb, SC_ComboBoxArrow, widget).adjusted(1, 0, -1, 0);
+ if (active) {
+ painter->save();
+ painter->fillRect(ar, d->highlightBrush(option, cmb->state & State_Sunken));
+ painter->setPen(highlightedOutlineColor);
+ painter->drawLine(ar.topLeft(), ar.bottomLeft());
+ painter->restore();
+ }
+ ar.adjust(5, 5, -2, -2);
+ if (option->state & State_Enabled)
+ flags |= State_Enabled;
+ QStyleOption arrowOpt(0);
+ arrowOpt.rect = ar;
+ arrowOpt.palette = cmb->palette;
+ arrowOpt.state = flags;
+ QWindowsStyle::drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, painter, widget);
+ }
+ }
+ } else {
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ QWindowsVistaStyle::drawComplexControl(control, option, painter, widget);
+ else
+ QWindowsXPStyle::drawComplexControl(control, option, painter, widget);
+ }
+ break;
+
+ case CC_ToolButton:
+ if (const QStyleOptionToolButton *toolbutton = qstyleoption_cast<const QStyleOptionToolButton *>(option))
+ {
+ QRect button;
+ button = subControlRect(control, toolbutton, SC_ToolButton, widget);
+ if ((widget && qobject_cast<QToolBar*>(widget->parentWidget())) &&
+ ((toolbutton->state & State_MouseOver && toolbutton->state & State_Enabled)
+ || toolbutton->state & State_On)) {
+ QLinearGradient menubargradient2(button.topLeft(), button.bottomLeft());
+
+ bool act = (toolbutton->state & State_Sunken) || (toolbutton->state & State_On);
+ painter->setPen(d->highlightOutlineColor(option, act));
+ painter->setBrush(d->highlightBrush(option, act));
+ painter->drawRect(button.adjusted(0, 0, -2, -1));
+
+ QStyleOptionComplex comp;
+ comp.init(widget);
+ comp.rect = button;
+ QStyleOptionToolButton label = *toolbutton;
+ int fw = pixelMetric(PM_DefaultFrameWidth, option, widget);
+ label.rect = button.adjusted(fw, fw, -fw, -fw);
+ label.features &= ~QStyleOptionToolButton::Arrow;
+ drawControl(CE_ToolButtonLabel, &label, painter, widget);
+
+ if (toolbutton->subControls & SC_ToolButtonMenu) {
+ QStyleOption tool = *toolbutton;
+ tool.rect = QWindowsStyle::subControlRect(control, toolbutton, SC_ToolButtonMenu, widget);
+ painter->setPen(d->highlightOutlineColor(option, act));
+ painter->setBrush(d->highlightBrush(option, toolbutton->activeSubControls & SC_ToolButtonMenu));
+ painter->drawRect(tool.rect.adjusted(-2, 0, -1, -1));
+ tool.rect.adjust(2, 3, -2, -2);
+ drawPrimitive(PE_IndicatorArrowDown, &tool, painter, widget);
+ }
+ } else
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ QWindowsVistaStyle::drawComplexControl(control, option, painter, widget);
+ else
+ QWindowsXPStyle::drawComplexControl(control, option, painter, widget);
+ }
+ break;
+
+ default:
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ QWindowsVistaStyle::drawComplexControl(control, option, painter, widget);
+ else
+ QWindowsXPStyle::drawComplexControl(control, option, painter, widget);
+ break;
+ }
+}
+
+/*!
+ \reimp
+ */
+QSize DotNetStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const
+{
+ QSize newSize;
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ newSize = QWindowsVistaStyle::sizeFromContents(type, option, size, widget);
+ else
+ newSize = QWindowsXPStyle::sizeFromContents(type, option, size, widget);
+
+ switch (type) {
+ case CT_LineEdit:
+ if (widget && qobject_cast<QToolBar*>(widget->parentWidget())) {
+ newSize = QWindowsStyle::sizeFromContents(type, option, size, widget);
+ newSize += QSize(0, 2);
+ }
+ break;
+ case CT_ComboBox:
+ if (widget && qobject_cast<QToolBar*>(widget->parentWidget())) {
+ newSize = QWindowsStyle::sizeFromContents(type, option, size, widget);
+ newSize += QSize(0, 2);
+ }
+ break;
+ case CT_MenuBarItem:
+ newSize += QSize(0, 1);
+ break;
+ case CT_MenuItem:
+ if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ newSize = QWindowsStyle::sizeFromContents(type, option, size, widget);
+ if (menuitem->menuItemType == QStyleOptionMenuItem::Separator){
+ newSize.setHeight(2);
+ } else {
+ newSize.rwidth() += 10;
+ //ensure menu items have uniform height
+ if (newSize.height() < 22)
+ newSize.setHeight(22);
+ }
+ }
+ break;
+ case CT_Menu:
+ //work around for a menu frame issue (same as xp style)
+ newSize = size;
+ newSize -= QSize(1,2);
+ break;
+ default:
+ break;
+ }
+ return newSize;
+}
+
+/*!
+ \reimp
+ */
+QRect DotNetStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
+{
+ QRect rect;
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ rect = QWindowsVistaStyle::subElementRect(element, option, widget);
+ else
+ rect = QWindowsXPStyle::subElementRect(element, option, widget);
+ if (element == SE_DockWidgetCloseButton || element == SE_DockWidgetFloatButton)
+ rect.translate(0, 1);
+ return rect;
+}
+
+/*!
+ \reimp
+ */
+QRect DotNetStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option,
+ SubControl subControl, const QWidget *widget) const
+{
+ QRect rect;
+ if (control == CC_ComboBox && widget && qobject_cast<QToolBar*>(widget->parentWidget()))
+ rect = QWindowsStyle::subControlRect(control, option, subControl, widget);
+ else if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ rect = QWindowsVistaStyle::subControlRect(control, option, subControl, widget);
+ else
+ rect = QWindowsXPStyle::subControlRect(control, option, subControl, widget);
+
+ return rect;
+}
+
+/*!
+ \reimp
+ */
+QStyle::SubControl DotNetStyle::hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ const QPoint &pos, const QWidget *widget) const
+{
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ return QWindowsVistaStyle::hitTestComplexControl(control, option, pos, widget);
+ else
+ return QWindowsXPStyle::hitTestComplexControl(control, option, pos, widget);
+}
+
+/*!
+ \reimp
+ */
+int DotNetStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
+{
+ int retval = 0;
+
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ retval = QWindowsVistaStyle::pixelMetric(metric, option, widget);
+ else
+ retval = QWindowsXPStyle::pixelMetric(metric, option, widget);
+
+ switch (metric) {
+ case PM_ToolBarItemSpacing:
+ retval = 2;
+ break;
+ case PM_ToolBarIconSize:
+ retval = 16;
+ break;
+ case PM_MenuHMargin:
+ retval = 1;
+ break;
+ case PM_MenuVMargin:
+ retval = 1;
+ break;
+ case PM_MenuBarPanelWidth:
+ retval = 0;
+ break;
+ case PM_MenuPanelWidth:
+ retval = 1;
+ break;
+ case PM_DockWidgetTitleBarButtonMargin:
+ retval = 6;
+ break;
+ case PM_DefaultFrameWidth:
+ case PM_SpinBoxFrameWidth:
+ if (widget && qobject_cast<QToolBar*>(widget->parentWidget()))
+ retval = 2;
+ break;
+ case PM_ButtonShiftVertical:
+ case PM_ButtonShiftHorizontal:
+ if (widget && qobject_cast<QToolBar*>(widget->parentWidget()))
+ retval = 0;
+ break;
+ default:
+ break;
+ }
+ return retval;
+}
+
+/*!
+ \reimp
+ */
+QPalette DotNetStyle::standardPalette() const
+{
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ return QWindowsVistaStyle::standardPalette();
+ else
+ return QWindowsXPStyle::standardPalette();
+}
+
+
+void DotNetStylePrivate::updatePalette()
+{
+ //Detect color palette
+ const int maxlength = 256;
+ WCHAR themeFileName[maxlength];
+ WCHAR themeColor[maxlength];
+ internalPalette = Classic;
+ if (pIsAppThemed && pIsAppThemed() && pGetCurrentThemeName(themeFileName, maxlength, themeColor, maxlength, NULL, 0) == S_OK) {
+ QString name = QString::fromUtf16((ushort *)themeFileName);
+ QString color = QString::fromUtf16((ushort *)themeColor);
+ if (theme == DotNetStyle::Standard) {
+ if (name.endsWith("Luna.msstyles")) {
+ if (color == "Metallic")
+ internalPalette = Silver;
+ else
+ internalPalette = System;
+ }
+ } else { //Office style
+ if (name.endsWith("Luna.msstyles")) {
+ if (color == "HomeStead")
+ internalPalette = Olive;
+ else if (color == "Metallic")
+ internalPalette = Silver;
+ else
+ internalPalette = Blue;
+ } else if (name.endsWith("Aero.msstyles")) {
+ internalPalette = Blue;
+ }
+ }
+ }
+
+ switch (internalPalette) {
+ case Blue:
+ menuSeparatorColor = QColor(106, 140, 203);
+ menuBackgroundColor = QColor(246, 246, 246);
+ menuFrameColor = QColor(0, 45, 150);
+ break;
+ case Silver:
+ menuSeparatorColor = QColor(110, 109, 143);
+ menuBackgroundColor = QColor(254, 250, 255);
+ menuFrameColor = QColor(124, 124, 148);
+ break;
+ case Olive:
+ menuSeparatorColor = QColor(96, 128, 88);
+ menuBackgroundColor = QColor(244, 244, 238);
+ menuFrameColor = QColor(117, 141, 94);
+ break;
+ default:
+ menuFrameColor = currentPal.dark().color().lighter(108);
+ menuSeparatorColor = currentPal.background().color().darker(110);
+ menuBackgroundColor = currentPal.light().color();
+ menuBackgroundColor.setHsv(
+ menuBackgroundColor.hue(),
+ 3 * menuBackgroundColor.saturation()/8 ,
+ 250);
+ break;
+ }
+}
+
+/*!
+ \reimp
+ */
+void DotNetStyle::polish(QApplication *app)
+{
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ QWindowsVistaStyle::polish(app);
+ else
+ QWindowsXPStyle::polish(app);
+ d->currentPal = app->palette();
+ d->updatePalette();
+}
+
+/*!
+ \reimp
+ */
+void DotNetStyle::unpolish(QApplication *app)
+{
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ QWindowsVistaStyle::unpolish(app);
+ else
+ QWindowsXPStyle::unpolish(app);
+}
+
+/*!
+ \reimp
+ */
+void DotNetStyle::polish(QWidget *widget)
+{
+ if (qobject_cast<QMainWindow *>(widget))
+ widget->setAttribute(Qt::WA_StyledBackground);
+ else if (qobject_cast<QLineEdit*>(widget))
+ widget->setAttribute(Qt::WA_Hover);
+ else if (qobject_cast<QComboBox*>(widget))
+ widget->setAttribute(Qt::WA_Hover);
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ QWindowsVistaStyle::polish(widget);
+ else
+ QWindowsXPStyle::polish(widget);
+}
+
+/*!
+ \reimp
+ */
+void DotNetStyle::unpolish(QWidget *widget)
+{
+ if (qobject_cast<QMainWindow *>(widget))
+ widget->setAttribute(Qt::WA_StyledBackground, false);
+ else if (qobject_cast<QLineEdit*>(widget))
+ widget->setAttribute(Qt::WA_Hover, false);
+ else if (qobject_cast<QComboBox*>(widget))
+ widget->setAttribute(Qt::WA_Hover, false);
+
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ QWindowsVistaStyle::unpolish(widget);
+ else
+ QWindowsXPStyle::unpolish(widget);
+}
+
+/*!
+ \reimp
+ */
+void DotNetStyle::polish(QPalette &pal)
+{
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ QWindowsVistaStyle::polish(pal);
+ else
+ QWindowsXPStyle::polish(pal);
+}
+
+/*!
+ \reimp
+ */
+QPixmap DotNetStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *widget) const
+{
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ return QWindowsVistaStyle::standardPixmap(standardPixmap, opt, widget);
+ else
+ return QWindowsXPStyle::standardPixmap(standardPixmap, opt, widget);
+}
+
+/*!
+ \reimp
+*/
+int DotNetStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget,
+ QStyleHintReturn *returnData) const
+{
+ int ret = 0;
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ ret = QWindowsVistaStyle::styleHint(hint, option, widget, returnData);
+ else
+ ret = QWindowsXPStyle::styleHint(hint, option, widget, returnData);
+ return ret;
+}
+
+#endif //USE_DOTNET_STYLE
diff --git a/src/fqterm/3rdparty/dotnetstyle.h b/src/fqterm/3rdparty/dotnetstyle.h
new file mode 100644
index 0000000..16326b6
--- /dev/null
+++ b/src/fqterm/3rdparty/dotnetstyle.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2007-2007 Trolltech ASA. All rights reserved.
+**
+** This file is part of the DotNetStyle project on Trolltech Labs.
+**
+** This file may be used under the terms of the GNU General Public
+** License version 2.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of
+** this file. Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+** http://www.trolltech.com/products/qt/opensource.html
+**
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://www.trolltech.com/products/qt/licensing.html or contact the
+** sales department at sales@trolltech.com.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+
+#ifndef QTDOTNETSTYLE_H
+#define QTDOTNETSTYLE_H
+#ifdef USE_DOTNET_STYLE
+#include <QtGui/QWindowsVistastyle.h>
+
+class QLinearGradient;
+class QBrush;
+
+class DotNetStylePrivate;
+class DotNetStyle : public QWindowsVistaStyle
+{
+public:
+ enum ColorTheme {
+ Standard,
+ Office
+ };
+ DotNetStyle();
+
+ DotNetStyle(ColorTheme palette);
+
+ ~DotNetStyle();
+
+ void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget = 0) const;
+ void drawControl(ControlElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const;
+ void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const;
+ QSize sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const;
+
+ QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const;
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
+ SubControl sc, const QWidget *widget) const;
+
+ SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ const QPoint &pos, const QWidget *widget = 0) const;
+
+ QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *widget = 0) const;
+ int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0,
+ QStyleHintReturn *returnData = 0) const;
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
+ void polish(QWidget *widget);
+ void unpolish(QWidget *widget);
+ void polish(QPalette &pal);
+ void polish(QApplication *app);
+ void unpolish(QApplication *app);
+ QPalette standardPalette() const;
+ DotNetStylePrivate *d;
+};
+#endif //USE_DOTNET_STYLE
+#endif
diff --git a/src/fqterm/3rdparty/qxtglobal.h b/src/fqterm/3rdparty/qxtglobal.h
new file mode 100644
index 0000000..575372d
--- /dev/null
+++ b/src/fqterm/3rdparty/qxtglobal.h
@@ -0,0 +1,207 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtCore module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
+ **
+ ** <http://libqxt.org> <foundation@libqxt.org>
+ **
+ ****************************************************************************/
+
+#ifndef QXTGLOBAL_H
+#define QXTGLOBAL_H
+
+#include <QtGlobal>
+
+#define QXT_VERSION 0x000600
+#define QXT_VERSION_STR "0.6.0"
+
+//--------------------------global macros------------------------------
+
+#ifndef QXT_NO_MACROS
+
+#endif // QXT_NO_MACROS
+
+//--------------------------export macros------------------------------
+
+#define QXT_DLLEXPORT DO_NOT_USE_THIS_ANYMORE
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_CORE)
+# define QXT_CORE_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_CORE_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_CORE_EXPORT
+#endif // BUILD_QXT_CORE
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_GUI)
+# define QXT_GUI_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_GUI_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_GUI_EXPORT
+#endif // BUILD_QXT_GUI
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_NETWORK)
+# define QXT_NETWORK_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_NETWORK_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_NETWORK_EXPORT
+#endif // BUILD_QXT_NETWORK
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_SQL)
+# define QXT_SQL_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_SQL_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_SQL_EXPORT
+#endif // BUILD_QXT_SQL
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_WEB)
+# define QXT_WEB_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_WEB_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_WEB_EXPORT
+#endif // BUILD_QXT_WEB
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_BERKELEY)
+# define QXT_BERKELEY_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_BERKELEY_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_BERKELEY_EXPORT
+#endif // BUILD_QXT_BERKELEY
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_ZEROCONF)
+# define QXT_ZEROCONF_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_ZEROCONF_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_ZEROCONF_EXPORT
+#endif // QXT_ZEROCONF_EXPORT
+
+#if defined BUILD_QXT_CORE || defined BUILD_QXT_GUI || defined BUILD_QXT_SQL || defined BUILD_QXT_NETWORK || defined BUILD_QXT_WEB || defined BUILD_QXT_BERKELEY || defined BUILD_QXT_ZEROCONF
+# define BUILD_QXT
+#endif
+
+QXT_CORE_EXPORT const char* qxtVersion();
+
+#ifndef QT_BEGIN_NAMESPACE
+#define QT_BEGIN_NAMESPACE
+#endif
+
+#ifndef QT_END_NAMESPACE
+#define QT_END_NAMESPACE
+#endif
+
+#ifndef QT_FORWARD_DECLARE_CLASS
+#define QT_FORWARD_DECLARE_CLASS(Class) class Class;
+#endif
+
+/****************************************************************************
+** This file is derived from code bearing the following notice:
+** The sole author of this file, Adam Higerd, has explicitly disclaimed all
+** copyright interest and protection for the content within. This file has
+** been placed in the public domain according to United States copyright
+** statute and case law. In jurisdictions where this public domain dedication
+** is not legally recognized, anyone who receives a copy of this file is
+** permitted to use, modify, duplicate, and redistribute this file, in whole
+** or in part, with no restrictions or conditions. In these jurisdictions,
+** this file shall be copyright (C) 2006-2008 by Adam Higerd.
+****************************************************************************/
+
+#define QXT_DECLARE_PRIVATE(PUB) friend class PUB##Private; QxtPrivateInterface<PUB, PUB##Private> qxt_d;
+#define QXT_DECLARE_PUBLIC(PUB) friend class PUB;
+#define QXT_INIT_PRIVATE(PUB) qxt_d.setPublic(this);
+#define QXT_D(PUB) PUB##Private& d = qxt_d()
+#define QXT_P(PUB) PUB& p = qxt_p()
+
+template <typename PUB>
+class QxtPrivate
+{
+public:
+ virtual ~QxtPrivate()
+ {}
+ inline void QXT_setPublic(PUB* pub)
+ {
+ qxt_p_ptr = pub;
+ }
+
+protected:
+ inline PUB& qxt_p()
+ {
+ return *qxt_p_ptr;
+ }
+ inline const PUB& qxt_p() const
+ {
+ return *qxt_p_ptr;
+ }
+
+private:
+ PUB* qxt_p_ptr;
+};
+
+template <typename PUB, typename PVT>
+class QxtPrivateInterface
+{
+ friend class QxtPrivate<PUB>;
+public:
+ QxtPrivateInterface()
+ {
+ pvt = new PVT;
+ }
+ ~QxtPrivateInterface()
+ {
+ delete pvt;
+ }
+
+ inline void setPublic(PUB* pub)
+ {
+ pvt->QXT_setPublic(pub);
+ }
+ inline PVT& operator()()
+ {
+ return *static_cast<PVT*>(pvt);
+ }
+ inline const PVT& operator()() const
+ {
+ return *static_cast<PVT*>(pvt);
+ }
+private:
+ QxtPrivateInterface(const QxtPrivateInterface&) { }
+ QxtPrivateInterface& operator=(const QxtPrivateInterface&) { }
+ QxtPrivate<PUB>* pvt;
+};
+
+#endif // QXT_GLOBAL
diff --git a/src/fqterm/3rdparty/qxtglobalshortcut.cpp b/src/fqterm/3rdparty/qxtglobalshortcut.cpp
new file mode 100644
index 0000000..0d8f557
--- /dev/null
+++ b/src/fqterm/3rdparty/qxtglobalshortcut.cpp
@@ -0,0 +1,193 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtGui module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
+ **
+ ** <http://libqxt.org> <foundation@libqxt.org>
+ **
+ ****************************************************************************/
+#include "qxtglobalshortcut.h"
+#include "qxtglobalshortcut_p.h"
+#include <QAbstractEventDispatcher>
+#include <QtDebug>
+
+bool QxtGlobalShortcutPrivate::error = false;
+int QxtGlobalShortcutPrivate::ref = 0;
+QAbstractEventDispatcher::EventFilter QxtGlobalShortcutPrivate::prevEventFilter = 0;
+QHash<QPair<quint32, quint32>, QxtGlobalShortcut*> QxtGlobalShortcutPrivate::shortcuts;
+
+QxtGlobalShortcutPrivate::QxtGlobalShortcutPrivate() : enabled(true), key(Qt::Key(0)), mods(Qt::NoModifier)
+{
+ if (!ref++)
+ prevEventFilter = QAbstractEventDispatcher::instance()->setEventFilter(eventFilter);
+}
+
+QxtGlobalShortcutPrivate::~QxtGlobalShortcutPrivate()
+{
+ if (!--ref)
+ QAbstractEventDispatcher::instance()->setEventFilter(prevEventFilter);
+}
+
+bool QxtGlobalShortcutPrivate::setShortcut(const QKeySequence& shortcut)
+{
+ Qt::KeyboardModifiers allMods = Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier;
+ key = shortcut.isEmpty() ? Qt::Key(0) : Qt::Key((shortcut[0] ^ allMods) & shortcut[0]);
+ mods = shortcut.isEmpty() ? Qt::KeyboardModifiers(0) : Qt::KeyboardModifiers(shortcut[0] & allMods);
+ const quint32 nativeKey = nativeKeycode(key);
+ const quint32 nativeMods = nativeModifiers(mods);
+ const bool res = registerShortcut(nativeKey, nativeMods);
+ shortcuts.insert(qMakePair(nativeKey, nativeMods), &qxt_p());
+ if (!res)
+ qWarning() << "QxtGlobalShortcut failed to register:" << QKeySequence(key + mods).toString();
+ return res;
+}
+
+bool QxtGlobalShortcutPrivate::unsetShortcut()
+{
+ const quint32 nativeKey = nativeKeycode(key);
+ const quint32 nativeMods = nativeModifiers(mods);
+ const bool res = unregisterShortcut(nativeKey, nativeMods);
+ shortcuts.remove(qMakePair(nativeKey, nativeMods));
+ if (!res)
+ qWarning() << "QxtGlobalShortcut failed to unregister:" << QKeySequence(key + mods).toString();
+ key = Qt::Key(0);
+ mods = Qt::KeyboardModifiers(0);
+ return res;
+}
+
+void QxtGlobalShortcutPrivate::activateShortcut(quint32 nativeKey, quint32 nativeMods)
+{
+ QxtGlobalShortcut* shortcut = shortcuts.value(qMakePair(nativeKey, nativeMods));
+ if (shortcut && shortcut->isEnabled())
+ emit shortcut->activated();
+}
+
+/*!
+ \class QxtGlobalShortcut
+ \inmodule QxtGui
+ \brief The QxtGlobalShortcut class provides a global shortcut aka "hotkey".
+
+ A global shortcut triggers even if the application is not active. This
+ makes it easy to implement applications that react to certain shortcuts
+ still if some other application is active or if the application is for
+ example minimized to the system tray.
+
+ Example usage:
+ \code
+ QxtGlobalShortcut* shortcut = new QxtGlobalShortcut(window);
+ connect(shortcut, SIGNAL(activated()), window, SLOT(toggleVisibility()));
+ shortcut->setShortcut(QKeySequence("Ctrl+Shift+F12"));
+ \endcode
+
+ \bold {Note:} Since Qxt 0.6 QxtGlobalShortcut no more requires QxtApplication.
+ */
+
+/*!
+ \fn QxtGlobalShortcut::activated()
+
+ This signal is emitted when the user types the shortcut's key sequence.
+
+ \sa shortcut
+ */
+
+/*!
+ Constructs a new QxtGlobalShortcut with \a parent.
+ */
+QxtGlobalShortcut::QxtGlobalShortcut(QObject* parent)
+ : QObject(parent)
+{
+ QXT_INIT_PRIVATE(QxtGlobalShortcut);
+}
+
+/*!
+ Constructs a new QxtGlobalShortcut with \a shortcut and \a parent.
+ */
+QxtGlobalShortcut::QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent)
+ : QObject(parent)
+{
+ QXT_INIT_PRIVATE(QxtGlobalShortcut);
+ setShortcut(shortcut);
+}
+
+/*!
+ Destructs the QxtGlobalShortcut.
+ */
+QxtGlobalShortcut::~QxtGlobalShortcut()
+{
+ if (qxt_d().key != 0)
+ qxt_d().unsetShortcut();
+}
+
+/*!
+ \property QxtGlobalShortcut::shortcut
+ \brief the shortcut key sequence
+
+ \bold {Note:} Notice that corresponding key press and release events are not
+ delivered for registered global shortcuts even if they are disabled.
+ Also, comma separated key sequences are not supported.
+ Only the first part is used:
+
+ \code
+ qxtShortcut->setShortcut(QKeySequence("Ctrl+Alt+A,Ctrl+Alt+B"));
+ Q_ASSERT(qxtShortcut->shortcut() == QKeySequence("Ctrl+Alt+A"));
+ \endcode
+ */
+QKeySequence QxtGlobalShortcut::shortcut() const
+{
+ return QKeySequence(qxt_d().key | qxt_d().mods);
+}
+
+bool QxtGlobalShortcut::setShortcut(const QKeySequence& shortcut)
+{
+ if (qxt_d().key != 0)
+ qxt_d().unsetShortcut();
+ return qxt_d().setShortcut(shortcut);
+}
+
+/*!
+ \property QxtGlobalShortcut::enabled
+ \brief whether the shortcut is enabled
+
+ A disabled shortcut does not get activated.
+
+ The default value is \c true.
+
+ \sa setDisabled()
+ */
+bool QxtGlobalShortcut::isEnabled() const
+{
+ return qxt_d().enabled;
+}
+
+void QxtGlobalShortcut::setEnabled(bool enabled)
+{
+ qxt_d().enabled = enabled;
+}
+
+/*!
+ Sets the shortcut \a disabled.
+
+ \sa enabled
+ */
+void QxtGlobalShortcut::setDisabled(bool disabled)
+{
+ qxt_d().enabled = !disabled;
+}
+
+#include "qxtglobalshortcut.moc" \ No newline at end of file
diff --git a/src/fqterm/3rdparty/qxtglobalshortcut.h b/src/fqterm/3rdparty/qxtglobalshortcut.h
new file mode 100644
index 0000000..8a352b8
--- /dev/null
+++ b/src/fqterm/3rdparty/qxtglobalshortcut.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtGui module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
+ **
+ ** <http://libqxt.org> <foundation@libqxt.org>
+ **
+ ****************************************************************************/
+#ifndef QXTGLOBALSHORTCUT_H
+#define QXTGLOBALSHORTCUT_H
+
+#include "qxtglobal.h"
+#include <QObject>
+#include <QKeySequence>
+class QxtGlobalShortcutPrivate;
+
+class QxtGlobalShortcut : public QObject
+{
+ Q_OBJECT
+ QXT_DECLARE_PRIVATE(QxtGlobalShortcut)
+ Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
+ Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut)
+
+public:
+ explicit QxtGlobalShortcut(QObject* parent = 0);
+ explicit QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent = 0);
+ virtual ~QxtGlobalShortcut();
+
+ QKeySequence shortcut() const;
+ bool setShortcut(const QKeySequence& shortcut);
+
+ bool isEnabled() const;
+
+public Q_SLOTS:
+ void setEnabled(bool enabled = true);
+ void setDisabled(bool disabled = true);
+
+Q_SIGNALS:
+ void activated();
+};
+
+#endif // QXTGLOBALSHORTCUT_H
diff --git a/src/fqterm/3rdparty/qxtglobalshortcut_mac.cpp b/src/fqterm/3rdparty/qxtglobalshortcut_mac.cpp
new file mode 100644
index 0000000..7bfbf00
--- /dev/null
+++ b/src/fqterm/3rdparty/qxtglobalshortcut_mac.cpp
@@ -0,0 +1,262 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtGui module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
+ **
+ ** <http://libqxt.org> <foundation@libqxt.org>
+ **
+ ****************************************************************************/
+#include <Carbon/Carbon.h>
+#include "qxtglobalshortcut_p.h"
+#include <QMap>
+#include <QHash>
+#include <QtDebug>
+#include <QApplication>
+
+typedef QPair<uint, uint> Identifier;
+static QMap<quint32, EventHotKeyRef> keyRefs;
+static QHash<Identifier, quint32> keyIDs;
+static quint32 hotKeySerial = 0;
+static bool qxt_mac_handler_installed = false;
+
+OSStatus qxt_mac_handle_hot_key(EventHandlerCallRef nextHandler, EventRef event, void* data)
+{
+ // pass event to the app event filter
+ Q_UNUSED(data);
+ qApp->macEventFilter(nextHandler, event);
+ return noErr;
+}
+
+bool QxtGlobalShortcutPrivate::eventFilter(void* message)
+//bool QxtGlobalShortcutPrivate::macEventFilter(EventHandlerCallRef caller, EventRef event)
+{
+ EventRef event = (EventRef) message;
+ if (GetEventClass(event) == kEventClassKeyboard && GetEventKind(event) == kEventHotKeyPressed)
+ {
+ EventHotKeyID keyID;
+ GetEventParameter(event, kEventParamDirectObject, typeEventHotKeyID, NULL, sizeof(keyID), NULL, &keyID);
+ Identifier id = keyIDs.key(keyID.id);
+ activateShortcut(id.second, id.first);
+ }
+ return false;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers)
+{
+ quint32 native = 0;
+ if (modifiers & Qt::ShiftModifier)
+ native |= shiftKeyBit;
+ if (modifiers & Qt::ControlModifier)
+ native |= cmdKey;
+ if (modifiers & Qt::AltModifier)
+ native |= optionKey;
+ if (modifiers & Qt::MetaModifier)
+ native |= controlKey;
+ if (modifiers & Qt::KeypadModifier)
+ native |= kEventKeyModifierNumLockMask;
+ return native;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key)
+{
+ UTF16Char ch;
+ // Constants found in NSEvent.h from AppKit.framework
+ switch (key)
+ {
+ case Qt::Key_Return:
+ return kVK_Return;
+ case Qt::Key_Enter:
+ return kVK_ANSI_KeypadEnter;
+ case Qt::Key_Tab:
+ return kVK_Tab;
+ case Qt::Key_Space:
+ return kVK_Space;
+ case Qt::Key_Backspace:
+ return kVK_Delete;
+ case Qt::Key_Control:
+ return kVK_Command;
+ case Qt::Key_Shift:
+ return kVK_Shift;
+ case Qt::Key_CapsLock:
+ return kVK_CapsLock;
+ case Qt::Key_Option:
+ return kVK_Option;
+ case Qt::Key_Meta:
+ return kVK_Control;
+ case Qt::Key_F17:
+ return kVK_F17;
+ case Qt::Key_VolumeUp:
+ return kVK_VolumeUp;
+ case Qt::Key_VolumeDown:
+ return kVK_VolumeDown;
+ case Qt::Key_F18:
+ return kVK_F18;
+ case Qt::Key_F19:
+ return kVK_F19;
+ case Qt::Key_F20:
+ return kVK_F20;
+ case Qt::Key_F5:
+ return kVK_F5;
+ case Qt::Key_F6:
+ return kVK_F6;
+ case Qt::Key_F7:
+ return kVK_F7;
+ case Qt::Key_F3:
+ return kVK_F3;
+ case Qt::Key_F8:
+ return kVK_F8;
+ case Qt::Key_F9:
+ return kVK_F9;
+ case Qt::Key_F11:
+ return kVK_F11;
+ case Qt::Key_F13:
+ return kVK_F13;
+ case Qt::Key_F16:
+ return kVK_F16;
+ case Qt::Key_F14:
+ return kVK_F14;
+ case Qt::Key_F10:
+ return kVK_F10;
+ case Qt::Key_F12:
+ return kVK_F12;
+ case Qt::Key_F15:
+ return kVK_F15;
+ case Qt::Key_Help:
+ return kVK_Help;
+ case Qt::Key_Home:
+ return kVK_Home;
+ case Qt::Key_PageUp:
+ return kVK_PageUp;
+ case Qt::Key_Delete:
+ return kVK_ForwardDelete;
+ case Qt::Key_F4:
+ return kVK_F4;
+ case Qt::Key_End:
+ return kVK_End;
+ case Qt::Key_F2:
+ return kVK_F2;
+ case Qt::Key_PageDown:
+ return kVK_PageDown;
+ case Qt::Key_F1:
+ return kVK_F1;
+ case Qt::Key_Left:
+ return kVK_LeftArrow;
+ case Qt::Key_Right:
+ return kVK_RightArrow;
+ case Qt::Key_Down:
+ return kVK_DownArrow;
+ case Qt::Key_Up:
+ return kVK_UpArrow;
+ default:
+ ;
+ }
+
+ if (key == Qt::Key_Escape) ch = 27;
+ else if (key == Qt::Key_Return) ch = 13;
+ else if (key == Qt::Key_Enter) ch = 3;
+ else if (key == Qt::Key_Tab) ch = 9;
+ else ch = key;
+
+ CFDataRef currentLayoutData;
+ TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
+
+ if (currentKeyboard == NULL)
+ return 0;
+
+ currentLayoutData = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
+ CFRelease(currentKeyboard);
+ if (currentLayoutData == NULL)
+ return 0;
+
+ UCKeyboardLayout* header = (UCKeyboardLayout*)CFDataGetBytePtr(currentLayoutData);
+ UCKeyboardTypeHeader* table = header->keyboardTypeList;
+
+ uint8_t *data = (uint8_t*)header;
+ // God, would a little documentation for this shit kill you...
+ for (quint32 i=0; i < header->keyboardTypeCount; i++)
+ {
+ UCKeyStateRecordsIndex* stateRec = 0;
+ if (table[i].keyStateRecordsIndexOffset != 0)
+ {
+ stateRec = reinterpret_cast<UCKeyStateRecordsIndex*>(data + table[i].keyStateRecordsIndexOffset);
+ if (stateRec->keyStateRecordsIndexFormat != kUCKeyStateRecordsIndexFormat) stateRec = 0;
+ }
+
+ UCKeyToCharTableIndex* charTable = reinterpret_cast<UCKeyToCharTableIndex*>(data + table[i].keyToCharTableIndexOffset);
+ if (charTable->keyToCharTableIndexFormat != kUCKeyToCharTableIndexFormat) continue;
+
+ for (quint32 j=0; j < charTable->keyToCharTableCount; j++)
+ {
+ UCKeyOutput* keyToChar = reinterpret_cast<UCKeyOutput*>(data + charTable->keyToCharTableOffsets[j]);
+ for (quint32 k=0; k < charTable->keyToCharTableSize; k++)
+ {
+ if (keyToChar[k] & kUCKeyOutputTestForIndexMask)
+ {
+ long idx = keyToChar[k] & kUCKeyOutputGetIndexMask;
+ if (stateRec && idx < stateRec->keyStateRecordCount)
+ {
+ UCKeyStateRecord* rec = reinterpret_cast<UCKeyStateRecord*>(data + stateRec->keyStateRecordOffsets[idx]);
+ if (rec->stateZeroCharData == ch) return k;
+ }
+ }
+ else if (!(keyToChar[k] & kUCKeyOutputSequenceIndexMask) && keyToChar[k] < 0xFFFE)
+ {
+ if (keyToChar[k] == ch) return k;
+ }
+ } // for k
+ } // for j
+ } // for i
+
+ return 0;
+}
+
+bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods)
+{
+ if (!qxt_mac_handler_installed)
+ {
+ EventTypeSpec t;
+ t.eventClass = kEventClassKeyboard;
+ t.eventKind = kEventHotKeyPressed;
+ InstallApplicationEventHandler(&qxt_mac_handle_hot_key, 1, &t, NULL, NULL);
+ }
+
+ EventHotKeyID keyID;
+ keyID.signature = 'cute';
+ keyID.id = ++hotKeySerial;
+
+ EventHotKeyRef ref = 0;
+ bool rv = !RegisterEventHotKey(nativeKey, nativeMods, keyID, GetApplicationEventTarget(), 0, &ref);
+ if (rv)
+ {
+ keyIDs.insert(Identifier(nativeMods, nativeKey), keyID.id);
+ keyRefs.insert(keyID.id, ref);
+ }
+ qDebug() << ref;
+ return rv;
+}
+
+bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods)
+{
+ Identifier id(nativeMods, nativeKey);
+ if (!keyIDs.contains(id)) return false;
+
+ EventHotKeyRef ref = keyRefs.take(keyIDs[id]);
+ keyIDs.remove(id);
+ return !UnregisterEventHotKey(ref);
+}
diff --git a/src/fqterm/3rdparty/qxtglobalshortcut_p.h b/src/fqterm/3rdparty/qxtglobalshortcut_p.h
new file mode 100644
index 0000000..4570396
--- /dev/null
+++ b/src/fqterm/3rdparty/qxtglobalshortcut_p.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtGui module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
+ **
+ ** <http://libqxt.org> <foundation@libqxt.org>
+ **
+ ****************************************************************************/
+#ifndef QXTGLOBALSHORTCUT_P_H
+#define QXTGLOBALSHORTCUT_P_H
+
+#include "qxtglobalshortcut.h"
+#include <QAbstractEventDispatcher>
+#include <QKeySequence>
+#include <QHash>
+
+class QxtGlobalShortcutPrivate : public QxtPrivate<QxtGlobalShortcut>
+{
+public:
+ QXT_DECLARE_PUBLIC(QxtGlobalShortcut)
+ QxtGlobalShortcutPrivate();
+ ~QxtGlobalShortcutPrivate();
+
+ bool enabled;
+ Qt::Key key;
+ Qt::KeyboardModifiers mods;
+
+ bool setShortcut(const QKeySequence& shortcut);
+ bool unsetShortcut();
+
+ static bool error;
+ static int ref;
+ static QAbstractEventDispatcher::EventFilter prevEventFilter;
+ static bool eventFilter(void* message);
+
+private:
+ static quint32 nativeKeycode(Qt::Key keycode);
+ static quint32 nativeModifiers(Qt::KeyboardModifiers modifiers);
+
+ static bool registerShortcut(quint32 nativeKey, quint32 nativeMods);
+ static bool unregisterShortcut(quint32 nativeKey, quint32 nativeMods);
+ static void activateShortcut(quint32 nativeKey, quint32 nativeMods);
+
+ static QHash<QPair<quint32, quint32>, QxtGlobalShortcut*> shortcuts;
+};
+
+#endif // QXTGLOBALSHORTCUT_P_H
diff --git a/src/fqterm/3rdparty/qxtglobalshortcut_win.cpp b/src/fqterm/3rdparty/qxtglobalshortcut_win.cpp
new file mode 100644
index 0000000..4099989
--- /dev/null
+++ b/src/fqterm/3rdparty/qxtglobalshortcut_win.cpp
@@ -0,0 +1,214 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtGui module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
+ **
+ ** <http://libqxt.org> <foundation@libqxt.org>
+ **
+ ****************************************************************************/
+#include "qxtglobalshortcut_p.h"
+#include <qt_windows.h>
+
+bool QxtGlobalShortcutPrivate::eventFilter(void* message)
+{
+ MSG* msg = static_cast<MSG*>(message);
+ if (msg->message == WM_HOTKEY)
+ {
+ const quint32 keycode = HIWORD(msg->lParam);
+ const quint32 modifiers = LOWORD(msg->lParam);
+ activateShortcut(keycode, modifiers);
+ }
+ return false;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers)
+{
+ // MOD_ALT, MOD_CONTROL, (MOD_KEYUP), MOD_SHIFT, MOD_WIN
+ quint32 native = 0;
+ if (modifiers & Qt::ShiftModifier)
+ native |= MOD_SHIFT;
+ if (modifiers & Qt::ControlModifier)
+ native |= MOD_CONTROL;
+ if (modifiers & Qt::AltModifier)
+ native |= MOD_ALT;
+ if (modifiers & Qt::MetaModifier)
+ native |= MOD_WIN;
+ // TODO: resolve these?
+ //if (modifiers & Qt::KeypadModifier)
+ //if (modifiers & Qt::GroupSwitchModifier)
+ return native;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key)
+{
+ switch (key)
+ {
+ case Qt::Key_Escape:
+ return VK_ESCAPE;
+ case Qt::Key_Tab:
+ case Qt::Key_Backtab:
+ return VK_TAB;
+ case Qt::Key_Backspace:
+ return VK_BACK;
+ case Qt::Key_Return:
+ case Qt::Key_Enter:
+ return VK_RETURN;
+ case Qt::Key_Insert:
+ return VK_INSERT;
+ case Qt::Key_Delete:
+ return VK_DELETE;
+ case Qt::Key_Pause:
+ return VK_PAUSE;
+ case Qt::Key_Print:
+ return VK_PRINT;
+ case Qt::Key_Clear:
+ return VK_CLEAR;
+ case Qt::Key_Home:
+ return VK_HOME;
+ case Qt::Key_End:
+ return VK_END;
+ case Qt::Key_Left:
+ return VK_LEFT;
+ case Qt::Key_Up:
+ return VK_UP;
+ case Qt::Key_Right:
+ return VK_RIGHT;
+ case Qt::Key_Down:
+ return VK_DOWN;
+ case Qt::Key_PageUp:
+ return VK_PRIOR;
+ case Qt::Key_PageDown:
+ return VK_NEXT;
+ case Qt::Key_F1:
+ return VK_F1;
+ case Qt::Key_F2:
+ return VK_F2;
+ case Qt::Key_F3:
+ return VK_F3;
+ case Qt::Key_F4:
+ return VK_F4;
+ case Qt::Key_F5:
+ return VK_F5;
+ case Qt::Key_F6:
+ return VK_F6;
+ case Qt::Key_F7:
+ return VK_F7;
+ case Qt::Key_F8:
+ return VK_F8;
+ case Qt::Key_F9:
+ return VK_F9;
+ case Qt::Key_F10:
+ return VK_F10;
+ case Qt::Key_F11:
+ return VK_F11;
+ case Qt::Key_F12:
+ return VK_F12;
+ case Qt::Key_F13:
+ return VK_F13;
+ case Qt::Key_F14:
+ return VK_F14;
+ case Qt::Key_F15:
+ return VK_F15;
+ case Qt::Key_F16:
+ return VK_F16;
+ case Qt::Key_F17:
+ return VK_F17;
+ case Qt::Key_F18:
+ return VK_F18;
+ case Qt::Key_F19:
+ return VK_F19;
+ case Qt::Key_F20:
+ return VK_F20;
+ case Qt::Key_F21:
+ return VK_F21;
+ case Qt::Key_F22:
+ return VK_F22;
+ case Qt::Key_F23:
+ return VK_F23;
+ case Qt::Key_F24:
+ return VK_F24;
+ case Qt::Key_Space:
+ return VK_SPACE;
+ case Qt::Key_Asterisk:
+ return VK_MULTIPLY;
+ case Qt::Key_Plus:
+ return VK_ADD;
+ case Qt::Key_Comma:
+ return VK_SEPARATOR;
+ case Qt::Key_Minus:
+ return VK_SUBTRACT;
+ case Qt::Key_Slash:
+ return VK_DIVIDE;
+
+ // numbers
+ case Qt::Key_0:
+ case Qt::Key_1:
+ case Qt::Key_2:
+ case Qt::Key_3:
+ case Qt::Key_4:
+ case Qt::Key_5:
+ case Qt::Key_6:
+ case Qt::Key_7:
+ case Qt::Key_8:
+ case Qt::Key_9:
+ return key;
+
+ // letters
+ case Qt::Key_A:
+ case Qt::Key_B:
+ case Qt::Key_C:
+ case Qt::Key_D:
+ case Qt::Key_E:
+ case Qt::Key_F:
+ case Qt::Key_G:
+ case Qt::Key_H:
+ case Qt::Key_I:
+ case Qt::Key_J:
+ case Qt::Key_K:
+ case Qt::Key_L:
+ case Qt::Key_M:
+ case Qt::Key_N:
+ case Qt::Key_O:
+ case Qt::Key_P:
+ case Qt::Key_Q:
+ case Qt::Key_R:
+ case Qt::Key_S:
+ case Qt::Key_T:
+ case Qt::Key_U:
+ case Qt::Key_V:
+ case Qt::Key_W:
+ case Qt::Key_X:
+ case Qt::Key_Y:
+ case Qt::Key_Z:
+ return key;
+
+ default:
+ return 0;
+ }
+}
+
+bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods)
+{
+ return RegisterHotKey(0, nativeMods ^ nativeKey, nativeMods, nativeKey);
+}
+
+bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods)
+{
+ return UnregisterHotKey(0, nativeMods ^ nativeKey);
+}
diff --git a/src/fqterm/3rdparty/qxtglobalshortcut_x11.cpp b/src/fqterm/3rdparty/qxtglobalshortcut_x11.cpp
new file mode 100644
index 0000000..2b2e6b7
--- /dev/null
+++ b/src/fqterm/3rdparty/qxtglobalshortcut_x11.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtGui module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
+ **
+ ** <http://libqxt.org> <foundation@libqxt.org>
+ **
+ ****************************************************************************/
+#include "qxtglobalshortcut_p.h"
+#include <QX11Info>
+#include <X11/Xlib.h>
+
+static int (*original_x_errhandler)(Display* display, XErrorEvent* event);
+
+static int qxt_x_errhandler(Display* display, XErrorEvent *event)
+{
+ Q_UNUSED(display);
+ switch (event->error_code)
+ {
+ case BadAccess:
+ case BadValue:
+ case BadWindow:
+ if (event->request_code == 33 /* X_GrabKey */ ||
+ event->request_code == 34 /* X_UngrabKey */)
+ {
+ QxtGlobalShortcutPrivate::error = true;
+ //TODO:
+ //char errstr[256];
+ //XGetErrorText(dpy, err->error_code, errstr, 256);
+ }
+ default:
+ return 0;
+ }
+}
+
+bool QxtGlobalShortcutPrivate::eventFilter(void* message)
+{
+ XEvent* event = static_cast<XEvent*>(message);
+ if (event->type == KeyPress)
+ {
+ XKeyEvent* key = (XKeyEvent*) event;
+ activateShortcut(key->keycode,
+ // Mod1Mask == Alt, Mod4Mask == Meta
+ key->state & (ShiftMask | ControlMask | Mod1Mask | Mod4Mask));
+ }
+ return false;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers)
+{
+ // ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, and Mod5Mask
+ quint32 native = 0;
+ if (modifiers & Qt::ShiftModifier)
+ native |= ShiftMask;
+ if (modifiers & Qt::ControlModifier)
+ native |= ControlMask;
+ if (modifiers & Qt::AltModifier)
+ native |= Mod1Mask;
+ // TODO: resolve these?
+ //if (modifiers & Qt::MetaModifier)
+ //if (modifiers & Qt::KeypadModifier)
+ //if (modifiers & Qt::GroupSwitchModifier)
+ return native;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key)
+{
+ Display* display = QX11Info::display();
+ return XKeysymToKeycode(display, XStringToKeysym(QKeySequence(key).toString().toLatin1().data()));
+}
+
+bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods)
+{
+ Display* display = QX11Info::display();
+ Window window = QX11Info::appRootWindow();
+ Bool owner = True;
+ int pointer = GrabModeAsync;
+ int keyboard = GrabModeAsync;
+ error = false;
+ original_x_errhandler = XSetErrorHandler(qxt_x_errhandler);
+ XGrabKey(display, nativeKey, nativeMods, window, owner, pointer, keyboard);
+ XGrabKey(display, nativeKey, nativeMods | Mod2Mask, window, owner, pointer, keyboard); // allow numlock
+ XSync(display, False);
+ XSetErrorHandler(original_x_errhandler);
+ return !error;
+}
+
+bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods)
+{
+ Display* display = QX11Info::display();
+ Window window = QX11Info::appRootWindow();
+ error = false;
+ original_x_errhandler = XSetErrorHandler(qxt_x_errhandler);
+ XUngrabKey(display, nativeKey, nativeMods, window);
+ XUngrabKey(display, nativeKey, nativeMods | Mod2Mask, window); // allow numlock
+ XSync(display, False);
+ XSetErrorHandler(original_x_errhandler);
+ return !error;
+}
diff --git a/src/fqterm/3rdparty/uaocodec.cpp b/src/fqterm/3rdparty/uaocodec.cpp
new file mode 100644
index 0000000..2e70b78
--- /dev/null
+++ b/src/fqterm/3rdparty/uaocodec.cpp
@@ -0,0 +1,15761 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "uaocodec.h"
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_TEXTCODEC
+
+#define InRange(c, lower, upper) (((c) >= (lower)) && ((c) <= (upper)))
+#define IsLatin(c) ((c) < 0x80)
+#define IsFirstByte(c) (InRange((c), 0x81, 0xFE))
+#define IsSecondByteRange1(c) (InRange((c), 0x40, 0x7E))
+#define IsSecondByteRange2(c) (InRange((c), 0xA1, 0xFE))
+#define IsSecondByte(c) (IsSecondByteRange1(c) || IsSecondByteRange2(c))
+
+#define QValidChar(u) ((u) ? QChar((ushort)(u)) : QChar(QChar::ReplacementCharacter))
+
+
+int UAOCodec::_mibEnum()
+{
+ return 0;
+}
+
+QByteArray UAOCodec::_name()
+{
+ return "UAO";
+}
+
+/*
+ * ucs4 to big5hkscs convert routing
+ */
+
+typedef struct {
+ ushort index; /* index into big table */
+ ushort used; /* bitmask of used entries */
+} Summary16;
+
+static const ushort big5_to_ucs[] =
+{
+19991, 20002, 20012, 20053, 20066, 20106, 20144, 20203, 20205, 20220,
+20252, 20362, 20479, 20546, 20560, 20600, 20696, 20702, 20724, 20758,
+20810, 20817, 20836, 20842, 20869, 20880, 20893, 20902, 20904, 20905,
+20935, 20950, 20955, 20972, 20988, 21003, 21012, 21013, 21024, 21035,
+21049, 21071, 21105, 21136, 21138, 21140, 21148, 21167, 21173, 21200,
+21248, 21255, 21284, 21318, 21343, 21395, 21424, 21469, 21539, 21584,
+21585, 21642, 21661, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 21667, 21684, 21712,
+21795, 21823, 21836, 21843, 21853, 21868, 21918, 21929, 21996, 22005,
+22051, 22096, 22140, 22154, 22164, 22176, 22191, 22232, 22272, 22361,
+22373, 22399, 22405, 22409, 22433, 22444, 22452, 22464, 22472, 22483,
+22511, 22596, 22636, 22674, 22682, 22706, 22712, 22757, 22779, 22786,
+22795, 22800, 22808, 22811, 29836, 29837, 29849, 29851, 29860, 29876,
+29881, 29896, 29900, 29904, 29907, 30018, 30037, 30062, 30093, 30110,
+30172, 30252, 30287, 30289, 30323, 30324, 30373, 30425, 30478, 30479,
+30552, 30578, 30583, 30584, 30586, 30587, 30616, 30639, 30654, 30659,
+30661, 30667, 30685, 30694, 30708, 30750, 30781, 30786, 30788, 30795,
+30801, 21782, 22775, 38964, 33883, 28948, 33398, 35158, 40236, 40206,
+36527, 24674, 26214, 34510, 25785, 37772, 22107, 28485, 35532, 29001,
+24012, 34633, 39464, 31658, 36107, 39255, 23597, 32331, 38938, 20518,
+25458, 40568, 30783, 40633, 40634, 36046, 35715, 61305, 33931, 37284,
+31331, 25776, 24061, 24214, 32865, 26965, 31466, 28710, 26812, 31095,
+28060, 36841, 31074, 22178, 34687, 21093, 31108, 28300, 37271, 31622,
+38956, 26717, 20397, 34222, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 31725, 34635,
+20534, 26893, 27542, 24910, 20855, 30495, 20516, 32622, 30452, 27097,
+24803, 25334, 21599, 38788, 22092, 20677, 22040, 34398, 22834, 22875,
+22877, 22883, 22892, 22939, 22999, 23019, 23066, 23210, 23248, 23281,
+23350, 23497, 23539, 23571, 23580, 23582, 23635, 23705, 23708, 23738,
+23739, 23745, 23797, 23802, 23829, 23832, 23870, 23891, 23900, 23917,
+23923, 23924, 23948, 23952, 23993, 24016, 24019, 24135, 24164, 24271,
+24272, 24298, 24304, 24329, 24332, 24337, 24353, 24372, 24385, 24389,
+24401, 24412, 24422, 24451, 24560, 24650, 24672, 24715, 24742, 24798,
+24849, 24864, 24865, 24892, 24893, 24984, 25015, 25076, 25107, 25117,
+25118, 25143, 24186, 27664, 21454, 20267, 20302, 21556, 22257, 22766,
+22841, 22918, 23596, 20915, 20914, 28798, 35265, 35282, 36125, 36710,
+20122, 26469, 20177, 20004, 21327, 23626, 20872, 24213, 25269, 19996,
+20105, 29366, 31868, 32416, 21351, 36711, 37048, 38271, 38376, 20384,
+20387, 20822, 21017, 21170, 21364, 22850, 24069, 26594, 27769, 20026,
+32419, 32418, 32426, 32427, 32421, 32422, 32417, 32989, 33486, 35745,
+35746, 35747, 36126, 36127, 20891, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 36712,
+38377, 38886, 39029, 39118, 39134, 20457, 20204, 20261, 20010, 20262,
+20179, 20923, 21018, 21093, 21592, 23089, 23385, 23777, 23707, 23704,
+24072, 24211, 24452, 25375, 26102, 26187, 20070, 27902, 27971, 20044,
+29421, 29384, 20137, 30757, 31210, 32442, 32433, 32441, 32431, 32445,
+32432, 32423, 32429, 32435, 32440, 32439, 32961, 33033, 21005, 35760,
+35750, 35752, 35751, 35754, 35759, 35757, 35755, 23682, 36130, 36129,
+36713, 36715, 38025, 38024, 38026, 38027, 38378, 38453, 38485, 38473,
+39269, 39532, 39592, 20266, 20255, 20390, 20391, 21153, 21160, 21306,
+21442, 21713, 38382, 34900, 22269, 22362, 22441, 25191, 22815, 23044,
+22919, 19987, 23558, 23625, 23781, 23703, 24102, 24080, 24352, 24378,
+20174, 24469, 20932, 24581, 25195, 25346, 25194, 25249, 25379, 36133,
+21551, 26011, 26025, 26172, 21206, 24323, 26465, 26541, 26432, 27682,
+20937, 27973, 28170, 27882, 27814, 20928, 29301, 29424, 29616, 20135,
+27605, 24322, 20247, 32458, 32479, 32461, 32459, 32460, 32454, 32453,
+32452, 32456, 32449, 32450, 38069, 20064, 33626, 33550, 33682, 24196,
+33483, 22788, 26415, 34926, 35269, 35268, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+35775, 35766, 35776, 35767, 35768, 35774, 35772, 35769, 36137, 36131,
+36143, 36135, 36138, 36139, 36717, 36719, 36825, 36830, 36851, 38039,
+38035, 38031, 38034, 38381, 38472, 38470, 38452, 39030, 39031, 40060,
+40479, 21348, 40614, 22791, 20263, 20254, 20975, 21056, 21019, 21171,
+21195, 20007, 21333, 21727, 21796, 20052, 22260, 23591, 22330, 25253,
+22490, 22774, 23090, 23547, 23706, 24103, 24079, 21397, 21417, 24694,
+38391, 24812, 24699, 24700, 25315, 25381, 25442, 25196, 26531, 26635,
+26632, 38054, 27531, 22771, 27695, 27689, 28044, 20945, 28270, 28065,
+27748, 27979, 27985, 28067, 26080, 29369, 33487, 30011, 30153, 21457,
+30423, 30746, 31174, 31383, 31508, 31499, 32478, 32467, 32466, 32477,
+19997, 32476, 32473, 32474, 32470, 32475, 32899, 32958, 32960, 21326,
+33713, 33484, 34394, 35270, 35780, 35789, 35777, 35778, 35791, 35781,
+35784, 35787, 35785, 35786, 35779, 36142, 36148, 36144, 36155, 36146,
+36153, 36154, 36149, 20080, 36140, 36152, 36151, 36722, 36724, 36726,
+36827, 37038, 20065, 38046, 38062, 38041, 38048, 38055, 38045, 38052,
+38051, 38389, 38384, 24320, 38386, 38388, 38387, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 38431, 38454, 38451, 38887, 39033, 39034, 39035, 39274, 39277,
+39272, 39278, 39276, 20911, 39533, 20081, 20538, 20256, 20165, 20542,
+20260, 20588, 38130, 21183, 31215, 27719, 21527, 21596, 21595, 22253,
+22278, 28034, 22359, 22366, 22488, 33556, 22885, 22920, 29233, 24574,
+24582, 24698, 25439, 25250, 25443, 26500, 26198, 26197, 26104, 20250,
+19994, 26497, 26472, 26722, 26539, 23681, 27807, 28781, 28287, 28369,
+27815, 28902, 28860, 28800, 28949, 29239, 29422, 29502, 29682, 24403,
+30415, 30544, 30529, 38606, 30860, 33410, 31509, 31908, 32463, 32482,
+32465, 32485, 32486, 20041, 32673, 22307, 32928, 33050, 32959, 33041,
+33636, 33479, 21494, 33716, 34398, 34383, 21495, 34568, 34476, 34917,
+35013, 35815, 35813, 35814, 35797, 35799, 35800, 35801, 35811, 35802,
+35805, 35803, 35809, 35810, 35808, 35807, 36156, 36164, 36158, 36159,
+36160, 36161, 36162, 36165, 36739, 36733, 36732, 36734, 20892, 36816,
+36798, 36829, 36807, 37049, 38068, 38067, 38073, 38072, 38078, 38080,
+38085, 38057, 38082, 38083, 38089, 38091, 38044, 38093, 38079, 38086,
+38392, 38504, 38589, 30005, 39044, 39037, 39039, 39036, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 39041, 39042, 39282, 39284, 39281, 39280, 39536, 39534,
+39535, 40480, 20389, 20392, 21294, 21388, 23581, 21589, 21497, 21949,
+21863, 21716, 22242, 22270, 23576, 22443, 22545, 23551, 26790, 22842,
+22849, 22954, 23454, 23517, 23545, 23649, 23853, 23702, 24065, 24124,
+24443, 24577, 24815, 24696, 24813, 24808, 25602, 25524, 25530, 30021,
+33635, 26538, 28378, 28173, 27721, 28385, 28382, 28176, 28072, 28063,
+27818, 28180, 28183, 28068, 33639, 23572, 33638, 29425, 29712, 29595,
+30111, 30113, 30127, 30186, 23613, 30417, 30805, 31087, 31096, 31181,
+31216, 27964, 31389, 31546, 31581, 32509, 32510, 32508, 32496, 32491,
+32511, 32039, 32512, 32434, 32494, 32504, 32501, 32438, 32500, 32490,
+32513, 32502, 32602, 38395, 33669, 30422, 33642, 33485, 34432, 35829,
+35821, 35820, 35748, 35819, 35823, 35828, 35824, 35826, 35825, 35827,
+35822, 23486, 36168, 36170, 36213, 36214, 36741, 36740, 36731, 36828,
+36874, 36882, 38128, 38134, 38108, 38125, 38114, 38124, 38120, 38133,
+38115, 38402, 38394, 38397, 38401, 38400, 38469, 39047, 39046, 39122,
+39290, 39292, 39285, 39287, 39539, 32942, 39600, 40483, 40482, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 20964, 40784, 20159, 20202, 20215, 20396, 20393,
+20461, 21095, 21016, 21073, 21053, 21385, 21792, 22068, 21719, 22040,
+21943, 21880, 21501, 22687, 22367, 22368, 22549, 23092, 23157, 22953,
+23047, 23046, 23485, 23457, 20889, 23618, 23956, 24092, 24223, 21416,
+24217, 21422, 24191, 24377, 24198, 34385, 24551, 24578, 24751, 24814,
+24868, 24579, 25370, 25169, 25438, 25320, 25376, 25242, 25528, 25599,
+25932, 25968, 26242, 26165, 26679, 26729, 26530, 26631, 27004, 26728,
+20048, 26526, 27431, 27527, 27572, 27974, 27900, 27905, 27975, 28291,
+28070, 28071, 27988, 28909, 22870, 33721, 30126, 30353, 30385, 30424,
+30830, 30721, 31377, 31351, 32532, 32451, 32428, 32516, 32517, 32521,
+32534, 32536, 32447, 32526, 32531, 32525, 32514, 32520, 32519, 39554,
+32610, 33014, 32932, 33714, 33643, 33931, 34430, 34583, 21355, 35850,
+35845, 35848, 35846, 35806, 35831, 35832, 35838, 35839, 35844, 35843,
+35841, 35770, 35812, 35847, 35837, 35840, 31446, 36180, 36175, 36171,
+36145, 36134, 36172, 36132, 21334, 36176, 36136, 36179, 36341, 36745,
+36742, 36749, 36744, 36743, 36718, 36750, 36747, 36746, 36866, 36801,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 37051, 37073, 37011, 38156, 38161, 38144,
+38138, 38096, 38148, 38109, 38160, 38153, 38155, 38049, 38146, 38398,
+38405, 24041, 39049, 39052, 20859, 39295, 39297, 39548, 39547, 39543,
+39542, 39549, 39550, 39545, 39544, 39607, 38393, 40063, 40065, 40489,
+40486, 40632, 40831, 20454, 20647, 20394, 24130, 21058, 21544, 21725,
+22003, 22438, 22363, 22859, 34949, 23398, 23548, 23466, 20973, 24811,
+25044, 24518, 25112, 25317, 25377, 25374, 25454, 25523, 25321, 25441,
+25285, 25373, 21382, 26195, 26196, 26137, 26726, 27178, 26641, 26925,
+26725, 26426, 26721, 28096, 27987, 27901, 27978, 27811, 28582, 28177,
+28861, 28903, 28783, 28907, 28950, 29420, 29585, 29935, 30232, 21346,
+30610, 30742, 30875, 31215, 39062, 31267, 31397, 31491, 31579, 32546,
+32547, 33830, 32538, 21439, 32543, 32540, 32537, 32457, 33147, 20852,
+33329, 33633, 33831, 33436, 34434, 33828, 35044, 20146, 35278, 35867,
+35866, 35855, 35763, 35851, 35853, 35856, 35864, 35834, 35858, 35859,
+35773, 35861, 35865, 35852, 35862, 36182, 36752, 36753, 36755, 36751,
+21150, 36873, 36831, 36797, 36951, 37050, 38189, 38191, 38192, 38169,
+38065, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 38050, 38177, 24405, 38126, 38181,
+38182, 38175, 38178, 38193, 38414, 38543, 38505, 38745, 33148, 39050,
+39048, 39057, 39060, 22836, 39059, 39056, 39302, 39279, 39300, 39301,
+39559, 39560, 39558, 39608, 39612, 40077, 40501, 40490, 40495, 40493,
+40499, 40857, 40863, 20248, 20607, 20648, 21169, 21659, 21523, 21387,
+22489, 23156, 23252, 23351, 23604, 23654, 23679, 23896, 24110, 24357,
+24212, 24691, 25103, 20987, 25380, 25319, 25311, 25601, 25947, 27609,
+26279, 26723, 26816, 26727, 26633, 27183, 27539, 27617, 27870, 28392,
+27982, 28059, 28389, 28073, 28493, 33829, 28799, 28891, 28905, 22681,
+29406, 33719, 29615, 29815, 30184, 30103, 30699, 30970, 30710, 31699,
+31914, 38214, 31937, 32553, 32489, 32554, 32533, 32551, 32503, 32541,
+24635, 32437, 32555, 32420, 32549, 32358, 32550, 22768, 32874, 32852,
+32824, 33043, 32966, 33080, 33037, 20020, 20030, 33392, 34103, 34015,
+20111, 34684, 34632, 20149, 35099, 35274, 35868, 35876, 35878, 35762,
+35854, 35875, 35874, 35466, 35879, 36186, 36187, 36141, 36185, 36235,
+36758, 36759, 27586, 36757, 33286, 36824, 36808, 37213, 38208, 38209,
+38170, 38190, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 38194, 38149, 38180, 38202,
+38201, 38203, 38206, 38199, 38420, 38421, 38417, 38385, 38544, 38582,
+34429, 38889, 39063, 39123, 39563, 39567, 40092, 40091, 40084, 40081,
+40511, 40509, 28857, 25995, 19995, 22108, 22329, 22418, 23158, 25041,
+25193, 25527, 25200, 25781, 25670, 25822, 25783, 26029, 27103, 26588,
+27099, 26592, 27428, 24402, 27553, 27899, 28182, 28388, 28174, 28293,
+27983, 28908, 28952, 29367, 29454, 29934, 30112, 30545, 30784, 31036,
+31313, 31229, 31388, 31373, 31659, 31783, 31658, 31697, 31616, 31918,
+32455, 32558, 32469, 32557, 32483, 32559, 32728, 32844, 32834, 33040,
+33169, 26087, 33832, 34013, 33632, 34546, 34633, 35280, 35294, 35871,
+35880, 35884, 35882, 36184, 36434, 36857, 36344, 36527, 36716, 36761,
+36841, 21307, 37233, 38225, 38145, 38056, 38221, 38215, 38224, 38226,
+38217, 38422, 38383, 38423, 38425, 26434, 21452, 38607, 40481, 39069,
+39068, 39064, 39066, 39067, 39311, 39306, 39304, 39569, 39617, 40104,
+40100, 40107, 40103, 40515, 40517, 40516, 22404, 22364, 23456, 24222,
+24208, 24809, 24576, 25042, 25314, 26103, 27249, 26911, 27016, 27257,
+28487, 28625, 27813, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 28626, 27896, 28865,
+29261, 29322, 20861, 29549, 29626, 29756, 30068, 30250, 30861, 31095,
+31283, 31614, 33575, 32462, 32499, 32472, 32599, 32564, 33211, 33402,
+34222, 33647, 34433, 34631, 35014, 34948, 35889, 35782, 35885, 35890,
+35749, 35887, 36192, 36190, 36343, 36762, 36735, 36766, 36793, 38236,
+38237, 38238, 38142, 38231, 38232, 38230, 38233, 38197, 38210, 38143,
+37694, 20851, 38471, 38590, 38654, 38892, 38901, 31867, 39072, 39125,
+39314, 39313, 39579, 39575, 40120, 40115, 40109, 40119, 40529, 40521,
+40522, 40524, 40527, 20029, 40628, 21149, 21657, 22052, 20005, 23453,
+24748, 24527, 25318, 25600, 32999, 27015, 28572, 28491, 28809, 29649,
+30719, 30778, 30718, 30782, 31398, 31454, 31609, 31726, 36779, 32548,
+32487, 32578, 33002, 33328, 34108, 34106, 33446, 33529, 34164, 34461,
+35124, 35273, 35302, 35758, 35793, 35893, 36194, 36193, 36280, 37322,
+38047, 38105, 38152, 38416, 39128, 39286, 39269, 39582, 33150, 39578,
+40131, 40133, 20826, 40835, 40836, 20458, 21995, 21869, 22179, 23646,
+24807, 24913, 25668, 25658, 26003, 27185, 26639, 26818, 27516, 28866,
+29306, 38262, 29838, 30302, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 32544, 32493,
+20848, 34259, 34510, 35272, 35892, 25252, 35465, 36163, 36364, 36291,
+36347, 36720, 36777, 38256, 38253, 38081, 38107, 38094, 38255, 38220,
+21709, 39038, 39074, 39144, 39537, 39584, 34022, 39585, 39621, 40141,
+40143, 33722, 40548, 40542, 40839, 40840, 21870, 20456, 20645, 21587,
+23402, 24005, 23782, 24367, 25674, 26435, 27426, 28393, 29473, 21472,
+30270, 30307, 31548, 31809, 32843, 33039, 34989, 34924, 35835, 36174,
+36189, 36399, 36396, 36756, 37094, 38136, 37492, 38657, 38801, 32366,
+39076, 39556, 39553, 40150, 40098, 40148, 40151, 40551, 40485, 40761,
+40841, 40842, 40858, 24651, 25371, 25605, 29906, 31363, 32552, 33250,
+33821, 34506, 21464, 36902, 36923, 38259, 38084, 38757, 26174, 39181,
+24778, 39551, 39564, 39635, 39633, 40157, 40158, 40156, 40502, 22065,
+22365, 25597, 30251, 30315, 32641, 34453, 35753, 35863, 35894, 33395,
+36195, 37247, 38643, 28789, 38701, 39078, 39588, 39699, 39751, 40078,
+40560, 40557, 30839, 30416, 40140, 40844, 40843, 21381, 27012, 28286,
+31729, 31657, 34542, 35266, 36433, 34885, 38053, 39045, 39307, 39627,
+40649, 28390, 30633, 38218, 38831, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 39540,
+39589, 32518, 35872, 36495, 37245, 38075, 37550, 38179, 40132, 40072,
+40681, 20991, 40550, 39562, 40563, 40510, 38074, 20162, 34381, 27538,
+22439, 22395, 25099, 20451, 21037, 21389, 21593, 21370, 32424, 33543,
+38023, 38022, 21591, 24362, 31059, 32446, 37071, 38028, 21072, 21286,
+22261, 22445, 23045, 23741, 23811, 28062, 28172, 28867, 30502, 32448,
+32464, 33003, 38030, 38032, 38037, 38029, 38379, 22955, 23899, 24701,
+26720, 26536, 27817, 27976, 30066, 30743, 32471, 33757, 35271, 35765,
+35790, 35794, 36150, 36147, 36730, 36725, 36728, 36911, 37075, 37124,
+38059, 38060, 38043, 38063, 38061, 38058, 38390, 38503, 39032, 39275,
+40697, 20251, 20603, 20325, 21794, 22450, 24047, 24493, 28828, 33557,
+29426, 29614, 32488, 32480, 32481, 32671, 33645, 34545, 35795, 35798,
+35817, 35796, 35804, 36241, 36738, 36737, 37036, 38090, 38088, 38064,
+38066, 38070, 38157, 38092, 38077, 38076, 39043, 39040, 20971, 40702,
+20606, 21787, 23901, 24123, 24747, 24749, 24580, 25132, 25111, 25247,
+25248, 25532, 26724, 26473, 33637, 27986, 27812, 28829, 30386, 30720,
+32507, 32498, 32495, 32506, 33715, 35275, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+35830, 36167, 38129, 38098, 38097, 38101, 38111, 38123, 38127, 38122,
+38135, 38102, 38117, 39121, 21055, 21154, 21715, 21586, 23810, 23780,
+24209, 24870, 25378, 26912, 27637, 39053, 28061, 28514, 28064, 28375,
+29711, 29825, 30231, 32515, 32535, 32524, 32527, 32529, 33628, 33932,
+33553, 33473, 35833, 35836, 35842, 36181, 37112, 38162, 38103, 38141,
+38163, 38154, 38116, 38150, 38151, 38164, 38406, 38403, 38739, 39055,
+39293, 39541, 39552, 40066, 40488, 21714, 21717, 21721, 23250, 23748,
+24639, 27546, 27981, 28904, 29443, 29423, 30876, 31405, 32279, 32539,
+33927, 33640, 33929, 33630, 33720, 33431, 34547, 35816, 35857, 35860,
+35869, 37072, 38185, 38188, 38166, 38167, 38140, 38171, 38165, 38174,
+38036, 38415, 38408, 38409, 38410, 38412, 38413, 40498, 40497, 21724,
+24113, 24697, 25672, 58305, 27894, 29461, 29971, 30213, 30187, 30807,
+31654, 31578, 31976, 32545, 32807, 33631, 33718, 34544, 35042, 35279,
+35873, 35788, 35877, 36292, 38200, 38196, 38113, 38198, 38418, 39271,
+40082, 40085, 40504, 40505, 40506, 40832, 24636, 25669, 25784, 27898,
+30102, 32523, 32873, 33641, 34789, 34414, 35764, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 35881, 36188, 36157, 36760, 37021, 38227, 38112, 38204, 38223,
+34021, 38890, 39273, 39568, 39570, 39571, 38411, 40105, 40096, 40520,
+40513, 40518, 21411, 21590, 22406, 27104, 26638, 27655, 27895, 28486,
+31074, 32562, 32563, 32628, 33315, 34511, 34431, 35043, 35281, 35311,
+35886, 38235, 38239, 38250, 38214, 38121, 38891, 39073, 39312, 39618,
+40117, 40118, 40123, 40113, 40526, 40491, 40700, 21950, 25732, 26634,
+26533, 26636, 32561, 32845, 33551, 33480, 34162, 34548, 34686, 38132,
+38246, 38248, 38241, 38243, 38212, 38251, 38119, 38244, 38137, 38426,
+39071, 39316, 39546, 39581, 39583, 39576, 40535, 40538, 40540, 40838,
+40837, 20649, 23743, 30152, 25786, 27017, 28384, 30779, 31901, 32425,
+32556, 34105, 36166, 38257, 38396, 39129, 39586, 39574, 39580, 40101,
+40142, 40144, 40547, 40536, 40574, 20865, 23048, 28757, 25874, 30271,
+31656, 31860, 33339, 35276, 36345, 36318, 36729, 38228, 38252, 39587,
+39557, 40149, 40099, 40102, 40552, 40503, 40859, 26686, 26916, 34016,
+38624, 36723, 40159, 40095, 40553, 40556, 40554, 40555, 40519, 28751,
+31766, 35888, 39628, 31550, 31900, 32565, 33044, 36479, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 38247, 40090, 36273, 36508, 37246, 35891, 39070, 39079,
+39591, 40492, 25094, 38404, 40097, 40514, 31160, 25300, 36299, 29648,
+23467, 25296, 27585, 20943, 31108, 21525, 28508, 34972, 37095, 20857,
+25144, 25243, 25383, 25531, 25566, 25594, 25745, 25792, 25825, 25846,
+25861, 25909, 25934, 25963, 25992, 26073, 26142, 26171, 26175, 26180,
+26199, 26217, 26227, 26243, 26300, 26303, 26305, 26357, 26362, 26363,
+26382, 26390, 26423, 26468, 26470, 26534, 26535, 26537, 26619, 26621,
+26624, 26625, 26629, 26654, 26698, 26706, 26709, 26713, 26765, 26809,
+26831, 20616, 38184, 40087, 26914, 26918, 220, 58591, 58592, 252,
+58594, 58595, 220, 252, 26934, 26977, 33477, 33482, 33496, 33560,
+33562, 33571, 33606, 33627, 33634, 33644, 33646, 33692, 33695, 33717,
+33724, 33783, 33834, 33864, 33884, 33890, 33924, 33928, 34012, 34019,
+34104, 34138, 34199, 34219, 34241, 34323, 34326, 8715, 34581, 34672,
+34685, 34699, 34728, 34759, 34768, 34823, 34830, 34855, 34990, 8712,
+34997, 35007, 35045, 35061, 35100, 35101, 35191, 35303, 35383, 35500,
+35546, 35675, 35697, 35883, 35898, 35964, 35982, 36014, 36114, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 36169, 36173, 36209, 36360, 36410, 36464, 36505,
+36528, 36529, 36549, 36550, 36558, 36579, 36620, 36721, 36727, 36775,
+36847, 36878, 36921, 36965, 37001, 37086, 37141, 37334, 37339, 37342,
+37345, 37349, 37366, 37372, 37417, 37420, 65287, 37465, 37495, 37613,
+37690, 58701, 58702, 29227, 20866, 20886, 20023, 20843, 20799, 58709,
+58710, 26409, 27706, 21378, 30098, 32896, 34916, 19974, 58718, 58719,
+58720, 11927, 21241, 21269, 8225, 58725, 13316, 58727, 58728, 58729,
+58730, 58731, 20981, 58733, 23662, 58735, 22231, 20128, 20907, 11904,
+27079, 58741, 9550, 9688, 9689, 9794, 9654, 9668, 8597, 8252,
+ 182, 8704, 8616, 8596, 8962, 58755, 58756, 20124, 24746, 22311,
+22258, 21307, 22769, 36920, 38560, 26628, 21942, 39365, 35585, 20870,
+32257, 24540, 27431, 27572, 26716, 22885, 31311, 20206, 20385, 30011,
+28784, 20250, 24724, 28023, 32117, 22730, 25040, 25313, 27579, 35226,
+23398, 27005, 21917, 28167, 58794, 24059, 38501, 21223, 23515, 28450,
+38306, 27475, 35251, 27671, 24112, 25135, 29344, 34384, 26087, 24613,
+25312, 25369, 34394, 23777, 25375, 29421, 37111, 38911, 26241, 21220,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 35641, 21306, 39366, 21234, 58824, 24452,
+33550, 24693, 25522, 28179, 32076, 34509, 36605, 32153, 40335, 25731,
+30476, 20537, 21091, 38522, 22287, 26908, 27177, 38997, 39443, 21427,
+21577, 23087, 35492, 24195, 28207, 37489, 21495, 22269, 40658, 31296,
+30741, 28168, 25998, 27507, 21092, 38609, 21442, 26719, 24808, 36059,
+27531, 27503, 20816, 36766, 28287, 23455, 20889, 33294, 25448, 37320,
+23551, 21454, 34886, 24467, 28171, 29539, 32294, 31899, 20966, 23558,
+31216, 28169, 28988, 22888, 26465, 29366, 20055, 27972, 21104, 30067,
+32260, 22732, 23330, 35698, 37304, 35302, 22065, 23517, 23613, 22259,
+31883, 37204, 31298, 38543, 39620, 26530, 25968, 25454, 28716, 22768,
+25993, 38745, 31363, 25666, 32118, 23554, 27973, 25126, 36341, 37549,
+28508, 36983, 36984, 32330, 31109, 30094, 22766, 20105, 33624, 25436,
+25407, 24035, 31379, 35013, 20711, 23652, 32207, 39442, 22679, 24974,
+34101, 36104, 33235, 23646, 32154, 22549, 23550, 24111, 28382, 28381,
+25246, 27810, 28655, 21336, 22022, 22243, 26029, 24382, 36933, 26172,
+37619, 24193, 24500, 32884, 25074, 22618, 36883, 37444, 28857, 36578,
+20253, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 38651, 28783, 24403, 20826, 30423,
+31282, 38360, 24499, 27602, 29420, 35501, 23626, 38627, 24336, 24745,
+33075, 25309, 24259, 22770, 26757, 21338, 34180, 40614, 32283, 30330,
+39658, 25244, 27996, 27996, 25935, 25975, 20398, 25173, 20175, 36794,
+22793, 27497, 33303, 31807, 21253, 23453, 25265, 27873, 32990, 30770,
+35914, 39165, 22696, 27598, 28288, 33032, 40665, 35379, 34220, 36493,
+19982, 35465, 25671, 27096, 35617, 26332, 26469, 38972, 20081, 35239,
+31452, 38534, 26053, 20001, 29471, 32209, 28057, 22593, 31036, 21169,
+25147, 38666, 40802, 26278, 27508, 24651, 32244, 37676, 28809, 21172,
+27004, 37682, 28286, 24357, 20096, 26365, 22985, 23437, 23947, 27179,
+26907, 21936, 31874, 36796, 27018, 21682, 40235, 38635, 26905, 25539,
+39364, 20967, 26626, 36795, 20685, 23776, 26627, 20970, 21250, 30834,
+30033, 30048, 22138, 37618, 22592, 26622, 20451, 26466, 31870, 21249,
+20452, 20453, 20969, 21498, 21720, 22222, 22310, 22327, 22328, 22408,
+22451, 22442, 22448, 22486, 22640, 22713, 22743, 23670, 23740, 23749,
+23742, 23926, 24342, 24634, 25525, 26433, 26467, 26529, 26810, 26917,
+26920, 27258, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 26915, 26913, 27006, 27009,
+27101, 27182, 27250, 27423, 27615, 28181, 29077, 29927, 29938, 29936,
+29937, 29944, 29957, 30057, 30314, 30836, 31437, 31439, 31445, 31443,
+31457, 31472, 31490, 31763, 31767, 31888, 31917, 31936, 31960, 32155,
+32261, 32359, 32387, 32400, 33188, 33373, 33826, 34009, 34352, 34475,
+34543, 34992, 35011, 35012, 35076, 59183, 36542, 36552, 36684, 36791,
+36826, 36903, 36950, 37685, 37691, 37817, 38282, 38294, 38777, 38790,
+38800, 39082, 39830, 39831, 39860, 39887, 39889, 39890, 39922, 39921,
+39984, 40007, 40026, 40176, 40262, 40292, 40363, 20036, 21583, 25368,
+39857, 40041, 40263, 40293, 39983, 40639, 20916, 21610, 26528, 39822,
+37032, 20914, 13869, 25285, 21189, 26545, 21709, 24658, 21441, 28913,
+22531, 21855, 37390, 30528, 29756, 29002, 28377, 21472, 29486, 35023,
+30861, 32675, 32171, 36394, 37979, 25452, 24487, 23557, 32827, 23791,
+14776, 29009, 36045, 38894, 22642, 23139, 32632, 23895, 24943, 27032,
+32137, 31918, 32179, 28545, 23290, 22715, 29269, 30286, 36653, 37561,
+40286, 40623, 32583, 40388, 36120, 20915, 34412, 21668, 21414, 21030,
+26422, 20001, 21364, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 24313, 21177, 21647,
+24312, 22956, 24625, 29248, 33047, 30267, 24333, 26187, 26280, 24932,
+25423, 28895, 27940, 31911, 31945, 21465, 25933, 22338, 29647, 32966,
+13649, 27445, 30849, 21452, 29483, 29482, 29641, 30026, 23033, 29124,
+29966, 32220, 39393, 35241, 28662, 14935, 25834, 15341, 27809, 28284,
+30055, 22633, 22633, 20996, 59338, 24967, 25658, 33263, 59342, 20917,
+20945, 27769, 22815, 36857, 39153, 25911, 33033, 34996, 14890, 36525,
+32663, 39440, 32037, 27336, 20876, 21031, 59360, 33050, 21408, 21410,
+27738, 27703, 33304, 21894, 24315, 20937, 30897, 37474, 21357, 20931,
+59374, 33905, 35207, 38765, 35728, 38563, 24316, 38583, 20814, 39952,
+26160, 37461, 30728, 37701, 37491, 37737, 59390, 59391, 59392, 59393,
+37343, 37338, 30804, 30822, 30856, 30902, 30919, 30930, 30935, 8491,
+ 8651, 30948, 30958, 30960, 30961, 30965, 31026, 31027, 31030, 31064,
+12307, 31065, 31089, 31102, 31107, 31110, 31111, 31121, 31129, 31135,
+31141, 31202, 31217, 31220, 31274, 31290, 31301, 31333, 31420, 31426,
+31433, 31451, 31465, 31486, 31500, 31527, 31529, 31554, 31555, 31573,
+31599, 31666, 27102, 27129, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 37238, 33114,
+33527, 21579, 33074, 32957, 33816, 37214, 37232, 37260, 33096, 59459,
+17462, 33113, 32927, 59463, 21833, 21537, 21722, 21554, 21945, 21652,
+59470, 30802, 30789, 30796, 59474, 33981, 33820, 33476, 59478, 33915,
+35629, 59481, 22347, 59483, 59484, 22341, 34766, 22112, 21994, 22139,
+32956, 59491, 30904, 27148, 21708, 31696, 31724, 31738, 31765, 31771,
+31797, 31812, 31853, 31886, 31928, 31939, 31974, 31981, 31987, 31989,
+31993, 59511, 31996, 32139, 32151, 32164, 32168, 32205, 32208, 32211,
+32229, 32253, 27154, 27170, 27184, 27190, 27237, 59527, 59528, 59529,
+59530, 59531, 59532, 59533, 59534, 27251, 27256, 59537, 59538, 27260,
+27305, 27306, 9450, 9312, 9313, 9314, 9315, 9316, 9317, 9318,
+ 9319, 9320, 9321, 9322, 9323, 9324, 9325, 9326, 9327, 9328,
+ 9329, 9330, 9331, 37700, 37805, 37830, 37861, 37914, 37921, 37950,
+37953, 37971, 37978, 38042, 38071, 38104, 38110, 38131, 38147, 38158,
+38159, 38168, 38173, 38186, 38187, 38207, 38213, 38222, 38242, 38245,
+38249, 38258, 38279, 38297, 38304, 38322, 38502, 38557, 38575, 38578,
+38707, 38715, 38733, 38735, 38737, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 38741,
+38756, 38763, 38769, 38802, 38834, 38898, 38973, 38996, 39077, 39107,
+39130, 39150, 39197, 39200, 39267, 39296, 39303, 39309, 39315, 39317,
+39356, 39368, 39410, 39606, 39641, 39646, 39695, 39753, 39794, 39811,
+39839, 39867, 39907, 39925, 39936, 39940, 39963, 9398, 9399, 9400,
+ 9401, 9402, 9403, 9404, 9405, 9406, 9407, 9408, 9409, 9410,
+ 9411, 9412, 9413, 9414, 9415, 9416, 9417, 9418, 9419, 9420,
+ 9421, 9422, 9423, 9424, 9425, 9426, 9427, 9428, 9429, 9430,
+ 9431, 9432, 9433, 9434, 9435, 9436, 9437, 9438, 9439, 9440,
+ 9441, 9442, 9443, 9444, 9445, 9446, 9447, 9448, 9449, 174,
+ 8482, 59697, 59698, 40054, 10102, 10103, 10104, 10105, 10106, 10107,
+10108, 10109, 10110, 10111, 40069, 40070, 40071, 40075, 40080, 40094,
+40110, 40112, 40114, 40116, 40122, 40124, 40125, 40134, 40135, 40138,
+40139, 40147, 40152, 40153, 40162, 40171, 40172, 40234, 40264, 40272,
+40314, 40390, 40523, 40533, 40539, 40561, 40618, 40637, 40644, 40674,
+40682, 40712, 40715, 40717, 40737, 40772, 40785, 40861, 64014, 64015,
+64017, 64019, 64020, 64024, 64031, 64032, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+64033, 64035, 64036, 64039, 64040, 64041, 19972, 20015, 20097, 20103,
+20131, 20151, 20156, 20216, 20264, 20265, 20279, 20290, 20293, 20299,
+20338, 20386, 20400, 20413, 20424, 20428, 20464, 20466, 20473, 20483,
+20488, 20532, 20539, 20568, 20582, 20609, 20624, 20668, 20688, 20703,
+20705, 20732, 20749, 20779, 20832, 20910, 20920, 20946, 20962, 20997,
+21044, 21052, 21081, 21096, 21113, 21156, 21196, 21287, 21314, 21341,
+21373, 21374, 21445, 21456, 21458, 21502, 21613, 21637, 21651, 21662,
+21689, 21731, 21743, 21773, 21784, 21797, 21800, 21803, 21831, 21881,
+21904, 21940, 21953, 21975, 21976, 22011, 20404, 22049, 8707, 22098,
+59852, 9787, 59854, 59855, 22109, 9332, 9333, 9334, 9335, 9336,
+ 9337, 9338, 9339, 9340, 9341, 9342, 9343, 9344, 9345, 9346,
+ 9347, 9348, 9349, 9350, 9351, 22113, 22153, 22155, 22174, 22177,
+22193, 22201, 22207, 22230, 22255, 22293, 22301, 22322, 22333, 22335,
+22339, 8660, 22398, 22410, 22413, 22416, 22428, 22459, 22462, 22468,
+22494, 22526, 22546, 22562, 22599, 22620, 22623, 22643, 22695, 22698,
+22704, 22709, 22710, 22731, 22736, 22752, 22789, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 22801, 22921, 22932, 22938, 22943, 22960, 22968, 22980, 23023,
+23024, 23032, 23042, 23051, 23053, 23058, 23073, 23076, 23079, 23082,
+23083, 23084, 23101, 23109, 23124, 23129, 23137, 23144, 23147, 23150,
+23153, 23161, 23166, 23169, 23170, 23174, 23176, 23185, 23193, 23200,
+23201, 23211, 23235, 23246, 23247, 23251, 23268, 23280, 23294, 23309,
+23313, 23317, 23327, 23339, 23361, 23364, 23366, 23370, 23375, 23400,
+23412, 23414, 23420, 23426, 23440, 9372, 9373, 9374, 9375, 9376,
+ 9377, 9378, 9379, 9380, 9381, 9382, 9383, 9384, 9385, 9386,
+ 9387, 9388, 9389, 9390, 9391, 9392, 9393, 9394, 9395, 9396,
+ 9397, 60009, 12850, 12849, 27307, 23446, 9352, 9353, 9354, 9355,
+ 9356, 9357, 9358, 9359, 9360, 9361, 9362, 9363, 9364, 9365,
+ 9366, 9367, 9368, 9369, 9370, 9371, 23509, 23511, 23587, 23685,
+23710, 23746, 23824, 23852, 23855, 23880, 23894, 23920, 23931, 23941,
+23972, 23979, 23990, 24001, 24023, 24073, 24136, 24210, 24253, 24334,
+24434, 24497, 24514, 24539, 24543, 24611, 24702, 24791, 24839, 24844,
+24857, 24866, 24912, 24928, 24961, 24981, 25017, 25024, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 25039, 25043, 25050, 25232, 25393, 8835, 25399, 25465,
+25483, 25537, 25570, 25574, 25595, 25598, 25607, 25650, 25656, 25659,
+25690, 25713, 25724, 25741, 25775, 25780, 25782, 25821, 25829, 25866,
+25873, 25887, 25951, 25965, 25990, 26037, 26046, 26065, 26068, 26083,
+26111, 26136, 26147, 26211, 26219, 26237, 26245, 26258, 26266, 26276,
+26285, 26291, 26294, 26317, 26318, 26370, 26380, 26393, 26436, 26475,
+26511, 26532, 26559, 26582, 26583, 8834, 26637, 26640, 26651, 26678,
+26695, 26710, 26756, 26760, 26813, 26819, 26821, 26882, 26883, 26889,
+26904, 26947, 26950, 26980, 26983, 26994, 27013, 27039, 27042, 27089,
+27093, 27094, 39457, 39462, 39471, 27329, 22975, 27105, 27139, 27162,
+27164, 27180, 27181, 27187, 27203, 27205, 27212, 27219, 27223, 27235,
+27252, 27266, 27274, 27279, 27289, 27303, 27313, 27317, 27326, 27337,
+27348, 27352, 27382, 27479, 27514, 27612, 27676, 27697, 27736, 27758,
+27765, 27775, 27823, 27851, 27871, 27903, 27906, 27909, 27910, 27942,
+27991, 27995, 28017, 28033, 28047, 28069, 28081, 28158, 28162, 28164,
+28175, 28184, 28202, 28240, 28249, 28314, 28341, 28344, 28379, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 28410, 28420, 28427, 28428, 28438, 28439, 28468,
+28477, 28502, 28537, 28554, 28573, 28575, 28603, 28606, 28627, 28633,
+28664, 28675, 28747, 28749, 28752, 28756, 28764, 28775, 28791, 28793,
+28811, 28815, 28832, 28835, 28837, 28838, 28839, 28868, 28876, 28880,
+28886, 618, 603, 230, 652, 593, 596, 650, 605, 601,
+ 602, 604, 609, 7747, 7753, 330, 7739, 629, 240, 643,
+ 658, 679, 676, 227, 60294, 60295, 623, 632, 647, 60299,
+ 199, 339, 594, 65351, 715, 719, 65345, 65346, 65348, 65349,
+65350, 65352, 65353, 65354, 65355, 65356, 65357, 65358, 65359, 65360,
+65362, 65363, 65364, 65365, 65366, 65367, 65370, 28917, 12832, 12833,
+12834, 12835, 12836, 12837, 12838, 12839, 12840, 12841, 28926, 28933,
+28957, 28969, 28971, 28972, 28979, 28981, 28987, 28990, 28992, 29007,
+29035, 29045, 29047, 29052, 29054, 29068, 29070, 29073, 29078, 29090,
+29091, 29101, 29108, 29111, 29114, 29137, 29149, 29163, 29184, 29193,
+29198, 29199, 29206, 29207, 29220, 23204, 29230, 8838, 29271, 29276,
+29332, 29444, 29456, 29505, 29556, 29580, 29583, 29592, 29596, 29598,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 29607, 29610, 29653, 29665, 29666, 29668,
+29670, 29679, 29683, 8839, 29689, 29691, 29698, 29713, 29714, 29716,
+29717, 29719, 29721, 29724, 29726, 29727, 29751, 29752, 29753, 29763,
+29765, 29767, 29768, 29769, 29779, 29782, 29797, 29803, 29804, 29812,
+29818, 29826, 21378, 24191, 20008, 24186, 20886, 23424, 21353, 11911,
+60436, 21251, 9746, 33401, 17553, 11916, 11914, 20022, 60444, 21274,
+60446, 60447, 11925, 60449, 60450, 9492, 20058, 36790, 24308, 20872,
+20101, 60457, 20031, 60459, 60460, 20059, 21430, 36710, 32415, 35744,
+36125, 40479, 38376, 38021, 38429, 25164, 27701, 20155, 24516, 28780,
+11950, 21475, 27362, 39483, 39484, 39512, 39516, 39523, 9742, 8594,
+ 8592, 8593, 8595, 8680, 8678, 8679, 8681, 8680, 8678, 8679,
+ 8681, 9758, 9756, 9755, 9759, 12310, 12311, 9675, 10005, 10003,
+22267, 9789, 22813, 26189, 29221, 10025, 10017, 9786, 9785, 60515,
+60516, 60517, 60518, 60519, 23672, 9836, 9834, 23249, 23479, 23804,
+60526, 9993, 9986, 60529, 60530, 60531, 60532, 23765, 26478, 29793,
+29853, 32595, 34195, 10063, 60540, 60541, 23928, 24379, 60544, 9473,
+ 9475, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 60547, 60548, 60549, 60550, 60551,
+60552, 60553, 60554, 60555, 60556, 60557, 60558, 60559, 60560, 60561,
+39602, 39648, 39700, 39732, 39737, 39744, 39760, 39807, 9788, 32149,
+ 9729, 38708, 9730, 60575, 60576, 60577, 9992, 60579, 60580, 60581,
+60582, 60583, 60584, 60585, 8507, 8481, 26343, 28247, 60590, 29015,
+31178, 8470, 33132, 35577, 38998, 60597, 60598, 9760, 60600, 9828,
+ 9824, 9831, 9827, 9826, 9830, 9825, 9829, 60609, 60610, 27364,
+ 8478, 13250, 13272, 13217, 60616, 13221, 60618, 60619, 60620, 60621,
+60622, 9745, 39809, 39819, 39821, 39901, 39913, 39917, 39924, 39967,
+39968, 39974, 40019, 40029, 40059, 40204, 40214, 8626, 27397, 36073,
+36082, 36099, 36113, 36124, 36218, 36265, 36288, 36353, 36366, 36422,
+36456, 36465, 36478, 36480, 36534, 36537, 36540, 36547, 36580, 36589,
+36594, 36656, 36673, 36682, 36773, 36787, 36792, 36810, 36815, 36872,
+36915, 36919, 36964, 36972, 37289, 37302, 37316, 37370, 37384, 37395,
+37409, 37416, 37419, 37429, 37436, 37441, 37464, 37469, 37471, 37483,
+37486, 37505, 37508, 37513, 37519, 37553, 37562, 37567, 37588, 37595,
+37603, 37605, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 37611, 37612, 37620, 37622,
+37629, 37635, 37639, 37680, 37681, 37696, 37698, 37699, 37727, 37730,
+37734, 37736, 37747, 37748, 37752, 37757, 37761, 37764, 37766, 37767,
+37776, 37788, 37792, 37816, 37819, 37821, 37823, 37835, 37843, 37851,
+37856, 37872, 37873, 37875, 37876, 37889, 37892, 37896, 37911, 37915,
+37917, 37924, 37925, 37926, 37933, 37954, 37955, 37965, 37972, 37976,
+37989, 37991, 37996, 38009, 38011, 38264, 38277, 38310, 38314, 38486,
+38523, 38565, 38644, 38683, 38710, 38720, 38721, 38743, 38791, 38793,
+38811, 38833, 38845, 38848, 38850, 38866, 38880, 38932, 38933, 38947,
+38963, 39016, 39095, 39097, 39111, 39114, 39136, 39137, 39148, 39157,
+40225, 40244, 40249, 40265, 40270, 40301, 8759, 40302, 40316, 40323,
+40339, 40357, 8748, 40381, 27521, 27569, 40015, 40592, 40384, 60817,
+60818, 9775, 9776, 9783, 9779, 9780, 9781, 9778, 9782, 9777,
+40393, 40404, 40444, 40458, 40460, 40462, 40472, 40571, 40581, 40610,
+40620, 40625, 40641, 40646, 40647, 40689, 40696, 40743, 39182, 39193,
+39196, 39223, 39261, 39266, 39323, 39332, 39338, 39352, 39392, 39398,
+39413, 39455, 32254, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 32263, 32347, 32357,
+32364, 32567, 32576, 32577, 32585, 32594, 32655, 32659, 32692, 32733,
+32743, 32762, 32770, 32776, 32814, 32815, 32828, 32935, 33036, 33066,
+33076, 33090, 33110, 33156, 33189, 33252, 33364, 33381, 33403, 33415,
+33471, 33506, 33518, 33528, 33532, 33535, 33547, 33565, 33597, 33623,
+33681, 33708, 33741, 33773, 33797, 33812, 33814, 33825, 33838, 33854,
+33866, 33875, 33877, 33880, 33892, 33906, 33919, 33920, 33938, 33939,
+33942, 33955, 33982, 34014, 34017, 34018, 34020, 34040, 34051, 34053,
+34064, 34099, 8208, 34114, 34124, 34130, 34143, 34159, 34160, 34163,
+34262, 34272, 34286, 34300, 34317, 34319, 34324, 34344, 34370, 34373,
+34418, 34972, 23405, 33079, 60958, 39224, 21874, 21867, 60962, 13774,
+21873, 21946, 22001, 13778, 22000, 22021, 22050, 22061, 22083, 22046,
+22162, 31949, 21530, 21523, 21655, 26353, 30004, 21581, 22180, 22175,
+25811, 25390, 25592, 25886, 20088, 27626, 27698, 27709, 27746, 27826,
+28152, 28201, 28278, 28290, 28294, 28347, 28383, 28386, 28433, 28452,
+28532, 28561, 28597, 28659, 28661, 28859, 28864, 28943, 8706, 29013,
+29043, 29050, 61016, 21027, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 61018, 13393,
+61020, 36812, 61022, 61023, 192, 200, 204, 210, 217, 193,
+ 205, 211, 218, 257, 275, 299, 333, 363, 470, 196,
+ 203, 207, 214, 220, 198, 199, 209, 195, 213, 225,
+ 233, 237, 243, 250, 472, 228, 235, 239, 246, 252,
+ 230, 231, 241, 227, 245, 462, 283, 464, 466, 468,
+ 474, 197, 201, 29064, 216, 208, 7922, 222, 223, 170,
+ 161, 224, 232, 236, 242, 249, 476, 229, 29080, 29143,
+ 248, 240, 7923, 254, 255, 186, 191, 226, 234, 238,
+ 244, 251, 29173, 194, 202, 206, 212, 219, 184, 164,
+61110, 402, 12288, 65292, 12289, 12290, 65294, 8231, 65307, 65306,
+65311, 65281, 65072, 8230, 8229, 65104, 65105, 65106, 183, 65108,
+65109, 65110, 65111, 65372, 8211, 65073, 8212, 65075, 9588, 65076,
+65103, 65288, 65289, 65077, 65078, 65371, 65373, 65079, 65080, 12308,
+12309, 65081, 65082, 12304, 12305, 65083, 65084, 12298, 12299, 65085,
+65086, 12296, 12297, 65087, 65088, 12300, 12301, 65089, 65090, 12302,
+12303, 65091, 65092, 65113, 65114, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 65115,
+65116, 65117, 65118, 8216, 8217, 8220, 8221, 12317, 12318, 8245,
+ 8242, 65283, 65286, 65290, 8251, 167, 12291, 9675, 9679, 9651,
+ 9650, 9678, 9734, 9733, 9671, 9670, 9633, 9632, 9661, 9660,
+12963, 8453, 175, 65507, 65343, 717, 65097, 65098, 65101, 65102,
+65099, 65100, 65119, 65120, 65121, 65291, 65293, 215, 247, 177,
+ 8730, 65308, 65310, 65309, 8806, 8807, 8800, 8734, 8786, 8801,
+65122, 65123, 65124, 65125, 65126, 65374, 8745, 8746, 8869, 8736,
+ 8735, 8895, 13266, 13265, 8747, 8750, 8757, 8756, 9792, 9794,
+ 8853, 8857, 8593, 8595, 8592, 8594, 8598, 8599, 8601, 8600,
+ 8741, 8739, 65295, 65340, 8725, 65128, 65284, 65509, 12306, 65504,
+65505, 65285, 65312, 8451, 8457, 65129, 65130, 65131, 13269, 13212,
+13213, 13214, 13262, 13217, 13198, 13199, 13252, 176, 20825, 20827,
+20830, 20829, 20833, 20835, 21991, 29929, 31950, 9601, 9602, 9603,
+ 9604, 9605, 9606, 9607, 9608, 9615, 9614, 9613, 9612, 9611,
+ 9610, 9609, 9532, 9524, 9516, 9508, 9500, 9620, 9472, 9474,
+ 9621, 9484, 9488, 9492, 9496, 9581, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 9582, 9584, 9583, 9552, 9566, 9578, 9569, 9698, 9699, 9701,
+ 9700, 9585, 9586, 9587, 65296, 65297, 65298, 65299, 65300, 65301,
+65302, 65303, 65304, 65305, 8544, 8545, 8546, 8547, 8548, 8549,
+ 8550, 8551, 8552, 8553, 12321, 12322, 12323, 12324, 12325, 12326,
+12327, 12328, 12329, 21313, 21316, 21317, 65313, 65314, 65315, 65316,
+65317, 65318, 65319, 65320, 65321, 65322, 65323, 65324, 65325, 65326,
+65327, 65328, 65329, 65330, 65331, 65332, 65333, 65334, 65335, 65336,
+65337, 65338, 65345, 65346, 65347, 65348, 65349, 65350, 65351, 65352,
+65353, 65354, 65355, 65356, 65357, 65358, 65359, 65360, 65361, 65362,
+65363, 65364, 65365, 65366, 65367, 65368, 65369, 65370, 913, 914,
+ 915, 916, 917, 918, 919, 920, 921, 922, 923, 924,
+ 925, 926, 927, 928, 929, 931, 932, 933, 934, 935,
+ 936, 937, 945, 946, 947, 948, 949, 950, 951, 952,
+ 953, 954, 955, 956, 957, 958, 959, 960, 961, 963,
+ 964, 965, 966, 967, 968, 969, 12549, 12550, 12551, 12552,
+12553, 12554, 12555, 12556, 12557, 12558, 12559, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 12560, 12561, 12562, 12563, 12564, 12565, 12566, 12567, 12568,
+12569, 12570, 12571, 12572, 12573, 12574, 12575, 12576, 12577, 12578,
+12579, 12580, 12581, 12582, 12583, 12584, 12585, 729, 713, 714,
+ 711, 715, 9216, 9217, 9218, 9219, 9220, 9221, 9222, 9223,
+ 9224, 9225, 9226, 9227, 9228, 9229, 9230, 9231, 9232, 9233,
+ 9234, 9235, 9236, 9237, 9238, 9239, 9240, 9241, 9242, 9243,
+ 9244, 9245, 9246, 9247, 9249, 8364, 63561, 63562, 63563, 63564,
+63565, 63566, 63567, 63568, 63569, 63570, 63571, 63572, 63573, 63574,
+63575, 63576, 63577, 63578, 63579, 63580, 63581, 63582, 63583, 63584,
+63585, 63586, 63587, 63588, 63589, 19968, 20057, 19969, 19971, 20035,
+20061, 20102, 20108, 20154, 20799, 20837, 20843, 20960, 20992, 20993,
+21147, 21269, 21313, 21340, 21448, 19977, 19979, 19976, 19978, 20011,
+20024, 20961, 20037, 20040, 20063, 20062, 20110, 20129, 20800, 20995,
+21242, 21315, 21449, 21475, 22303, 22763, 22805, 22823, 22899, 23376,
+23377, 23379, 23544, 23567, 23586, 23608, 23665, 24029, 24037, 24049,
+24050, 24051, 24062, 24178, 24318, 24331, 24339, 25165, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 19985, 19984, 19981, 20013, 20016, 20025, 20043, 23609,
+20104, 20113, 20117, 20114, 20116, 20130, 20161, 20160, 20163, 20166,
+20167, 20173, 20170, 20171, 20164, 20803, 20801, 20839, 20845, 20846,
+20844, 20887, 20982, 20998, 20999, 21000, 21243, 21246, 21247, 21270,
+21305, 21320, 21319, 21317, 21342, 21380, 21451, 21450, 21453, 22764,
+22825, 22827, 22826, 22829, 23380, 23569, 23588, 23610, 23663, 24052,
+24187, 24319, 24340, 24341, 24515, 25096, 25142, 25163, 25166, 25903,
+25991, 26007, 26020, 26041, 26085, 26352, 26376, 26408, 27424, 27490,
+27513, 27595, 27604, 27611, 27663, 27700, 28779, 29226, 29238, 29243,
+29255, 29273, 29275, 29356, 29579, 19993, 19990, 19989, 19988, 19992,
+20027, 20045, 20047, 20046, 20197, 20184, 20180, 20181, 20182, 20183,
+20195, 20196, 20185, 20190, 20805, 20804, 20873, 20874, 20908, 20985,
+20986, 20984, 21002, 21152, 21151, 21253, 21254, 21271, 21277, 20191,
+21322, 21321, 21345, 21344, 21359, 21358, 21435, 21487, 21476, 21491,
+21484, 21486, 21481, 21480, 21500, 21496, 21493, 21483, 21478, 21482,
+21490, 21489, 21488, 21477, 21485, 21499, 22235, 22234, 22806, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 22830, 22833, 22900, 22902, 23381, 23427, 23612,
+24040, 24039, 24038, 24066, 24067, 24179, 24188, 24321, 24344, 24343,
+24517, 25098, 25171, 25172, 25170, 25169, 26021, 26086, 26414, 26412,
+26410, 26411, 26413, 27491, 27597, 27665, 27664, 27704, 27713, 27712,
+27710, 29359, 29572, 29577, 29916, 29926, 29976, 29983, 29992, 29993,
+30000, 30001, 30002, 30003, 30091, 30333, 30382, 30399, 30446, 30683,
+30690, 30707, 31034, 31166, 31348, 31435, 19998, 19999, 20050, 20051,
+20073, 20121, 20132, 20134, 20133, 20223, 20233, 20249, 20234, 20245,
+20237, 20240, 20241, 20239, 20210, 20214, 20219, 20208, 20211, 20221,
+20225, 20235, 20809, 20807, 20806, 20808, 20840, 20849, 20877, 20912,
+21015, 21009, 21010, 21006, 21014, 21155, 21256, 21281, 21280, 21360,
+21361, 21513, 21519, 21516, 21514, 21520, 21505, 21515, 21508, 21521,
+21517, 21512, 21507, 21518, 21510, 21522, 22240, 22238, 22237, 22323,
+22320, 22312, 22317, 22316, 22319, 22313, 22809, 22810, 22839, 22840,
+22916, 22904, 22915, 22909, 22905, 22914, 22913, 23383, 23384, 23431,
+23432, 23429, 23433, 23546, 23574, 23673, 24030, 24070, 24182, 24180,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 24335, 24347, 24537, 24534, 25102, 25100,
+25101, 25104, 25187, 25179, 25176, 25910, 26089, 26088, 26092, 26093,
+26354, 26355, 26377, 26429, 26420, 26417, 26421, 27425, 27492, 27515,
+27670, 27741, 27735, 27737, 27743, 27744, 27728, 27733, 27745, 27739,
+27725, 27726, 28784, 29279, 29277, 30334, 31481, 31859, 31992, 32566,
+32650, 32701, 32769, 32771, 32780, 32786, 32819, 32895, 32905, 32907,
+32908, 33251, 33258, 33267, 33276, 33292, 33307, 33311, 33390, 33394,
+33406, 34411, 34880, 34892, 34915, 35199, 38433, 20018, 20136, 20301,
+20303, 20295, 20311, 20318, 20276, 20315, 20309, 20272, 20304, 20305,
+20285, 20282, 20280, 20291, 20308, 20284, 20294, 20323, 20316, 20320,
+20271, 20302, 20278, 20313, 20317, 20296, 20314, 20812, 20811, 20813,
+20853, 20918, 20919, 21029, 21028, 21033, 21034, 21032, 21163, 21161,
+21162, 21164, 21283, 21363, 21365, 21533, 21549, 21534, 21566, 21542,
+21582, 21543, 21574, 21571, 21555, 21576, 21570, 21531, 21545, 21578,
+21561, 21563, 21560, 21550, 21557, 21558, 21536, 21564, 21568, 21553,
+21547, 21535, 21548, 22250, 22256, 22244, 22251, 22346, 22353, 22336,
+22349, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 22343, 22350, 22334, 22352, 22351,
+22331, 22767, 22846, 22941, 22930, 22952, 22942, 22947, 22937, 22934,
+22925, 22948, 22931, 22922, 22949, 23389, 23388, 23386, 23387, 23436,
+23435, 23439, 23596, 23616, 23617, 23615, 23614, 23696, 23697, 23700,
+23692, 24043, 24076, 24207, 24199, 24202, 24311, 24324, 24351, 24420,
+24418, 24439, 24441, 24536, 24524, 24535, 24525, 24561, 24555, 24568,
+24554, 25106, 25105, 25220, 25239, 25238, 25216, 25206, 25225, 25197,
+25226, 25212, 25214, 25209, 25203, 25234, 25199, 25240, 25198, 25237,
+25235, 25233, 25222, 25913, 25915, 25912, 26097, 26356, 26463, 26446,
+26447, 26448, 26449, 26460, 26454, 26462, 26441, 26438, 26464, 26451,
+26455, 27493, 27599, 27714, 27742, 27801, 27777, 27784, 27785, 27781,
+27803, 27754, 27770, 27792, 27760, 27788, 27752, 27798, 27794, 27773,
+27779, 27762, 27774, 27764, 27782, 27766, 27789, 27796, 27800, 27778,
+28790, 28796, 28797, 28792, 29282, 29281, 29280, 29380, 29378, 29590,
+29996, 29995, 30007, 30008, 30338, 30447, 30691, 31169, 31168, 31167,
+31350, 31995, 32597, 32918, 32915, 32925, 32920, 32923, 32922, 32946,
+33391, 33426, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 33419, 33421, 35211, 35282,
+35328, 35895, 35910, 35925, 35997, 36196, 36208, 36275, 36523, 36554,
+36763, 36784, 36802, 36806, 36805, 36804, 24033, 37009, 37026, 37034,
+37030, 37027, 37193, 37318, 37324, 38450, 38446, 38449, 38442, 38444,
+20006, 20054, 20083, 20107, 20123, 20126, 20139, 20140, 20335, 20381,
+20365, 20339, 20351, 20332, 20379, 20363, 20358, 20355, 20336, 20341,
+20360, 20329, 20347, 20374, 20350, 20367, 20369, 20346, 20820, 20818,
+20821, 20841, 20855, 20854, 20856, 20925, 20989, 21051, 21048, 21047,
+21050, 21040, 21038, 21046, 21057, 21182, 21179, 21330, 21332, 21331,
+21329, 21350, 21367, 21368, 21369, 21462, 21460, 21463, 21619, 21621,
+21654, 21624, 21653, 21632, 21627, 21623, 21636, 21650, 21638, 21628,
+21648, 21617, 21622, 21644, 21658, 21602, 21608, 21643, 21629, 21646,
+22266, 22403, 22391, 22378, 22377, 22369, 22374, 22372, 22396, 22812,
+22857, 22855, 22856, 22852, 22868, 22974, 22971, 22996, 22969, 22958,
+22993, 22982, 22992, 22989, 22987, 22995, 22986, 22959, 22963, 22994,
+22981, 23391, 23396, 23395, 23447, 23450, 23448, 23452, 23449, 23451,
+23578, 23624, 23621, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 23622, 23735, 23713,
+23736, 23721, 23723, 23729, 23731, 24088, 24090, 24086, 24085, 24091,
+24081, 24184, 24218, 24215, 24220, 24213, 24214, 24310, 24358, 24359,
+24361, 24448, 24449, 24447, 24444, 24541, 24544, 24573, 24565, 24575,
+24591, 24596, 24623, 24629, 24598, 24618, 24597, 24609, 24615, 24617,
+24619, 24603, 25110, 25109, 25151, 25150, 25152, 25215, 25289, 25292,
+25284, 25279, 25282, 25273, 25298, 25307, 25259, 25299, 25300, 25291,
+25288, 25256, 25277, 25276, 25296, 25305, 25287, 25293, 25269, 25306,
+25265, 25304, 25302, 25303, 25286, 25260, 25294, 25918, 26023, 26044,
+26106, 26132, 26131, 26124, 26118, 26114, 26126, 26112, 26127, 26133,
+26122, 26119, 26381, 26379, 26477, 26507, 26517, 26481, 26524, 26483,
+26487, 26503, 26525, 26519, 26479, 26480, 26495, 26505, 26494, 26512,
+26485, 26522, 26515, 26492, 26474, 26482, 27427, 27494, 27495, 27519,
+27667, 27675, 27875, 27880, 27891, 27825, 27852, 27877, 27827, 27837,
+27838, 27836, 27874, 27819, 27861, 27859, 27832, 27844, 27833, 27841,
+27822, 27863, 27845, 27889, 27839, 27835, 27873, 27867, 27850, 27820,
+27887, 27868, 27862, 27872, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 28821, 28814,
+28818, 28810, 28825, 29228, 29229, 29240, 29256, 29287, 29289, 29376,
+29390, 29401, 29399, 29392, 29609, 29608, 29599, 29611, 29605, 30013,
+30109, 30105, 30106, 30340, 30402, 30450, 30452, 30693, 30717, 31038,
+31040, 31041, 31177, 31176, 31354, 31353, 31482, 31998, 32596, 32652,
+32651, 32773, 32954, 32933, 32930, 32945, 32929, 32939, 32937, 32948,
+32938, 32943, 33253, 33278, 33293, 33459, 33437, 33433, 33453, 33469,
+33439, 33465, 33457, 33452, 33445, 33455, 33464, 33443, 33456, 33470,
+33463, 34382, 34417, 21021, 34920, 36555, 36814, 36820, 36817, 37045,
+37048, 37041, 37046, 37319, 37329, 38263, 38272, 38428, 38464, 38463,
+38459, 38468, 38466, 38585, 38632, 38738, 38750, 20127, 20141, 20142,
+20449, 20405, 20399, 20415, 20448, 20433, 20431, 20445, 20419, 20406,
+20440, 20447, 20426, 20439, 20398, 20432, 20420, 20418, 20442, 20430,
+20446, 20407, 20823, 20882, 20881, 20896, 21070, 21059, 21066, 21069,
+21068, 21067, 21063, 21191, 21193, 21187, 21185, 21261, 21335, 21371,
+21402, 21467, 21676, 21696, 21672, 21710, 21705, 21688, 21670, 21683,
+21703, 21698, 21693, 21674, 21697, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 21700,
+21704, 21679, 21675, 21681, 21691, 21673, 21671, 21695, 22271, 22402,
+22411, 22432, 22435, 22434, 22478, 22446, 22419, 22869, 22865, 22863,
+22862, 22864, 23004, 23000, 23039, 23011, 23016, 23043, 23013, 23018,
+23002, 23014, 23041, 23035, 23401, 23459, 23462, 23460, 23458, 23461,
+23553, 23630, 23631, 23629, 23627, 23769, 23762, 24055, 24093, 24101,
+24095, 24189, 24224, 24230, 24314, 24328, 24365, 24421, 24456, 24453,
+24458, 24459, 24455, 24460, 24457, 24594, 24605, 24608, 24613, 24590,
+24616, 24653, 24688, 24680, 24674, 24646, 24643, 24684, 24683, 24682,
+24676, 25153, 25308, 25366, 25353, 25340, 25325, 25345, 25326, 25341,
+25351, 25329, 25335, 25327, 25324, 25342, 25332, 25361, 25346, 25919,
+25925, 26027, 26045, 26082, 26149, 26157, 26144, 26151, 26159, 26143,
+26152, 26161, 26148, 26359, 26623, 26579, 26609, 26580, 26576, 26604,
+26550, 26543, 26613, 26601, 26607, 26564, 26577, 26548, 26586, 26597,
+26552, 26575, 26590, 26611, 26544, 26585, 26594, 26589, 26578, 27498,
+27523, 27526, 27573, 27602, 27607, 27679, 27849, 27915, 27954, 27946,
+27969, 27941, 27916, 27953, 27934, 27927, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+27963, 27965, 27966, 27958, 27931, 27893, 27961, 27943, 27960, 27945,
+27950, 27957, 27918, 27947, 28843, 28858, 28851, 28844, 28847, 28845,
+28856, 28846, 28836, 29232, 29298, 29295, 29300, 29417, 29408, 29409,
+29623, 29642, 29627, 29618, 29645, 29632, 29619, 29978, 29997, 30031,
+30028, 30030, 30027, 30123, 30116, 30117, 30114, 30115, 30328, 30342,
+30343, 30344, 30408, 30406, 30403, 30405, 30465, 30457, 30456, 30473,
+30475, 30462, 30460, 30471, 30684, 30722, 30740, 30732, 30733, 31046,
+31049, 31048, 31047, 31161, 31162, 31185, 31186, 31179, 31359, 31361,
+31487, 31485, 31869, 32002, 32005, 32000, 32009, 32007, 32004, 32006,
+32568, 32654, 32703, 32772, 32784, 32781, 32785, 32822, 32982, 32997,
+32986, 32963, 32964, 32972, 32993, 32987, 32974, 32990, 32996, 32989,
+33268, 33314, 33511, 33539, 33541, 33507, 33499, 33510, 33540, 33509,
+33538, 33545, 33490, 33495, 33521, 33537, 33500, 33492, 33489, 33502,
+33491, 33503, 33519, 33542, 34384, 34425, 34427, 34426, 34893, 34923,
+35201, 35284, 35336, 35330, 35331, 35998, 36000, 36212, 36211, 36276,
+36557, 36556, 36848, 36838, 36834, 36842, 36837, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 36845, 36843, 36836, 36840, 37066, 37070, 37057, 37059, 37195,
+37194, 37325, 38274, 38480, 38475, 38476, 38477, 38754, 38761, 38859,
+38893, 38899, 38913, 39080, 39131, 39135, 39318, 39321, 20056, 20147,
+20492, 20493, 20515, 20463, 20518, 20517, 20472, 20521, 20502, 20486,
+20540, 20511, 20506, 20498, 20497, 20474, 20480, 20500, 20520, 20465,
+20513, 20491, 20505, 20504, 20467, 20462, 20525, 20522, 20478, 20523,
+20489, 20860, 20900, 20901, 20898, 20941, 20940, 20934, 20939, 21078,
+21084, 21076, 21083, 21085, 21290, 21375, 21407, 21405, 21471, 21736,
+21776, 21761, 21815, 21756, 21733, 21746, 21766, 21754, 21780, 21737,
+21741, 21729, 21769, 21742, 21738, 21734, 21799, 21767, 21757, 21775,
+22275, 22276, 22466, 22484, 22475, 22467, 22537, 22799, 22871, 22872,
+22874, 23057, 23064, 23068, 23071, 23067, 23059, 23020, 23072, 23075,
+23081, 23077, 23052, 23049, 23403, 23640, 23472, 23475, 23478, 23476,
+23470, 23477, 23481, 23480, 23556, 23633, 23637, 23632, 23789, 23805,
+23803, 23786, 23784, 23792, 23798, 23809, 23796, 24046, 24109, 24107,
+24235, 24237, 24231, 24369, 24466, 24465, 24464, 24665, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 24675, 24677, 24656, 24661, 24685, 24681, 24687, 24708,
+24735, 24730, 24717, 24724, 24716, 24709, 24726, 25159, 25331, 25352,
+25343, 25422, 25406, 25391, 25429, 25410, 25414, 25423, 25417, 25402,
+25424, 25405, 25386, 25387, 25384, 25421, 25420, 25928, 25929, 26009,
+26049, 26053, 26178, 26185, 26191, 26179, 26194, 26188, 26181, 26177,
+26360, 26388, 26389, 26391, 26657, 26680, 26696, 26694, 26707, 26681,
+26690, 26708, 26665, 26803, 26647, 26700, 26705, 26685, 26612, 26704,
+26688, 26684, 26691, 26666, 26693, 26643, 26648, 26689, 27530, 27529,
+27575, 27683, 27687, 27688, 27686, 27684, 27888, 28010, 28053, 28040,
+28039, 28006, 28024, 28023, 27993, 28051, 28012, 28041, 28014, 27994,
+28020, 28009, 28044, 28042, 28025, 28037, 28005, 28052, 28874, 28888,
+28900, 28889, 28872, 28879, 29241, 29305, 29436, 29433, 29437, 29432,
+29431, 29574, 29677, 29705, 29678, 29664, 29674, 29662, 30036, 30045,
+30044, 30042, 30041, 30142, 30149, 30151, 30130, 30131, 30141, 30140,
+30137, 30146, 30136, 30347, 30384, 30410, 30413, 30414, 30505, 30495,
+30496, 30504, 30697, 30768, 30759, 30776, 30749, 30772, 30775, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 30757, 30765, 30752, 30751, 30770, 31061, 31056,
+31072, 31071, 31062, 31070, 31069, 31063, 31066, 31204, 31203, 31207,
+31199, 31206, 31209, 31192, 31364, 31368, 31449, 31494, 31505, 31881,
+32033, 32023, 32011, 32010, 32032, 32034, 32020, 32016, 32021, 32026,
+32028, 32013, 32025, 32027, 32570, 32607, 32660, 32709, 32705, 32774,
+32792, 32789, 32793, 32791, 32829, 32831, 33009, 33026, 33008, 33029,
+33005, 33012, 33030, 33016, 33011, 33032, 33021, 33034, 33020, 33007,
+33261, 33260, 33280, 33296, 33322, 33323, 33320, 33324, 33467, 33579,
+33618, 33620, 33610, 33592, 33616, 33609, 33589, 33588, 33615, 33586,
+33593, 33590, 33559, 33600, 33585, 33576, 33603, 34388, 34442, 34474,
+34451, 34468, 34473, 34444, 34467, 34460, 34928, 34935, 34945, 34946,
+34941, 34937, 35352, 35344, 35342, 35340, 35349, 35338, 35351, 35347,
+35350, 35343, 35345, 35912, 35962, 35961, 36001, 36002, 36215, 36524,
+36562, 36564, 36559, 36785, 36865, 36870, 36855, 36864, 36858, 36852,
+36867, 36861, 36869, 36856, 37013, 37089, 37085, 37090, 37202, 37197,
+37196, 37336, 37341, 37335, 37340, 37337, 38275, 38498, 38499, 38497,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 38491, 38493, 38500, 38488, 38494, 38587,
+39138, 39340, 39592, 39640, 39717, 39730, 39740, 20094, 20602, 20605,
+20572, 20551, 20547, 20556, 20570, 20553, 20581, 20598, 20558, 20565,
+20597, 20596, 20599, 20559, 20495, 20591, 20589, 20828, 20885, 20976,
+21098, 21103, 21202, 21209, 21208, 21205, 21264, 21263, 21273, 21311,
+21312, 21310, 21443, 26364, 21830, 21866, 21862, 21828, 21854, 21857,
+21827, 21834, 21809, 21846, 21839, 21845, 21807, 21860, 21816, 21806,
+21852, 21804, 21859, 21811, 21825, 21847, 22280, 22283, 22281, 22495,
+22533, 22538, 22534, 22496, 22500, 22522, 22530, 22581, 22519, 22521,
+22816, 22882, 23094, 23105, 23113, 23142, 23146, 23104, 23100, 23138,
+23130, 23110, 23114, 23408, 23495, 23493, 23492, 23490, 23487, 23494,
+23561, 23560, 23559, 23648, 23644, 23645, 23815, 23814, 23822, 23835,
+23830, 23842, 23825, 23849, 23828, 23833, 23844, 23847, 23831, 24034,
+24120, 24118, 24115, 24119, 24247, 24248, 24246, 24245, 24254, 24373,
+24375, 24407, 24428, 24425, 24427, 24471, 24473, 24478, 24472, 24481,
+24480, 24476, 24703, 24739, 24713, 24736, 24744, 24779, 24756, 24806,
+24765, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 24773, 24763, 24757, 24796, 24764,
+24792, 24789, 24774, 24799, 24760, 24794, 24775, 25114, 25115, 25160,
+25504, 25511, 25458, 25494, 25506, 25509, 25463, 25447, 25496, 25514,
+25457, 25513, 25481, 25475, 25499, 25451, 25512, 25476, 25480, 25497,
+25505, 25516, 25490, 25487, 25472, 25467, 25449, 25448, 25466, 25949,
+25942, 25937, 25945, 25943, 21855, 25935, 25944, 25941, 25940, 26012,
+26011, 26028, 26063, 26059, 26060, 26062, 26205, 26202, 26212, 26216,
+26214, 26206, 26361, 21207, 26395, 26753, 26799, 26786, 26771, 26805,
+26751, 26742, 26801, 26791, 26775, 26800, 26755, 26820, 26797, 26758,
+26757, 26772, 26781, 26792, 26783, 26785, 26754, 27442, 27578, 27627,
+27628, 27691, 28046, 28092, 28147, 28121, 28082, 28129, 28108, 28132,
+28155, 28154, 28165, 28103, 28107, 28079, 28113, 28078, 28126, 28153,
+28088, 28151, 28149, 28101, 28114, 28186, 28085, 28122, 28139, 28120,
+28138, 28145, 28142, 28136, 28102, 28100, 28074, 28140, 28095, 28134,
+28921, 28937, 28938, 28925, 28911, 29245, 29309, 29313, 29468, 29467,
+29462, 29459, 29465, 29575, 29701, 29706, 29699, 29702, 29694, 29709,
+29920, 29942, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 29943, 29980, 29986, 30053,
+30054, 30050, 30064, 30095, 30164, 30165, 30133, 30154, 30157, 30350,
+30420, 30418, 30427, 30519, 30526, 30524, 30518, 30520, 30522, 30827,
+30787, 30798, 31077, 31080, 31085, 31227, 31378, 31381, 31520, 31528,
+31515, 31532, 31526, 31513, 31518, 31534, 31890, 31895, 31893, 32070,
+32067, 32113, 32046, 32057, 32060, 32064, 32048, 32051, 32068, 32047,
+32066, 32050, 32049, 32573, 32670, 32666, 32716, 32718, 32722, 32796,
+32842, 32838, 33071, 33046, 33059, 33067, 33065, 33072, 33060, 33282,
+33333, 33335, 33334, 33337, 33678, 33694, 33688, 33656, 33698, 33686,
+33725, 33707, 33682, 33674, 33683, 33673, 33696, 33655, 33659, 33660,
+33670, 33703, 34389, 24426, 34503, 34496, 34486, 34500, 34485, 34502,
+34507, 34481, 34479, 34505, 34899, 34974, 34952, 34987, 34962, 34966,
+34957, 34955, 35219, 35215, 35370, 35357, 35363, 35365, 35377, 35373,
+35359, 35355, 35362, 35913, 35930, 36009, 36012, 36011, 36008, 36010,
+36007, 36199, 36198, 36286, 36282, 36571, 36575, 36889, 36877, 36890,
+36887, 36899, 36895, 36893, 36880, 36885, 36894, 36896, 36879, 36898,
+36886, 36891, 36884, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 37096, 37101, 37117,
+37207, 37326, 37365, 37350, 37347, 37351, 37357, 37353, 38281, 38506,
+38517, 38515, 38520, 38512, 38516, 38518, 38519, 38508, 38592, 38634,
+38633, 31456, 31455, 38914, 38915, 39770, 40165, 40565, 40575, 40613,
+40635, 20642, 20621, 20613, 20633, 20625, 20608, 20630, 20632, 20634,
+26368, 20977, 21106, 21108, 21109, 21097, 21214, 21213, 21211, 21338,
+21413, 21883, 21888, 21927, 21884, 21898, 21917, 21912, 21890, 21916,
+21930, 21908, 21895, 21899, 21891, 21939, 21934, 21919, 21822, 21938,
+21914, 21947, 21932, 21937, 21886, 21897, 21931, 21913, 22285, 22575,
+22570, 22580, 22564, 22576, 22577, 22561, 22557, 22560, 22777, 22778,
+22880, 23159, 23194, 23167, 23186, 23195, 23207, 23411, 23409, 23506,
+23500, 23507, 23504, 23562, 23563, 23601, 23884, 23888, 23860, 23879,
+24061, 24133, 24125, 24128, 24131, 24190, 24266, 24257, 24258, 24260,
+24380, 24429, 24489, 24490, 24488, 24785, 24801, 24754, 24758, 24800,
+24860, 24867, 24826, 24853, 24816, 24827, 24820, 24936, 24817, 24846,
+24822, 24841, 24832, 24850, 25119, 25161, 25507, 25484, 25551, 25536,
+25577, 25545, 25542, 25549, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 25554, 25571,
+25552, 25569, 25558, 25581, 25582, 25462, 25588, 25578, 25563, 25682,
+25562, 25593, 25950, 25958, 25954, 25955, 26001, 26000, 26031, 26222,
+26224, 26228, 26230, 26223, 26257, 26234, 26238, 26231, 26366, 26367,
+26399, 26397, 26874, 26837, 26848, 26840, 26839, 26885, 26847, 26869,
+26862, 26855, 26873, 26834, 26866, 26851, 26827, 26829, 26893, 26898,
+26894, 26825, 26842, 26990, 26875, 27454, 27450, 27453, 27544, 27542,
+27580, 27631, 27694, 27695, 27692, 28207, 28216, 28244, 28193, 28210,
+28263, 28234, 28192, 28197, 28195, 28187, 28251, 28248, 28196, 28246,
+28270, 28205, 28198, 28271, 28212, 28237, 28218, 28204, 28227, 28189,
+28222, 28363, 28297, 28185, 28238, 28259, 28228, 28274, 28265, 28255,
+28953, 28954, 28966, 28976, 28961, 28982, 29038, 28956, 29260, 29316,
+29312, 29494, 29477, 29492, 29481, 29754, 29738, 29747, 29730, 29733,
+29749, 29750, 29748, 29743, 29723, 29734, 29736, 29989, 29990, 30059,
+30058, 30178, 30171, 30179, 30169, 30168, 30174, 30176, 30331, 30332,
+30358, 30355, 30388, 30428, 30543, 30701, 30813, 30828, 30831, 31245,
+31240, 31243, 31237, 31232, 31384, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 31383,
+31382, 31461, 31459, 31561, 31574, 31558, 31568, 31570, 31572, 31565,
+31563, 31567, 31569, 31903, 31909, 32094, 32080, 32104, 32085, 32043,
+32110, 32114, 32097, 32102, 32098, 32112, 32115, 21892, 32724, 32725,
+32779, 32850, 32901, 33109, 33108, 33099, 33105, 33102, 33081, 33094,
+33086, 33100, 33107, 33140, 33298, 33308, 33769, 33795, 33784, 33805,
+33760, 33733, 33803, 33729, 33775, 33777, 33780, 33879, 33802, 33776,
+33804, 33740, 33789, 33778, 33738, 33848, 33806, 33796, 33756, 33799,
+33748, 33759, 34395, 34527, 34521, 34541, 34516, 34523, 34532, 34512,
+34526, 34903, 35009, 35010, 34993, 35203, 35222, 35387, 35424, 35413,
+35422, 35388, 35393, 35412, 35419, 35408, 35398, 35380, 35386, 35382,
+35414, 35937, 35970, 36015, 36028, 36019, 36029, 36033, 36027, 36032,
+36020, 36023, 36022, 36031, 36024, 36234, 36229, 36225, 36302, 36317,
+36299, 36314, 36305, 36300, 36315, 36294, 36603, 36600, 36604, 36764,
+36910, 36917, 36913, 36920, 36914, 36918, 37122, 37109, 37129, 37118,
+37219, 37221, 37327, 37396, 37397, 37411, 37385, 37406, 37389, 37392,
+37383, 37393, 38292, 38287, 38283, 38289, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+38291, 38290, 38286, 38538, 38542, 38539, 38525, 38533, 38534, 38541,
+38514, 38532, 38593, 38597, 38596, 38598, 38599, 38639, 38642, 38860,
+38917, 38918, 38920, 39143, 39146, 39151, 39145, 39154, 39149, 39342,
+39341, 40643, 40653, 40657, 20098, 20653, 20661, 20658, 20659, 20677,
+20670, 20652, 20663, 20667, 20655, 20679, 21119, 21111, 21117, 21215,
+21222, 21220, 21218, 21219, 21295, 21983, 21992, 21971, 21990, 21966,
+21980, 21959, 21969, 21987, 21988, 21999, 21978, 21985, 21957, 21958,
+21989, 21961, 22290, 22291, 22622, 22609, 22616, 22615, 22618, 22612,
+22635, 22604, 22637, 22602, 22626, 22610, 22603, 22887, 23233, 23241,
+23244, 23230, 23229, 23228, 23219, 23234, 23218, 23913, 23919, 24140,
+24185, 24265, 24264, 24338, 24409, 24492, 24494, 24858, 24847, 24904,
+24863, 24819, 24859, 24825, 24833, 24840, 24910, 24908, 24900, 24909,
+24894, 24884, 24871, 24845, 24838, 24887, 25121, 25122, 25619, 25662,
+25630, 25642, 25645, 25661, 25644, 25615, 25628, 25620, 25613, 25654,
+25622, 25623, 25606, 25964, 26015, 26032, 26263, 26249, 26247, 26248,
+26262, 26244, 26264, 26253, 26371, 27028, 26989, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 26970, 26999, 26976, 26964, 26997, 26928, 27010, 26954, 26984,
+26987, 26974, 26963, 27001, 27014, 26973, 26979, 26971, 27463, 27506,
+27584, 27583, 27603, 27645, 28322, 28335, 28371, 28342, 28354, 28304,
+28317, 28359, 28357, 28325, 28312, 28348, 28346, 28331, 28369, 28310,
+28316, 28356, 28372, 28330, 28327, 28340, 29006, 29017, 29033, 29028,
+29001, 29031, 29020, 29036, 29030, 29004, 29029, 29022, 28998, 29032,
+29014, 29242, 29266, 29495, 29509, 29503, 29502, 29807, 29786, 29781,
+29791, 29790, 29761, 29759, 29785, 29787, 29788, 30070, 30072, 30208,
+30192, 30209, 30194, 30193, 30202, 30207, 30196, 30195, 30430, 30431,
+30555, 30571, 30566, 30558, 30563, 30585, 30570, 30572, 30556, 30565,
+30568, 30562, 30702, 30862, 30896, 30871, 30872, 30860, 30857, 30844,
+30865, 30867, 30847, 31098, 31103, 31105, 33836, 31165, 31260, 31258,
+31264, 31252, 31263, 31262, 31391, 31392, 31607, 31680, 31584, 31598,
+31591, 31921, 31923, 31925, 32147, 32121, 32145, 32129, 32143, 32091,
+32622, 32617, 32618, 32626, 32681, 32680, 32676, 32854, 32856, 32902,
+32900, 33137, 33136, 33144, 33125, 33134, 33139, 33131, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 33145, 33146, 33126, 33285, 33351, 33922, 33911, 33853,
+33841, 33909, 33894, 33899, 33865, 33900, 33883, 33852, 33845, 33889,
+33891, 33897, 33901, 33862, 34398, 34396, 34399, 34553, 34579, 34568,
+34567, 34560, 34558, 34555, 34562, 34563, 34566, 34570, 34905, 35039,
+35028, 35033, 35036, 35032, 35037, 35041, 35018, 35029, 35026, 35228,
+35299, 35435, 35442, 35443, 35430, 35433, 35440, 35463, 35452, 35427,
+35488, 35441, 35461, 35437, 35426, 35438, 35436, 35449, 35451, 35390,
+35432, 35938, 35978, 35977, 36042, 36039, 36040, 36036, 36018, 36035,
+36034, 36037, 36321, 36319, 36328, 36335, 36339, 36346, 36330, 36324,
+36326, 36530, 36611, 36617, 36606, 36618, 36767, 36786, 36939, 36938,
+36947, 36930, 36948, 36924, 36949, 36944, 36935, 36943, 36942, 36941,
+36945, 36926, 36929, 37138, 37143, 37228, 37226, 37225, 37321, 37431,
+37463, 37432, 37437, 37440, 37438, 37467, 37451, 37476, 37457, 37428,
+37449, 37453, 37445, 37433, 37439, 37466, 38296, 38552, 38548, 38549,
+38605, 38603, 38601, 38602, 38647, 38651, 38649, 38646, 38742, 38772,
+38774, 38928, 38929, 38931, 38922, 38930, 38924, 39164, 39156, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 39165, 39166, 39347, 39345, 39348, 39649, 40169,
+40578, 40718, 40723, 40736, 20711, 20718, 20709, 20694, 20717, 20698,
+20693, 20687, 20689, 20721, 20686, 20713, 20834, 20979, 21123, 21122,
+21297, 21421, 22014, 22016, 22043, 22039, 22013, 22036, 22022, 22025,
+22029, 22030, 22007, 22038, 22047, 22024, 22032, 22006, 22296, 22294,
+22645, 22654, 22659, 22675, 22666, 22649, 22661, 22653, 22781, 22821,
+22818, 22820, 22890, 22889, 23265, 23270, 23273, 23255, 23254, 23256,
+23267, 23413, 23518, 23527, 23521, 23525, 23526, 23528, 23522, 23524,
+23519, 23565, 23650, 23940, 23943, 24155, 24163, 24149, 24151, 24148,
+24275, 24278, 24330, 24390, 24432, 24505, 24903, 24895, 24907, 24951,
+24930, 24931, 24927, 24922, 24920, 24949, 25130, 25735, 25688, 25684,
+25764, 25720, 25695, 25722, 25681, 25703, 25652, 25709, 25723, 25970,
+26017, 26071, 26070, 26274, 26280, 26269, 27036, 27048, 27029, 27073,
+27054, 27091, 27083, 27035, 27063, 27067, 27051, 27060, 27088, 27085,
+27053, 27084, 27046, 27075, 27043, 27465, 27468, 27699, 28467, 28436,
+28414, 28435, 28404, 28457, 28478, 28448, 28460, 28431, 28418, 28450,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 28415, 28399, 28422, 28465, 28472, 28466,
+28451, 28437, 28459, 28463, 28552, 28458, 28396, 28417, 28402, 28364,
+28407, 29076, 29081, 29053, 29066, 29060, 29074, 29246, 29330, 29334,
+29508, 29520, 29796, 29795, 29802, 29808, 29805, 29956, 30097, 30247,
+30221, 30219, 30217, 30227, 30433, 30435, 30596, 30589, 30591, 30561,
+30913, 30879, 30887, 30899, 30889, 30883, 31118, 31119, 31117, 31278,
+31281, 31402, 31401, 31469, 31471, 31649, 31637, 31627, 31605, 31639,
+31645, 31636, 31631, 31672, 31623, 31620, 31929, 31933, 31934, 32187,
+32176, 32156, 32189, 32190, 32160, 32202, 32180, 32178, 32177, 32186,
+32162, 32191, 32181, 32184, 32173, 32210, 32199, 32172, 32624, 32736,
+32737, 32735, 32862, 32858, 32903, 33104, 33152, 33167, 33160, 33162,
+33151, 33154, 33255, 33274, 33287, 33300, 33310, 33355, 33993, 33983,
+33990, 33988, 33945, 33950, 33970, 33948, 33995, 33976, 33984, 34003,
+33936, 33980, 34001, 33994, 34623, 34588, 34619, 34594, 34597, 34612,
+34584, 34645, 34615, 34601, 35059, 35074, 35060, 35065, 35064, 35069,
+35048, 35098, 35055, 35494, 35468, 35486, 35491, 35469, 35489, 35475,
+35492, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 35498, 35493, 35496, 35480, 35473,
+35482, 35495, 35946, 35981, 35980, 36051, 36049, 36050, 36203, 36249,
+36245, 36348, 36628, 36626, 36629, 36627, 36771, 36960, 36952, 36956,
+36963, 36953, 36958, 36962, 36957, 36955, 37145, 37144, 37150, 37237,
+37240, 37239, 37236, 37496, 37504, 37509, 37528, 37526, 37499, 37523,
+37532, 37544, 37500, 37521, 38305, 38312, 38313, 38307, 38309, 38308,
+38553, 38556, 38555, 38604, 38610, 38656, 38780, 38789, 38902, 38935,
+38936, 39087, 39089, 39171, 39173, 39180, 39177, 39361, 39599, 39600,
+39654, 39745, 39746, 40180, 40182, 40179, 40636, 40763, 40778, 20740,
+20736, 20731, 20725, 20729, 20738, 20744, 20745, 20741, 20956, 21127,
+21128, 21129, 21133, 21130, 21232, 21426, 22062, 22075, 22073, 22066,
+22079, 22068, 22057, 22099, 22094, 22103, 22132, 22070, 22063, 22064,
+22656, 22687, 22686, 22707, 22684, 22702, 22697, 22694, 22893, 23305,
+23291, 23307, 23285, 23308, 23304, 23534, 23532, 23529, 23531, 23652,
+23653, 23965, 23956, 24162, 24159, 24161, 24290, 24282, 24287, 24285,
+24291, 24288, 24392, 24433, 24503, 24501, 24950, 24935, 24942, 24925,
+24917, 24962, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 24956, 24944, 24939, 24958,
+24999, 24976, 25003, 24974, 25004, 24986, 24996, 24980, 25006, 25134,
+25705, 25711, 25721, 25758, 25778, 25736, 25744, 25776, 25765, 25747,
+25749, 25769, 25746, 25774, 25773, 25771, 25754, 25772, 25753, 25762,
+25779, 25973, 25975, 25976, 26286, 26283, 26292, 26289, 27171, 27167,
+27112, 27137, 27166, 27161, 27133, 27169, 27155, 27146, 27123, 27138,
+27141, 27117, 27153, 27472, 27470, 27556, 27589, 27590, 28479, 28540,
+28548, 28497, 28518, 28500, 28550, 28525, 28507, 28536, 28526, 28558,
+28538, 28528, 28516, 28567, 28504, 28373, 28527, 28512, 28511, 29087,
+29100, 29105, 29096, 29270, 29339, 29518, 29527, 29801, 29835, 29827,
+29822, 29824, 30079, 30240, 30249, 30239, 30244, 30246, 30241, 30242,
+30362, 30394, 30436, 30606, 30599, 30604, 30609, 30603, 30923, 30917,
+30906, 30922, 30910, 30933, 30908, 30928, 31295, 31292, 31296, 31293,
+31287, 31291, 31407, 31406, 31661, 31665, 31684, 31668, 31686, 31687,
+31681, 31648, 31692, 31946, 32224, 32244, 32239, 32251, 32216, 32236,
+32221, 32232, 32227, 32218, 32222, 32233, 32158, 32217, 32242, 32249,
+32629, 32631, 32687, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 32745, 32806, 33179,
+33180, 33181, 33184, 33178, 33176, 34071, 34109, 34074, 34030, 34092,
+34093, 34067, 34065, 34083, 34081, 34068, 34028, 34085, 34047, 34054,
+34690, 34676, 34678, 34656, 34662, 34680, 34664, 34649, 34647, 34636,
+34643, 34907, 34909, 35088, 35079, 35090, 35091, 35093, 35082, 35516,
+35538, 35527, 35524, 35477, 35531, 35576, 35506, 35529, 35522, 35519,
+35504, 35542, 35533, 35510, 35513, 35547, 35916, 35918, 35948, 36064,
+36062, 36070, 36068, 36076, 36077, 36066, 36067, 36060, 36074, 36065,
+36205, 36255, 36259, 36395, 36368, 36381, 36386, 36367, 36393, 36383,
+36385, 36382, 36538, 36637, 36635, 36639, 36649, 36646, 36650, 36636,
+36638, 36645, 36969, 36974, 36968, 36973, 36983, 37168, 37165, 37159,
+37169, 37255, 37257, 37259, 37251, 37573, 37563, 37559, 37610, 37548,
+37604, 37569, 37555, 37564, 37586, 37575, 37616, 37554, 38317, 38321,
+38660, 38662, 38663, 38665, 38752, 38797, 38795, 38799, 38945, 38955,
+38940, 39091, 39178, 39187, 39186, 39192, 39389, 39376, 39391, 39387,
+39377, 39381, 39378, 39385, 39607, 39662, 39663, 39719, 39749, 39748,
+39799, 39791, 40198, 40201, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 40195, 40617,
+40638, 40654, 22696, 40786, 20754, 20760, 20756, 20752, 20757, 20864,
+20906, 20957, 21137, 21139, 21235, 22105, 22123, 22137, 22121, 22116,
+22136, 22122, 22120, 22117, 22129, 22127, 22124, 22114, 22134, 22721,
+22718, 22727, 22725, 22894, 23325, 23348, 23416, 23536, 23566, 24394,
+25010, 24977, 25001, 24970, 25037, 25014, 25022, 25034, 25032, 25136,
+25797, 25793, 25803, 25787, 25788, 25818, 25796, 25799, 25794, 25805,
+25791, 25810, 25812, 25790, 25972, 26310, 26313, 26297, 26308, 26311,
+26296, 27197, 27192, 27194, 27225, 27243, 27224, 27193, 27204, 27234,
+27233, 27211, 27207, 27189, 27231, 27208, 27481, 27511, 27653, 28610,
+28593, 28577, 28611, 28580, 28609, 28583, 28595, 28608, 28601, 28598,
+28582, 28576, 28596, 29118, 29129, 29136, 29138, 29128, 29141, 29113,
+29134, 29145, 29148, 29123, 29124, 29544, 29852, 29859, 29848, 29855,
+29854, 29922, 29964, 29965, 30260, 30264, 30266, 30439, 30437, 30624,
+30622, 30623, 30629, 30952, 30938, 30956, 30951, 31142, 31309, 31310,
+31302, 31308, 31307, 31418, 31705, 31761, 31689, 31716, 31707, 31713,
+31721, 31718, 31957, 31958, 32266, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 32273,
+32264, 32283, 32291, 32286, 32285, 32265, 32272, 32633, 32690, 32752,
+32753, 32750, 32808, 33203, 33193, 33192, 33275, 33288, 33368, 33369,
+34122, 34137, 34120, 34152, 34153, 34115, 34121, 34157, 34154, 34142,
+34691, 34719, 34718, 34722, 34701, 34913, 35114, 35122, 35109, 35115,
+35105, 35242, 35238, 35558, 35578, 35563, 35569, 35584, 35548, 35559,
+35566, 35582, 35585, 35586, 35575, 35565, 35571, 35574, 35580, 35947,
+35949, 35987, 36084, 36420, 36401, 36404, 36418, 36409, 36405, 36667,
+36655, 36664, 36659, 36776, 36774, 36981, 36980, 36984, 36978, 36988,
+36986, 37172, 37266, 37664, 37686, 37624, 37683, 37679, 37666, 37628,
+37675, 37636, 37658, 37648, 37670, 37665, 37653, 37678, 37657, 38331,
+38567, 38568, 38570, 38613, 38670, 38673, 38678, 38669, 38675, 38671,
+38747, 38748, 38758, 38808, 38960, 38968, 38971, 38967, 38957, 38969,
+38948, 39184, 39208, 39198, 39195, 39201, 39194, 39405, 39394, 39409,
+39608, 39612, 39675, 39661, 39720, 39825, 40213, 40227, 40230, 40232,
+40210, 40219, 40664, 40660, 40845, 40860, 20778, 20767, 20769, 20786,
+21237, 22158, 22144, 22160, 22149, 22151, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+22159, 22741, 22739, 22737, 22734, 23344, 23338, 23332, 23418, 23607,
+23656, 23996, 23994, 23997, 23992, 24171, 24396, 24509, 25033, 25026,
+25031, 25062, 25035, 25138, 25140, 25806, 25802, 25816, 25824, 25840,
+25830, 25836, 25841, 25826, 25837, 25986, 25987, 26329, 26326, 27264,
+27284, 27268, 27298, 27292, 27355, 27299, 27262, 27287, 27280, 27296,
+27484, 27566, 27610, 27656, 28632, 28657, 28639, 28640, 28635, 28644,
+28651, 28655, 28544, 28652, 28641, 28649, 28629, 28654, 28656, 29159,
+29151, 29166, 29158, 29157, 29165, 29164, 29172, 29152, 29237, 29254,
+29552, 29554, 29865, 29872, 29862, 29864, 30278, 30274, 30284, 30442,
+30643, 30634, 30640, 30636, 30631, 30637, 30703, 30967, 30970, 30964,
+30959, 30977, 31143, 31146, 31319, 31423, 31751, 31757, 31742, 31735,
+31756, 31712, 31968, 31964, 31966, 31970, 31967, 31961, 31965, 32302,
+32318, 32326, 32311, 32306, 32323, 32299, 32317, 32305, 32325, 32321,
+32308, 32313, 32328, 32309, 32319, 32303, 32580, 32755, 32764, 32881,
+32882, 32880, 32879, 32883, 33222, 33219, 33210, 33218, 33216, 33215,
+33213, 33225, 33214, 33256, 33289, 33393, 34218, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 34180, 34174, 34204, 34193, 34196, 34223, 34203, 34183, 34216,
+34186, 34407, 34752, 34769, 34739, 34770, 34758, 34731, 34747, 34746,
+34760, 34763, 35131, 35126, 35140, 35128, 35133, 35244, 35598, 35607,
+35609, 35611, 35594, 35616, 35613, 35588, 35600, 35905, 35903, 35955,
+36090, 36093, 36092, 36088, 36091, 36264, 36425, 36427, 36424, 36426,
+36676, 36670, 36674, 36677, 36671, 36991, 36989, 36996, 36993, 36994,
+36992, 37177, 37283, 37278, 37276, 37709, 37762, 37672, 37749, 37706,
+37733, 37707, 37656, 37758, 37740, 37723, 37744, 37722, 37716, 38346,
+38347, 38348, 38344, 38342, 38577, 38584, 38614, 38684, 38686, 38816,
+38867, 38982, 39094, 39221, 39425, 39423, 39854, 39851, 39850, 39853,
+40251, 40255, 40587, 40655, 40670, 40668, 40669, 40667, 40766, 40779,
+21474, 22165, 22190, 22745, 22744, 23352, 24413, 25059, 25139, 25844,
+25842, 25854, 25862, 25850, 25851, 25847, 26039, 26332, 26406, 27315,
+27308, 27331, 27323, 27320, 27330, 27310, 27311, 27487, 27512, 27567,
+28681, 28683, 28670, 28678, 28666, 28689, 28687, 29179, 29180, 29182,
+29176, 29559, 29557, 29863, 29887, 29973, 30294, 30296, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 30290, 30653, 30655, 30651, 30652, 30990, 31150, 31329,
+31330, 31328, 31428, 31429, 31787, 31783, 31786, 31774, 31779, 31777,
+31975, 32340, 32341, 32350, 32346, 32353, 32338, 32345, 32584, 32761,
+32763, 32887, 32886, 33229, 33231, 33290, 34255, 34217, 34253, 34256,
+34249, 34224, 34234, 34233, 34214, 34799, 34796, 34802, 34784, 35206,
+35250, 35316, 35624, 35641, 35628, 35627, 35920, 36101, 36441, 36451,
+36454, 36452, 36447, 36437, 36544, 36681, 36685, 36999, 36995, 37000,
+37291, 37292, 37328, 37780, 37770, 37782, 37794, 37811, 37806, 37804,
+37808, 37784, 37786, 37783, 38356, 38358, 38352, 38357, 38626, 38620,
+38617, 38619, 38622, 38692, 38819, 38822, 38829, 38905, 38989, 38991,
+38988, 38990, 38995, 39098, 39230, 39231, 39229, 39214, 39333, 39438,
+39617, 39683, 39686, 39759, 39758, 39757, 39882, 39881, 39933, 39880,
+39872, 40273, 40285, 40288, 40672, 40725, 40748, 20787, 22181, 22750,
+22751, 22754, 23541, 40848, 24300, 25074, 25079, 25078, 25077, 25856,
+25871, 26336, 26333, 27365, 27357, 27354, 27347, 28699, 28703, 28712,
+28698, 28701, 28693, 28696, 29190, 29197, 29272, 29346, 29560, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 29562, 29885, 29898, 29923, 30087, 30086, 30303,
+30305, 30663, 31001, 31153, 31339, 31337, 31806, 31807, 31800, 31805,
+31799, 31808, 32363, 32365, 32377, 32361, 32362, 32645, 32371, 32694,
+32697, 32696, 33240, 34281, 34269, 34282, 34261, 34276, 34277, 34295,
+34811, 34821, 34829, 34809, 34814, 35168, 35167, 35158, 35166, 35649,
+35676, 35672, 35657, 35674, 35662, 35663, 35654, 35673, 36104, 36106,
+36476, 36466, 36487, 36470, 36460, 36474, 36468, 36692, 36686, 36781,
+37002, 37003, 37297, 37294, 37857, 37841, 37855, 37827, 37832, 37852,
+37853, 37846, 37858, 37837, 37848, 37860, 37847, 37864, 38364, 38580,
+38627, 38698, 38695, 38753, 38876, 38907, 39006, 39000, 39003, 39100,
+39237, 39241, 39446, 39449, 39693, 39912, 39911, 39894, 39899, 40329,
+40289, 40306, 40298, 40300, 40594, 40599, 40595, 40628, 21240, 22184,
+22199, 22198, 22196, 22204, 22756, 23360, 23363, 23421, 23542, 24009,
+25080, 25082, 25880, 25876, 25881, 26342, 26407, 27372, 28734, 28720,
+28722, 29200, 29563, 29903, 30306, 30309, 31014, 31018, 31020, 31019,
+31431, 31478, 31820, 31811, 31821, 31983, 31984, 36782, 32381, 32380,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 32386, 32588, 32768, 33242, 33382, 34299,
+34297, 34321, 34298, 34310, 34315, 34311, 34314, 34836, 34837, 35172,
+35258, 35320, 35696, 35692, 35686, 35695, 35679, 35691, 36111, 36109,
+36489, 36481, 36485, 36482, 37300, 37323, 37912, 37891, 37885, 38369,
+38704, 39108, 39250, 39249, 39336, 39467, 39472, 39479, 39477, 39955,
+39949, 40569, 40629, 40680, 40751, 40799, 40803, 40801, 20791, 20792,
+22209, 22208, 22210, 22804, 23660, 24013, 25084, 25086, 25885, 25884,
+26005, 26345, 27387, 27396, 27386, 27570, 28748, 29211, 29351, 29910,
+29908, 30313, 30675, 31824, 32399, 32396, 32700, 34327, 34349, 34330,
+34851, 34850, 34849, 34847, 35178, 35180, 35261, 35700, 35703, 35709,
+36115, 36490, 36493, 36491, 36703, 36783, 37306, 37934, 37939, 37941,
+37946, 37944, 37938, 37931, 38370, 38712, 38713, 38706, 38911, 39015,
+39013, 39255, 39493, 39491, 39488, 39486, 39631, 39764, 39761, 39981,
+39973, 40367, 40372, 40386, 40376, 40605, 40687, 40729, 40796, 40806,
+40807, 20796, 20795, 22216, 22218, 22217, 23423, 24020, 24018, 24398,
+25087, 25892, 27402, 27489, 28753, 28760, 29568, 29924, 30090, 30318,
+30316, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 31155, 31840, 31839, 32894, 32893,
+33247, 35186, 35183, 35324, 35712, 36118, 36119, 36497, 36499, 36705,
+37192, 37956, 37969, 37970, 38717, 38718, 38851, 38849, 39019, 39253,
+39509, 39501, 39634, 39706, 40009, 39985, 39998, 39995, 40403, 40407,
+40756, 40812, 40810, 40852, 22220, 24022, 25088, 25891, 25899, 25898,
+26348, 27408, 29914, 31434, 31844, 31843, 31845, 32403, 32406, 32404,
+33250, 34360, 34367, 34865, 35722, 37008, 37007, 37987, 37984, 37988,
+38760, 39023, 39260, 39514, 39515, 39511, 39635, 39636, 39633, 40020,
+40023, 40022, 40421, 40607, 40692, 22225, 22761, 25900, 28766, 30321,
+30322, 30679, 32592, 32648, 34870, 34873, 34914, 35731, 35730, 35734,
+33399, 36123, 37312, 37994, 38722, 38728, 38724, 38854, 39024, 39519,
+39714, 39768, 40031, 40441, 40442, 40572, 40573, 40711, 40823, 40818,
+24307, 27414, 28771, 31852, 31854, 34875, 35264, 36513, 37313, 38002,
+38000, 39025, 39262, 39638, 39715, 40652, 28772, 30682, 35738, 38007,
+38857, 39522, 39525, 32412, 35740, 36522, 37317, 38013, 38014, 38012,
+40055, 40056, 40695, 35924, 38015, 40474, 29224, 39530, 39729, 40475,
+40478, 31858, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 9312, 9313, 9314, 9315,
+ 9316, 9317, 9318, 9319, 9320, 9321, 9332, 9333, 9334, 9335,
+ 9336, 9337, 9338, 9339, 9340, 9341, 8560, 8561, 8562, 8563,
+ 8564, 8565, 8566, 8567, 8568, 8569, 20022, 20031, 20101, 20128,
+20866, 20886, 20907, 21241, 21304, 21353, 21430, 22794, 23424, 24027,
+24186, 24191, 24308, 24400, 24417, 25908, 26080, 30098, 30326, 36789,
+38582, 168, 710, 12541, 12542, 12445, 12446, 12291, 20189, 12293,
+12294, 12295, 12540, 65339, 65341, 10045, 12353, 12354, 12355, 12356,
+12357, 12358, 12359, 12360, 12361, 12362, 12363, 12364, 12365, 12366,
+12367, 12368, 12369, 12370, 12371, 12372, 12373, 12374, 12375, 12376,
+12377, 12378, 12379, 12380, 12381, 12382, 12383, 12384, 12385, 12386,
+12387, 12388, 12389, 12390, 12391, 12392, 12393, 12394, 12395, 12396,
+12397, 12398, 12399, 12400, 12401, 12402, 12403, 12404, 12405, 12406,
+12407, 12408, 12409, 12410, 12411, 12412, 12413, 12414, 12415, 12416,
+12417, 12418, 12419, 12420, 12421, 12422, 12423, 12424, 12425, 12426,
+12427, 12428, 12429, 12430, 12431, 12432, 12433, 12434, 12435, 12449,
+12450, 12451, 12452, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 12453, 12454, 12455,
+12456, 12457, 12458, 12459, 12460, 12461, 12462, 12463, 12464, 12465,
+12466, 12467, 12468, 12469, 12470, 12471, 12472, 12473, 12474, 12475,
+12476, 12477, 12478, 12479, 12480, 12481, 12482, 12483, 12484, 12485,
+12486, 12487, 12488, 12489, 12490, 12491, 12492, 12493, 12494, 12495,
+12496, 12497, 12498, 12499, 12500, 12501, 12502, 12503, 12504, 12505,
+12506, 12507, 12508, 12509, 12510, 12511, 12512, 12513, 12514, 12515,
+12516, 12517, 12518, 12519, 12520, 12521, 12522, 12523, 12524, 12525,
+12526, 12527, 12528, 12529, 12530, 12531, 12532, 12533, 12534, 1040,
+ 1041, 1042, 1043, 1044, 1045, 1025, 1046, 1047, 1048, 1049,
+ 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059,
+ 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069,
+ 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1105, 1078,
+ 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088,
+ 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098,
+ 1099, 1100, 1101, 1102, 1103, 8679, 8632, 8633, 12751, 63462,
+20058, 63464, 20994, 17553, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 40880, 20872,
+40881, 63470, 63471, 63472, 63473, 63474, 63475, 63476, 63477, 63478,
+63479, 63480, 63481, 63482, 12443, 12444, 12436, 12535, 12536, 12537,
+12538, 12539, 65377, 65378, 65379, 65380, 65381, 65382, 65383, 65384,
+65385, 65386, 65387, 65388, 65389, 65390, 65391, 65392, 65393, 65394,
+65395, 65396, 65506, 65508, 65287, 65282, 12849, 8470, 8481, 65397,
+65398, 65399, 65400, 65401, 65402, 65403, 65404, 65405, 65406, 65407,
+65408, 65409, 65410, 65411, 65412, 65413, 65414, 65415, 65416, 65417,
+65418, 65419, 65420, 65421, 65422, 65423, 65424, 65425, 65426, 65427,
+65428, 65429, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437,
+65438, 65439, 20034, 20060, 20981, 21274, 21378, 19975, 19980, 20039,
+20109, 22231, 64012, 23662, 24435, 19983, 20871, 19982, 20014, 20115,
+20162, 20169, 20168, 20888, 21244, 21356, 21433, 22304, 22787, 22828,
+23568, 24063, 26081, 27571, 27596, 27668, 29247, 20017, 20028, 20200,
+20188, 20201, 20193, 20189, 20186, 21004, 21276, 21324, 22306, 22307,
+22807, 22831, 23425, 23428, 23570, 23611, 23668, 23667, 24068, 24192,
+24194, 24521, 25097, 25168, 27669, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 27702,
+27715, 27711, 27707, 29358, 29360, 29578, 31160, 32906, 38430, 20238,
+20248, 20268, 20213, 20244, 20209, 20224, 20215, 20232, 20253, 20226,
+20229, 20258, 20243, 20228, 20212, 20242, 20913, 21011, 21001, 21008,
+21158, 21282, 21279, 21325, 21386, 21511, 22241, 22239, 22318, 22314,
+22324, 22844, 22912, 22908, 22917, 22907, 22910, 22903, 22911, 23382,
+23573, 23589, 23676, 23674, 23675, 23678, 24031, 24181, 24196, 24322,
+24346, 24436, 24533, 24532, 24527, 25180, 25182, 25188, 25185, 25190,
+25186, 25177, 25184, 25178, 25189, 26095, 26094, 26430, 26425, 26424,
+26427, 26426, 26431, 26428, 26419, 27672, 27718, 27730, 27740, 27727,
+27722, 27732, 27723, 27724, 28785, 29278, 29364, 29365, 29582, 29994,
+30335, 31349, 32593, 33400, 33404, 33408, 33405, 33407, 34381, 35198,
+37017, 37015, 37016, 37019, 37012, 38434, 38436, 38432, 38435, 20310,
+20283, 20322, 20297, 20307, 20324, 20286, 20327, 20306, 20319, 20289,
+20312, 20269, 20275, 20287, 20321, 20879, 20921, 21020, 21022, 21025,
+21165, 21166, 21257, 21347, 21362, 21390, 21391, 21552, 21559, 21546,
+21588, 21573, 21529, 21532, 21541, 21528, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+21565, 21583, 21569, 21544, 21540, 21575, 22254, 22247, 22245, 22337,
+22341, 22348, 22345, 22347, 22354, 22790, 22848, 22950, 22936, 22944,
+22935, 22926, 22946, 22928, 22927, 22951, 22945, 23438, 23442, 23592,
+23594, 23693, 23695, 23688, 23691, 23689, 23698, 23690, 23686, 23699,
+23701, 24032, 24074, 24078, 24203, 24201, 24204, 24200, 24205, 24325,
+24349, 24440, 24438, 24530, 24529, 24528, 24557, 24552, 24558, 24563,
+24545, 24548, 24547, 24570, 24559, 24567, 24571, 24576, 24564, 25146,
+25219, 25228, 25230, 25231, 25236, 25223, 25201, 25211, 25210, 25200,
+25217, 25224, 25207, 25213, 25202, 25204, 25911, 26096, 26100, 26099,
+26098, 26101, 26437, 26439, 26457, 26453, 26444, 26440, 26461, 26445,
+26458, 26443, 27600, 27673, 27674, 27768, 27751, 27755, 27780, 27787,
+27791, 27761, 27759, 27753, 27802, 27757, 27783, 27797, 27804, 27750,
+27763, 27749, 27771, 27790, 28788, 28794, 29283, 29375, 29373, 29379,
+29382, 29377, 29370, 29381, 29589, 29591, 29587, 29588, 29586, 30010,
+30009, 30100, 30101, 30337, 31037, 32820, 32917, 32921, 32912, 32914,
+32924, 33424, 33423, 33413, 33422, 33425, 33427, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 33418, 33411, 33412, 35960, 36809, 36799, 37023, 37025, 37029,
+37022, 37031, 37024, 38448, 38440, 38447, 38445, 20019, 20376, 20348,
+20357, 20349, 20352, 20359, 20342, 20340, 20361, 20356, 20343, 20300,
+20375, 20330, 20378, 20345, 20353, 20344, 20368, 20380, 20372, 20382,
+20370, 20354, 20373, 20331, 20334, 20894, 20924, 20926, 21045, 21042,
+21043, 21062, 21041, 21180, 21258, 21259, 21308, 21394, 21396, 21639,
+21631, 21633, 21649, 21634, 21640, 21611, 21626, 21630, 21605, 21612,
+21620, 21606, 21645, 21615, 21601, 21600, 21656, 21603, 21607, 21604,
+22263, 22265, 22383, 22386, 22381, 22379, 22385, 22384, 22390, 22400,
+22389, 22395, 22387, 22388, 22370, 22376, 22397, 22796, 22853, 22965,
+22970, 22991, 22990, 22962, 22988, 22977, 22966, 22972, 22979, 22998,
+22961, 22973, 22976, 22984, 22964, 22983, 23394, 23397, 23443, 23445,
+23620, 23623, 23726, 23716, 23712, 23733, 23727, 23720, 23724, 23711,
+23715, 23725, 23714, 23722, 23719, 23709, 23717, 23734, 23728, 23718,
+24087, 24084, 24089, 24360, 24354, 24355, 24356, 24404, 24450, 24446,
+24445, 24542, 24549, 24621, 24614, 24601, 24626, 24587, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 24628, 24586, 24599, 24627, 24602, 24606, 24620, 24610,
+24589, 24592, 24622, 24595, 24593, 24588, 24585, 24604, 25108, 25149,
+25261, 25268, 25297, 25278, 25258, 25270, 25290, 25262, 25267, 25263,
+25275, 25257, 25264, 25272, 25917, 26024, 26043, 26121, 26108, 26116,
+26130, 26120, 26107, 26115, 26123, 26125, 26117, 26109, 26129, 26128,
+26358, 26378, 26501, 26476, 26510, 26514, 26486, 26491, 26520, 26502,
+26500, 26484, 26509, 26508, 26490, 26527, 26513, 26521, 26499, 26493,
+26497, 26488, 26489, 26516, 27429, 27520, 27518, 27614, 27677, 27795,
+27884, 27883, 27886, 27865, 27830, 27860, 27821, 27879, 27831, 27856,
+27842, 27834, 27843, 27846, 27885, 27890, 27858, 27869, 27828, 27786,
+27805, 27776, 27870, 27840, 27952, 27853, 27847, 27824, 27897, 27855,
+27881, 27857, 28820, 28824, 28805, 28819, 28806, 28804, 28817, 28822,
+28802, 28826, 28803, 29290, 29398, 29387, 29400, 29385, 29404, 29394,
+29396, 29402, 29388, 29393, 29604, 29601, 29613, 29606, 29602, 29600,
+29612, 29597, 29917, 29928, 30015, 30016, 30014, 30092, 30104, 30383,
+30451, 30449, 30448, 30453, 30712, 30716, 30713, 30715, 30714, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 30711, 31042, 31039, 31173, 31352, 31355, 31483,
+31861, 31997, 32821, 32911, 32942, 32931, 32952, 32949, 32941, 33312,
+33440, 33472, 33451, 33434, 33432, 33435, 33461, 33447, 33454, 33468,
+33438, 33466, 33460, 33448, 33441, 33449, 33474, 33444, 33475, 33462,
+33442, 34416, 34415, 34413, 34414, 35926, 36818, 36811, 36819, 36813,
+36822, 36821, 36823, 37042, 37044, 37039, 37043, 37040, 38457, 38461,
+38460, 38458, 38467, 20429, 20421, 20435, 20402, 20425, 20427, 20417,
+20436, 20444, 20441, 20411, 20403, 20443, 20423, 20438, 20410, 20416,
+20409, 20460, 21060, 21065, 21184, 21186, 21309, 21372, 21399, 21398,
+21401, 21400, 21690, 21665, 21677, 21669, 21711, 21699, 33549, 21687,
+21678, 21718, 21686, 21701, 21702, 21664, 21616, 21692, 21666, 21694,
+21618, 21726, 21680, 22453, 22430, 22431, 22436, 22412, 22423, 22429,
+22427, 22420, 22424, 22415, 22425, 22437, 22426, 22421, 22772, 22797,
+22867, 23009, 23006, 23022, 23040, 23025, 23005, 23034, 23037, 23036,
+23030, 23012, 23026, 23031, 23003, 23017, 23027, 23029, 23008, 23038,
+23028, 23021, 23464, 23628, 23760, 23768, 23756, 23767, 23755, 23771,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 23774, 23770, 23753, 23751, 23754, 23766,
+23763, 23764, 23759, 23752, 23750, 23758, 23775, 23800, 24057, 24097,
+24098, 24099, 24096, 24100, 24240, 24228, 24226, 24219, 24227, 24229,
+24327, 24366, 24406, 24454, 24631, 24633, 24660, 24690, 24670, 24645,
+24659, 24647, 24649, 24667, 24652, 24640, 24642, 24671, 24612, 24644,
+24664, 24678, 24686, 25154, 25155, 25295, 25357, 25355, 25333, 25358,
+25347, 25323, 25337, 25359, 25356, 25336, 25334, 25344, 25363, 25364,
+25338, 25365, 25339, 25328, 25921, 25923, 26026, 26047, 26166, 26145,
+26162, 26165, 26140, 26150, 26146, 26163, 26155, 26170, 26141, 26164,
+26169, 26158, 26383, 26384, 26561, 26610, 26568, 26554, 26588, 26555,
+26616, 26584, 26560, 26551, 26565, 26603, 26596, 26591, 26549, 26573,
+26547, 26615, 26614, 26606, 26595, 26562, 26553, 26574, 26599, 26608,
+26546, 26620, 26566, 26605, 26572, 26542, 26598, 26587, 26618, 26569,
+26570, 26563, 26602, 26571, 27432, 27522, 27524, 27574, 27606, 27608,
+27616, 27680, 27681, 27944, 27956, 27949, 27935, 27964, 27967, 27922,
+27914, 27866, 27955, 27908, 27929, 27962, 27930, 27921, 27904, 27933,
+27970, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 27905, 27928, 27959, 27907, 27919,
+27968, 27911, 27936, 27948, 27912, 27938, 27913, 27920, 28855, 28831,
+28862, 28849, 28848, 28833, 28852, 28853, 28841, 29249, 29257, 29258,
+29292, 29296, 29299, 29294, 29386, 29412, 29416, 29419, 29407, 29418,
+29414, 29411, 29573, 29644, 29634, 29640, 29637, 29625, 29622, 29621,
+29620, 29675, 29631, 29639, 29630, 29635, 29638, 29624, 29643, 29932,
+29934, 29998, 30023, 30024, 30119, 30122, 30329, 30404, 30472, 30467,
+30468, 30469, 30474, 30455, 30459, 30458, 30695, 30696, 30726, 30737,
+30738, 30725, 30736, 30735, 30734, 30729, 30723, 30739, 31050, 31052,
+31051, 31045, 31044, 31189, 31181, 31183, 31190, 31182, 31360, 31358,
+31441, 31488, 31489, 31866, 31864, 31865, 31871, 31872, 31873, 32003,
+32008, 32001, 32600, 32657, 32653, 32702, 32775, 32782, 32783, 32788,
+32823, 32984, 32967, 32992, 32977, 32968, 32962, 32976, 32965, 32995,
+32985, 32988, 32970, 32981, 32969, 32975, 32983, 32998, 32973, 33279,
+33313, 33428, 33497, 33534, 33529, 33543, 33512, 33536, 33493, 33594,
+33515, 33494, 33524, 33516, 33505, 33522, 33525, 33548, 33531, 33526,
+33520, 33514, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 33508, 33504, 33530, 33523,
+33517, 34423, 34420, 34428, 34419, 34881, 34894, 34919, 34922, 34921,
+35283, 35332, 35335, 36210, 36835, 36833, 36846, 36832, 37105, 37053,
+37055, 37077, 37061, 37054, 37063, 37067, 37064, 37332, 37331, 38484,
+38479, 38481, 38483, 38474, 38478, 20510, 20485, 20487, 20499, 20514,
+20528, 20507, 20469, 20468, 20531, 20535, 20524, 20470, 20471, 20503,
+20508, 20512, 20519, 20533, 20527, 20529, 20494, 20826, 20884, 20883,
+20938, 20932, 20933, 20936, 20942, 21089, 21082, 21074, 21086, 21087,
+21077, 21090, 21197, 21262, 21406, 21798, 21730, 21783, 21778, 21735,
+21747, 21732, 21786, 21759, 21764, 21768, 21739, 21777, 21765, 21745,
+21770, 21755, 21751, 21752, 21728, 21774, 21763, 21771, 22273, 22274,
+22476, 22578, 22485, 22482, 22458, 22470, 22461, 22460, 22456, 22454,
+22463, 22471, 22480, 22457, 22465, 22798, 22858, 23065, 23062, 23085,
+23086, 23061, 23055, 23063, 23050, 23070, 23091, 23404, 23463, 23469,
+23468, 23555, 23638, 23636, 23788, 23807, 23790, 23793, 23799, 23808,
+23801, 24105, 24104, 24232, 24238, 24234, 24236, 24371, 24368, 24423,
+24669, 24666, 24679, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 24641, 24738, 24712,
+24704, 24722, 24705, 24733, 24707, 24725, 24731, 24727, 24711, 24732,
+24718, 25113, 25158, 25330, 25360, 25430, 25388, 25412, 25413, 25398,
+25411, 25572, 25401, 25419, 25418, 25404, 25385, 25409, 25396, 25432,
+25428, 25433, 25389, 25415, 25395, 25434, 25425, 25400, 25431, 25408,
+25416, 25930, 25926, 26054, 26051, 26052, 26050, 26186, 26207, 26183,
+26193, 26386, 26387, 26655, 26650, 26697, 26674, 26675, 26683, 26699,
+26703, 26646, 26673, 26652, 26677, 26667, 26669, 26671, 26702, 26692,
+26676, 26653, 26642, 26644, 26662, 26664, 26670, 26701, 26682, 26661,
+26656, 27436, 27439, 27437, 27441, 27444, 27501, 32898, 27528, 27622,
+27620, 27624, 27619, 27618, 27623, 27685, 28026, 28003, 28004, 28022,
+27917, 28001, 28050, 27992, 28002, 28013, 28015, 28049, 28045, 28143,
+28031, 28038, 27998, 28007, 28000, 28055, 28016, 28028, 27999, 28034,
+28056, 27951, 28008, 28043, 28030, 28032, 28036, 27926, 28035, 28027,
+28029, 28021, 28048, 28892, 28883, 28881, 28893, 28875, 32569, 28898,
+28887, 28882, 28894, 28896, 28884, 28877, 28869, 28870, 28871, 28890,
+28878, 28897, 29250, 29304, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 29303, 29302,
+29440, 29434, 29428, 29438, 29430, 29427, 29435, 29441, 29651, 29657,
+29669, 29654, 29628, 29671, 29667, 29673, 29660, 29650, 29659, 29652,
+29661, 29658, 29655, 29656, 29672, 29918, 29919, 29940, 29941, 29985,
+30043, 30047, 30128, 30145, 30139, 30148, 30144, 30143, 30134, 30138,
+30346, 30409, 30493, 30491, 30480, 30483, 30482, 30499, 30481, 30485,
+30489, 30490, 30498, 30503, 30755, 30764, 30754, 30773, 30767, 30760,
+30766, 30763, 30753, 30761, 30771, 30762, 30769, 31060, 31067, 31055,
+31068, 31059, 31058, 31057, 31211, 31212, 31200, 31214, 31213, 31210,
+31196, 31198, 31197, 31366, 31369, 31365, 31371, 31372, 31370, 31367,
+31448, 31504, 31492, 31507, 31493, 31503, 31496, 31498, 31502, 31497,
+31506, 31876, 31889, 31882, 31884, 31880, 31885, 31877, 32030, 32029,
+32017, 32014, 32024, 32022, 32019, 32031, 32018, 32015, 32012, 32604,
+32609, 32606, 32608, 32605, 32603, 32662, 32658, 32707, 32706, 32704,
+32790, 32830, 32825, 33018, 33010, 33017, 33013, 33025, 33019, 33024,
+33281, 33327, 33317, 33587, 33581, 33604, 33561, 33617, 33573, 33622,
+33599, 33601, 33574, 33564, 33570, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 33602,
+33614, 33563, 33578, 33544, 33596, 33613, 33558, 33572, 33568, 33591,
+33583, 33577, 33607, 33605, 33612, 33619, 33566, 33580, 33611, 33575,
+33608, 34387, 34386, 34466, 34472, 34454, 34445, 34449, 34462, 34439,
+34455, 34438, 34443, 34458, 34437, 34469, 34457, 34465, 34471, 34453,
+34456, 34446, 34461, 34448, 34452, 34883, 34884, 34925, 34933, 34934,
+34930, 34944, 34929, 34943, 34927, 34947, 34942, 34932, 34940, 35346,
+35911, 35927, 35963, 36004, 36003, 36214, 36216, 36277, 36279, 36278,
+36561, 36563, 36862, 36853, 36866, 36863, 36859, 36868, 36860, 36854,
+37078, 37088, 37081, 37082, 37091, 37087, 37093, 37080, 37083, 37079,
+37084, 37092, 37200, 37198, 37199, 37333, 37346, 37338, 38492, 38495,
+38588, 39139, 39647, 39727, 20095, 20592, 20586, 20577, 20574, 20576,
+20563, 20555, 20573, 20594, 20552, 20557, 20545, 20571, 20554, 20578,
+20501, 20549, 20575, 20585, 20587, 20579, 20580, 20550, 20544, 20590,
+20595, 20567, 20561, 20944, 21099, 21101, 21100, 21102, 21206, 21203,
+21293, 21404, 21877, 21878, 21820, 21837, 21840, 21812, 21802, 21841,
+21858, 21814, 21813, 21808, 21842, 21829, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+21772, 21810, 21861, 21838, 21817, 21832, 21805, 21819, 21824, 21835,
+22282, 22279, 22523, 22548, 22498, 22518, 22492, 22516, 22528, 22509,
+22525, 22536, 22520, 22539, 22515, 22479, 22535, 22510, 22499, 22514,
+22501, 22508, 22497, 22542, 22524, 22544, 22503, 22529, 22540, 22513,
+22505, 22512, 22541, 22532, 22876, 23136, 23128, 23125, 23143, 23134,
+23096, 23093, 23149, 23120, 23135, 23141, 23148, 23123, 23140, 23127,
+23107, 23133, 23122, 23108, 23131, 23112, 23182, 23102, 23117, 23097,
+23116, 23152, 23145, 23111, 23121, 23126, 23106, 23132, 23410, 23406,
+23489, 23488, 23641, 23838, 23819, 23837, 23834, 23840, 23820, 23848,
+23821, 23846, 23845, 23823, 23856, 23826, 23843, 23839, 23854, 24126,
+24116, 24241, 24244, 24249, 24242, 24243, 24374, 24376, 24475, 24470,
+24479, 24714, 24720, 24710, 24766, 24752, 24762, 24787, 24788, 24783,
+24804, 24793, 24797, 24776, 24753, 24795, 24759, 24778, 24767, 24771,
+24781, 24768, 25394, 25445, 25482, 25474, 25469, 25533, 25502, 25517,
+25501, 25495, 25515, 25486, 25455, 25479, 25488, 25454, 25519, 25461,
+25500, 25453, 25518, 25468, 25508, 25403, 25503, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 25464, 25477, 25473, 25489, 25485, 25456, 25939, 26061, 26213,
+26209, 26203, 26201, 26204, 26210, 26392, 26745, 26759, 26768, 26780,
+26733, 26734, 26798, 26795, 26966, 26735, 26787, 26796, 26793, 26741,
+26740, 26802, 26767, 26743, 26770, 26748, 26731, 26738, 26794, 26752,
+26737, 26750, 26779, 26774, 26763, 26784, 26761, 26788, 26744, 26747,
+26769, 26764, 26762, 26749, 27446, 27443, 27447, 27448, 27537, 27535,
+27533, 27534, 27532, 27690, 28096, 28075, 28084, 28083, 28276, 28076,
+28137, 28130, 28087, 28150, 28116, 28160, 28104, 28128, 28127, 28118,
+28094, 28133, 28124, 28125, 28123, 28148, 28106, 28093, 28141, 28144,
+28090, 28117, 28098, 28111, 28105, 28112, 28146, 28115, 28157, 28119,
+28109, 28131, 28091, 28922, 28941, 28919, 28951, 28916, 28940, 28912,
+28932, 28915, 28944, 28924, 28927, 28934, 28947, 28928, 28920, 28918,
+28939, 28930, 28942, 29310, 29307, 29308, 29311, 29469, 29463, 29447,
+29457, 29464, 29450, 29448, 29439, 29455, 29470, 29576, 29686, 29688,
+29685, 29700, 29697, 29693, 29703, 29696, 29690, 29692, 29695, 29708,
+29707, 29684, 29704, 30052, 30051, 30158, 30162, 30159, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 30155, 30156, 30161, 30160, 30351, 30345, 30419, 30521,
+30511, 30509, 30513, 30514, 30516, 30515, 30525, 30501, 30523, 30517,
+30792, 30802, 30793, 30797, 30794, 30796, 30758, 30789, 30800, 31076,
+31079, 31081, 31082, 31075, 31083, 31073, 31163, 31226, 31224, 31222,
+31223, 31375, 31380, 31376, 31541, 31559, 31540, 31525, 31536, 31522,
+31524, 31539, 31512, 31530, 31517, 31537, 31531, 31533, 31535, 31538,
+31544, 31514, 31523, 31892, 31896, 31894, 31907, 32053, 32061, 32056,
+32054, 32058, 32069, 32044, 32041, 32065, 32071, 32062, 32063, 32074,
+32059, 32040, 32611, 32661, 32668, 32669, 32667, 32714, 32715, 32717,
+32720, 32721, 32711, 32719, 32713, 32799, 32798, 32795, 32839, 32835,
+32840, 33048, 33061, 33049, 33051, 33069, 33055, 33068, 33054, 33057,
+33045, 33063, 33053, 33058, 33297, 33336, 33331, 33338, 33332, 33330,
+33396, 33680, 33699, 33704, 33677, 33658, 33651, 33700, 33652, 33679,
+33665, 33685, 33689, 33653, 33684, 33705, 33661, 33667, 33676, 33693,
+33691, 33706, 33675, 33662, 33701, 33711, 33672, 33687, 33712, 33663,
+33702, 33671, 33710, 33654, 33690, 34393, 34390, 34495, 34487, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 34498, 34497, 34501, 34490, 34480, 34504, 34489,
+34483, 34488, 34508, 34484, 34491, 34492, 34499, 34493, 34494, 34898,
+34953, 34965, 34984, 34978, 34986, 34970, 34961, 34977, 34975, 34968,
+34983, 34969, 34971, 34967, 34980, 34988, 34956, 34963, 34958, 35202,
+35286, 35289, 35285, 35376, 35367, 35372, 35358, 35897, 35899, 35932,
+35933, 35965, 36005, 36221, 36219, 36217, 36284, 36290, 36281, 36287,
+36289, 36568, 36574, 36573, 36572, 36567, 36576, 36577, 36900, 36875,
+36881, 36892, 36876, 36897, 37103, 37098, 37104, 37108, 37106, 37107,
+37076, 37099, 37100, 37097, 37206, 37208, 37210, 37203, 37205, 37356,
+37364, 37361, 37363, 37368, 37348, 37369, 37354, 37355, 37367, 37352,
+37358, 38266, 38278, 38280, 38524, 38509, 38507, 38513, 38511, 38591,
+38762, 38916, 39141, 39319, 20635, 20629, 20628, 20638, 20619, 20643,
+20611, 20620, 20622, 20637, 20584, 20636, 20626, 20610, 20615, 20831,
+20948, 21266, 21265, 21412, 21415, 21905, 21928, 21925, 21933, 21879,
+22085, 21922, 21907, 21896, 21903, 21941, 21889, 21923, 21906, 21924,
+21885, 21900, 21926, 21887, 21909, 21921, 21902, 22284, 22569, 22583,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 22553, 22558, 22567, 22563, 22568, 22517,
+22600, 22565, 22556, 22555, 22579, 22591, 22582, 22574, 22585, 22584,
+22573, 22572, 22587, 22881, 23215, 23188, 23199, 23162, 23202, 23198,
+23160, 23206, 23164, 23205, 23212, 23189, 23214, 23095, 23172, 23178,
+23191, 23171, 23179, 23209, 23163, 23165, 23180, 23196, 23183, 23187,
+23197, 23530, 23501, 23499, 23508, 23505, 23498, 23502, 23564, 23600,
+23863, 23875, 23915, 23873, 23883, 23871, 23861, 23889, 23886, 23893,
+23859, 23866, 23890, 23869, 23857, 23897, 23874, 23865, 23881, 23864,
+23868, 23858, 23862, 23872, 23877, 24132, 24129, 24408, 24486, 24485,
+24491, 24777, 24761, 24780, 24802, 24782, 24772, 24852, 24818, 24842,
+24854, 24837, 24821, 24851, 24824, 24828, 24830, 24769, 24835, 24856,
+24861, 24848, 24831, 24836, 24843, 25162, 25492, 25521, 25520, 25550,
+25573, 25576, 25583, 25539, 25757, 25587, 25546, 25568, 25590, 25557,
+25586, 25589, 25697, 25567, 25534, 25565, 25564, 25540, 25560, 25555,
+25538, 25543, 25548, 25547, 25544, 25584, 25559, 25561, 25906, 25959,
+25962, 25956, 25948, 25960, 25957, 25996, 26013, 26014, 26030, 26064,
+26066, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 26236, 26220, 26235, 26240, 26225,
+26233, 26218, 26226, 26369, 26892, 26835, 26884, 26844, 26922, 26860,
+26858, 26865, 26895, 26838, 26871, 26859, 26852, 26870, 26899, 26896,
+26867, 26849, 26887, 26828, 26888, 26992, 26804, 26897, 26863, 26822,
+26900, 26872, 26832, 26877, 26876, 26856, 26891, 26890, 26903, 26830,
+26824, 26845, 26846, 26854, 26868, 26833, 26886, 26836, 26857, 26901,
+26917, 26823, 27449, 27451, 27455, 27452, 27540, 27543, 27545, 27541,
+27581, 27632, 27634, 27635, 27696, 28156, 28230, 28231, 28191, 28233,
+28296, 28220, 28221, 28229, 28258, 28203, 28223, 28225, 28253, 28275,
+28188, 28211, 28235, 28224, 28241, 28219, 28163, 28206, 28254, 28264,
+28252, 28257, 28209, 28200, 28256, 28273, 28267, 28217, 28194, 28208,
+28243, 28261, 28199, 28280, 28260, 28279, 28245, 28281, 28242, 28262,
+28213, 28214, 28250, 28960, 28958, 28975, 28923, 28974, 28977, 28963,
+28965, 28962, 28978, 28959, 28968, 28986, 28955, 29259, 29274, 29320,
+29321, 29318, 29317, 29323, 29458, 29451, 29488, 29474, 29489, 29491,
+29479, 29490, 29485, 29478, 29475, 29493, 29452, 29742, 29740, 29744,
+29739, 29718, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 29722, 29729, 29741, 29745,
+29732, 29731, 29725, 29737, 29728, 29746, 29947, 29999, 30063, 30060,
+30183, 30170, 30177, 30182, 30173, 30175, 30180, 30167, 30357, 30354,
+30426, 30534, 30535, 30532, 30541, 30533, 30538, 30542, 30539, 30540,
+30686, 30700, 30816, 30820, 30821, 30812, 30829, 30833, 30826, 30830,
+30832, 30825, 30824, 30814, 30818, 31092, 31091, 31090, 31088, 31234,
+31242, 31235, 31244, 31236, 31385, 31462, 31460, 31562, 31547, 31556,
+31560, 31564, 31566, 31552, 31576, 31557, 31906, 31902, 31912, 31905,
+32088, 32111, 32099, 32083, 32086, 32103, 32106, 32079, 32109, 32092,
+32107, 32082, 32084, 32105, 32081, 32095, 32078, 32574, 32575, 32613,
+32614, 32674, 32672, 32673, 32727, 32849, 32847, 32848, 33022, 32980,
+33091, 33098, 33106, 33103, 33095, 33085, 33101, 33082, 33254, 33262,
+33271, 33272, 33273, 33284, 33340, 33341, 33343, 33397, 33595, 33743,
+33785, 33827, 33728, 33768, 33810, 33767, 33764, 33788, 33782, 33808,
+33734, 33736, 33771, 33763, 33727, 33793, 33757, 33765, 33752, 33791,
+33761, 33739, 33742, 33750, 33781, 33737, 33801, 33807, 33758, 33809,
+33798, 33730, 33779, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 33749, 33786, 33735,
+33745, 33770, 33811, 33731, 33772, 33774, 33732, 33787, 33751, 33762,
+33819, 33755, 33790, 34520, 34530, 34534, 34515, 34531, 34522, 34538,
+34525, 34539, 34524, 34540, 34537, 34519, 34536, 34513, 34888, 34902,
+34901, 35002, 35031, 35001, 35000, 35008, 35006, 34998, 35004, 34999,
+35005, 34994, 35073, 35017, 35221, 35224, 35223, 35293, 35290, 35291,
+35406, 35405, 35385, 35417, 35392, 35415, 35416, 35396, 35397, 35410,
+35400, 35409, 35402, 35404, 35407, 35935, 35969, 35968, 36026, 36030,
+36016, 36025, 36021, 36228, 36224, 36233, 36312, 36307, 36301, 36295,
+36310, 36316, 36303, 36309, 36313, 36296, 36311, 36293, 36591, 36599,
+36602, 36601, 36582, 36590, 36581, 36597, 36583, 36584, 36598, 36587,
+36593, 36588, 36596, 36585, 36909, 36916, 36911, 37126, 37164, 37124,
+37119, 37116, 37128, 37113, 37115, 37121, 37120, 37127, 37125, 37123,
+37217, 37220, 37215, 37218, 37216, 37377, 37386, 37413, 37379, 37402,
+37414, 37391, 37388, 37376, 37394, 37375, 37373, 37382, 37380, 37415,
+37378, 37404, 37412, 37401, 37399, 37381, 37398, 38267, 38285, 38284,
+38288, 38535, 38526, 38536, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 38537, 38531,
+38528, 38594, 38600, 38595, 38641, 38640, 38764, 38768, 38766, 38919,
+39081, 39147, 40166, 40697, 20099, 20100, 20150, 20669, 20671, 20678,
+20654, 20676, 20682, 20660, 20680, 20674, 20656, 20673, 20666, 20657,
+20683, 20681, 20662, 20664, 20951, 21114, 21112, 21115, 21116, 21955,
+21979, 21964, 21968, 21963, 21962, 21981, 21952, 21972, 21956, 21993,
+21951, 21970, 21901, 21967, 21973, 21986, 21974, 21960, 22002, 21965,
+21977, 21954, 22292, 22611, 22632, 22628, 22607, 22605, 22601, 22639,
+22613, 22606, 22621, 22617, 22629, 22619, 22589, 22627, 22641, 22780,
+23239, 23236, 23243, 23226, 23224, 23217, 23221, 23216, 23231, 23240,
+23227, 23238, 23223, 23232, 23242, 23220, 23222, 23245, 23225, 23184,
+23510, 23512, 23513, 23583, 23603, 23921, 23907, 23882, 23909, 23922,
+23916, 23902, 23912, 23911, 23906, 24048, 24143, 24142, 24138, 24141,
+24139, 24261, 24268, 24262, 24267, 24263, 24384, 24495, 24493, 24823,
+24905, 24906, 24875, 24901, 24886, 24882, 24878, 24902, 24879, 24911,
+24873, 24896, 25120, 37224, 25123, 25125, 25124, 25541, 25585, 25579,
+25616, 25618, 25609, 25632, 25636, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 25651,
+25667, 25631, 25621, 25624, 25657, 25655, 25634, 25635, 25612, 25638,
+25648, 25640, 25665, 25653, 25647, 25610, 25626, 25664, 25637, 25639,
+25611, 25575, 25627, 25646, 25633, 25614, 25967, 26002, 26067, 26246,
+26252, 26261, 26256, 26251, 26250, 26265, 26260, 26232, 26400, 26982,
+26975, 26936, 26958, 26978, 26993, 26943, 26949, 26986, 26937, 26946,
+26967, 26969, 27002, 26952, 26953, 26933, 26988, 26931, 26941, 26981,
+26864, 27000, 26932, 26985, 26944, 26991, 26948, 26998, 26968, 26945,
+26996, 26956, 26939, 26955, 26935, 26972, 26959, 26961, 26930, 26962,
+26927, 27003, 26940, 27462, 27461, 27459, 27458, 27464, 27457, 27547,
+64013, 27643, 27644, 27641, 27639, 27640, 28315, 28374, 28360, 28303,
+28352, 28319, 28307, 28308, 28320, 28337, 28345, 28358, 28370, 28349,
+28353, 28318, 28361, 28343, 28336, 28365, 28326, 28367, 28338, 28350,
+28355, 28380, 28376, 28313, 28306, 28302, 28301, 28324, 28321, 28351,
+28339, 28368, 28362, 28311, 28334, 28323, 28999, 29012, 29010, 29027,
+29024, 28993, 29021, 29026, 29042, 29048, 29034, 29025, 28994, 29016,
+28995, 29003, 29040, 29023, 29008, 29011, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+28996, 29005, 29018, 29263, 29325, 29324, 29329, 29328, 29326, 29500,
+29506, 29499, 29498, 29504, 29514, 29513, 29764, 29770, 29771, 29778,
+29777, 29783, 29760, 29775, 29776, 29774, 29762, 29766, 29773, 29780,
+29921, 29951, 29950, 29949, 29981, 30073, 30071, 27011, 30191, 30223,
+30211, 30199, 30206, 30204, 30201, 30200, 30224, 30203, 30198, 30189,
+30197, 30205, 30361, 30389, 30429, 30549, 30559, 30560, 30546, 30550,
+30554, 30569, 30567, 30548, 30553, 30573, 30688, 30855, 30874, 30868,
+30863, 30852, 30869, 30853, 30854, 30881, 30851, 30841, 30873, 30848,
+30870, 30843, 31100, 31106, 31101, 31097, 31249, 31256, 31257, 31250,
+31255, 31253, 31266, 31251, 31259, 31248, 31395, 31394, 31390, 31467,
+31590, 31588, 31597, 31604, 31593, 31602, 31589, 31603, 31601, 31600,
+31585, 31608, 31606, 31587, 31922, 31924, 31919, 32136, 32134, 32128,
+32141, 32127, 32133, 32122, 32142, 32123, 32131, 32124, 32140, 32148,
+32132, 32125, 32146, 32621, 32619, 32615, 32616, 32620, 32678, 32677,
+32679, 32731, 32732, 32801, 33124, 33120, 33143, 33116, 33129, 33115,
+33122, 33138, 26401, 33118, 33142, 33127, 33135, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 33092, 33121, 33309, 33353, 33348, 33344, 33346, 33349, 34033,
+33855, 33878, 33910, 33913, 33935, 33933, 33893, 33873, 33856, 33926,
+33895, 33840, 33869, 33917, 33882, 33881, 33908, 33907, 33885, 34055,
+33886, 33847, 33850, 33844, 33914, 33859, 33912, 33842, 33861, 33833,
+33753, 33867, 33839, 33858, 33837, 33887, 33904, 33849, 33870, 33868,
+33874, 33903, 33989, 33934, 33851, 33863, 33846, 33843, 33896, 33918,
+33860, 33835, 33888, 33876, 33902, 33872, 34571, 34564, 34551, 34572,
+34554, 34518, 34549, 34637, 34552, 34574, 34569, 34561, 34550, 34573,
+34565, 35030, 35019, 35021, 35022, 35038, 35035, 35034, 35020, 35024,
+35205, 35227, 35295, 35301, 35300, 35297, 35296, 35298, 35292, 35302,
+35446, 35462, 35455, 35425, 35391, 35447, 35458, 35460, 35445, 35459,
+35457, 35444, 35450, 35900, 35915, 35914, 35941, 35940, 35942, 35974,
+35972, 35973, 36044, 36200, 36201, 36241, 36236, 36238, 36239, 36237,
+36243, 36244, 36240, 36242, 36336, 36320, 36332, 36337, 36334, 36304,
+36329, 36323, 36322, 36327, 36338, 36331, 36340, 36614, 36607, 36609,
+36608, 36613, 36615, 36616, 36610, 36619, 36946, 36927, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 36932, 36937, 36925, 37136, 37133, 37135, 37137, 37142,
+37140, 37131, 37134, 37230, 37231, 37448, 37458, 37424, 37434, 37478,
+37427, 37477, 37470, 37507, 37422, 37450, 37446, 37485, 37484, 37455,
+37472, 37479, 37487, 37430, 37473, 37488, 37425, 37460, 37475, 37456,
+37490, 37454, 37459, 37452, 37462, 37426, 38303, 38300, 38302, 38299,
+38546, 38547, 38545, 38551, 38606, 38650, 38653, 38648, 38645, 38771,
+38775, 38776, 38770, 38927, 38925, 38926, 39084, 39158, 39161, 39343,
+39346, 39344, 39349, 39597, 39595, 39771, 40170, 40173, 40167, 40576,
+40701, 20710, 20692, 20695, 20712, 20723, 20699, 20714, 20701, 20708,
+20691, 20716, 20720, 20719, 20707, 20704, 20952, 21120, 21121, 21225,
+21227, 21296, 21420, 22055, 22037, 22028, 22034, 22012, 22031, 22044,
+22017, 22035, 22018, 22010, 22045, 22020, 22015, 22009, 22665, 22652,
+22672, 22680, 22662, 22657, 22655, 22644, 22667, 22650, 22663, 22673,
+22670, 22646, 22658, 22664, 22651, 22676, 22671, 22782, 22891, 23260,
+23278, 23269, 23253, 23274, 23258, 23277, 23275, 23283, 23266, 23264,
+23259, 23276, 23262, 23261, 23257, 23272, 23263, 23415, 23520, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 23523, 23651, 23938, 23936, 23933, 23942, 23930,
+23937, 23927, 23946, 23945, 23944, 23934, 23932, 23949, 23929, 23935,
+24152, 24153, 24147, 24280, 24273, 24279, 24270, 24284, 24277, 24281,
+24274, 24276, 24388, 24387, 24431, 24502, 24876, 24872, 24897, 24926,
+24945, 24947, 24914, 24915, 24946, 24940, 24960, 24948, 24916, 24954,
+24923, 24933, 24891, 24938, 24929, 24918, 25129, 25127, 25131, 25643,
+25677, 25691, 25693, 25716, 25718, 25714, 25715, 25725, 25717, 25702,
+25766, 25678, 25730, 25694, 25692, 25675, 25683, 25696, 25680, 25727,
+25663, 25708, 25707, 25689, 25701, 25719, 25971, 26016, 26273, 26272,
+26271, 26373, 26372, 26402, 27057, 27062, 27081, 27040, 27086, 27030,
+27056, 27052, 27068, 27025, 27033, 27022, 27047, 27021, 27049, 27070,
+27055, 27071, 27076, 27069, 27044, 27092, 27065, 27082, 27034, 27087,
+27059, 27027, 27050, 27041, 27038, 27097, 27031, 27024, 27074, 27061,
+27045, 27078, 27466, 27469, 27467, 27550, 27551, 27552, 27587, 27588,
+27646, 28366, 28405, 28401, 28419, 28453, 28408, 28471, 28411, 28462,
+28425, 28494, 28441, 28442, 28455, 28440, 28475, 28434, 28397, 28426,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 28470, 28531, 28409, 28398, 28461, 28480,
+28464, 28476, 28469, 28395, 28423, 28430, 28483, 28421, 28413, 28406,
+28473, 28444, 28412, 28474, 28447, 28429, 28446, 28424, 28449, 29063,
+29072, 29065, 29056, 29061, 29058, 29071, 29051, 29062, 29057, 29079,
+29252, 29267, 29335, 29333, 29331, 29507, 29517, 29521, 29516, 29794,
+29811, 29809, 29813, 29810, 29799, 29806, 29952, 29954, 29955, 30077,
+30096, 30230, 30216, 30220, 30229, 30225, 30218, 30228, 30392, 30593,
+30588, 30597, 30594, 30574, 30592, 30575, 30590, 30595, 30898, 30890,
+30900, 30893, 30888, 30846, 30891, 30878, 30885, 30880, 30892, 30882,
+30884, 31128, 31114, 31115, 31126, 31125, 31124, 31123, 31127, 31112,
+31122, 31120, 31275, 31306, 31280, 31279, 31272, 31270, 31400, 31403,
+31404, 31470, 31624, 31644, 31626, 31633, 31632, 31638, 31629, 31628,
+31643, 31630, 31621, 31640, 21124, 31641, 31652, 31618, 31931, 31935,
+31932, 31930, 32167, 32183, 32194, 32163, 32170, 32193, 32192, 32197,
+32157, 32206, 32196, 32198, 32203, 32204, 32175, 32185, 32150, 32188,
+32159, 32166, 32174, 32169, 32161, 32201, 32627, 32738, 32739, 32741,
+32734, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 32804, 32861, 32860, 33161, 33158,
+33155, 33159, 33165, 33164, 33163, 33301, 33943, 33956, 33953, 33951,
+33978, 33998, 33986, 33964, 33966, 33963, 33977, 33972, 33985, 33997,
+33962, 33946, 33969, 34000, 33949, 33959, 33979, 33954, 33940, 33991,
+33996, 33947, 33961, 33967, 33960, 34006, 33944, 33974, 33999, 33952,
+34007, 34004, 34002, 34011, 33968, 33937, 34401, 34611, 34595, 34600,
+34667, 34624, 34606, 34590, 34593, 34585, 34587, 34627, 34604, 34625,
+34622, 34630, 34592, 34610, 34602, 34605, 34620, 34578, 34618, 34609,
+34613, 34626, 34598, 34599, 34616, 34596, 34586, 34608, 34577, 35063,
+35047, 35057, 35058, 35066, 35070, 35054, 35068, 35062, 35067, 35056,
+35052, 35051, 35229, 35233, 35231, 35230, 35305, 35307, 35304, 35499,
+35481, 35467, 35474, 35471, 35478, 35901, 35944, 35945, 36053, 36047,
+36055, 36246, 36361, 36354, 36351, 36365, 36349, 36362, 36355, 36359,
+36358, 36357, 36350, 36352, 36356, 36624, 36625, 36622, 36621, 37155,
+37148, 37152, 37154, 37151, 37149, 37146, 37156, 37153, 37147, 37242,
+37234, 37241, 37235, 37541, 37540, 37494, 37531, 37498, 37536, 37524,
+37546, 37517, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 37542, 37530, 37547, 37497,
+37527, 37503, 37539, 37614, 37518, 37506, 37525, 37538, 37501, 37512,
+37537, 37514, 37510, 37516, 37529, 37543, 37502, 37511, 37545, 37533,
+37515, 37421, 38558, 38561, 38655, 38744, 38781, 38778, 38782, 38787,
+38784, 38786, 38779, 38788, 38785, 38783, 38862, 38861, 38934, 39085,
+39086, 39170, 39168, 39175, 39325, 39324, 39363, 39353, 39355, 39354,
+39362, 39357, 39367, 39601, 39651, 39655, 39742, 39743, 39776, 39777,
+39775, 40177, 40178, 40181, 40615, 20735, 20739, 20784, 20728, 20742,
+20743, 20726, 20734, 20747, 20748, 20733, 20746, 21131, 21132, 21233,
+21231, 22088, 22082, 22092, 22069, 22081, 22090, 22089, 22086, 22104,
+22106, 22080, 22067, 22077, 22060, 22078, 22072, 22058, 22074, 22298,
+22699, 22685, 22705, 22688, 22691, 22703, 22700, 22693, 22689, 22783,
+23295, 23284, 23293, 23287, 23286, 23299, 23288, 23298, 23289, 23297,
+23303, 23301, 23311, 23655, 23961, 23959, 23967, 23954, 23970, 23955,
+23957, 23968, 23964, 23969, 23962, 23966, 24169, 24157, 24160, 24156,
+32243, 24283, 24286, 24289, 24393, 24498, 24971, 24963, 24953, 25009,
+25008, 24994, 24969, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 24987, 24979, 25007,
+25005, 24991, 24978, 25002, 24993, 24973, 24934, 25011, 25133, 25710,
+25712, 25750, 25760, 25733, 25751, 25756, 25743, 25739, 25738, 25740,
+25763, 25759, 25704, 25777, 25752, 25974, 25978, 25977, 25979, 26034,
+26035, 26293, 26288, 26281, 26290, 26295, 26282, 26287, 27136, 27142,
+27159, 27109, 27128, 27157, 27121, 27108, 27168, 27135, 27116, 27106,
+27163, 27165, 27134, 27175, 27122, 27118, 27156, 27127, 27111, 27200,
+27144, 27110, 27131, 27149, 27132, 27115, 27145, 27140, 27160, 27173,
+27151, 27126, 27174, 27143, 27124, 27158, 27473, 27557, 27555, 27554,
+27558, 27649, 27648, 27647, 27650, 28481, 28454, 28542, 28551, 28614,
+28562, 28557, 28553, 28556, 28514, 28495, 28549, 28506, 28566, 28534,
+28524, 28546, 28501, 28530, 28498, 28496, 28503, 28564, 28563, 28509,
+28416, 28513, 28523, 28541, 28519, 28560, 28499, 28555, 28521, 28543,
+28565, 28515, 28535, 28522, 28539, 29106, 29103, 29083, 29104, 29088,
+29082, 29097, 29109, 29085, 29093, 29086, 29092, 29089, 29098, 29084,
+29095, 29107, 29336, 29338, 29528, 29522, 29534, 29535, 29536, 29533,
+29531, 29537, 29530, 29529, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 29538, 29831,
+29833, 29834, 29830, 29825, 29821, 29829, 29832, 29820, 29817, 29960,
+29959, 30078, 30245, 30238, 30233, 30237, 30236, 30243, 30234, 30248,
+30235, 30364, 30365, 30366, 30363, 30605, 30607, 30601, 30600, 30925,
+30907, 30927, 30924, 30929, 30926, 30932, 30920, 30915, 30916, 30921,
+31130, 31137, 31136, 31132, 31138, 31131, 27510, 31289, 31410, 31412,
+31411, 31671, 31691, 31678, 31660, 31694, 31663, 31673, 31690, 31669,
+31941, 31944, 31948, 31947, 32247, 32219, 32234, 32231, 32215, 32225,
+32259, 32250, 32230, 32246, 32241, 32240, 32238, 32223, 32630, 32684,
+32688, 32685, 32749, 32747, 32746, 32748, 32742, 32744, 32868, 32871,
+33187, 33183, 33182, 33173, 33186, 33177, 33175, 33302, 33359, 33363,
+33362, 33360, 33358, 33361, 34084, 34107, 34063, 34048, 34089, 34062,
+34057, 34061, 34079, 34058, 34087, 34076, 34043, 34091, 34042, 34056,
+34060, 34036, 34090, 34034, 34069, 34039, 34027, 34035, 34044, 34066,
+34026, 34025, 34070, 34046, 34088, 34077, 34094, 34050, 34045, 34078,
+34038, 34097, 34086, 34023, 34024, 34032, 34031, 34041, 34072, 34080,
+34096, 34059, 34073, 34095, 34402, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 34646,
+34659, 34660, 34679, 34785, 34675, 34648, 34644, 34651, 34642, 34657,
+34650, 34641, 34654, 34669, 34666, 34640, 34638, 34655, 34653, 34671,
+34668, 34682, 34670, 34652, 34661, 34639, 34683, 34677, 34658, 34663,
+34665, 34906, 35077, 35084, 35092, 35083, 35095, 35096, 35097, 35078,
+35094, 35089, 35086, 35081, 35234, 35236, 35235, 35309, 35312, 35308,
+35535, 35526, 35512, 35539, 35537, 35540, 35541, 35515, 35543, 35518,
+35520, 35525, 35544, 35523, 35514, 35517, 35545, 35902, 35917, 35983,
+36069, 36063, 36057, 36072, 36058, 36061, 36071, 36256, 36252, 36257,
+36251, 36384, 36387, 36389, 36388, 36398, 36373, 36379, 36374, 36369,
+36377, 36390, 36391, 36372, 36370, 36376, 36371, 36380, 36375, 36378,
+36652, 36644, 36632, 36634, 36640, 36643, 36630, 36631, 36979, 36976,
+36975, 36967, 36971, 37167, 37163, 37161, 37162, 37170, 37158, 37166,
+37253, 37254, 37258, 37249, 37250, 37252, 37248, 37584, 37571, 37572,
+37568, 37593, 37558, 37583, 37617, 37599, 37592, 37609, 37591, 37597,
+37580, 37615, 37570, 37608, 37578, 37576, 37582, 37606, 37581, 37589,
+37577, 37600, 37598, 37607, 37585, 37587, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+37557, 37601, 37574, 37556, 38268, 38316, 38315, 38318, 38320, 38564,
+38562, 38611, 38661, 38664, 38658, 38746, 38794, 38798, 38792, 38864,
+38863, 38942, 38941, 38950, 38953, 38952, 38944, 38939, 38951, 39090,
+39176, 39162, 39185, 39188, 39190, 39191, 39189, 39388, 39373, 39375,
+39379, 39380, 39374, 39369, 39382, 39384, 39371, 39383, 39372, 39603,
+39660, 39659, 39667, 39666, 39665, 39750, 39747, 39783, 39796, 39793,
+39782, 39798, 39797, 39792, 39784, 39780, 39788, 40188, 40186, 40189,
+40191, 40183, 40199, 40192, 40185, 40187, 40200, 40197, 40196, 40579,
+40659, 40719, 40720, 20764, 20755, 20759, 20762, 20753, 20958, 21300,
+21473, 22128, 22112, 22126, 22131, 22118, 22115, 22125, 22130, 22110,
+22135, 22300, 22299, 22728, 22717, 22729, 22719, 22714, 22722, 22716,
+22726, 23319, 23321, 23323, 23329, 23316, 23315, 23312, 23318, 23336,
+23322, 23328, 23326, 23535, 23980, 23985, 23977, 23975, 23989, 23984,
+23982, 23978, 23976, 23986, 23981, 23983, 23988, 24167, 24168, 24166,
+24175, 24297, 24295, 24294, 24296, 24293, 24395, 24508, 24989, 25000,
+24982, 25029, 25012, 25030, 25025, 25036, 25018, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 25023, 25016, 24972, 25815, 25814, 25808, 25807, 25801, 25789,
+25737, 25795, 25819, 25843, 25817, 25907, 25983, 25980, 26018, 26312,
+26302, 26304, 26314, 26315, 26319, 26301, 26299, 26298, 26316, 26403,
+27188, 27238, 27209, 27239, 27186, 27240, 27198, 27229, 27245, 27254,
+27227, 27217, 27176, 27226, 27195, 27199, 27201, 27242, 27236, 27216,
+27215, 27220, 27247, 27241, 27232, 27196, 27230, 27222, 27221, 27213,
+27214, 27206, 27477, 27476, 27478, 27559, 27562, 27563, 27592, 27591,
+27652, 27651, 27654, 28589, 28619, 28579, 28615, 28604, 28622, 28616,
+28510, 28612, 28605, 28574, 28618, 28584, 28676, 28581, 28590, 28602,
+28588, 28586, 28623, 28607, 28600, 28578, 28617, 28587, 28621, 28591,
+28594, 28592, 29125, 29122, 29119, 29112, 29142, 29120, 29121, 29131,
+29140, 29130, 29127, 29135, 29117, 29144, 29116, 29126, 29146, 29147,
+29341, 29342, 29545, 29542, 29543, 29548, 29541, 29547, 29546, 29823,
+29850, 29856, 29844, 29842, 29845, 29857, 29963, 30080, 30255, 30253,
+30257, 30269, 30259, 30268, 30261, 30258, 30256, 30395, 30438, 30618,
+30621, 30625, 30620, 30619, 30626, 30627, 30613, 30617, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 30615, 30941, 30953, 30949, 30954, 30942, 30947, 30939,
+30945, 30946, 30957, 30943, 30944, 31140, 31300, 31304, 31303, 31414,
+31416, 31413, 31409, 31415, 31710, 31715, 31719, 31709, 31701, 31717,
+31706, 31720, 31737, 31700, 31722, 31714, 31708, 31723, 31704, 31711,
+31954, 31956, 31959, 31952, 31953, 32274, 32289, 32279, 32268, 32287,
+32288, 32275, 32270, 32284, 32277, 32282, 32290, 32267, 32271, 32278,
+32269, 32276, 32293, 32292, 32579, 32635, 32636, 32634, 32689, 32751,
+32810, 32809, 32876, 33201, 33190, 33198, 33209, 33205, 33195, 33200,
+33196, 33204, 33202, 33207, 33191, 33266, 33365, 33366, 33367, 34134,
+34117, 34155, 34125, 34131, 34145, 34136, 34112, 34118, 34148, 34113,
+34146, 34116, 34129, 34119, 34147, 34110, 34139, 34161, 34126, 34158,
+34165, 34133, 34151, 34144, 34188, 34150, 34141, 34132, 34149, 34156,
+34403, 34405, 34404, 34715, 34703, 34711, 34707, 34706, 34696, 34689,
+34710, 34712, 34681, 34695, 34723, 34693, 34704, 34705, 34717, 34692,
+34708, 34716, 34714, 34697, 35102, 35110, 35120, 35117, 35118, 35111,
+35121, 35106, 35113, 35107, 35119, 35116, 35103, 35313, 35552, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 35554, 35570, 35572, 35573, 35549, 35604, 35556,
+35551, 35568, 35528, 35550, 35553, 35560, 35583, 35567, 35579, 35985,
+35986, 35984, 36085, 36078, 36081, 36080, 36083, 36204, 36206, 36261,
+36263, 36403, 36414, 36408, 36416, 36421, 36406, 36412, 36413, 36417,
+36400, 36415, 36541, 36662, 36654, 36661, 36658, 36665, 36663, 36660,
+36982, 36985, 36987, 36998, 37114, 37171, 37173, 37174, 37267, 37264,
+37265, 37261, 37263, 37671, 37662, 37640, 37663, 37638, 37647, 37754,
+37688, 37692, 37659, 37667, 37650, 37633, 37702, 37677, 37646, 37645,
+37579, 37661, 37626, 37669, 37651, 37625, 37623, 37684, 37634, 37668,
+37631, 37673, 37689, 37685, 37674, 37652, 37644, 37643, 37630, 37641,
+37632, 37627, 37654, 38332, 38349, 38334, 38329, 38330, 38326, 38335,
+38325, 38333, 38569, 38612, 38667, 38674, 38672, 38809, 38807, 38804,
+38896, 38904, 38965, 38959, 38962, 39204, 39199, 39207, 39209, 39326,
+39406, 39404, 39397, 39396, 39408, 39395, 39402, 39401, 39399, 39609,
+39615, 39604, 39611, 39670, 39674, 39673, 39671, 39731, 39808, 39813,
+39815, 39804, 39806, 39803, 39810, 39827, 39826, 39824, 39802, 39829,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 39805, 39816, 40229, 40215, 40224, 40222,
+40212, 40233, 40221, 40216, 40226, 40208, 40217, 40223, 40584, 40582,
+40583, 40622, 40621, 40661, 40662, 40698, 40722, 40765, 20774, 20773,
+20770, 20772, 20768, 20777, 21236, 22163, 22156, 22157, 22150, 22148,
+22147, 22142, 22146, 22143, 22145, 22742, 22740, 22735, 22738, 23341,
+23333, 23346, 23331, 23340, 23335, 23334, 23343, 23342, 23419, 23537,
+23538, 23991, 24172, 24170, 24510, 24507, 25027, 25013, 25020, 25063,
+25056, 25061, 25060, 25064, 25054, 25839, 25833, 25827, 25835, 25828,
+25832, 25985, 25984, 26038, 26074, 26322, 27277, 27286, 27265, 27301,
+27273, 27295, 27291, 27297, 27294, 27271, 27283, 27278, 27285, 27267,
+27304, 27300, 27281, 27263, 27302, 27290, 27269, 27276, 27282, 27483,
+27565, 27657, 28620, 28585, 28660, 28628, 28643, 28636, 28653, 28647,
+28646, 28638, 28658, 28637, 28642, 28648, 29153, 29169, 29160, 29170,
+29156, 29168, 29154, 29555, 29550, 29551, 29847, 29874, 29867, 29840,
+29866, 29869, 29873, 29861, 29871, 29968, 29969, 29970, 29967, 30084,
+30275, 30280, 30281, 30279, 30372, 30441, 30645, 30635, 30642, 30647,
+30646, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 30644, 30641, 30632, 30704, 30963,
+30973, 30978, 30971, 30972, 30962, 30981, 30969, 30974, 30980, 31147,
+31144, 31324, 31323, 31318, 31320, 31316, 31322, 31422, 31424, 31425,
+31749, 31759, 31730, 31744, 31743, 31739, 31758, 31732, 31755, 31731,
+31746, 31753, 31747, 31745, 31736, 31741, 31750, 31728, 31729, 31760,
+31754, 31976, 32301, 32316, 32322, 32307, 38984, 32312, 32298, 32329,
+32320, 32327, 32297, 32332, 32304, 32315, 32310, 32324, 32314, 32581,
+32639, 32638, 32637, 32756, 32754, 32812, 33211, 33220, 33228, 33226,
+33221, 33223, 33212, 33257, 33371, 33370, 33372, 34179, 34176, 34191,
+34215, 34197, 34208, 34187, 34211, 34171, 34212, 34202, 34206, 34167,
+34172, 34185, 34209, 34170, 34168, 34135, 34190, 34198, 34182, 34189,
+34201, 34205, 34177, 34210, 34178, 34184, 34181, 34169, 34166, 34200,
+34192, 34207, 34408, 34750, 34730, 34733, 34757, 34736, 34732, 34745,
+34741, 34748, 34734, 34761, 34755, 34754, 34764, 34743, 34735, 34756,
+34762, 34740, 34742, 34751, 34744, 34749, 34782, 34738, 35125, 35123,
+35132, 35134, 35137, 35154, 35127, 35138, 35245, 35247, 35246, 35314,
+35315, 35614, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 35608, 35606, 35601, 35589,
+35595, 35618, 35599, 35602, 35605, 35591, 35597, 35592, 35590, 35612,
+35603, 35610, 35919, 35952, 35954, 35953, 35951, 35989, 35988, 36089,
+36207, 36430, 36429, 36435, 36432, 36428, 36423, 36675, 36672, 36997,
+36990, 37176, 37274, 37282, 37275, 37273, 37279, 37281, 37277, 37280,
+37793, 37763, 37807, 37732, 37718, 37703, 37756, 37720, 37724, 37750,
+37705, 37712, 37713, 37728, 37741, 37775, 37708, 37738, 37753, 37719,
+37717, 37714, 37711, 37745, 37751, 37755, 37729, 37726, 37731, 37735,
+37760, 37710, 37721, 38343, 38336, 38345, 38339, 38341, 38327, 38574,
+38576, 38572, 38688, 38687, 38680, 38685, 38681, 38810, 38817, 38812,
+38814, 38813, 38869, 38868, 38897, 38977, 38980, 38986, 38985, 38981,
+38979, 39205, 39211, 39212, 39210, 39219, 39218, 39215, 39213, 39217,
+39216, 39320, 39331, 39329, 39426, 39418, 39412, 39415, 39417, 39416,
+39414, 39419, 39421, 39422, 39420, 39427, 39614, 39678, 39677, 39681,
+39676, 39752, 39834, 39848, 39838, 39835, 39846, 39841, 39845, 39844,
+39814, 39842, 39840, 39855, 40243, 40257, 40295, 40246, 40238, 40239,
+40241, 40248, 40240, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 40261, 40258, 40259,
+40254, 40247, 40256, 40253, 32757, 40237, 40586, 40585, 40589, 40624,
+40648, 40666, 40699, 40703, 40740, 40739, 40738, 40788, 40864, 20785,
+20781, 20782, 22168, 22172, 22167, 22170, 22173, 22169, 22896, 23356,
+23657, 23658, 24000, 24173, 24174, 25048, 25055, 25069, 25070, 25073,
+25066, 25072, 25067, 25046, 25065, 25855, 25860, 25853, 25848, 25857,
+25859, 25852, 26004, 26075, 26330, 26331, 26328, 27333, 27321, 27325,
+27361, 27334, 27322, 27318, 27319, 27335, 27316, 27309, 27486, 27593,
+27659, 28679, 28684, 28685, 28673, 28677, 28692, 28686, 28671, 28672,
+28667, 28710, 28668, 28663, 28682, 29185, 29183, 29177, 29187, 29181,
+29558, 29880, 29888, 29877, 29889, 29886, 29878, 29883, 29890, 29972,
+29971, 30300, 30308, 30297, 30288, 30291, 30295, 30298, 30374, 30397,
+30444, 30658, 30650, 30975, 30988, 30995, 30996, 30985, 30992, 30994,
+30993, 31149, 31148, 31327, 31772, 31785, 31769, 31776, 31775, 31789,
+31773, 31782, 31784, 31778, 31781, 31792, 32348, 32336, 32342, 32355,
+32344, 32354, 32351, 32337, 32352, 32343, 32339, 32693, 32691, 32759,
+32760, 32885, 33233, 33234, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 33232, 33375,
+33374, 34228, 34246, 34240, 34243, 34242, 34227, 34229, 34237, 34247,
+34244, 34239, 34251, 34254, 34248, 34245, 34225, 34230, 34258, 34340,
+34232, 34231, 34238, 34409, 34791, 34790, 34786, 34779, 34795, 34794,
+34789, 34783, 34803, 34788, 34772, 34780, 34771, 34797, 34776, 34787,
+34724, 34775, 34777, 34817, 34804, 34792, 34781, 35155, 35147, 35151,
+35148, 35142, 35152, 35153, 35145, 35626, 35623, 35619, 35635, 35632,
+35637, 35655, 35631, 35644, 35646, 35633, 35621, 35639, 35622, 35638,
+35630, 35620, 35643, 35645, 35642, 35906, 35957, 35993, 35992, 35991,
+36094, 36100, 36098, 36096, 36444, 36450, 36448, 36439, 36438, 36446,
+36453, 36455, 36443, 36442, 36449, 36445, 36457, 36436, 36678, 36679,
+36680, 36683, 37160, 37178, 37179, 37182, 37288, 37285, 37287, 37295,
+37290, 37813, 37772, 37778, 37815, 37787, 37789, 37769, 37799, 37774,
+37802, 37790, 37798, 37781, 37768, 37785, 37791, 37773, 37809, 37777,
+37810, 37796, 37800, 37812, 37795, 37797, 38354, 38355, 38353, 38579,
+38615, 38618, 24002, 38623, 38616, 38621, 38691, 38690, 38693, 38828,
+38830, 38824, 38827, 38820, 38826, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 38818,
+38821, 38871, 38873, 38870, 38872, 38906, 38992, 38993, 38994, 39096,
+39233, 39228, 39226, 39439, 39435, 39433, 39437, 39428, 39441, 39434,
+39429, 39431, 39430, 39616, 39644, 39688, 39684, 39685, 39721, 39733,
+39754, 39756, 39755, 39879, 39878, 39875, 39871, 39873, 39861, 39864,
+39891, 39862, 39876, 39865, 39869, 40284, 40275, 40271, 40266, 40283,
+40267, 40281, 40278, 40268, 40279, 40274, 40276, 40287, 40280, 40282,
+40590, 40588, 40671, 40705, 40704, 40726, 40741, 40747, 40746, 40745,
+40744, 40780, 40789, 20788, 20789, 21142, 21239, 21428, 22187, 22189,
+22182, 22183, 22186, 22188, 22746, 22749, 22747, 22802, 23357, 23358,
+23359, 24003, 24176, 24511, 25083, 25863, 25872, 25869, 25865, 25868,
+25870, 25988, 26078, 26077, 26334, 27367, 27360, 27340, 27345, 27353,
+27339, 27359, 27356, 27344, 27371, 27343, 27341, 27358, 27488, 27568,
+27660, 28697, 28711, 28704, 28694, 28715, 28705, 28706, 28707, 28713,
+28695, 28708, 28700, 28714, 29196, 29194, 29191, 29186, 29189, 29349,
+29350, 29348, 29347, 29345, 29899, 29893, 29879, 29891, 29974, 30304,
+30665, 30666, 30660, 30705, 31005, 31003, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+31009, 31004, 30999, 31006, 31152, 31335, 31336, 31795, 31804, 31801,
+31788, 31803, 31980, 31978, 32374, 32373, 32376, 32368, 32375, 32367,
+32378, 32370, 32372, 32360, 32587, 32586, 32643, 32646, 32695, 32765,
+32766, 32888, 33239, 33237, 33380, 33377, 33379, 34283, 34289, 34285,
+34265, 34273, 34280, 34266, 34263, 34284, 34290, 34296, 34264, 34271,
+34275, 34268, 34257, 34288, 34278, 34287, 34270, 34274, 34816, 34810,
+34819, 34806, 34807, 34825, 34828, 34827, 34822, 34812, 34824, 34815,
+34826, 34818, 35170, 35162, 35163, 35159, 35169, 35164, 35160, 35165,
+35161, 35208, 35255, 35254, 35318, 35664, 35656, 35658, 35648, 35667,
+35670, 35668, 35659, 35669, 35665, 35650, 35666, 35671, 35907, 35959,
+35958, 35994, 36102, 36103, 36105, 36268, 36266, 36269, 36267, 36461,
+36472, 36467, 36458, 36463, 36475, 36546, 36690, 36689, 36687, 36688,
+36691, 36788, 37184, 37183, 37296, 37293, 37854, 37831, 37839, 37826,
+37850, 37840, 37881, 37868, 37836, 37849, 37801, 37862, 37834, 37844,
+37870, 37859, 37845, 37828, 37838, 37824, 37842, 37863, 38269, 38362,
+38363, 38625, 38697, 38699, 38700, 38696, 38694, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 38835, 38839, 38838, 38877, 38878, 38879, 39004, 39001, 39005,
+38999, 39103, 39101, 39099, 39102, 39240, 39239, 39235, 39334, 39335,
+39450, 39445, 39461, 39453, 39460, 39451, 39458, 39456, 39463, 39459,
+39454, 39452, 39444, 39618, 39691, 39690, 39694, 39692, 39735, 39914,
+39915, 39904, 39902, 39908, 39910, 39906, 39920, 39892, 39895, 39916,
+39900, 39897, 39909, 39893, 39905, 39898, 40311, 40321, 40330, 40324,
+40328, 40305, 40320, 40312, 40326, 40331, 40332, 40317, 40299, 40308,
+40309, 40304, 40297, 40325, 40307, 40315, 40322, 40303, 40313, 40319,
+40327, 40296, 40596, 40593, 40640, 40700, 40749, 40768, 40769, 40781,
+40790, 40791, 40792, 21303, 22194, 22197, 22195, 22755, 23365, 24006,
+24007, 24302, 24303, 24512, 24513, 25081, 25879, 25878, 25877, 25875,
+26079, 26344, 26339, 26340, 27379, 27376, 27370, 27368, 27385, 27377,
+27374, 27375, 28732, 28725, 28719, 28727, 28724, 28721, 28738, 28728,
+28735, 28730, 28729, 28736, 28731, 28723, 28737, 29203, 29204, 29352,
+29565, 29564, 29882, 30379, 30378, 30398, 30445, 30668, 30670, 30671,
+30669, 30706, 31013, 31011, 31015, 31016, 31012, 31017, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 31154, 31342, 31340, 31341, 31479, 31817, 31816, 31818,
+31815, 31813, 31982, 32379, 32382, 32385, 32384, 32698, 32767, 32889,
+33243, 33241, 33291, 33384, 33385, 34338, 34303, 34305, 34302, 34331,
+34304, 34294, 34308, 34313, 34309, 34316, 34301, 34841, 34832, 34833,
+34839, 34835, 34838, 35171, 35174, 35257, 35319, 35680, 35690, 35677,
+35688, 35683, 35685, 35687, 35693, 36270, 36486, 36488, 36484, 36697,
+36694, 36695, 36693, 36696, 36698, 37005, 37187, 37185, 37303, 37301,
+37298, 37299, 37899, 37907, 37883, 37920, 37903, 37908, 37886, 37909,
+37904, 37928, 37913, 37901, 37877, 37888, 37879, 37895, 37902, 37910,
+37906, 37882, 37897, 37880, 37898, 37887, 37884, 37900, 37878, 37905,
+37894, 38366, 38368, 38367, 38702, 38703, 38841, 38843, 38909, 38910,
+39008, 39010, 39011, 39007, 39105, 39106, 39248, 39246, 39257, 39244,
+39243, 39251, 39474, 39476, 39473, 39468, 39466, 39478, 39465, 39470,
+39480, 39469, 39623, 39626, 39622, 39696, 39698, 39697, 39947, 39944,
+39927, 39941, 39954, 39928, 40000, 39943, 39950, 39942, 39959, 39956,
+39945, 40351, 40345, 40356, 40349, 40338, 40344, 40336, 40347, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 40352, 40340, 40348, 40362, 40343, 40353, 40346,
+40354, 40360, 40350, 40355, 40383, 40361, 40342, 40358, 40359, 40601,
+40603, 40602, 40677, 40676, 40679, 40678, 40752, 40750, 40795, 40800,
+40798, 40797, 40793, 40849, 20794, 20793, 21144, 21143, 22211, 22205,
+22206, 23368, 23367, 24011, 24015, 24305, 25085, 25883, 27394, 27388,
+27395, 27384, 27392, 28739, 28740, 28746, 28744, 28745, 28741, 28742,
+29213, 29210, 29209, 29566, 29975, 30314, 30672, 31021, 31025, 31023,
+31828, 31827, 31986, 32394, 32391, 32392, 32395, 32390, 32397, 32589,
+32699, 32816, 33245, 34328, 34346, 34342, 34335, 34339, 34332, 34329,
+34343, 34350, 34337, 34336, 34345, 34334, 34341, 34857, 34845, 34843,
+34848, 34852, 34844, 34859, 34890, 35181, 35177, 35182, 35179, 35322,
+35705, 35704, 35653, 35706, 35707, 36112, 36116, 36271, 36494, 36492,
+36702, 36699, 36701, 37190, 37188, 37189, 37305, 37951, 37947, 37942,
+37929, 37949, 37948, 37936, 37945, 37930, 37943, 37932, 37952, 37937,
+38373, 38372, 38371, 38709, 38714, 38847, 38881, 39012, 39113, 39110,
+39104, 39256, 39254, 39481, 39485, 39494, 39492, 39490, 39489, 39482,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 39487, 39629, 39701, 39703, 39704, 39702,
+39738, 39762, 39979, 39965, 39964, 39980, 39971, 39976, 39977, 39972,
+39969, 40375, 40374, 40380, 40385, 40391, 40394, 40399, 40382, 40389,
+40387, 40379, 40373, 40398, 40377, 40378, 40364, 40392, 40369, 40365,
+40396, 40371, 40397, 40370, 40570, 40604, 40683, 40686, 40685, 40731,
+40728, 40730, 40753, 40782, 40805, 40804, 40850, 20153, 22214, 22213,
+22219, 22897, 23371, 23372, 24021, 24017, 24306, 25889, 25888, 25894,
+25890, 27403, 27400, 27401, 27661, 28757, 28758, 28759, 28754, 29214,
+29215, 29353, 29567, 29912, 29909, 29913, 29911, 30317, 30381, 31029,
+31156, 31344, 31345, 31831, 31836, 31833, 31835, 31834, 31988, 31985,
+32401, 32591, 32647, 33246, 33387, 34356, 34357, 34355, 34348, 34354,
+34358, 34860, 34856, 34854, 34858, 34853, 35185, 35263, 35262, 35323,
+35710, 35716, 35714, 35718, 35717, 35711, 36117, 36501, 36500, 36506,
+36498, 36496, 36502, 36503, 36704, 36706, 37191, 37964, 37968, 37962,
+37963, 37967, 37959, 37957, 37960, 37961, 37958, 38719, 38883, 39018,
+39017, 39115, 39252, 39259, 39502, 39507, 39508, 39500, 39503, 39496,
+39498, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 39497, 39506, 39504, 39632, 39705,
+39723, 39739, 39766, 39765, 40006, 40008, 39999, 40004, 39993, 39987,
+40001, 39996, 39991, 39988, 39986, 39997, 39990, 40411, 40402, 40414,
+40410, 40395, 40400, 40412, 40401, 40415, 40425, 40409, 40408, 40406,
+40437, 40405, 40413, 40630, 40688, 40757, 40755, 40754, 40770, 40811,
+40853, 40866, 20797, 21145, 22760, 22759, 22898, 23373, 24024, 34863,
+24399, 25089, 25091, 25092, 25897, 25893, 26006, 26347, 27409, 27410,
+27407, 27594, 28763, 28762, 29218, 29570, 29569, 29571, 30320, 30676,
+31847, 31846, 32405, 33388, 34362, 34368, 34361, 34364, 34353, 34363,
+34366, 34864, 34866, 34862, 34867, 35190, 35188, 35187, 35326, 35724,
+35726, 35723, 35720, 35909, 36121, 36504, 36708, 36707, 37308, 37986,
+37973, 37981, 37975, 37982, 38852, 38853, 38912, 39510, 39513, 39710,
+39711, 39712, 40018, 40024, 40016, 40010, 40013, 40011, 40021, 40025,
+40012, 40014, 40443, 40439, 40431, 40419, 40427, 40440, 40420, 40438,
+40417, 40430, 40422, 40434, 40432, 40418, 40428, 40436, 40435, 40424,
+40429, 40642, 40656, 40690, 40691, 40710, 40732, 40760, 40759, 40758,
+40771, 40783, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 40817, 40816, 40814, 40815,
+22227, 22221, 23374, 23661, 25901, 26349, 26350, 27411, 28767, 28769,
+28765, 28768, 29219, 29915, 29925, 30677, 31032, 31159, 31158, 31850,
+32407, 32649, 33389, 34371, 34872, 34871, 34869, 34891, 35732, 35733,
+36510, 36511, 36512, 36509, 37310, 37309, 37314, 37995, 37992, 37993,
+38629, 38726, 38723, 38727, 38855, 38885, 39518, 39637, 39769, 40035,
+40039, 40038, 40034, 40030, 40032, 40450, 40446, 40455, 40451, 40454,
+40453, 40448, 40449, 40457, 40447, 40445, 40452, 40608, 40734, 40774,
+40820, 40821, 40822, 22228, 25902, 26040, 27416, 27417, 27415, 27418,
+28770, 29222, 29354, 30680, 30681, 31033, 31849, 31851, 31990, 32410,
+32408, 32411, 32409, 33248, 33249, 34374, 34375, 34376, 35193, 35194,
+35196, 35195, 35327, 35736, 35737, 36517, 36516, 36515, 37998, 37997,
+37999, 38001, 38003, 38729, 39026, 39263, 40040, 40046, 40045, 40459,
+40461, 40464, 40463, 40466, 40465, 40609, 40693, 40713, 40775, 40824,
+40827, 40826, 40825, 22302, 28774, 31855, 34876, 36274, 36518, 37315,
+38004, 38008, 38006, 38005, 39520, 40052, 40051, 40049, 40053, 40468,
+40467, 40694, 40714, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 40868, 28776, 28773,
+31991, 34410, 34878, 34877, 34879, 35742, 35996, 36521, 36553, 38731,
+39027, 39028, 39116, 39265, 39339, 39524, 39526, 39527, 39716, 40469,
+40471, 40776, 25095, 27422, 29223, 34380, 36520, 38018, 38016, 38017,
+39529, 39528, 39726, 40473, 29225, 34379, 35743, 38019, 40057, 40631,
+30325, 39531, 40058, 40477, 28777, 28778, 40612, 40830, 40777, 40856,
+30849, 37561, 35023, 22715, 24658, 31911, 23290, 9556, 9574, 9559,
+ 9568, 9580, 9571, 9562, 9577, 9565, 9554, 9572, 9557, 9566,
+ 9578, 9569, 9560, 9575, 9563, 9555, 9573, 9558, 9567, 9579,
+ 9570, 9561, 9576, 9564, 9553, 9552, 9581, 9582, 9584, 9583,
+ 9619, 57344, 57345, 57346, 57347, 57348, 57349, 57350, 57351, 57352,
+57353, 57354, 57355, 57356, 57357, 57358, 57359, 57360, 57361, 57362,
+57363, 57364, 57365, 57366, 57367, 57368, 57369, 57370, 57371, 57372,
+57373, 57374, 57375, 57376, 57377, 57378, 57379, 29234, 29244, 29286,
+29314, 29327, 29343, 29357, 29361, 29368, 29374, 29389, 29403, 29476,
+29487, 29496, 29497, 29629, 29646, 29681, 29814, 29858, 29953, 29977,
+29987, 30012, 30020, 30025, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 30029, 30061,
+30082, 30083, 30089, 30124, 30166, 30185, 30272, 30285, 30292, 30312,
+30336, 30339, 30352, 30391, 30393, 30477, 30494, 30531, 30744, 30748,
+30777, 30780, 30791, 30806, 30842, 30901, 30905, 30918, 30937, 30983,
+31024, 31028, 31035, 31104, 31133, 31171, 31201, 31238, 31246, 31299,
+31312, 31427, 31442, 31458, 31463, 31480, 31542, 31586, 31596, 31610,
+31611, 31642, 31646, 31647, 31650, 31655, 31734, 31762, 31764, 31823,
+31830, 31832, 31915, 31994, 32072, 32075, 32119, 32212, 32213, 32214,
+32228, 32333, 32349, 32383, 32393, 32398, 32402, 32468, 32497, 32530,
+32560, 32625, 32642, 32686, 32710, 32800, 32802, 32805, 32817, 32863,
+32872, 32940, 32951, 20890, 21526, 21524, 13535, 19581, 25283, 57508,
+57509, 57510, 21707, 57512, 21948, 32950, 20903, 57516, 57517, 57518,
+21779, 33318, 57521, 21790, 21982, 25529, 26776, 57526, 21762, 21865,
+30132, 25596, 40580, 37418, 57533, 57534, 57535, 35015, 24734, 22053,
+28997, 23282, 57541, 21135, 22095, 30611, 34694, 36397, 33206, 13822,
+29174, 57550, 34820, 37765, 57553, 57554, 30310, 57556, 40050, 57558,
+25294, 57560, 40598, 18825, 31955, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 36570,
+40619, 25831, 57567, 33450, 26471, 28018, 30982, 31172, 32590, 34798,
+57575, 33726, 34351, 35237, 17935, 57580, 39112, 39232, 39245, 39436,
+39639, 40600, 40742, 57588, 20227, 57590, 20281, 20274, 20395, 20566,
+57595, 20526, 20646, 20697, 20750, 20717, 20737, 20980, 21023, 21088,
+21079, 21146, 21201, 21216, 21217, 20947, 20959, 30022, 20990, 21298,
+21292, 21299, 21419, 21418, 40846, 21609, 21660, 21466, 27338, 21875,
+57625, 13782, 57627, 22033, 22093, 57630, 22100, 13811, 57633, 22342,
+22394, 22375, 22586, 22502, 22493, 22592, 57641, 22566, 22748, 22967,
+23001, 23584, 57647, 23761, 23785, 23878, 23950, 57652, 24053, 24075,
+24082, 24110, 24158, 57658, 24397, 31357, 23491, 31419, 57663, 57664,
+24484, 24506, 24508, 57668, 24695, 24740, 24755, 24829, 24880, 57674,
+24988, 24921, 24957, 24924, 25471, 25058, 28885, 25145, 25192, 25221,
+25218, 25254, 25301, 25444, 25397, 25744, 14940, 26184, 26215, 26398,
+26627, 26540, 26617, 26806, 26924, 26881, 26880, 26826, 26995, 27008,
+26942, 57706, 27058, 27072, 27018, 27130, 27113, 27314, 27218, 27293,
+27421, 27474, 27642, 15569, 27854, 28239, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+28089, 28484, 57723, 28634, 28801, 31180, 28980, 15820, 29046, 57730,
+57731, 29205, 29264, 29319, 29484, 29362, 29410, 29442, 29512, 29480,
+29519, 29553, 25989, 57744, 29789, 29800, 29982, 30035, 30074, 30369,
+30412, 30500, 30507, 16485, 30803, 30931, 30936, 40318, 30895, 57760,
+24898, 31145, 39994, 31188, 57765, 31277, 31294, 31305, 31453, 31450,
+30147, 30215, 30210, 57774, 30311, 30319, 22048, 35431, 40727, 31519,
+31634, 31651, 31695, 57784, 31740, 31810, 31825, 31837, 31856, 31870,
+31878, 31875, 31916, 31943, 31938, 57796, 31962, 57798, 32077, 32090,
+32245, 32295, 32366, 40597, 21107, 32797, 32866, 32867, 32870, 32859,
+32934, 33027, 40577, 33224, 57815, 36768, 33270, 33306, 57819, 34673,
+34729, 34700, 40606, 34753, 40476, 57826, 34774, 34805, 34831, 34840,
+34861, 34882, 34885, 39989, 34926, 34986, 34976, 25245, 35139, 35149,
+29042, 34910, 57843, 33533, 17591, 33488, 33669, 40194, 40809, 33824,
+57851, 34010, 33965, 17659, 34123, 57856, 34306, 34320, 25553, 35209,
+35210, 35220, 40005, 35260, 35454, 35401, 35596, 35651, 35713, 35660,
+57871, 36013, 36075, 36087, 36108, 36226, 36262, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 36308, 36392, 36431, 36471, 36469, 36519, 36633, 57885, 36700,
+40260, 37060, 37201, 57890, 37212, 37209, 37223, 37244, 37262, 37307,
+40616, 36950, 36940, 37374, 37474, 37566, 37739, 37742, 37818, 37927,
+38295, 38311, 57909, 38456, 57911, 38531, 38550, 38529, 38589, 38659,
+38689, 38705, 38751, 38815, 38836, 38840, 38842, 38846, 38856, 40639,
+38943, 38958, 40869, 38983, 38987, 39014, 39020, 39092, 40794, 39132,
+39142, 39234, 39225, 39227, 40787, 39242, 40773, 19326, 39386, 31432,
+39610, 39613, 40706, 39722, 57951, 39725, 39650, 39682, 39679, 19463,
+39689, 19460, 19515, 39823, 39837, 39856, 39948, 39957, 39946, 39935,
+39982, 33000, 33001, 33004, 33038, 27705, 20074, 38465, 22770, 31074,
+26658, 57978, 57979, 33031, 22487, 17642, 25653, 34100, 16607, 57986,
+26906, 39938, 30129, 33747, 29041, 27147, 57993, 27258, 39668, 57996,
+57997, 30649, 25904, 28054, 22071, 26405, 27179, 32093, 36961, 20120,
+31910, 31545, 58009, 22901, 14023, 28799, 58013, 28299, 58015, 58016,
+38749, 37584, 22356, 58020, 16089, 58022, 58023, 24985, 29792, 28991,
+31022, 23190, 37704, 26254, 20477, 37697, 13908, 23925, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 28702, 25979, 28813, 24269, 58039, 24743, 31408, 24419,
+58043, 29687, 58045, 29800, 30132, 58048, 39785, 189, 8531, 8532,
+ 188, 190, 8533, 8534, 8535, 8536, 8537, 8538, 34450, 34464,
+34477, 34482, 34725, 34737, 8539, 8540, 8541, 8542, 34778, 34895,
+34912, 34951, 34959, 34960, 35046, 35071, 35072, 35108, 35143, 35156,
+35173, 35200, 35217, 35356, 35369, 35371, 35384, 35389, 8978, 35472,
+35476, 35484, 35497, 35503, 35508, 35562, 35615, 8240, 35647, 35661,
+35678, 35682, 35689, 35739, 35921, 35995, 35999, 36052, 36054, 33042,
+33073, 33078, 33119, 33133, 33149, 33171, 33194, 33208, 33217, 33321,
+33325, 33326, 33342, 33378, 33386, 33416
+};
+
+static const uchar ucs_to_big5[][2] =
+{
+ {'\x00','\x00'},{'\x00','\x01'},{'\x00','\x02'},{'\x00','\x03'},{'\x00','\x04'},
+ {'\x00','\x05'},{'\x00','\x06'},{'\x00','\x07'},{'\x00','\x08'},{'\x00','\x09'},
+ {'\x00','\x0a'},{'\x00','\x0b'},{'\x00','\x0c'},{'\x00','\x0d'},{'\x00','\x0e'},
+ {'\x00','\x0f'},{'\x00','\x10'},{'\x00','\x11'},{'\x00','\x12'},{'\x00','\x13'},
+ {'\x00','\x14'},{'\x00','\x15'},{'\x00','\x16'},{'\x00','\x17'},{'\x00','\x18'},
+ {'\x00','\x19'},{'\x00','\x1a'},{'\x00','\x1b'},{'\x00','\x1c'},{'\x00','\x1d'},
+ {'\x00','\x1e'},{'\x00','\x1f'},{'\x00','\x20'},{'\x00','\x21'},{'\x00','\x22'},
+ {'\x00','\x23'},{'\x00','\x24'},{'\x00','\x25'},{'\x00','\x26'},{'\x00','\x27'},
+ {'\x00','\x28'},{'\x00','\x29'},{'\x00','\x2a'},{'\x00','\x2b'},{'\x00','\x2c'},
+ {'\x00','\x2d'},{'\x00','\x2e'},{'\x00','\x2f'},{'\x00','\x30'},{'\x00','\x31'},
+ {'\x00','\x32'},{'\x00','\x33'},{'\x00','\x34'},{'\x00','\x35'},{'\x00','\x36'},
+ {'\x00','\x37'},{'\x00','\x38'},{'\x00','\x39'},{'\x00','\x3a'},{'\x00','\x3b'},
+ {'\x00','\x3c'},{'\x00','\x3d'},{'\x00','\x3e'},{'\x00','\x3f'},{'\x00','\x40'},
+ {'\x00','\x41'},{'\x00','\x42'},{'\x00','\x43'},{'\x00','\x44'},{'\x00','\x45'},
+ {'\x00','\x46'},{'\x00','\x47'},{'\x00','\x48'},{'\x00','\x49'},{'\x00','\x4a'},
+ {'\x00','\x4b'},{'\x00','\x4c'},{'\x00','\x4d'},{'\x00','\x4e'},{'\x00','\x4f'},
+ {'\x00','\x50'},{'\x00','\x51'},{'\x00','\x52'},{'\x00','\x53'},{'\x00','\x54'},
+ {'\x00','\x55'},{'\x00','\x56'},{'\x00','\x57'},{'\x00','\x58'},{'\x00','\x59'},
+ {'\x00','\x5a'},{'\x00','\x5b'},{'\x00','\x5c'},{'\x00','\x5d'},{'\x00','\x5e'},
+ {'\x00','\x5f'},{'\x00','\x60'},{'\x00','\x61'},{'\x00','\x62'},{'\x00','\x63'},
+ {'\x00','\x64'},{'\x00','\x65'},{'\x00','\x66'},{'\x00','\x67'},{'\x00','\x68'},
+ {'\x00','\x69'},{'\x00','\x6a'},{'\x00','\x6b'},{'\x00','\x6c'},{'\x00','\x6d'},
+ {'\x00','\x6e'},{'\x00','\x6f'},{'\x00','\x70'},{'\x00','\x71'},{'\x00','\x72'},
+ {'\x00','\x73'},{'\x00','\x74'},{'\x00','\x75'},{'\x00','\x76'},{'\x00','\x77'},
+ {'\x00','\x78'},{'\x00','\x79'},{'\x00','\x7a'},{'\x00','\x7b'},{'\x00','\x7c'},
+ {'\x00','\x7d'},{'\x00','\x7e'},{'\x00','\x7f'},{'\x00','\x80'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa0','\xdf'},{'\xa2','\x46'},{'\xa2','\x47'},{'\xa0','\xfc'},
+ {'\xa2','\x44'},{'\x7c','\x20'},{'\xa1','\xb1'},{'\xc6','\xd8'},{'\x63','\x20'},
+ {'\xa0','\xde'},{'\x00','\x00'},{'\x00','\x00'},{'\x2d','\x20'},{'\x97','\xfb'},
+ {'\xa1','\xc2'},{'\xa2','\x58'},{'\xa1','\xd3'},{'\x32','\x20'},{'\x33','\x20'},
+ {'\xa1','\xac'},{'\xa3','\x67'},{'\x91','\xf8'},{'\xa1','\x50'},{'\xa0','\xfb'},
+ {'\x31','\x20'},{'\xa0','\xee'},{'\x00','\x00'},{'\xfe','\xb3'},{'\xfe','\xb0'},
+ {'\xfe','\xb4'},{'\xa0','\xef'},{'\xa0','\xa7'},{'\xa0','\xac'},{'\xa0','\xf6'},
+ {'\xa0','\xbe'},{'\xa0','\xb6'},{'\xa0','\xd6'},{'\xa0','\xbb'},{'\xa0','\xbc'},
+ {'\xa0','\xa8'},{'\xa0','\xd7'},{'\xa0','\xf7'},{'\xa0','\xb7'},{'\xa0','\xa9'},
+ {'\xa0','\xad'},{'\xa0','\xf8'},{'\xa0','\xb8'},{'\xa0','\xda'},{'\xa0','\xbd'},
+ {'\xa0','\xaa'},{'\xa0','\xae'},{'\xa0','\xf9'},{'\xa0','\xbf'},{'\xa0','\xb9'},
+ {'\xa1','\xd1'},{'\xa0','\xd9'},{'\xa0','\xab'},{'\xa0','\xaf'},{'\xa0','\xfa'},
+ {'\xa0','\xba'},{'\x59','\x20'},{'\xa0','\xdc'},{'\xa0','\xdd'},{'\xa0','\xe0'},
+ {'\xa0','\xc0'},{'\xa0','\xf0'},{'\xa0','\xce'},{'\xa0','\xc6'},{'\xa0','\xe6'},
+ {'\xa0','\xcb'},{'\xa0','\xcc'},{'\xa0','\xe1'},{'\xa0','\xc1'},{'\xa0','\xf1'},
+ {'\xa0','\xc7'},{'\xa0','\xe2'},{'\xa0','\xc2'},{'\xa0','\xf2'},{'\xa0','\xc8'},
+ {'\xa0','\xea'},{'\xa0','\xcd'},{'\xa0','\xe3'},{'\xa0','\xc3'},{'\xa0','\xf3'},
+ {'\xa0','\xcf'},{'\xa0','\xc9'},{'\xa1','\xd2'},{'\xa0','\xe9'},{'\xa0','\xe4'},
+ {'\xa0','\xc4'},{'\xa0','\xf4'},{'\xa0','\xca'},{'\x79','\x20'},{'\xa0','\xec'},
+ {'\xa0','\xed'},{'\x00','\x00'},{'\xa0','\xb0'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xa0','\xb1'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa0','\xd1'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa0','\xb2'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x9b','\xd5'},{'\x00','\x00'},{'\x00','\x00'},{'\xa0','\xb3'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xe5'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa0','\xb4'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa0','\xfe'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa0','\xd0'},{'\x00','\x00'},{'\xa0','\xd2'},
+ {'\x00','\x00'},{'\xa0','\xd3'},{'\x00','\x00'},{'\xa0','\xd4'},{'\x00','\x00'},
+ {'\xa0','\xb5'},{'\x00','\x00'},{'\xa0','\xc5'},{'\x00','\x00'},{'\xa0','\xd5'},
+ {'\x00','\x00'},{'\xa0','\xe5'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xcb'},{'\x9b','\xe6'},
+ {'\x00','\x00'},{'\x9b','\xcc'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x9b','\xcf'},{'\x9b','\xd0'},{'\x9b','\xc8'},{'\x9b','\xd1'},
+ {'\x9b','\xce'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xd2'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xc7'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xe0'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xd7'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xe1'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xd9'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xe2'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x9b','\xcd'},{'\x00','\x00'},{'\x9b','\xca'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xda'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x9b','\xdc'},{'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xdb'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xc6','\xd9'},{'\xa3','\xbe'},{'\x00','\x00'},{'\xa3','\xbc'},{'\xa3','\xbd'},
+ {'\xa3','\xbf'},{'\x00','\x00'},{'\xa1','\xc5'},{'\x00','\x00'},{'\x9b','\xe9'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa3','\xbb'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa3','\x44'},{'\xa3','\x45'},
+ {'\xa3','\x46'},{'\xa3','\x47'},{'\xa3','\x48'},{'\xa3','\x49'},{'\xa3','\x4a'},
+ {'\xa3','\x4b'},{'\xa3','\x4c'},{'\xa3','\x4d'},{'\xa3','\x4e'},{'\xa3','\x4f'},
+ {'\xa3','\x50'},{'\xa3','\x51'},{'\xa3','\x52'},{'\xa3','\x53'},{'\xa3','\x54'},
+ {'\x00','\x00'},{'\xa3','\x55'},{'\xa3','\x56'},{'\xa3','\x57'},{'\xa3','\x58'},
+ {'\xa3','\x59'},{'\xa3','\x5a'},{'\xa3','\x5b'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xa3','\x5c'},{'\xa3','\x5d'},{'\xa3','\x5e'},{'\xa3','\x5f'},{'\xa3','\x60'},
+ {'\xa3','\x61'},{'\xa3','\x62'},{'\xa3','\x63'},{'\xa3','\x64'},{'\xa3','\x65'},
+ {'\xa3','\x66'},{'\xa3','\x67'},{'\xa3','\x68'},{'\xa3','\x69'},{'\xa3','\x6a'},
+ {'\xa3','\x6b'},{'\xa3','\x6c'},{'\x00','\x00'},{'\xa3','\x6d'},{'\xa3','\x6e'},
+ {'\xa3','\x6f'},{'\xa3','\x70'},{'\xa3','\x71'},{'\xa3','\x72'},{'\xa3','\x73'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xc7','\xf9'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xc7','\xf3'},{'\xc7','\xf4'},{'\xc7','\xf5'},{'\xc7','\xf6'},{'\xc7','\xf7'},
+ {'\xc7','\xf8'},{'\xc7','\xfa'},{'\xc7','\xfb'},{'\xc7','\xfc'},{'\xc7','\xfd'},
+ {'\xc7','\xfe'},{'\xc8','\x40'},{'\xc8','\x41'},{'\xc8','\x42'},{'\xc8','\x43'},
+ {'\xc8','\x44'},{'\xc8','\x45'},{'\xc8','\x46'},{'\xc8','\x47'},{'\xc8','\x48'},
+ {'\xc8','\x49'},{'\xc8','\x4a'},{'\xc8','\x4b'},{'\xc8','\x4c'},{'\xc8','\x4d'},
+ {'\xc8','\x4e'},{'\xc8','\x4f'},{'\xc8','\x50'},{'\xc8','\x51'},{'\xc8','\x52'},
+ {'\xc8','\x53'},{'\xc8','\x54'},{'\xc8','\x55'},{'\xc8','\x56'},{'\xc8','\x57'},
+ {'\xc8','\x58'},{'\xc8','\x59'},{'\xc8','\x5a'},{'\xc8','\x5c'},{'\xc8','\x5d'},
+ {'\xc8','\x5e'},{'\xc8','\x5f'},{'\xc8','\x60'},{'\xc8','\x61'},{'\xc8','\x62'},
+ {'\xc8','\x63'},{'\xc8','\x64'},{'\xc8','\x65'},{'\xc8','\x66'},{'\xc8','\x67'},
+ {'\xc8','\x68'},{'\xc8','\x69'},{'\xc8','\x6a'},{'\xc8','\x6b'},{'\xc8','\x6c'},
+ {'\xc8','\x6d'},{'\xc8','\x6e'},{'\xc8','\x6f'},{'\xc8','\x70'},{'\xc8','\x71'},
+ {'\xc8','\x72'},{'\xc8','\x73'},{'\xc8','\x74'},{'\xc8','\x75'},{'\x00','\x00'},
+ {'\xc8','\x5b'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xd6'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xd3'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xd4'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa0','\xdb'},{'\xa0','\xeb'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9f','\xec'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa1','\x56'},{'\xa1','\x58'},{'\xa2','\x77'},{'\xa1','\xfc'},
+ {'\x00','\x00'},{'\xa1','\xa5'},{'\xa1','\xa6'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xa1','\xa7'},{'\xa1','\xa8'},{'\x00','\x00'},{'\x00','\x00'},{'\xa1','\xcf'},
+ {'\x91','\xde'},{'\xa1','\x45'},{'\x00','\x00'},{'\xa3','\xbb'},{'\xa1','\x4c'},
+ {'\xa1','\x4b'},{'\xa1','\x45'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xfe','\xe2'},{'\x00','\x00'},{'\xa1','\xac'},{'\xa1','\xb2'},{'\x00','\x00'},
+ {'\xa1','\xab'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa1','\xb0'},{'\x91','\xf7'},{'\x00','\x00'},{'\xa1','\xc3'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa3','\xe1'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa2','\x4a'},{'\x00','\x00'},{'\xa1','\xc1'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa2','\x4b'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x9d','\xcf'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9d','\xe2'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x9d','\xc9'},{'\x97','\xfc'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x96','\x52'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x9d','\xc8'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xfe','\xb1'},{'\xfe','\xb2'},{'\xfe','\xb5'},{'\xfe','\xb6'},
+ {'\xfe','\xb7'},{'\xfe','\xb8'},{'\xfe','\xb9'},{'\xfe','\xba'},{'\xfe','\xc1'},
+ {'\xfe','\xc2'},{'\xfe','\xc3'},{'\xfe','\xc4'},{'\x00','\x00'},{'\xa2','\xb9'},
+ {'\xa2','\xba'},{'\xa2','\xbb'},{'\xa2','\xbc'},{'\xa2','\xbd'},{'\xa2','\xbe'},
+ {'\xa2','\xbf'},{'\xa2','\xc0'},{'\xa2','\xc1'},{'\xa2','\xc2'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xc6','\xb5'},{'\xc6','\xb6'},{'\xc6','\xb7'},{'\xc6','\xb8'},{'\xc6','\xb9'},
+ {'\xc6','\xba'},{'\xc6','\xbb'},{'\xc6','\xbc'},{'\xc6','\xbd'},{'\xc6','\xbe'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa1','\xf6'},{'\xa1','\xf4'},{'\xa1','\xf7'},
+ {'\xa1','\xf5'},{'\x91','\xfb'},{'\x91','\xf6'},{'\xa1','\xf8'},{'\xa1','\xf9'},
+ {'\xa1','\xfb'},{'\xa1','\xfa'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x91','\xfa'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x9d','\xfd'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc8','\x77'},{'\xc8','\x78'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x96','\x53'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x99','\x65'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9d','\x4a'},{'\xc8','\x76'},
+ {'\x9d','\x49'},{'\x9d','\x4c'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x91','\xf9'},
+ {'\x00','\x00'},{'\xa0','\x79'},{'\x98','\xf9'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa1','\xbe'},{'\x91','\x6b'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x91','\x5f'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa3','\x53'},
+ {'\x00','\x00'},{'\xa3','\x55'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xa2','\x41'},{'\xa2','\x42'},{'\x00','\x00'},{'\xa2','\x58'},{'\x00','\x00'},
+ {'\xa1','\xd4'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa1','\xdb'},
+ {'\xa1','\xe8'},{'\xa1','\xe7'},{'\x00','\x00'},{'\x00','\x00'},{'\xa1','\xfd'},
+ {'\x00','\x00'},{'\xa1','\xfc'},{'\x00','\x00'},{'\xa3','\x4e'},{'\xa2','\xe4'},
+ {'\xa1','\xe4'},{'\xa1','\xe5'},{'\xa1','\xec'},{'\x9f','\x4c'},{'\x00','\x00'},
+ {'\xa1','\xed'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa1','\xef'},{'\xa1','\xee'},{'\xa1','\x47'},{'\x9f','\x46'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa1','\xdc'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xa1','\xda'},{'\xa1','\xdd'},{'\x00','\x00'},{'\xa1','\xdd'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa1','\xd8'},{'\xa1','\xd9'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9a','\xe0'},
+ {'\x9a','\xa6'},{'\x00','\x00'},{'\x00','\x00'},{'\x9c','\x72'},{'\x9c','\xaa'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa1','\xf2'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa1','\xf3'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa1','\xe6'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xa1','\xe9'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x91','\xfc'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa1','\x5b'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xfe','\xd9'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa3','\xc0'},{'\xa3','\xc1'},{'\xa3','\xc2'},{'\xa3','\xc3'},
+ {'\xa3','\xc4'},{'\xa3','\xc5'},{'\xa3','\xc6'},{'\xa3','\xc7'},{'\xa3','\xc8'},
+ {'\xa3','\xc9'},{'\xa3','\xca'},{'\xa3','\xcb'},{'\xa3','\xcc'},{'\xa3','\xcd'},
+ {'\xa3','\xce'},{'\xa3','\xcf'},{'\xa3','\xd0'},{'\xa3','\xd1'},{'\xa3','\xd2'},
+ {'\xa3','\xd3'},{'\xa3','\xd4'},{'\xa3','\xd5'},{'\xa3','\xd6'},{'\xa3','\xd7'},
+ {'\xa3','\xd8'},{'\xa3','\xd9'},{'\xa3','\xda'},{'\xa3','\xdb'},{'\xa3','\xdc'},
+ {'\xa3','\xdd'},{'\xa3','\xde'},{'\xa3','\xdf'},{'\x00','\x00'},{'\xa3','\xe0'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xa1'},{'\xc6','\xa2'},{'\xc6','\xa3'},
+ {'\xc6','\xa4'},{'\xc6','\xa5'},{'\xc6','\xa6'},{'\xc6','\xa7'},{'\xc6','\xa8'},
+ {'\xc6','\xa9'},{'\xc6','\xaa'},{'\x97','\x4b'},{'\x97','\x4c'},{'\x97','\x4d'},
+ {'\x97','\x4e'},{'\x97','\x4f'},{'\x97','\x50'},{'\x97','\x51'},{'\x97','\x52'},
+ {'\x97','\x53'},{'\x97','\x54'},{'\xc6','\xab'},{'\xc6','\xac'},{'\xc6','\xad'},
+ {'\xc6','\xae'},{'\xc6','\xaf'},{'\xc6','\xb0'},{'\xc6','\xb1'},{'\xc6','\xb2'},
+ {'\xc6','\xb3'},{'\xc6','\xb4'},{'\x99','\x4b'},{'\x99','\x4c'},{'\x99','\x4d'},
+ {'\x99','\x4e'},{'\x99','\x4f'},{'\x99','\x50'},{'\x99','\x51'},{'\x99','\x52'},
+ {'\x99','\x53'},{'\x99','\x54'},{'\x9a','\x41'},{'\x9a','\x42'},{'\x9a','\x43'},
+ {'\x9a','\x44'},{'\x9a','\x45'},{'\x9a','\x46'},{'\x9a','\x47'},{'\x9a','\x48'},
+ {'\x9a','\x49'},{'\x9a','\x4a'},{'\x9a','\x4b'},{'\x9a','\x4c'},{'\x9a','\x4d'},
+ {'\x9a','\x4e'},{'\x9a','\x4f'},{'\x9a','\x50'},{'\x9a','\x51'},{'\x9a','\x52'},
+ {'\x9a','\x53'},{'\x9a','\x54'},{'\x99','\xe1'},{'\x99','\xe2'},{'\x99','\xe3'},
+ {'\x99','\xe4'},{'\x99','\xe5'},{'\x99','\xe6'},{'\x99','\xe7'},{'\x99','\xe8'},
+ {'\x99','\xe9'},{'\x99','\xea'},{'\x99','\xeb'},{'\x99','\xec'},{'\x99','\xed'},
+ {'\x99','\xee'},{'\x99','\xef'},{'\x99','\xf0'},{'\x99','\xf1'},{'\x99','\xf2'},
+ {'\x99','\xf3'},{'\x99','\xf4'},{'\x99','\xf5'},{'\x99','\xf6'},{'\x99','\xf7'},
+ {'\x99','\xf8'},{'\x99','\xf9'},{'\x99','\xfa'},{'\x97','\xc7'},{'\x97','\xc8'},
+ {'\x97','\xc9'},{'\x97','\xca'},{'\x97','\xcb'},{'\x97','\xcc'},{'\x97','\xcd'},
+ {'\x97','\xce'},{'\x97','\xcf'},{'\x97','\xd0'},{'\x97','\xd1'},{'\x97','\xd2'},
+ {'\x97','\xd3'},{'\x97','\xd4'},{'\x97','\xd5'},{'\x97','\xd6'},{'\x97','\xd7'},
+ {'\x97','\xd8'},{'\x97','\xd9'},{'\x97','\xda'},{'\x97','\xdb'},{'\x97','\xdc'},
+ {'\x97','\xdd'},{'\x97','\xde'},{'\x97','\xdf'},{'\x97','\xe0'},{'\x97','\xe1'},
+ {'\x97','\xe2'},{'\x97','\xe3'},{'\x97','\xe4'},{'\x97','\xe5'},{'\x97','\xe6'},
+ {'\x97','\xe7'},{'\x97','\xe8'},{'\x97','\xe9'},{'\x97','\xea'},{'\x97','\xeb'},
+ {'\x97','\xec'},{'\x97','\xed'},{'\x97','\xee'},{'\x97','\xef'},{'\x97','\xf0'},
+ {'\x97','\xf1'},{'\x97','\xf2'},{'\x97','\xf3'},{'\x97','\xf4'},{'\x97','\xf5'},
+ {'\x97','\xf6'},{'\x97','\xf7'},{'\x97','\xf8'},{'\x97','\xf9'},{'\x97','\xfa'},
+ {'\x97','\x40'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa2','\x77'},{'\x9d','\x7d'},{'\xa2','\x78'},
+ {'\x9d','\x7e'},{'\xa1','\x4c'},{'\xa1','\x4c'},{'\xa1','\x4a'},{'\xa1','\x4a'},
+ {'\xa1','\x4b'},{'\xa1','\x4b'},{'\xa1','\x55'},{'\xa1','\x55'},{'\xa2','\x7a'},
+ {'\xa2','\x7a'},{'\xa2','\x7a'},{'\xa2','\x7a'},{'\xa2','\x7b'},{'\xa2','\x7b'},
+ {'\xa2','\x7b'},{'\xa2','\x7b'},{'\xa2','\x7c'},{'\xa2','\x7c'},{'\xa2','\x7c'},
+ {'\xa2','\x7c'},{'\xa2','\x7d'},{'\xa2','\x7d'},{'\xa2','\x7d'},{'\xa2','\x7d'},
+ {'\xa2','\x75'},{'\xa2','\x75'},{'\xa2','\x75'},{'\xa2','\x75'},{'\xa2','\x75'},
+ {'\xa2','\x75'},{'\xa2','\x75'},{'\xa2','\x75'},{'\xa2','\x74'},{'\xa2','\x74'},
+ {'\xa2','\x74'},{'\xa2','\x74'},{'\xa2','\x74'},{'\xa2','\x74'},{'\xa2','\x74'},
+ {'\xa2','\x74'},{'\xa2','\x73'},{'\xa2','\x73'},{'\xa2','\x73'},{'\xa2','\x73'},
+ {'\xa2','\x73'},{'\xa2','\x73'},{'\xa2','\x73'},{'\xa2','\x73'},{'\xa2','\x72'},
+ {'\xa2','\x72'},{'\xa2','\x72'},{'\xa2','\x72'},{'\xa2','\x72'},{'\xa2','\x72'},
+ {'\xa2','\x72'},{'\xa2','\x72'},{'\xa2','\x71'},{'\xa2','\x71'},{'\xa2','\x71'},
+ {'\xa2','\x71'},{'\xa2','\x71'},{'\xa2','\x71'},{'\xa2','\x71'},{'\xa2','\x71'},
+ {'\xa2','\x71'},{'\xa2','\x71'},{'\xa2','\x71'},{'\xa2','\x71'},{'\xa2','\x71'},
+ {'\xa2','\x71'},{'\xa2','\x71'},{'\xa2','\x71'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x91','\xf0'},{'\x00','\x00'},{'\xf9','\xf9'},{'\xf9','\xf8'},{'\xf9','\xe6'},
+ {'\xf9','\xef'},{'\xf9','\xdd'},{'\xf9','\xe8'},{'\xf9','\xf1'},{'\xf9','\xdf'},
+ {'\xf9','\xec'},{'\xf9','\xf5'},{'\xf9','\xe3'},{'\xf9','\xee'},{'\xf9','\xf7'},
+ {'\xf9','\xe5'},{'\xf9','\xe9'},{'\xf9','\xf2'},{'\xf9','\xe0'},{'\xf9','\xeb'},
+ {'\xf9','\xf4'},{'\xf9','\xe2'},{'\xf9','\xe7'},{'\xf9','\xf0'},{'\xf9','\xde'},
+ {'\xf9','\xed'},{'\xf9','\xf6'},{'\xf9','\xe4'},{'\xf9','\xea'},{'\xf9','\xf3'},
+ {'\xf9','\xe1'},{'\xa2','\x7e'},{'\xa2','\xa1'},{'\xa2','\xa3'},{'\xa2','\xa2'},
+ {'\xa2','\xac'},{'\xa2','\xad'},{'\xa2','\xae'},{'\xa1','\x5a'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa2','\x62'},{'\xa2','\x63'},{'\xa2','\x64'},{'\xa2','\x65'},
+ {'\xa2','\x66'},{'\xa2','\x67'},{'\xa2','\x68'},{'\xa2','\x69'},{'\xa2','\x70'},
+ {'\xa2','\x6f'},{'\xa2','\x6e'},{'\xa2','\x6d'},{'\xa2','\x6c'},{'\xa2','\x6b'},
+ {'\xa2','\x6a'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xf9','\xfe'},
+ {'\xa2','\x76'},{'\xa2','\x79'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa1','\xbd'},{'\xa1','\xbc'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xa1','\xb6'},{'\xa1','\xb5'},{'\x00','\x00'},{'\x00','\x00'},{'\x91','\xf4'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xa1','\xbf'},{'\xa1','\xbe'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x91','\xf5'},{'\x00','\x00'},
+ {'\xa1','\xbb'},{'\xa1','\xba'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xa1','\xb3'},{'\x00','\x00'},{'\x00','\x00'},{'\xa1','\xb7'},{'\xa1','\xb4'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x91','\xf1'},{'\x91','\xf2'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa2','\xa8'},{'\xa2','\xa9'},
+ {'\xa2','\xab'},{'\xa2','\xaa'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa1','\xb3'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9d','\xba'},
+ {'\x9d','\xbc'},{'\x00','\x00'},{'\x00','\x00'},{'\xa1','\xb9'},{'\xa1','\xb8'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa1','\xf3'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x9d','\x40'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x9d','\xed'},{'\x9c','\xd1'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x9d','\x4f'},{'\x9d','\x4e'},{'\x00','\x00'},{'\x9d','\x4d'},{'\x9d','\x50'},
+ {'\x9d','\xd5'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x9f','\x55'},{'\x9f','\x56'},{'\x9f','\x5d'},{'\x9f','\x5b'},{'\x9f','\x58'},
+ {'\x9f','\x59'},{'\x9f','\x5a'},{'\x9f','\x5c'},{'\x9f','\x57'},{'\x00','\x00'},
+ {'\x9d','\x5e'},{'\x9d','\x5d'},{'\x98','\xfc'},{'\x9d','\xb8'},{'\x9d','\x57'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa1','\xf0'},{'\xa1','\xf2'},{'\xa1','\xf1'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9d','\xd8'},
+ {'\x9d','\xdd'},{'\x9d','\xdb'},{'\x9d','\xda'},{'\x9d','\xd7'},{'\x9d','\xde'},
+ {'\x9d','\xdc'},{'\x9d','\xd9'},{'\x00','\x00'},{'\x00','\x00'},{'\x9d','\x66'},
+ {'\x00','\x00'},{'\x9d','\x65'},{'\xa2','\xea'},{'\x00','\x00'},{'\xa1','\xad'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x9d','\x6c'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x9d','\xc0'},{'\x9d','\x6b'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9d','\x55'},{'\x00','\x00'},
+ {'\x9d','\x54'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x9d','\x5c'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x9d','\x5b'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xc6','\xe6'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9d','\x77'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x98','\x41'},{'\x98','\x42'},{'\x98','\x43'},
+ {'\x98','\x44'},{'\x98','\x45'},{'\x98','\x46'},{'\x98','\x47'},{'\x98','\x48'},
+ {'\x98','\x49'},{'\x98','\x4a'},{'\xc6','\xa1'},{'\xc6','\xa2'},{'\xc6','\xa3'},
+ {'\xc6','\xa4'},{'\xc6','\xa5'},{'\xc6','\xa6'},{'\xc6','\xa7'},{'\xc6','\xa8'},
+ {'\xc6','\xa9'},{'\xc6','\xaa'},{'\x98','\x41'},{'\x98','\x42'},{'\x98','\x43'},
+ {'\x98','\x44'},{'\x98','\x45'},{'\x98','\x46'},{'\x98','\x47'},{'\x98','\x48'},
+ {'\x98','\x49'},{'\x98','\x4a'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x91','\xed'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x9c','\xce'},{'\x00','\x00'},{'\x00','\x00'},{'\x9c','\xd5'},
+ {'\x00','\x00'},{'\x9c','\xd4'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x9c','\xdb'},{'\x00','\x00'},{'\x91','\xdb'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x91','\xc9'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x9c','\xf7'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xbf'},
+ {'\xc6','\xc0'},{'\x00','\x00'},{'\xc6','\xc1'},{'\x00','\x00'},{'\xc6','\xc2'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xc3'},
+ {'\xc6','\xc4'},{'\xc6','\xc5'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xc6','\xc6'},{'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xc7'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xc8'},{'\x00','\x00'},{'\xc6','\xc9'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xc6','\xca'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xc6','\xcb'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xcc'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xcd'},{'\xc6','\xce'},
+ {'\xc6','\xcf'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xd0'},
+ {'\xc6','\xd1'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xd2'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xd3'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xc6','\xd4'},{'\xc6','\xd5'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xd6'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xd7'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa1','\x40'},{'\xa1','\x42'},
+ {'\xa1','\x43'},{'\xa1','\xb2'},{'\x00','\x00'},{'\xc6','\xe0'},{'\xc6','\xe1'},
+ {'\xc6','\xe2'},{'\xa1','\x71'},{'\xa1','\x72'},{'\xa1','\x6d'},{'\xa1','\x6e'},
+ {'\xa1','\x75'},{'\xa1','\x76'},{'\xa1','\x79'},{'\xa1','\x7a'},{'\xa1','\x69'},
+ {'\xa1','\x6a'},{'\xa2','\x45'},{'\x96','\x5d'},{'\xa1','\x65'},{'\xa1','\x66'},
+ {'\x9d','\x51'},{'\x9d','\x52'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa1','\xe3'},{'\xa1','\xa9'},{'\xa1','\xaa'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa2','\xc3'},{'\xa2','\xc4'},{'\xa2','\xc5'},{'\xa2','\xc6'},
+ {'\xa2','\xc7'},{'\xa2','\xc8'},{'\xa2','\xc9'},{'\xa2','\xca'},{'\xa2','\xcb'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa1','\xca'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa2','\xcc'},
+ {'\xa2','\xcd'},{'\xa2','\xce'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xe7'},{'\xc6','\xe8'},
+ {'\xc6','\xe9'},{'\xc6','\xea'},{'\xc6','\xeb'},{'\xc6','\xec'},{'\xc6','\xed'},
+ {'\xc6','\xee'},{'\xc6','\xef'},{'\xc6','\xf0'},{'\xc6','\xf1'},{'\xc6','\xf2'},
+ {'\xc6','\xf3'},{'\xc6','\xf4'},{'\xc6','\xf5'},{'\xc6','\xf6'},{'\xc6','\xf7'},
+ {'\xc6','\xf8'},{'\xc6','\xf9'},{'\xc6','\xfa'},{'\xc6','\xfb'},{'\xc6','\xfc'},
+ {'\xc6','\xfd'},{'\xc6','\xfe'},{'\xc7','\x40'},{'\xc7','\x41'},{'\xc7','\x42'},
+ {'\xc7','\x43'},{'\xc7','\x44'},{'\xc7','\x45'},{'\xc7','\x46'},{'\xc7','\x47'},
+ {'\xc7','\x48'},{'\xc7','\x49'},{'\xc7','\x4a'},{'\xc7','\x4b'},{'\xc7','\x4c'},
+ {'\xc7','\x4d'},{'\xc7','\x4e'},{'\xc7','\x4f'},{'\xc7','\x50'},{'\xc7','\x51'},
+ {'\xc7','\x52'},{'\xc7','\x53'},{'\xc7','\x54'},{'\xc7','\x55'},{'\xc7','\x56'},
+ {'\xc7','\x57'},{'\xc7','\x58'},{'\xc7','\x59'},{'\xc7','\x5a'},{'\xc7','\x5b'},
+ {'\xc7','\x5c'},{'\xc7','\x5d'},{'\xc7','\x5e'},{'\xc7','\x5f'},{'\xc7','\x60'},
+ {'\xc7','\x61'},{'\xc7','\x62'},{'\xc7','\x63'},{'\xc7','\x64'},{'\xc7','\x65'},
+ {'\xc7','\x66'},{'\xc7','\x67'},{'\xc7','\x68'},{'\xc7','\x69'},{'\xc7','\x6a'},
+ {'\xc7','\x6b'},{'\xc7','\x6c'},{'\xc7','\x6d'},{'\xc7','\x6e'},{'\xc7','\x6f'},
+ {'\xc7','\x70'},{'\xc7','\x71'},{'\xc7','\x72'},{'\xc7','\x73'},{'\xc7','\x74'},
+ {'\xc7','\x75'},{'\xc7','\x76'},{'\xc7','\x77'},{'\xc7','\x78'},{'\xc7','\x79'},
+ {'\xc7','\x7a'},{'\xc8','\xb3'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xc8','\xb1'},{'\xc8','\xb2'},
+ {'\xc6','\xdc'},{'\xc6','\xdd'},{'\x00','\x00'},{'\x00','\x00'},{'\xc7','\x7b'},
+ {'\xc7','\x7c'},{'\xc7','\x7d'},{'\xc7','\x7e'},{'\xc7','\xa1'},{'\xc7','\xa2'},
+ {'\xc7','\xa3'},{'\xc7','\xa4'},{'\xc7','\xa5'},{'\xc7','\xa6'},{'\xc7','\xa7'},
+ {'\xc7','\xa8'},{'\xc7','\xa9'},{'\xc7','\xaa'},{'\xc7','\xab'},{'\xc7','\xac'},
+ {'\xc7','\xad'},{'\xc7','\xae'},{'\xc7','\xaf'},{'\xc7','\xb0'},{'\xc7','\xb1'},
+ {'\xc7','\xb2'},{'\xc7','\xb3'},{'\xc7','\xb4'},{'\xc7','\xb5'},{'\xc7','\xb6'},
+ {'\xc7','\xb7'},{'\xc7','\xb8'},{'\xc7','\xb9'},{'\xc7','\xba'},{'\xc7','\xbb'},
+ {'\xc7','\xbc'},{'\xc7','\xbd'},{'\xc7','\xbe'},{'\xc7','\xbf'},{'\xc7','\xc0'},
+ {'\xc7','\xc1'},{'\xc7','\xc2'},{'\xc7','\xc3'},{'\xc7','\xc4'},{'\xc7','\xc5'},
+ {'\xc7','\xc6'},{'\xc7','\xc7'},{'\xc7','\xc8'},{'\xc7','\xc9'},{'\xc7','\xca'},
+ {'\xc7','\xcb'},{'\xc7','\xcc'},{'\xc7','\xcd'},{'\xc7','\xce'},{'\xc7','\xcf'},
+ {'\xc7','\xd0'},{'\xc7','\xd1'},{'\xc7','\xd2'},{'\xc7','\xd3'},{'\xc7','\xd4'},
+ {'\xc7','\xd5'},{'\xc7','\xd6'},{'\xc7','\xd7'},{'\xc7','\xd8'},{'\xc7','\xd9'},
+ {'\xc7','\xda'},{'\xc7','\xdb'},{'\xc7','\xdc'},{'\xc7','\xdd'},{'\xc7','\xde'},
+ {'\xc7','\xdf'},{'\xc7','\xe0'},{'\xc7','\xe1'},{'\xc7','\xe2'},{'\xc7','\xe3'},
+ {'\xc7','\xe4'},{'\xc7','\xe5'},{'\xc7','\xe6'},{'\xc7','\xe7'},{'\xc7','\xe8'},
+ {'\xc7','\xe9'},{'\xc7','\xea'},{'\xc7','\xeb'},{'\xc7','\xec'},{'\xc7','\xed'},
+ {'\xc7','\xee'},{'\xc7','\xef'},{'\xc7','\xf0'},{'\xc7','\xf1'},{'\xc7','\xf2'},
+ {'\xc8','\xb4'},{'\xc8','\xb5'},{'\xc8','\xb6'},{'\xc8','\xb7'},{'\xc8','\xb8'},
+ {'\xc6','\xe3'},{'\xc6','\xda'},{'\xc6','\xdb'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa3','\x74'},
+ {'\xa3','\x75'},{'\xa3','\x76'},{'\xa3','\x77'},{'\xa3','\x78'},{'\xa3','\x79'},
+ {'\xa3','\x7a'},{'\xa3','\x7b'},{'\xa3','\x7c'},{'\xa3','\x7d'},{'\xa3','\x7e'},
+ {'\xa3','\xa1'},{'\xa3','\xa2'},{'\xa3','\xa3'},{'\xa3','\xa4'},{'\xa3','\xa5'},
+ {'\xa3','\xa6'},{'\xa3','\xa7'},{'\xa3','\xa8'},{'\xa3','\xa9'},{'\xa3','\xaa'},
+ {'\xa3','\xab'},{'\xa3','\xac'},{'\xa3','\xad'},{'\xa3','\xae'},{'\xa3','\xaf'},
+ {'\xa3','\xb0'},{'\xa3','\xb1'},{'\xa3','\xb2'},{'\xa3','\xb3'},{'\xa3','\xb4'},
+ {'\xa3','\xb5'},{'\xa3','\xb6'},{'\xa3','\xb7'},{'\xa3','\xb8'},{'\xa3','\xb9'},
+ {'\xa3','\xba'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xa4','\x40'},{'\xa4','\x47'},{'\xa4','\x54'},{'\xa5','\x7c'},{'\xa4','\x57'},
+ {'\xa4','\xa4'},{'\xa4','\x55'},{'\xa5','\xd2'},{'\xa4','\x41'},{'\xa4','\xfe'},
+ {'\xa4','\x42'},{'\xa4','\xd1'},{'\xa6','\x61'},{'\xa4','\x48'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xc8','\x79'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x9c','\x41'},{'\x9c','\x42'},{'\x9c','\x43'},
+ {'\x9c','\x44'},{'\x9c','\x45'},{'\x9c','\x46'},{'\x9c','\x47'},{'\x9c','\x48'},
+ {'\x9c','\x49'},{'\x9c','\x4a'},{'\xa4','\xeb'},{'\xa4','\xf5'},{'\xa4','\xf4'},
+ {'\xa4','\xec'},{'\xaa','\xf7'},{'\xa4','\x67'},{'\xa4','\xe9'},{'\x99','\xfd'},
+ {'\x99','\xfc'},{'\xaa','\xc0'},{'\xa6','\x57'},{'\xaf','\x53'},{'\xb0','\x5d'},
+ {'\xaf','\xac'},{'\xb3','\xd2'},{'\xa5','\x4e'},{'\xa9','\x49'},{'\xbe','\xc7'},
+ {'\xba','\xca'},{'\xa5','\xf8'},{'\xb8','\xea'},{'\xa8','\xf3'},{'\xb2','\xbd'},
+ {'\xa5','\xf0'},{'\xa6','\xdb'},{'\xa6','\xdc'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa4','\x40'},{'\xa4','\x47'},
+ {'\xa4','\x54'},{'\xa5','\x7c'},{'\xa4','\xad'},{'\xa4','\xbb'},{'\xa4','\x43'},
+ {'\xa4','\x4b'},{'\xa4','\x45'},{'\xa4','\x51'},{'\xa4','\xeb'},{'\xa4','\xf5'},
+ {'\xa4','\xf4'},{'\xa4','\xec'},{'\xaa','\xf7'},{'\xa4','\x67'},{'\xa4','\xe9'},
+ {'\xae','\xe8'},{'\xa6','\xb3'},{'\xaa','\xc0'},{'\xa6','\x57'},{'\xaf','\x53'},
+ {'\xb0','\x5d'},{'\xaf','\xac'},{'\xb3','\xd2'},{'\xaf','\xb5'},{'\xa8','\x6b'},
+ {'\xa4','\x6b'},{'\xbe','\x41'},{'\xc0','\x75'},{'\xa6','\x4c'},{'\xaa','\x60'},
+ {'\xb6','\xb5'},{'\xa5','\xf0'},{'\xbc','\x67'},{'\xa1','\xc0'},{'\xa4','\x57'},
+ {'\xa4','\xa4'},{'\xa4','\x55'},{'\xa5','\xaa'},{'\xa5','\x6b'},{'\xc2','\xe5'},
+ {'\xa9','\x76'},{'\xbe','\xc7'},{'\xba','\xca'},{'\xa5','\xf8'},{'\xb8','\xea'},
+ {'\xa8','\xf3'},{'\xa9','\x5d'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x48','\x67'},
+ {'\x00','\x00'},{'\x65','\x56'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x64','\x61'},{'\x41','\x55'},{'\x00','\x00'},{'\x6f','\x56'},{'\x70','\x63'},
+ {'\x64','\x6d'},{'\x00','\x00'},{'\x00','\x00'},{'\x49','\x55'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x70','\x41'},
+ {'\x6e','\x41'},{'\x00','\x00'},{'\x6d','\x41'},{'\x6b','\x41'},{'\x4b','\x42'},
+ {'\x4d','\x42'},{'\x47','\x42'},{'\x00','\x00'},{'\x00','\x00'},{'\x70','\x46'},
+ {'\x6e','\x46'},{'\x00','\x00'},{'\x00','\x00'},{'\xa2','\x55'},{'\xa2','\x56'},
+ {'\x48','\x7a'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x66','\x6d'},
+ {'\x6e','\x6d'},{'\x00','\x00'},{'\xa2','\x50'},{'\xa2','\x51'},{'\xa2','\x52'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa2','\x54'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x9d','\xe7'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x50','\x61'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x70','\x73'},{'\x6e','\x73'},{'\x00','\x00'},
+ {'\x6d','\x73'},{'\x70','\x56'},{'\x6e','\x56'},{'\x00','\x00'},{'\x6d','\x56'},
+ {'\x6b','\x56'},{'\x4d','\x56'},{'\x70','\x57'},{'\x6e','\x57'},{'\x00','\x00'},
+ {'\x6d','\x57'},{'\x6b','\x57'},{'\x4d','\x57'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x9d','\xe3'},{'\x42','\x71'},{'\xa2','\x57'},{'\x63','\x64'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x64','\x42'},{'\x47','\x79'},{'\x68','\x61'},{'\x48','\x50'},
+ {'\x69','\x6e'},{'\x4b','\x4b'},{'\xa2','\x53'},{'\x6b','\x74'},{'\x6c','\x6d'},
+ {'\xa1','\xeb'},{'\xa1','\xea'},{'\x6c','\x78'},{'\x6d','\x62'},{'\xa2','\x4f'},
+ {'\x00','\x00'},{'\x50','\x48'},{'\x9d','\xe4'},{'\x00','\x00'},{'\x50','\x52'},
+ {'\x73','\x72'},{'\x53','\x76'},{'\x57','\x62'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x91','\xe0'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa0','\xa2'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xfb','\x44'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x95','\xb8'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa0','\x48'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa0','\x4c'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xfb','\xdf'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xfb','\xe5'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xfb','\x6f'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x95','\x42'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xfe','\x7d'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xfe','\x67'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x95','\x5e'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x95','\xde'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x95','\xc7'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xfc','\x61'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x95','\xc9'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xfc','\x7c'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xfc','\xa8'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xfe','\x71'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xfc','\xc2'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xfe','\x4d'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x96','\xad'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9c','\xd3'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xfd','\x5e'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xfe','\x4a'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xfd','\x67'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xfb','\xb0'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xfb','\x7d'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xfd','\xe3'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xfd','\xf1'},{'\x00','\x00'},{'\x00','\x00'},{'\xfd','\xef'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xfd','\xf2'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xfb','\x45'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa4','\x40'},{'\xa4','\x42'},
+ {'\x00','\x00'},{'\xa4','\x43'},{'\x98','\xa7'},{'\x00','\x00'},{'\x91','\xd7'},
+ {'\xc9','\x45'},{'\xa4','\x56'},{'\xa4','\x54'},{'\xa4','\x57'},{'\xa4','\x55'},
+ {'\xc9','\x46'},{'\xa4','\xa3'},{'\xc9','\x4f'},{'\xc9','\x4d'},{'\xa4','\xa2'},
+ {'\xa4','\xa1'},{'\x00','\x00'},{'\x83','\xfd'},{'\xa5','\x42'},{'\xa5','\x41'},
+ {'\xa5','\x40'},{'\x81','\x40'},{'\xa5','\x43'},{'\xa4','\xfe'},{'\x85','\xd2'},
+ {'\x8a','\xbd'},{'\x83','\x5b'},{'\x85','\x46'},{'\xa5','\xe0'},{'\xa5','\xe1'},
+ {'\x00','\x00'},{'\x93','\xe5'},{'\x81','\x41'},{'\x00','\x00'},{'\x83','\x55'},
+ {'\x8b','\xf2'},{'\xa8','\xc3'},{'\x84','\xca'},{'\x9c','\xc9'},{'\x00','\x00'},
+ {'\x83','\xaa'},{'\xa4','\x58'},{'\x81','\x42'},{'\xa4','\xa4'},{'\xc9','\x50'},
+ {'\x98','\xa8'},{'\xa4','\xa5'},{'\xc9','\x63'},{'\xa6','\xea'},{'\xcb','\xb1'},
+ {'\x8a','\x5a'},{'\x00','\x00'},{'\xc6','\xbf'},{'\x91','\xcc'},{'\xa4','\x59'},
+ {'\xa4','\xa6'},{'\x83','\x6f'},{'\xa5','\x44'},{'\xc9','\x64'},{'\x8b','\xed'},
+ {'\x8a','\x5b'},{'\xc6','\xc0'},{'\x00','\x00'},{'\x00','\x00'},{'\xc9','\x40'},
+ {'\xa4','\x44'},{'\x94','\xf2'},{'\xa4','\x5b'},{'\x00','\x00'},{'\xc9','\x47'},
+ {'\xa4','\x5c'},{'\x85','\xf3'},{'\x00','\x00'},{'\xa4','\xa7'},{'\x83','\xbf'},
+ {'\xa5','\x45'},{'\xa5','\x47'},{'\xa5','\x46'},{'\x87','\xe4'},{'\x00','\x00'},
+ {'\xa5','\xe2'},{'\xa5','\xe3'},{'\x84','\xce'},{'\x81','\x43'},{'\xa8','\xc4'},
+ {'\x92','\xe9'},{'\xad','\xbc'},{'\xa4','\x41'},{'\x9c','\xdf'},{'\x9c','\xe8'},
+ {'\xc9','\x41'},{'\xa4','\x45'},{'\xa4','\x5e'},{'\xa4','\x5d'},{'\x84','\x74'},
+ {'\x85','\x70'},{'\x81','\x44'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x83','\xbc'},{'\x00','\x00'},{'\x00','\x00'},{'\xa5','\xe4'},{'\xfe','\x41'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x85','\x67'},{'\x85','\xaf'},{'\x00','\x00'},{'\xa8','\xc5'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa0','\x61'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xb0','\xae'},
+ {'\xd4','\x4b'},{'\x93','\xfa'},{'\x98','\xa9'},{'\xb6','\xc3'},{'\xdc','\xb1'},
+ {'\xdc','\xb2'},{'\xc6','\xc1'},{'\xa4','\x46'},{'\x98','\xaa'},{'\xa4','\xa9'},
+ {'\x83','\x5c'},{'\x81','\x45'},{'\xa8','\xc6'},{'\xa4','\x47'},{'\xc9','\x48'},
+ {'\xa4','\x5f'},{'\x8a','\x5f'},{'\x00','\x00'},{'\xa4','\xaa'},{'\xa4','\xac'},
+ {'\xc9','\x51'},{'\xa4','\xad'},{'\xa4','\xab'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xfe','\x62'},{'\xa5','\xe5'},{'\x83','\x52'},{'\xa8','\xc7'},{'\x92','\x40'},
+ {'\x00','\x00'},{'\xa8','\xc8'},{'\xab','\x45'},{'\xc6','\xc2'},{'\xa4','\x60'},
+ {'\xa4','\xae'},{'\x98','\xab'},{'\xa5','\xe6'},{'\xa5','\xe8'},{'\xa5','\xe7'},
+ {'\x84','\x64'},{'\xa6','\xeb'},{'\x83','\xc2'},{'\x00','\x00'},{'\xa8','\xc9'},
+ {'\xa8','\xca'},{'\xab','\x46'},{'\xab','\x47'},{'\x00','\x00'},{'\x81','\x46'},
+ {'\x00','\x00'},{'\x89','\x5d'},{'\xad','\xbd'},{'\x00','\x00'},{'\x8a','\x62'},
+ {'\xdc','\xb3'},{'\x98','\xac'},{'\x00','\x00'},{'\xf6','\xd6'},{'\xa4','\x48'},
+ {'\x9c','\xf4'},{'\x98','\xad'},{'\x00','\x00'},{'\x00','\x00'},{'\x87','\xa3'},
+ {'\xa4','\xb0'},{'\xa4','\xaf'},{'\xc9','\x52'},{'\xa4','\xb1'},{'\xa4','\xb7'},
+ {'\x85','\xb2'},{'\xa4','\xb2'},{'\xa4','\xb3'},{'\xc9','\x54'},{'\xc9','\x53'},
+ {'\xa4','\xb5'},{'\xa4','\xb6'},{'\x00','\x00'},{'\xa4','\xb4'},{'\x84','\x47'},
+ {'\x93','\xc2'},{'\x00','\x00'},{'\x83','\x54'},{'\x00','\x00'},{'\x83','\xac'},
+ {'\xa5','\x4a'},{'\xa5','\x4b'},{'\xa5','\x4c'},{'\xa5','\x4d'},{'\xa5','\x49'},
+ {'\xa5','\x50'},{'\xc9','\x6a'},{'\x00','\x00'},{'\xc9','\x66'},{'\xc9','\x69'},
+ {'\xa5','\x51'},{'\xa5','\x61'},{'\x00','\x00'},{'\xc9','\x68'},{'\x00','\x00'},
+ {'\xa5','\x4e'},{'\xa5','\x4f'},{'\xa5','\x48'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xc9','\x65'},{'\xc9','\x67'},{'\x87','\xa4'},{'\x81','\x47'},{'\x83','\xa8'},
+ {'\x81','\x48'},{'\x92','\x54'},{'\x00','\x00'},{'\xa5','\xf5'},{'\xc9','\xb0'},
+ {'\xa5','\xf2'},{'\xa5','\xf6'},{'\xc9','\xba'},{'\xc9','\xae'},{'\xa5','\xf3'},
+ {'\xc9','\xb2'},{'\x98','\xae'},{'\x00','\x00'},{'\x00','\x00'},{'\xa5','\xf4'},
+ {'\x81','\x49'},{'\xa5','\xf7'},{'\x00','\x00'},{'\xa5','\xe9'},{'\xc9','\xb1'},
+ {'\xa5','\xf8'},{'\xc9','\xb5'},{'\xfb','\xba'},{'\xc9','\xb9'},{'\xc9','\xb6'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc9','\xb3'},{'\xa5','\xea'},{'\xa5','\xec'},
+ {'\xa5','\xf9'},{'\x00','\x00'},{'\xa5','\xee'},{'\xc9','\xab'},{'\xa5','\xf1'},
+ {'\xa5','\xef'},{'\xa5','\xf0'},{'\xc9','\xbb'},{'\xc9','\xb8'},{'\xc9','\xaf'},
+ {'\xa5','\xed'},{'\x00','\x00'},{'\x84','\x67'},{'\xc9','\xac'},{'\xa5','\xeb'},
+ {'\x85','\xd1'},{'\x8d','\xfd'},{'\x81','\x4a'},{'\xc9','\xb4'},{'\x84','\xc4'},
+ {'\x83','\xec'},{'\x85','\xb1'},{'\x00','\x00'},{'\xc9','\xb7'},{'\x00','\x00'},
+ {'\x85','\xb4'},{'\x83','\xa9'},{'\x83','\xab'},{'\x84','\xc3'},{'\x98','\xaf'},
+ {'\x98','\xb0'},{'\x83','\xeb'},{'\x83','\x43'},{'\xc9','\xad'},{'\xca','\x66'},
+ {'\x00','\x00'},{'\xa7','\x42'},{'\xa6','\xf4'},{'\x00','\x00'},{'\xfb','\xbd'},
+ {'\xca','\x67'},{'\xa6','\xf1'},{'\x00','\x00'},{'\xa7','\x44'},{'\x98','\xb1'},
+ {'\xa6','\xf9'},{'\xfb','\xbc'},{'\xa6','\xf8'},{'\xca','\x5b'},{'\xa6','\xfc'},
+ {'\xa6','\xf7'},{'\xca','\x60'},{'\xca','\x68'},{'\x00','\x00'},{'\xca','\x64'},
+ {'\x98','\xb2'},{'\xa6','\xfa'},{'\x00','\x00'},{'\x98','\xb3'},{'\xa6','\xfd'},
+ {'\xa6','\xee'},{'\xa7','\x47'},{'\xca','\x5d'},{'\x00','\x00'},{'\x98','\xb4'},
+ {'\xcb','\xbd'},{'\xa6','\xec'},{'\xa7','\x43'},{'\xa6','\xed'},{'\xa6','\xf5'},
+ {'\xa6','\xf6'},{'\xca','\x62'},{'\xca','\x5e'},{'\xa6','\xfb'},{'\xa6','\xf3'},
+ {'\xca','\x5a'},{'\xa6','\xef'},{'\xca','\x65'},{'\xa7','\x45'},{'\xa7','\x48'},
+ {'\xa6','\xf2'},{'\xa7','\x40'},{'\xa7','\x46'},{'\xa6','\xf0'},{'\xca','\x63'},
+ {'\xa7','\x41'},{'\xca','\x69'},{'\xca','\x5c'},{'\xa6','\xfe'},{'\xca','\x5f'},
+ {'\x8e','\x40'},{'\x00','\x00'},{'\xca','\x61'},{'\x00','\x00'},{'\xa8','\xd8'},
+ {'\xcb','\xbf'},{'\xcb','\xcb'},{'\xa8','\xd0'},{'\x00','\x00'},{'\xcb','\xcc'},
+ {'\xa8','\xcb'},{'\xa8','\xd5'},{'\x00','\x00'},{'\x98','\xb5'},{'\xa8','\xce'},
+ {'\xcb','\xb9'},{'\xa8','\xd6'},{'\xcb','\xb8'},{'\xcb','\xbc'},{'\xcb','\xc3'},
+ {'\xcb','\xc1'},{'\xa8','\xde'},{'\xa8','\xd9'},{'\xcb','\xb3'},{'\xcb','\xb5'},
+ {'\xa8','\xdb'},{'\xa8','\xcf'},{'\xcb','\xb6'},{'\xcb','\xc2'},{'\xcb','\xc9'},
+ {'\xa8','\xd4'},{'\xcb','\xbb'},{'\xcb','\xb4'},{'\xa8','\xd3'},{'\xcb','\xb7'},
+ {'\xa8','\xd7'},{'\xcb','\xba'},{'\x81','\x4b'},{'\xa8','\xd2'},{'\x00','\x00'},
+ {'\xa8','\xcd'},{'\x00','\x00'},{'\xa8','\xdc'},{'\xcb','\xc4'},{'\xa8','\xdd'},
+ {'\xcb','\xc8'},{'\x00','\x00'},{'\xcb','\xc6'},{'\xcb','\xca'},{'\xa8','\xda'},
+ {'\xcb','\xbe'},{'\xcb','\xb2'},{'\x00','\x00'},{'\xcb','\xc0'},{'\xa8','\xd1'},
+ {'\xcb','\xc5'},{'\xa8','\xcc'},{'\xcb','\xc7'},{'\x00','\x00'},{'\x83','\x65'},
+ {'\x92','\x55'},{'\x98','\xb6'},{'\x83','\x66'},{'\x00','\x00'},{'\x86','\xab'},
+ {'\x83','\xed'},{'\x83','\xee'},{'\x86','\xac'},{'\x87','\xa7'},{'\x88','\xca'},
+ {'\xfb','\xbe'},{'\x87','\xa6'},{'\x82','\x7d'},{'\xab','\x56'},{'\xab','\x4a'},
+ {'\x98','\xb7'},{'\x00','\x00'},{'\xcd','\xe0'},{'\xcd','\xe8'},{'\x98','\xf7'},
+ {'\xab','\x49'},{'\xab','\x51'},{'\xab','\x5d'},{'\x00','\x00'},{'\xcd','\xee'},
+ {'\xcd','\xec'},{'\xcd','\xe7'},{'\x00','\x00'},{'\x98','\xb8'},{'\x00','\x00'},
+ {'\xab','\x4b'},{'\xcd','\xed'},{'\xcd','\xe3'},{'\xab','\x59'},{'\xab','\x50'},
+ {'\xab','\x58'},{'\xcd','\xde'},{'\x00','\x00'},{'\xcd','\xea'},{'\x98','\xb9'},
+ {'\xcd','\xe1'},{'\xab','\x54'},{'\xcd','\xe2'},{'\x98','\xba'},{'\xcd','\xdd'},
+ {'\xab','\x5b'},{'\xab','\x4e'},{'\xab','\x57'},{'\xab','\x4d'},{'\x00','\x00'},
+ {'\xcd','\xdf'},{'\xcd','\xe4'},{'\x00','\x00'},{'\xcd','\xeb'},{'\xab','\x55'},
+ {'\xab','\x52'},{'\xcd','\xe6'},{'\xab','\x5a'},{'\xcd','\xe9'},{'\xcd','\xe5'},
+ {'\xab','\x4f'},{'\xab','\x5c'},{'\xab','\x53'},{'\xab','\x4c'},{'\xab','\x48'},
+ {'\x00','\x00'},{'\x8d','\xb9'},{'\x94','\x5f'},{'\x94','\x60'},{'\x88','\xc8'},
+ {'\x00','\x00'},{'\x8c','\xc8'},{'\x83','\xa7'},{'\x8c','\x6c'},{'\x00','\x00'},
+ {'\xcd','\xef'},{'\x87','\xa8'},{'\xad','\xd7'},{'\xad','\xc1'},{'\x98','\xbb'},
+ {'\xad','\xd1'},{'\x98','\xbc'},{'\xad','\xd6'},{'\xd0','\xd0'},{'\xd0','\xcf'},
+ {'\xd0','\xd4'},{'\xd0','\xd5'},{'\xad','\xc4'},{'\x98','\xbd'},{'\xad','\xcd'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xfe','\x7b'},{'\xad','\xda'},{'\x81','\x4c'},
+ {'\xad','\xce'},{'\x00','\x00'},{'\x00','\x00'},{'\x98','\xbe'},{'\x00','\x00'},
+ {'\xd0','\xc9'},{'\xad','\xc7'},{'\xd0','\xca'},{'\x98','\xbf'},{'\xad','\xdc'},
+ {'\x00','\x00'},{'\xad','\xd3'},{'\xad','\xbe'},{'\xad','\xbf'},{'\xd0','\xdd'},
+ {'\xb0','\xbf'},{'\x00','\x00'},{'\xad','\xcc'},{'\xad','\xcb'},{'\xd0','\xcb'},
+ {'\xad','\xcf'},{'\xd4','\x5b'},{'\xad','\xc6'},{'\xd0','\xd6'},{'\xad','\xd5'},
+ {'\xad','\xd4'},{'\xad','\xca'},{'\xd0','\xce'},{'\xd0','\xd7'},{'\x00','\x00'},
+ {'\xd0','\xc8'},{'\xad','\xc9'},{'\xd0','\xd8'},{'\xad','\xd2'},{'\xd0','\xcc'},
+ {'\xad','\xc0'},{'\x82','\xa9'},{'\xad','\xc3'},{'\xad','\xc2'},{'\xd0','\xd9'},
+ {'\xad','\xd0'},{'\xad','\xc5'},{'\xad','\xd9'},{'\xad','\xdb'},{'\xd0','\xd3'},
+ {'\xad','\xd8'},{'\xfb','\xc1'},{'\xd0','\xdb'},{'\xd0','\xcd'},{'\xd0','\xdc'},
+ {'\x00','\x00'},{'\xd0','\xd1'},{'\x98','\xc0'},{'\xd0','\xda'},{'\x82','\xa3'},
+ {'\xd0','\xd2'},{'\x00','\x00'},{'\x92','\xb2'},{'\x85','\xb0'},{'\x98','\xc1'},
+ {'\xad','\xc8'},{'\x00','\x00'},{'\x85','\xb3'},{'\x00','\x00'},{'\xd4','\x63'},
+ {'\xd4','\x57'},{'\x81','\x4d'},{'\xb0','\xb3'},{'\x00','\x00'},{'\xd4','\x5c'},
+ {'\xd4','\x62'},{'\xb0','\xb2'},{'\xd4','\x55'},{'\xb0','\xb6'},{'\xd4','\x59'},
+ {'\xd4','\x52'},{'\xb0','\xb4'},{'\xd4','\x56'},{'\xb0','\xb9'},{'\xb0','\xbe'},
+ {'\x81','\x4e'},{'\xd4','\x67'},{'\x00','\x00'},{'\xd4','\x51'},{'\x00','\x00'},
+ {'\xb0','\xba'},{'\xfb','\xbf'},{'\xd4','\x66'},{'\x98','\xc2'},{'\x00','\x00'},
+ {'\xb0','\xb5'},{'\xd4','\x58'},{'\xb0','\xb1'},{'\xd4','\x53'},{'\xd4','\x4f'},
+ {'\xd4','\x5d'},{'\xd4','\x50'},{'\xd4','\x4e'},{'\xd4','\x5a'},{'\xd4','\x60'},
+ {'\xd4','\x61'},{'\xb0','\xb7'},{'\x98','\xc3'},{'\x00','\x00'},{'\xd8','\x5b'},
+ {'\xd4','\x5e'},{'\xd4','\x4d'},{'\xd4','\x5f'},{'\x85','\xb5'},{'\xb0','\xc1'},
+ {'\xd4','\x64'},{'\xb0','\xc0'},{'\xd4','\x4c'},{'\x00','\x00'},{'\xd4','\x54'},
+ {'\xd4','\x65'},{'\xb0','\xbc'},{'\xb0','\xbb'},{'\xb0','\xb8'},{'\xb0','\xbd'},
+ {'\x81','\x4f'},{'\x00','\x00'},{'\xb0','\xaf'},{'\x8d','\xfe'},{'\x00','\x00'},
+ {'\xb0','\xb0'},{'\x8e','\x65'},{'\x89','\xc8'},{'\xb3','\xc8'},{'\x98','\xc4'},
+ {'\xd8','\x5e'},{'\xd8','\x57'},{'\x00','\x00'},{'\xb3','\xc5'},{'\x00','\x00'},
+ {'\xd8','\x5f'},{'\x90','\xf0'},{'\x00','\x00'},{'\x00','\x00'},{'\xd8','\x55'},
+ {'\xd8','\x58'},{'\xb3','\xc4'},{'\xd8','\x59'},{'\x00','\x00'},{'\x98','\xc5'},
+ {'\xb3','\xc7'},{'\xd8','\x5d'},{'\x00','\x00'},{'\xd8','\x53'},{'\xd8','\x52'},
+ {'\xb3','\xc9'},{'\x00','\x00'},{'\xb3','\xca'},{'\xb3','\xc6'},{'\xb3','\xcb'},
+ {'\xd8','\x51'},{'\xd8','\x5c'},{'\xd8','\x5a'},{'\xd8','\x54'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xb3','\xc3'},{'\xd8','\x56'},{'\x00','\x00'},
+ {'\x8c','\xc9'},{'\xfb','\xc2'},{'\x88','\xc9'},{'\x89','\xc9'},{'\x8f','\xfb'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xb6','\xca'},{'\xb6','\xc4'},{'\xdc','\xb7'},
+ {'\xb6','\xcd'},{'\xdc','\xbd'},{'\xdc','\xc0'},{'\xb6','\xc6'},{'\xb6','\xc7'},
+ {'\xdc','\xba'},{'\xb6','\xc5'},{'\xdc','\xc3'},{'\xb6','\xcb'},{'\xdc','\xc4'},
+ {'\x00','\x00'},{'\xdc','\xbf'},{'\xb6','\xcc'},{'\x98','\xc6'},{'\xdc','\xb4'},
+ {'\xb6','\xc9'},{'\xdc','\xb5'},{'\x00','\x00'},{'\xdc','\xbe'},{'\xdc','\xbc'},
+ {'\x00','\x00'},{'\xdc','\xb8'},{'\xb6','\xc8'},{'\xdc','\xb6'},{'\xb6','\xce'},
+ {'\xdc','\xbb'},{'\xdc','\xc2'},{'\xdc','\xb9'},{'\xdc','\xc1'},{'\x00','\x00'},
+ {'\x94','\x4f'},{'\xb9','\xb6'},{'\xb9','\xb3'},{'\x98','\xc7'},{'\xb9','\xb4'},
+ {'\x00','\x00'},{'\xe0','\xf9'},{'\xe0','\xf1'},{'\xb9','\xb2'},{'\xb9','\xaf'},
+ {'\xe0','\xf2'},{'\x81','\x50'},{'\xfb','\xc3'},{'\xb9','\xb1'},{'\xe0','\xf5'},
+ {'\x00','\x00'},{'\xe0','\xf7'},{'\x81','\x51'},{'\x98','\xc8'},{'\xe0','\xfe'},
+ {'\x98','\xc9'},{'\x00','\x00'},{'\xe0','\xfd'},{'\xe0','\xf8'},{'\xb9','\xae'},
+ {'\xe0','\xf0'},{'\xb9','\xac'},{'\xe0','\xf3'},{'\xb9','\xb7'},{'\xe0','\xf6'},
+ {'\x00','\x00'},{'\xe0','\xfa'},{'\xb9','\xb0'},{'\xb9','\xad'},{'\xe0','\xfc'},
+ {'\xe0','\xfb'},{'\xb9','\xb5'},{'\x00','\x00'},{'\xe0','\xf4'},{'\x81','\x52'},
+ {'\xbb','\xf8'},{'\xe4','\xec'},{'\x00','\x00'},{'\xe4','\xe9'},{'\xbb','\xf9'},
+ {'\x00','\x00'},{'\xbb','\xf7'},{'\x98','\xca'},{'\xe4','\xf0'},{'\xe4','\xed'},
+ {'\xe4','\xe6'},{'\xbb','\xf6'},{'\xfb','\xc6'},{'\xbb','\xfa'},{'\xe4','\xe7'},
+ {'\xbb','\xf5'},{'\xbb','\xfd'},{'\xe4','\xea'},{'\xe4','\xeb'},{'\xbb','\xfb'},
+ {'\xbb','\xfc'},{'\xe4','\xf1'},{'\xe4','\xee'},{'\xe4','\xef'},{'\x98','\xcb'},
+ {'\xfb','\xc4'},{'\x00','\x00'},{'\xbe','\xaa'},{'\xe8','\xf8'},{'\xbe','\xa7'},
+ {'\xe8','\xf5'},{'\xbe','\xa9'},{'\xbe','\xab'},{'\x81','\x53'},{'\xe8','\xf6'},
+ {'\xbe','\xa8'},{'\x00','\x00'},{'\xe8','\xf7'},{'\x00','\x00'},{'\xe8','\xf4'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc0','\x76'},{'\xec','\xbd'},{'\xc0','\x77'},
+ {'\xec','\xbb'},{'\x00','\x00'},{'\xec','\xbc'},{'\xec','\xba'},{'\xec','\xb9'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xec','\xbe'},{'\xc0','\x75'},{'\x98','\xcc'},
+ {'\x00','\x00'},{'\xef','\xb8'},{'\xef','\xb9'},{'\x00','\x00'},{'\xe4','\xe8'},
+ {'\xef','\xb7'},{'\xc0','\x78'},{'\xc3','\x5f'},{'\xf1','\xeb'},{'\xf1','\xec'},
+ {'\x00','\x00'},{'\xc4','\xd7'},{'\xc4','\xd8'},{'\xf5','\xc1'},{'\xf5','\xc0'},
+ {'\xc5','\x6c'},{'\xc5','\x6b'},{'\xf7','\xd0'},{'\x00','\x00'},{'\xa4','\x49'},
+ {'\xa4','\x61'},{'\xa4','\xb9'},{'\x00','\x00'},{'\xa4','\xb8'},{'\xa5','\x53'},
+ {'\xa5','\x52'},{'\xa5','\xfc'},{'\xa5','\xfb'},{'\xa5','\xfd'},{'\xa5','\xfa'},
+ {'\x81','\x54'},{'\xa7','\x4a'},{'\xa7','\x49'},{'\xa7','\x4b'},{'\x95','\xfc'},
+ {'\x00','\x00'},{'\x92','\xd1'},{'\x81','\x55'},{'\xa8','\xe0'},{'\x00','\x00'},
+ {'\xa8','\xdf'},{'\xa8','\xe1'},{'\x83','\x67'},{'\xab','\x5e'},{'\x00','\x00'},
+ {'\xa2','\x59'},{'\xd0','\xde'},{'\xa2','\x5a'},{'\xb0','\xc2'},{'\xa2','\x5c'},
+ {'\xa2','\x5b'},{'\xd8','\x60'},{'\x98','\xcd'},{'\xa2','\x5d'},{'\xb9','\xb8'},
+ {'\xa2','\x5e'},{'\x81','\x56'},{'\xa4','\x4a'},{'\x00','\x00'},{'\xa4','\xba'},
+ {'\xa5','\xfe'},{'\xa8','\xe2'},{'\x81','\x57'},{'\xa4','\x4b'},{'\xa4','\xbd'},
+ {'\xa4','\xbb'},{'\xa4','\xbc'},{'\x00','\x00'},{'\x8c','\xa3'},{'\xa6','\x40'},
+ {'\x00','\x00'},{'\x8b','\xd7'},{'\x89','\x55'},{'\xa7','\x4c'},{'\xa8','\xe4'},
+ {'\xa8','\xe3'},{'\xa8','\xe5'},{'\x90','\xbc'},{'\x00','\x00'},{'\x88','\xb5'},
+ {'\xad','\xdd'},{'\x8b','\xa6'},{'\x00','\x00'},{'\x00','\x00'},{'\xbe','\xac'},
+ {'\x90','\x54'},{'\xc6','\xc3'},{'\x00','\x00'},{'\x00','\x00'},{'\x81','\x58'},
+ {'\x92','\x4c'},{'\xc9','\x4e'},{'\x83','\x58'},{'\xa5','\x54'},{'\xa5','\x55'},
+ {'\x00','\x00'},{'\x95','\xe4'},{'\xa6','\x41'},{'\x00','\x00'},{'\xca','\x6a'},
+ {'\x81','\x59'},{'\xab','\x60'},{'\xab','\x5f'},{'\xd0','\xe0'},{'\xd0','\xdf'},
+ {'\xb0','\xc3'},{'\xc6','\xc4'},{'\xa4','\xbe'},{'\xc9','\x55'},{'\x87','\xc0'},
+ {'\xfb','\x41'},{'\x83','\x7e'},{'\x86','\x61'},{'\x81','\x5a'},{'\xcb','\xcd'},
+ {'\x00','\x00'},{'\xab','\x61'},{'\x00','\x00'},{'\xad','\xe0'},{'\x00','\x00'},
+ {'\xad','\xde'},{'\xad','\xdf'},{'\x81','\x5b'},{'\xfb','\x4e'},{'\x81','\x5c'},
+ {'\x81','\x5d'},{'\xbe','\xad'},{'\xc6','\xc5'},{'\xa5','\x56'},{'\x00','\x00'},
+ {'\x98','\xce'},{'\x85','\xad'},{'\xa6','\x42'},{'\xc9','\xbc'},{'\x83','\x4c'},
+ {'\x83','\x4b'},{'\x94','\xfb'},{'\x95','\xd5'},{'\xa7','\x4d'},{'\xa7','\x4e'},
+ {'\x98','\xcf'},{'\xca','\x6b'},{'\x00','\x00'},{'\x83','\xad'},{'\xcb','\xce'},
+ {'\xa8','\xe6'},{'\xcb','\xcf'},{'\x00','\x00'},{'\x84','\x60'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x95','\xf3'},{'\xd0','\xe2'},{'\xd0','\xe3'},{'\xad','\xe3'},
+ {'\x81','\x5e'},{'\xd0','\xe4'},{'\x84','\x5b'},{'\xd0','\xe1'},{'\xad','\xe4'},
+ {'\xad','\xe2'},{'\xad','\xe1'},{'\xd0','\xe5'},{'\x90','\xb6'},{'\xd4','\x68'},
+ {'\x84','\xee'},{'\x98','\xd0'},{'\xfb','\xcf'},{'\xd8','\x61'},{'\x00','\x00'},
+ {'\x81','\x5f'},{'\xdc','\xc5'},{'\xe1','\x40'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x81','\x60'},{'\xbb','\xfe'},{'\xbe','\xae'},{'\xe8','\xf9'},{'\xfb','\xd0'},
+ {'\xa4','\x4c'},{'\xa4','\x5a'},{'\x98','\xd1'},{'\x00','\x00'},{'\x87','\xa1'},
+ {'\x00','\x00'},{'\x92','\xe1'},{'\x94','\x4c'},{'\x00','\x00'},{'\x94','\x61'},
+ {'\x94','\x52'},{'\x8e','\x63'},{'\x81','\x61'},{'\x88','\xd7'},{'\x00','\x00'},
+ {'\x84','\xc5'},{'\xb0','\xc4'},{'\xb3','\xcd'},{'\x00','\x00'},{'\xb9','\xb9'},
+ {'\xfb','\xc7'},{'\xc9','\x42'},{'\xa4','\xbf'},{'\x00','\x00'},{'\xa5','\x59'},
+ {'\xa5','\x57'},{'\xa5','\x58'},{'\x89','\xdb'},{'\x81','\x62'},{'\xa8','\xe7'},
+ {'\xfb','\xd2'},{'\x8d','\xad'},{'\xa4','\x4d'},{'\xa4','\x4e'},{'\xc8','\x7d'},
+ {'\xa4','\x62'},{'\x95','\xcf'},{'\x98','\xd2'},{'\xa4','\xc0'},{'\xa4','\xc1'},
+ {'\xa4','\xc2'},{'\xc9','\xbe'},{'\xa5','\x5a'},{'\x81','\x63'},{'\xc9','\x6b'},
+ {'\x83','\xd2'},{'\xa6','\x46'},{'\x00','\x00'},{'\xc9','\xbf'},{'\xa6','\x44'},
+ {'\xa6','\x45'},{'\xc9','\xbd'},{'\x81','\x64'},{'\x81','\x65'},{'\xa6','\x47'},
+ {'\xa6','\x43'},{'\x87','\xaa'},{'\x83','\x68'},{'\x83','\xae'},{'\x84','\xc7'},
+ {'\xca','\x6c'},{'\xaa','\xec'},{'\xca','\x6d'},{'\xfb','\xc8'},{'\x81','\x66'},
+ {'\xca','\x6e'},{'\x00','\x00'},{'\xa0','\x7e'},{'\xa7','\x50'},{'\xa7','\x4f'},
+ {'\x95','\x7b'},{'\x95','\xe5'},{'\xa7','\x53'},{'\xa7','\x51'},{'\xa7','\x52'},
+ {'\x81','\x67'},{'\x00','\x00'},{'\x8d','\xba'},{'\xa8','\xed'},{'\x00','\x00'},
+ {'\xa8','\xec'},{'\xcb','\xd4'},{'\xcb','\xd1'},{'\xcb','\xd2'},{'\x98','\xd3'},
+ {'\xcb','\xd0'},{'\xa8','\xee'},{'\xa8','\xea'},{'\xa8','\xe9'},{'\x81','\x68'},
+ {'\xa8','\xeb'},{'\xa8','\xe8'},{'\x98','\xd4'},{'\x87','\xac'},{'\x00','\x00'},
+ {'\x8e','\xaf'},{'\x84','\xc6'},{'\xa8','\xef'},{'\x88','\xcc'},{'\xab','\x63'},
+ {'\xcd','\xf0'},{'\x00','\x00'},{'\xcb','\xd3'},{'\xab','\x68'},{'\x00','\x00'},
+ {'\xcd','\xf1'},{'\xab','\x64'},{'\xab','\x67'},{'\xab','\x66'},{'\xab','\x65'},
+ {'\xab','\x62'},{'\x81','\x69'},{'\x8d','\xc8'},{'\x87','\xab'},{'\xd0','\xe8'},
+ {'\x00','\x00'},{'\xad','\xe7'},{'\xd0','\xeb'},{'\xad','\xe5'},{'\xfb','\xca'},
+ {'\x00','\x00'},{'\x98','\xd5'},{'\xd0','\xe7'},{'\xad','\xe8'},{'\xad','\xe6'},
+ {'\xad','\xe9'},{'\xd0','\xe9'},{'\xd0','\xea'},{'\xfb','\xc9'},{'\xd0','\xe6'},
+ {'\xd0','\xec'},{'\x92','\xb3'},{'\x92','\xc9'},{'\x82','\x76'},{'\x00','\x00'},
+ {'\x87','\xa9'},{'\x98','\xd6'},{'\xb3','\xd1'},{'\xb0','\xc5'},{'\xd4','\x69'},
+ {'\xd4','\x6b'},{'\xd4','\x6a'},{'\xd4','\x6c'},{'\xb0','\xc6'},{'\x92','\xeb'},
+ {'\x81','\x6a'},{'\xb3','\xce'},{'\xfc','\xf5'},{'\xb3','\xcf'},{'\xb3','\xd0'},
+ {'\x00','\x00'},{'\xb6','\xd0'},{'\xdc','\xc7'},{'\x98','\xd7'},{'\xdc','\xc6'},
+ {'\xdc','\xc8'},{'\xdc','\xc9'},{'\xb6','\xd1'},{'\x00','\x00'},{'\xb6','\xcf'},
+ {'\xe1','\x41'},{'\xe1','\x42'},{'\xb9','\xbb'},{'\xb9','\xba'},{'\xe3','\x5a'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xbc','\x40'},{'\xbc','\x41'},{'\xbc','\x42'},
+ {'\xbc','\x44'},{'\xe4','\xf2'},{'\xe4','\xf3'},{'\xbc','\x43'},{'\x00','\x00'},
+ {'\xfb','\x69'},{'\x81','\x6b'},{'\xbe','\xaf'},{'\x81','\x6c'},{'\xbe','\xb0'},
+ {'\x81','\x6d'},{'\x00','\x00'},{'\xf1','\xed'},{'\xf5','\xc3'},{'\xf5','\xc2'},
+ {'\xf7','\xd1'},{'\xfb','\xcb'},{'\xa4','\x4f'},{'\x81','\x6e'},{'\x8b','\xef'},
+ {'\x89','\x74'},{'\xa5','\x5c'},{'\xa5','\x5b'},{'\x83','\xef'},{'\x8e','\xb0'},
+ {'\xa6','\x48'},{'\x98','\xd8'},{'\x00','\x00'},{'\xc9','\xc0'},{'\x00','\x00'},
+ {'\x83','\xf0'},{'\xa7','\x55'},{'\xa7','\x56'},{'\xa7','\x54'},{'\xa7','\x57'},
+ {'\xca','\x6f'},{'\xca','\x70'},{'\x81','\x6f'},{'\x00','\x00'},{'\x89','\xca'},
+ {'\x83','\x69'},{'\x84','\xc8'},{'\x93','\xf5'},{'\x81','\x70'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x95','\xa2'},{'\x00','\x00'},{'\xa8','\xf1'},
+ {'\xcb','\xd5'},{'\x00','\x00'},{'\xa8','\xf0'},{'\x85','\xb7'},{'\xcd','\xf2'},
+ {'\xab','\x6c'},{'\xcd','\xf3'},{'\xab','\x6b'},{'\x00','\x00'},{'\x95','\x44'},
+ {'\x00','\x00'},{'\xab','\x69'},{'\x00','\x00'},{'\xab','\x6a'},{'\x00','\x00'},
+ {'\x84','\xc9'},{'\x98','\xd9'},{'\xd0','\xed'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x81','\x71'},{'\xfb','\xcc'},{'\xb0','\xc7'},{'\xd4','\x6e'},{'\x00','\x00'},
+ {'\xb0','\xca'},{'\xd4','\x6d'},{'\xb1','\xe5'},{'\xb0','\xc9'},{'\xb0','\xc8'},
+ {'\x00','\x00'},{'\xb3','\xd4'},{'\x00','\x00'},{'\xb3','\xd3'},{'\xb3','\xd2'},
+ {'\xb6','\xd2'},{'\xfb','\xcd'},{'\xfb','\xce'},{'\xb6','\xd5'},{'\xb6','\xd6'},
+ {'\xb6','\xd4'},{'\x00','\x00'},{'\xb6','\xd3'},{'\x92','\x68'},{'\x00','\x00'},
+ {'\xe1','\x43'},{'\x00','\x00'},{'\xe1','\x44'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xe4','\xf5'},{'\xbc','\x45'},{'\xe4','\xf4'},{'\x92','\xa4'},
+ {'\xbe','\xb1'},{'\xec','\xbf'},{'\xc0','\x79'},{'\x00','\x00'},{'\xf1','\xee'},
+ {'\xc4','\x55'},{'\xc6','\xc6'},{'\xa4','\x63'},{'\xa4','\xc3'},{'\xc9','\x56'},
+ {'\x00','\x00'},{'\xa4','\xc4'},{'\xa4','\xc5'},{'\x81','\x72'},{'\x94','\x5e'},
+ {'\x94','\x53'},{'\x9c','\xd0'},{'\x00','\x00'},{'\xa5','\x5d'},{'\xa5','\x5e'},
+ {'\x81','\x73'},{'\xa6','\x49'},{'\xca','\x71'},{'\xcb','\xd6'},{'\xcb','\xd7'},
+ {'\x00','\x00'},{'\xab','\x6d'},{'\xd0','\xee'},{'\xb0','\xcc'},{'\xb0','\xcb'},
+ {'\xd8','\x63'},{'\xd8','\x62'},{'\x00','\x00'},{'\x00','\x00'},{'\xa4','\x50'},
+ {'\xa4','\xc6'},{'\xa5','\x5f'},{'\x00','\x00'},{'\xb0','\xcd'},{'\xc9','\x43'},
+ {'\x00','\x00'},{'\xc9','\x6c'},{'\xa5','\x60'},{'\x00','\x00'},{'\xc9','\xc2'},
+ {'\xa6','\x4b'},{'\xa6','\x4a'},{'\xc9','\xc1'},{'\xa7','\x58'},{'\x81','\x74'},
+ {'\x00','\x00'},{'\x8d','\xc9'},{'\x98','\xda'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xad','\xea'},{'\x00','\x00'},{'\xfb','\xd4'},{'\xd4','\x6f'},{'\x86','\xad'},
+ {'\xb6','\xd7'},{'\xe1','\x45'},{'\xb9','\xbc'},{'\xfb','\xd3'},{'\xfb','\xd5'},
+ {'\xe8','\xfa'},{'\x00','\x00'},{'\x00','\x00'},{'\xf3','\xfd'},{'\xc6','\xc7'},
+ {'\xa4','\xc7'},{'\x83','\xf1'},{'\x8b','\x4b'},{'\xcb','\xd8'},{'\xcd','\xf4'},
+ {'\xb0','\xd0'},{'\xb0','\xce'},{'\xb0','\xcf'},{'\xa4','\x51'},{'\x98','\xdb'},
+ {'\xa4','\x64'},{'\xa2','\xcd'},{'\xa4','\xca'},{'\x81','\x75'},{'\xa4','\xc9'},
+ {'\xa4','\xc8'},{'\xa5','\x63'},{'\xa5','\x62'},{'\x00','\x00'},{'\xc9','\x6d'},
+ {'\xc9','\xc3'},{'\x85','\x4f'},{'\x83','\x56'},{'\x00','\x00'},{'\xa8','\xf5'},
+ {'\xa8','\xf2'},{'\xa8','\xf4'},{'\xa8','\xf3'},{'\x84','\xcb'},{'\x88','\x6f'},
+ {'\xab','\x6e'},{'\x93','\x6d'},{'\x00','\x00'},{'\xb3','\xd5'},{'\x00','\x00'},
+ {'\xa4','\x52'},{'\x98','\xdc'},{'\xa4','\xcb'},{'\x81','\x76'},{'\xa5','\x65'},
+ {'\xa5','\x64'},{'\x89','\x41'},{'\xca','\x72'},{'\x84','\xc0'},{'\x00','\x00'},
+ {'\xa8','\xf6'},{'\x83','\x60'},{'\x00','\x00'},{'\xc6','\xc8'},{'\x00','\x00'},
+ {'\x88','\x55'},{'\xc9','\x57'},{'\x95','\xf2'},{'\xa5','\x67'},{'\xa5','\x66'},
+ {'\xa6','\x4c'},{'\xa6','\x4d'},{'\xca','\x73'},{'\xa7','\x59'},{'\x83','\x6a'},
+ {'\xa7','\x5a'},{'\x00','\x00'},{'\xa8','\xf7'},{'\xa8','\xf8'},{'\xa8','\xf9'},
+ {'\x8d','\xbd'},{'\xab','\x6f'},{'\xcd','\xf5'},{'\x98','\xdd'},{'\x98','\xde'},
+ {'\xad','\xeb'},{'\x00','\x00'},{'\x00','\x00'},{'\xc9','\x44'},{'\x00','\x00'},
+ {'\xa4','\xcc'},{'\x8d','\x6d'},{'\x88','\xe5'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x87','\xad'},{'\xc9','\xc4'},{'\x89','\xcd'},{'\x86','\xae'},{'\x8d','\xbb'},
+ {'\xca','\x74'},{'\xca','\x75'},{'\x00','\x00'},{'\x00','\x00'},{'\xcb','\xd9'},
+ {'\x81','\x77'},{'\xcb','\xda'},{'\x84','\xda'},{'\xcd','\xf7'},{'\xcd','\xf6'},
+ {'\xcd','\xf9'},{'\xcd','\xf8'},{'\xab','\x70'},{'\x00','\x00'},{'\xd4','\x70'},
+ {'\xad','\xed'},{'\xd0','\xef'},{'\xad','\xec'},{'\x95','\xe8'},{'\x00','\x00'},
+ {'\x95','\xe9'},{'\x8f','\xb6'},{'\xd8','\x64'},{'\xb3','\xd6'},{'\x95','\x7a'},
+ {'\xd8','\x65'},{'\x87','\xc5'},{'\x84','\xdb'},{'\xfb','\xd7'},{'\xfb','\xd6'},
+ {'\xe1','\x46'},{'\xb9','\xbd'},{'\x87','\xc7'},{'\x00','\x00'},{'\x81','\x78'},
+ {'\x00','\x00'},{'\xbc','\x46'},{'\x92','\xba'},{'\xf1','\xef'},{'\x00','\x00'},
+ {'\xc6','\xc9'},{'\x00','\x00'},{'\x00','\x00'},{'\xc9','\x58'},{'\x00','\x00'},
+ {'\xa5','\x68'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x89','\x4f'},
+ {'\x00','\x00'},{'\x95','\x48'},{'\x83','\xf2'},{'\xb0','\xd1'},{'\x00','\x00'},
+ {'\x98','\xdf'},{'\x00','\x00'},{'\x00','\x00'},{'\xa4','\x53'},{'\xa4','\x65'},
+ {'\xa4','\xce'},{'\xa4','\xcd'},{'\x8b','\x5a'},{'\xa4','\xcf'},{'\x83','\x42'},
+ {'\x00','\x00'},{'\x98','\xe0'},{'\x84','\xfa'},{'\x98','\xe1'},{'\x00','\x00'},
+ {'\xa8','\xfb'},{'\x00','\x00'},{'\xa8','\xfa'},{'\xa8','\xfc'},{'\x8d','\x40'},
+ {'\x95','\xb3'},{'\xfb','\xdb'},{'\xab','\x71'},{'\x00','\x00'},{'\x81','\x79'},
+ {'\x00','\x00'},{'\xad','\xee'},{'\x8c','\xd4'},{'\xe8','\xfb'},{'\xc2','\x4f'},
+ {'\xa4','\x66'},{'\xa5','\x6a'},{'\xa5','\x79'},{'\xa5','\x74'},{'\x00','\x00'},
+ {'\xa5','\x6f'},{'\xa5','\x6e'},{'\xa5','\x75'},{'\xa5','\x73'},{'\xa5','\x6c'},
+ {'\xa5','\x7a'},{'\xa5','\x6d'},{'\xa5','\x69'},{'\xa5','\x78'},{'\xa5','\x77'},
+ {'\xa5','\x76'},{'\xa5','\x6b'},{'\x00','\x00'},{'\xa5','\x72'},{'\x85','\xfc'},
+ {'\x86','\x41'},{'\xa5','\x71'},{'\x86','\xb1'},{'\x94','\x62'},{'\xa5','\x7b'},
+ {'\xa5','\x70'},{'\x87','\xb4'},{'\x98','\xe2'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xa6','\x53'},{'\x00','\x00'},{'\xa6','\x59'},{'\xa6','\x55'},{'\x00','\x00'},
+ {'\xa6','\x5b'},{'\xc9','\xc5'},{'\xa6','\x58'},{'\xa6','\x4e'},{'\xa6','\x51'},
+ {'\xa6','\x54'},{'\xa6','\x50'},{'\xa6','\x57'},{'\xa6','\x5a'},{'\xa6','\x4f'},
+ {'\xa6','\x52'},{'\xa6','\x56'},{'\xa6','\x5c'},{'\x89','\xcc'},{'\xfb','\x43'},
+ {'\x90','\xb8'},{'\xfb','\x42'},{'\x85','\xba'},{'\xca','\x7e'},{'\xca','\x7b'},
+ {'\xa0','\x55'},{'\xa7','\x67'},{'\xca','\x7c'},{'\xa7','\x5b'},{'\xa7','\x5d'},
+ {'\xa7','\x75'},{'\xa7','\x70'},{'\x96','\xb2'},{'\x00','\x00'},{'\x81','\x7a'},
+ {'\xca','\xa5'},{'\xca','\x7d'},{'\xa7','\x5f'},{'\xa7','\x61'},{'\xca','\xa4'},
+ {'\xa7','\x68'},{'\xca','\x78'},{'\xa7','\x74'},{'\xa7','\x76'},{'\xa7','\x5c'},
+ {'\xa7','\x6d'},{'\x84','\x51'},{'\xca','\x76'},{'\xa7','\x73'},{'\x96','\xb4'},
+ {'\xa7','\x64'},{'\x83','\x45'},{'\xa7','\x6e'},{'\xa7','\x6f'},{'\xca','\x77'},
+ {'\xa7','\x6c'},{'\xa7','\x6a'},{'\x00','\x00'},{'\xa7','\x6b'},{'\xa7','\x71'},
+ {'\xca','\xa1'},{'\xa7','\x5e'},{'\x00','\x00'},{'\xa7','\x72'},{'\xca','\xa3'},
+ {'\xa7','\x66'},{'\xa7','\x63'},{'\x00','\x00'},{'\xca','\x7a'},{'\xa7','\x62'},
+ {'\xca','\xa6'},{'\xa7','\x65'},{'\x92','\xbb'},{'\xa7','\x69'},{'\x96','\xa4'},
+ {'\x00','\x00'},{'\xa0','\x5a'},{'\xa7','\x60'},{'\xca','\xa2'},{'\x81','\x7b'},
+ {'\x81','\x7c'},{'\x8e','\xb2'},{'\x8c','\xca'},{'\xca','\x79'},{'\x86','\xb0'},
+ {'\x8f','\xb7'},{'\x8d','\xc2'},{'\x83','\xb0'},{'\x8d','\xbc'},{'\x00','\x00'},
+ {'\x85','\xbc'},{'\x85','\xbb'},{'\x00','\x00'},{'\x00','\x00'},{'\x82','\xaf'},
+ {'\xcb','\xeb'},{'\xcb','\xea'},{'\xa9','\x4f'},{'\xcb','\xed'},{'\xcb','\xef'},
+ {'\xcb','\xe4'},{'\xcb','\xe7'},{'\xcb','\xee'},{'\xa9','\x50'},{'\xfb','\xd9'},
+ {'\x94','\xfc'},{'\xcb','\xe1'},{'\xcb','\xe5'},{'\x98','\xe3'},{'\x00','\x00'},
+ {'\xcb','\xe9'},{'\xce','\x49'},{'\xa9','\x4b'},{'\xce','\x4d'},{'\xa8','\xfd'},
+ {'\xcb','\xe6'},{'\xa8','\xfe'},{'\xa9','\x4c'},{'\xa9','\x45'},{'\xa9','\x41'},
+ {'\x00','\x00'},{'\xcb','\xe2'},{'\xa9','\x44'},{'\xa9','\x49'},{'\xa9','\x52'},
+ {'\xcb','\xe3'},{'\xcb','\xdc'},{'\xa9','\x43'},{'\xcb','\xdd'},{'\xcb','\xdf'},
+ {'\x00','\x00'},{'\xa9','\x46'},{'\x98','\xe4'},{'\xa9','\x48'},{'\xcb','\xdb'},
+ {'\xcb','\xe0'},{'\x00','\x00'},{'\x81','\x7d'},{'\xa9','\x51'},{'\xa9','\x4d'},
+ {'\xcb','\xe8'},{'\xa9','\x53'},{'\x95','\xa3'},{'\xa9','\x4a'},{'\xcb','\xde'},
+ {'\xa9','\x47'},{'\x98','\xe5'},{'\x96','\xb6'},{'\xa9','\x42'},{'\xa9','\x40'},
+ {'\xa0','\x57'},{'\xcb','\xec'},{'\x8b','\xf0'},{'\xa9','\x4e'},{'\x89','\xcb'},
+ {'\xfb','\xda'},{'\x81','\x7e'},{'\x98','\xe6'},{'\x00','\x00'},{'\xce','\x48'},
+ {'\xcd','\xfb'},{'\xce','\x4b'},{'\x81','\xa1'},{'\x95','\x79'},{'\xcd','\xfd'},
+ {'\xab','\x78'},{'\xab','\xa8'},{'\xab','\x74'},{'\xab','\xa7'},{'\xab','\x7d'},
+ {'\xab','\xa4'},{'\xab','\x72'},{'\xcd','\xfc'},{'\xce','\x43'},{'\xab','\xa3'},
+ {'\xce','\x4f'},{'\xab','\xa5'},{'\x94','\x46'},{'\xab','\x79'},{'\x81','\xa2'},
+ {'\x00','\x00'},{'\xce','\x45'},{'\xce','\x42'},{'\xab','\x77'},{'\x98','\xe7'},
+ {'\xcd','\xfa'},{'\xab','\xa6'},{'\xce','\x4a'},{'\xab','\x7c'},{'\xce','\x4c'},
+ {'\xab','\xa9'},{'\xab','\x73'},{'\xab','\x7e'},{'\xab','\x7b'},{'\xce','\x40'},
+ {'\xab','\xa1'},{'\xce','\x46'},{'\xce','\x47'},{'\xab','\x7a'},{'\xab','\xa2'},
+ {'\xab','\x76'},{'\x00','\x00'},{'\xfb','\x4a'},{'\x96','\xcf'},{'\x8c','\xb7'},
+ {'\xab','\x75'},{'\xcd','\xfe'},{'\x81','\xa3'},{'\x83','\xf3'},{'\x8e','\xe2'},
+ {'\x8e','\xb1'},{'\x86','\xb4'},{'\x8e','\xe3'},{'\xce','\x44'},{'\x87','\xb0'},
+ {'\x94','\x63'},{'\x8e','\xe4'},{'\x96','\xb3'},{'\x00','\x00'},{'\x8f','\x4f'},
+ {'\x88','\xce'},{'\xce','\x4e'},{'\x84','\xcc'},{'\xd1','\x44'},{'\xad','\xfb'},
+ {'\xd0','\xf1'},{'\x98','\xe8'},{'\xd0','\xf6'},{'\xad','\xf4'},{'\xae','\x40'},
+ {'\xd0','\xf4'},{'\xad','\xef'},{'\xad','\xf9'},{'\xad','\xfe'},{'\xd0','\xfb'},
+ {'\x00','\x00'},{'\xad','\xfa'},{'\xad','\xfd'},{'\x98','\xe9'},{'\x00','\x00'},
+ {'\xd0','\xfe'},{'\xad','\xf5'},{'\xd0','\xf5'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xd1','\x42'},{'\xd1','\x43'},{'\x00','\x00'},{'\xad','\xf7'},
+ {'\xd1','\x41'},{'\xad','\xf3'},{'\xae','\x43'},{'\x00','\x00'},{'\xd0','\xf8'},
+ {'\x00','\x00'},{'\xad','\xf1'},{'\xfb','\x5a'},{'\xd1','\x46'},{'\xd0','\xf9'},
+ {'\xd0','\xfd'},{'\xad','\xf6'},{'\xae','\x42'},{'\xd0','\xfa'},{'\xad','\xfc'},
+ {'\xd1','\x40'},{'\xd1','\x47'},{'\xd4','\xa1'},{'\x98','\xea'},{'\xd1','\x45'},
+ {'\xae','\x44'},{'\xad','\xf0'},{'\xd0','\xfc'},{'\xd0','\xf3'},{'\xfb','\x52'},
+ {'\xad','\xf8'},{'\x00','\x00'},{'\x82','\x40'},{'\xd0','\xf2'},{'\x98','\xeb'},
+ {'\x00','\x00'},{'\xd0','\xf7'},{'\x8e','\x66'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xfb','\x55'},{'\x00','\x00'},{'\x87','\xae'},{'\x00','\x00'},{'\x8e','\x41'},
+ {'\x81','\xa4'},{'\x84','\xcd'},{'\x98','\xec'},{'\xd0','\xf0'},{'\xae','\x41'},
+ {'\x98','\xed'},{'\x00','\x00'},{'\xd4','\x77'},{'\x98','\xee'},{'\xb0','\xe4'},
+ {'\xd4','\xa7'},{'\xb0','\xe2'},{'\xb0','\xdf'},{'\xd4','\x7c'},{'\xb0','\xdb'},
+ {'\xd4','\xa2'},{'\xb0','\xe6'},{'\xd4','\x76'},{'\xd4','\x7b'},{'\xd4','\x7a'},
+ {'\xad','\xf2'},{'\xb0','\xe1'},{'\xd4','\xa5'},{'\x00','\x00'},{'\xd4','\xa8'},
+ {'\xd4','\x73'},{'\x00','\x00'},{'\xb3','\xe8'},{'\x81','\xa5'},{'\xd4','\xa9'},
+ {'\xb0','\xe7'},{'\x00','\x00'},{'\xb0','\xd9'},{'\xb0','\xd6'},{'\xd4','\x7e'},
+ {'\xb0','\xd3'},{'\x98','\xef'},{'\xd4','\xa6'},{'\x96','\xb1'},{'\xb0','\xda'},
+ {'\xd4','\xaa'},{'\x81','\xa6'},{'\xd4','\x74'},{'\xd4','\xa4'},{'\xb0','\xdd'},
+ {'\xd4','\x75'},{'\xd4','\x78'},{'\xd4','\x7d'},{'\x81','\xa7'},{'\x00','\x00'},
+ {'\xb0','\xde'},{'\xb0','\xdc'},{'\xb0','\xe8'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xb0','\xe3'},{'\x81','\xa8'},{'\xb0','\xd7'},
+ {'\xb1','\xd2'},{'\x00','\x00'},{'\xb0','\xd8'},{'\xd4','\x79'},{'\xb0','\xe5'},
+ {'\xb0','\xe0'},{'\xd4','\xa3'},{'\xb0','\xd5'},{'\x86','\xb3'},{'\x00','\x00'},
+ {'\xfb','\x5b'},{'\xb0','\xd4'},{'\xa0','\x46'},{'\x81','\xa9'},{'\x8c','\x6e'},
+ {'\x8c','\xc7'},{'\x00','\x00'},{'\x00','\x00'},{'\xa0','\x49'},{'\xa0','\x45'},
+ {'\xfb','\xdd'},{'\x00','\x00'},{'\xd4','\x71'},{'\xd4','\x72'},{'\xd8','\x6a'},
+ {'\x87','\xb3'},{'\x98','\xf0'},{'\x00','\x00'},{'\xb3','\xd7'},{'\xb3','\xda'},
+ {'\xd8','\x75'},{'\xb3','\xee'},{'\xd8','\x78'},{'\xb3','\xd8'},{'\xd8','\x71'},
+ {'\xb3','\xde'},{'\xb3','\xe4'},{'\xb5','\xbd'},{'\x00','\x00'},{'\x95','\xed'},
+ {'\xb3','\xe2'},{'\xd8','\x6e'},{'\xb3','\xef'},{'\xb3','\xdb'},{'\xb3','\xe3'},
+ {'\xd8','\x76'},{'\xdc','\xd7'},{'\xd8','\x7b'},{'\xd8','\x6f'},{'\x98','\xf1'},
+ {'\xd8','\x66'},{'\xd8','\x73'},{'\xd8','\x6d'},{'\xb3','\xe1'},{'\xd8','\x79'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xb3','\xdd'},{'\xb3','\xf1'},{'\xb3','\xea'},
+ {'\x00','\x00'},{'\xb3','\xdf'},{'\xb3','\xdc'},{'\x81','\xaa'},{'\xb3','\xe7'},
+ {'\x00','\x00'},{'\xd8','\x7a'},{'\xd8','\x6c'},{'\xd8','\x72'},{'\xd8','\x74'},
+ {'\xd8','\x68'},{'\xd8','\x77'},{'\xb3','\xd9'},{'\xd8','\x67'},{'\x81','\xab'},
+ {'\xb3','\xe0'},{'\xb3','\xf0'},{'\xb3','\xec'},{'\xd8','\x69'},{'\xb3','\xe6'},
+ {'\x00','\x00'},{'\x94','\x42'},{'\xb3','\xed'},{'\xb3','\xe9'},{'\xb3','\xe5'},
+ {'\x98','\xf2'},{'\xd8','\x70'},{'\x92','\x49'},{'\x87','\xb2'},{'\x00','\x00'},
+ {'\x96','\xb5'},{'\xa0','\x4a'},{'\xb3','\xeb'},{'\xfb','\x4c'},{'\x86','\xb2'},
+ {'\x8f','\xd9'},{'\xdc','\xd5'},{'\xdc','\xd1'},{'\x98','\xf3'},{'\xdc','\xe0'},
+ {'\xdc','\xca'},{'\xdc','\xd3'},{'\xb6','\xe5'},{'\xb6','\xe6'},{'\xb6','\xde'},
+ {'\xdc','\xdc'},{'\xb6','\xe8'},{'\xdc','\xcf'},{'\xdc','\xce'},{'\xdc','\xcc'},
+ {'\xdc','\xde'},{'\xb6','\xdc'},{'\xdc','\xd8'},{'\xdc','\xcd'},{'\xb6','\xdf'},
+ {'\xdc','\xd6'},{'\xb6','\xda'},{'\xdc','\xd2'},{'\xdc','\xd9'},{'\xdc','\xdb'},
+ {'\x98','\xf4'},{'\x98','\xf5'},{'\xdc','\xdf'},{'\xb6','\xe3'},{'\xdc','\xcb'},
+ {'\xb6','\xdd'},{'\xdc','\xd0'},{'\xfb','\x56'},{'\xb6','\xd8'},{'\x00','\x00'},
+ {'\xb6','\xe4'},{'\xdc','\xda'},{'\xb6','\xe0'},{'\xb6','\xe1'},{'\xb6','\xe7'},
+ {'\xb6','\xdb'},{'\xa2','\x5f'},{'\xb6','\xd9'},{'\xdc','\xd4'},{'\x96','\xc9'},
+ {'\x8c','\x6d'},{'\x81','\xac'},{'\x00','\x00'},{'\x00','\x00'},{'\xb6','\xe2'},
+ {'\xa0','\x4d'},{'\xa0','\x4b'},{'\xdc','\xdd'},{'\x88','\xcf'},{'\x00','\x00'},
+ {'\x81','\xad'},{'\xb9','\xcd'},{'\xb9','\xc8'},{'\x00','\x00'},{'\xe1','\x55'},
+ {'\xe1','\x51'},{'\x98','\xf6'},{'\xe1','\x4b'},{'\xb9','\xc2'},{'\xb9','\xbe'},
+ {'\xe1','\x54'},{'\xb9','\xbf'},{'\xe1','\x4e'},{'\xe1','\x50'},{'\x00','\x00'},
+ {'\xe1','\x53'},{'\xa0','\x4e'},{'\xb9','\xc4'},{'\x00','\x00'},{'\xb9','\xcb'},
+ {'\xb9','\xc5'},{'\x00','\x00'},{'\x00','\x00'},{'\xe1','\x49'},{'\xb9','\xc6'},
+ {'\xb9','\xc7'},{'\xe1','\x4c'},{'\xb9','\xcc'},{'\xfb','\xe1'},{'\xe1','\x4a'},
+ {'\xe1','\x4f'},{'\xb9','\xc3'},{'\xe1','\x48'},{'\xb9','\xc9'},{'\xb9','\xc1'},
+ {'\x82','\xb3'},{'\x00','\x00'},{'\x00','\x00'},{'\xb9','\xc0'},{'\xe1','\x4d'},
+ {'\xe1','\x52'},{'\xa0','\x52'},{'\xb9','\xca'},{'\xfc','\xd9'},{'\x98','\xf8'},
+ {'\xa0','\x4f'},{'\x81','\xae'},{'\x8b','\xf1'},{'\xfb','\x65'},{'\x00','\x00'},
+ {'\xe1','\x47'},{'\x00','\x00'},{'\xbc','\x4d'},{'\xe5','\x47'},{'\x00','\x00'},
+ {'\xe5','\x44'},{'\xa0','\x50'},{'\xbc','\x47'},{'\xbc','\x53'},{'\xbc','\x54'},
+ {'\x8d','\x51'},{'\xbc','\x4a'},{'\xe5','\x42'},{'\xbc','\x4c'},{'\xe4','\xf9'},
+ {'\xbc','\x52'},{'\xfe','\x5d'},{'\xe5','\x46'},{'\xbc','\x49'},{'\xe5','\x48'},
+ {'\xbc','\x48'},{'\x00','\x00'},{'\xe5','\x43'},{'\xe5','\x45'},{'\xbc','\x4b'},
+ {'\xe5','\x41'},{'\xe4','\xfa'},{'\xe4','\xf7'},{'\xa0','\x51'},{'\x00','\x00'},
+ {'\xd8','\x6b'},{'\xe4','\xfd'},{'\x00','\x00'},{'\xe4','\xf6'},{'\xe4','\xfc'},
+ {'\xe4','\xfb'},{'\x00','\x00'},{'\xe4','\xf8'},{'\xfb','\xe2'},{'\xbc','\x4f'},
+ {'\xfb','\x6a'},{'\x81','\xaf'},{'\x00','\x00'},{'\x98','\xfa'},{'\xbc','\x4e'},
+ {'\xfb','\xe4'},{'\x00','\x00'},{'\x00','\x00'},{'\xbc','\x50'},{'\xe4','\xfe'},
+ {'\xbe','\xb2'},{'\xe5','\x40'},{'\x82','\x4f'},{'\x8a','\xbe'},{'\x99','\x40'},
+ {'\xe9','\x45'},{'\x00','\x00'},{'\xe8','\xfd'},{'\x99','\x55'},{'\xbe','\xbe'},
+ {'\xe9','\x42'},{'\xbe','\xb6'},{'\xbe','\xba'},{'\xe9','\x41'},{'\x00','\x00'},
+ {'\xbe','\xb9'},{'\xbe','\xb5'},{'\xbe','\xb8'},{'\xbe','\xb3'},{'\xbe','\xbd'},
+ {'\xe9','\x43'},{'\xe8','\xfe'},{'\xbe','\xbc'},{'\xe8','\xfc'},{'\xbe','\xbb'},
+ {'\xe9','\x44'},{'\xe9','\x40'},{'\xbc','\x51'},{'\x00','\x00'},{'\xbe','\xbf'},
+ {'\xe9','\x46'},{'\xbe','\xb7'},{'\xbe','\xb4'},{'\x94','\x57'},{'\x96','\xca'},
+ {'\x81','\xb0'},{'\x00','\x00'},{'\xec','\xc6'},{'\xec','\xc8'},{'\xc0','\x7b'},
+ {'\xec','\xc9'},{'\xec','\xc7'},{'\xec','\xc5'},{'\xec','\xc4'},{'\xc0','\x7d'},
+ {'\xec','\xc3'},{'\xc0','\x7e'},{'\x00','\x00'},{'\x99','\x56'},{'\x81','\xb1'},
+ {'\x99','\x57'},{'\xec','\xc1'},{'\xec','\xc2'},{'\xc0','\x7a'},{'\xc0','\xa1'},
+ {'\xc0','\x7c'},{'\x00','\x00'},{'\xa0','\x53'},{'\xec','\xc0'},{'\x81','\xb2'},
+ {'\xc2','\x50'},{'\x00','\x00'},{'\xef','\xbc'},{'\xef','\xba'},{'\xef','\xbf'},
+ {'\xef','\xbd'},{'\x00','\x00'},{'\xef','\xbb'},{'\xef','\xbe'},{'\x99','\x58'},
+ {'\xa0','\x5c'},{'\x81','\xb3'},{'\x99','\x59'},{'\x82','\x74'},{'\x8c','\x6f'},
+ {'\xa0','\x5b'},{'\xc3','\x60'},{'\xf1','\xf2'},{'\xf1','\xf3'},{'\xc4','\x56'},
+ {'\x00','\x00'},{'\xf1','\xf4'},{'\xf1','\xf0'},{'\xf1','\xf5'},{'\xf1','\xf1'},
+ {'\xc2','\x51'},{'\x81','\xb4'},{'\x00','\x00'},{'\x99','\x5a'},{'\xf3','\xfe'},
+ {'\xf4','\x41'},{'\xc4','\x59'},{'\xf4','\x40'},{'\xc4','\x58'},{'\xc4','\x57'},
+ {'\x00','\x00'},{'\x99','\x5b'},{'\x00','\x00'},{'\x00','\x00'},{'\xc4','\x5a'},
+ {'\xf5','\xc5'},{'\xf5','\xc6'},{'\x99','\x5c'},{'\xc4','\xda'},{'\xc4','\xd9'},
+ {'\xc4','\xdb'},{'\xf5','\xc4'},{'\x00','\x00'},{'\xf6','\xd8'},{'\xf6','\xd7'},
+ {'\x00','\x00'},{'\xc5','\x6d'},{'\xc5','\x6f'},{'\xc5','\x6e'},{'\xf6','\xd9'},
+ {'\xc5','\xc8'},{'\xf8','\xa6'},{'\x94','\x64'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xc5','\xf1'},{'\x00','\x00'},{'\xf8','\xa5'},{'\xf8','\xee'},{'\x00','\x00'},
+ {'\x99','\x5d'},{'\xc9','\x49'},{'\x81','\xb5'},{'\x00','\x00'},{'\xa5','\x7d'},
+ {'\xa5','\x7c'},{'\x00','\x00'},{'\xa6','\x5f'},{'\xa6','\x5e'},{'\xc9','\xc7'},
+ {'\xa6','\x5d'},{'\xc9','\xc6'},{'\x86','\xb5'},{'\x93','\x6f'},{'\xa7','\x79'},
+ {'\xca','\xa9'},{'\x00','\x00'},{'\xca','\xa8'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xa7','\x77'},{'\xa7','\x7a'},{'\x00','\x00'},{'\x85','\xbd'},{'\xca','\xa7'},
+ {'\x99','\x5e'},{'\xa7','\x78'},{'\x83','\x46'},{'\x92','\x43'},{'\x92','\xf6'},
+ {'\x84','\xcf'},{'\x8d','\xca'},{'\x00','\x00'},{'\xcb','\xf0'},{'\x00','\x00'},
+ {'\xcb','\xf1'},{'\xa9','\x54'},{'\x9d','\x56'},{'\x00','\x00'},{'\x83','\xf6'},
+ {'\x86','\xb6'},{'\xab','\xaa'},{'\x81','\xb6'},{'\xd1','\x48'},{'\xd1','\x49'},
+ {'\xae','\x45'},{'\xae','\x46'},{'\x00','\x00'},{'\x85','\xbe'},{'\xd4','\xac'},
+ {'\xb0','\xe9'},{'\xb0','\xeb'},{'\xd4','\xab'},{'\xb0','\xea'},{'\xd8','\x7c'},
+ {'\xb3','\xf2'},{'\x00','\x00'},{'\x92','\xb5'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xb6','\xe9'},{'\xb6','\xea'},{'\xdc','\xe1'},{'\x99','\x5f'},{'\xb9','\xcf'},
+ {'\x00','\x00'},{'\xb9','\xce'},{'\x00','\x00'},{'\xe5','\x49'},{'\xe9','\x48'},
+ {'\xe9','\x47'},{'\x99','\x60'},{'\xf9','\x6b'},{'\xa4','\x67'},{'\xc9','\x59'},
+ {'\x00','\x00'},{'\xc9','\x6e'},{'\xc9','\x6f'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x94','\x65'},{'\x92','\x42'},{'\xa6','\x62'},{'\xa6','\x66'},{'\xc9','\xc9'},
+ {'\x00','\x00'},{'\xa6','\x64'},{'\xa6','\x63'},{'\xc9','\xc8'},{'\xa6','\x65'},
+ {'\xa6','\x61'},{'\x00','\x00'},{'\x99','\x61'},{'\xa6','\x60'},{'\xc9','\xca'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x94','\x66'},{'\x94','\x67'},{'\x8a','\xbf'},
+ {'\x84','\xd1'},{'\xa7','\xa6'},{'\x00','\x00'},{'\x99','\x62'},{'\xa7','\xa3'},
+ {'\x99','\x63'},{'\xa7','\x7d'},{'\xca','\xaa'},{'\x95','\xb5'},{'\x99','\x64'},
+ {'\x00','\x00'},{'\xca','\xab'},{'\xfb','\xe7'},{'\xa7','\xa1'},{'\x00','\x00'},
+ {'\xca','\xad'},{'\xa7','\x7b'},{'\xca','\xae'},{'\xca','\xac'},{'\xa7','\x7e'},
+ {'\xa7','\xa2'},{'\xa7','\xa5'},{'\xa7','\xa4'},{'\xa7','\x7c'},{'\xca','\xaf'},
+ {'\x00','\x00'},{'\xfe','\x6f'},{'\x00','\x00'},{'\x00','\x00'},{'\x85','\xc0'},
+ {'\x00','\x00'},{'\x81','\xb7'},{'\x83','\xf7'},{'\x88','\xd1'},{'\x8b','\x6f'},
+ {'\x8d','\x52'},{'\x85','\xc1'},{'\x87','\xb6'},{'\x87','\xb7'},{'\xa9','\x59'},
+ {'\xcb','\xfe'},{'\x00','\x00'},{'\xa9','\x5b'},{'\x81','\xb8'},{'\xa9','\x5a'},
+ {'\xfb','\xe9'},{'\xcc','\x40'},{'\xa9','\x58'},{'\xa9','\x57'},{'\xcb','\xf5'},
+ {'\x00','\x00'},{'\xcb','\xf4'},{'\x00','\x00'},{'\xcb','\xf2'},{'\xcb','\xf7'},
+ {'\xcb','\xf6'},{'\xcb','\xf3'},{'\xcb','\xfc'},{'\xcb','\xfd'},{'\xcb','\xfa'},
+ {'\xcb','\xf8'},{'\xa9','\x56'},{'\x00','\x00'},{'\x00','\x00'},{'\xfb','\xe8'},
+ {'\xcb','\xfb'},{'\xa9','\x5c'},{'\xcc','\x41'},{'\x99','\x66'},{'\x81','\xb9'},
+ {'\xcb','\xf9'},{'\x00','\x00'},{'\xab','\xab'},{'\xa9','\x55'},{'\x8b','\x6e'},
+ {'\x81','\xba'},{'\x8f','\xb8'},{'\x00','\x00'},{'\x94','\x68'},{'\x81','\xbb'},
+ {'\x99','\x67'},{'\xab','\xac'},{'\xce','\x54'},{'\x99','\x68'},{'\x00','\x00'},
+ {'\xce','\x5a'},{'\x99','\x69'},{'\x00','\x00'},{'\x8a','\xc0'},{'\xab','\xb2'},
+ {'\xce','\x58'},{'\xce','\x5e'},{'\x00','\x00'},{'\xce','\x55'},{'\xce','\x59'},
+ {'\xce','\x5b'},{'\xce','\x5d'},{'\xce','\x57'},{'\x99','\x6a'},{'\xce','\x56'},
+ {'\xce','\x51'},{'\xce','\x52'},{'\xab','\xad'},{'\x81','\xbc'},{'\xab','\xaf'},
+ {'\xab','\xae'},{'\xce','\x53'},{'\xce','\x5c'},{'\x88','\xd0'},{'\x8d','\xb6'},
+ {'\x00','\x00'},{'\x83','\xf8'},{'\x94','\x6a'},{'\x86','\xb8'},{'\x81','\xbd'},
+ {'\x8d','\xcb'},{'\xab','\xb1'},{'\x00','\x00'},{'\x94','\x6b'},{'\x00','\x00'},
+ {'\x8e','\x42'},{'\x94','\x69'},{'\x81','\xbe'},{'\xce','\x50'},{'\xd1','\x53'},
+ {'\x00','\x00'},{'\xd1','\x52'},{'\xd1','\x57'},{'\xd1','\x4e'},{'\x99','\x6b'},
+ {'\xd1','\x51'},{'\xd1','\x50'},{'\x99','\x6c'},{'\xd1','\x54'},{'\x81','\xbf'},
+ {'\xd1','\x58'},{'\xae','\x47'},{'\xae','\x4a'},{'\x99','\x6d'},{'\x00','\x00'},
+ {'\xd1','\x4f'},{'\xd1','\x55'},{'\x81','\xc0'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xae','\x49'},{'\xd1','\x4a'},{'\x00','\x00'},{'\xab','\xb0'},{'\xd4','\xba'},
+ {'\xd1','\x56'},{'\x00','\x00'},{'\xd1','\x4d'},{'\x81','\xc1'},{'\xae','\x48'},
+ {'\xd1','\x4c'},{'\x94','\x6c'},{'\xfe','\x49'},{'\x85','\xc2'},{'\x89','\xce'},
+ {'\x84','\xd3'},{'\x00','\x00'},{'\xd4','\xb1'},{'\xfb','\xec'},{'\x99','\x6e'},
+ {'\xb0','\xec'},{'\xb0','\xf0'},{'\xd4','\xc1'},{'\xd4','\xaf'},{'\xd4','\xbd'},
+ {'\xb0','\xf1'},{'\xd4','\xbf'},{'\xfb','\xeb'},{'\xd4','\xc5'},{'\x00','\x00'},
+ {'\xd4','\xc9'},{'\x00','\x00'},{'\x00','\x00'},{'\xd4','\xc0'},{'\xd4','\xb4'},
+ {'\xd4','\xbc'},{'\x81','\xc2'},{'\xd4','\xca'},{'\xd4','\xc8'},{'\xd4','\xbe'},
+ {'\xd4','\xb9'},{'\xd4','\xb2'},{'\xd8','\xa6'},{'\xd4','\xb0'},{'\xb0','\xf5'},
+ {'\xd4','\xb7'},{'\xb0','\xf6'},{'\xb0','\xf2'},{'\xd4','\xad'},{'\xd4','\xc3'},
+ {'\xd4','\xb5'},{'\x99','\x6f'},{'\x00','\x00'},{'\xd4','\xb3'},{'\xd4','\xc6'},
+ {'\xb0','\xf3'},{'\x95','\x4a'},{'\xd4','\xcc'},{'\xb0','\xed'},{'\xb0','\xef'},
+ {'\xd4','\xbb'},{'\xd4','\xb6'},{'\xae','\x4b'},{'\xb0','\xee'},{'\xd4','\xb8'},
+ {'\xd4','\xc7'},{'\xd4','\xcb'},{'\xd4','\xc2'},{'\x00','\x00'},{'\xd4','\xc4'},
+ {'\x86','\xb9'},{'\x99','\x70'},{'\x00','\x00'},{'\xd4','\xae'},{'\x87','\xb8'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xd8','\xa1'},{'\x00','\x00'},
+ {'\xd8','\xaa'},{'\xd8','\xa9'},{'\xb3','\xfa'},{'\xd8','\xa2'},{'\x00','\x00'},
+ {'\xb3','\xfb'},{'\xb3','\xf9'},{'\x99','\x71'},{'\xd8','\xa4'},{'\xb3','\xf6'},
+ {'\xd8','\xa8'},{'\xfb','\xef'},{'\xd8','\xa3'},{'\xd8','\xa5'},{'\xd8','\x7d'},
+ {'\xb3','\xf4'},{'\x00','\x00'},{'\xd8','\xb2'},{'\xd8','\xb1'},{'\xd8','\xae'},
+ {'\xb3','\xf3'},{'\xb3','\xf7'},{'\xb3','\xf8'},{'\xd1','\x4b'},{'\xd8','\xab'},
+ {'\xb3','\xf5'},{'\xb0','\xf4'},{'\xd8','\xad'},{'\xd8','\x7e'},{'\xd8','\xb0'},
+ {'\xd8','\xaf'},{'\xfb','\xea'},{'\xd8','\xb3'},{'\x00','\x00'},{'\xdc','\xef'},
+ {'\x00','\x00'},{'\xd8','\xac'},{'\x94','\x59'},{'\x93','\xe9'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x81','\xc3'},{'\x00','\x00'},{'\x00','\x00'},{'\x99','\x72'},
+ {'\xd8','\xa7'},{'\xdc','\xe7'},{'\xb6','\xf4'},{'\xb6','\xf7'},{'\xb6','\xf2'},
+ {'\xdc','\xe6'},{'\xdc','\xea'},{'\xdc','\xe5'},{'\x00','\x00'},{'\xb6','\xec'},
+ {'\xb6','\xf6'},{'\xdc','\xe2'},{'\xb6','\xf0'},{'\xdc','\xe9'},{'\x00','\x00'},
+ {'\xb6','\xee'},{'\xb6','\xed'},{'\xdc','\xec'},{'\xb6','\xef'},{'\xdc','\xee'},
+ {'\x99','\x73'},{'\xdc','\xeb'},{'\xb6','\xeb'},{'\x99','\x74'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xb6','\xf5'},{'\xdc','\xf0'},{'\xdc','\xe4'},{'\xdc','\xed'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xdc','\xe3'},{'\x95','\xcd'},{'\x00','\x00'},
+ {'\xb6','\xf1'},{'\x81','\xc4'},{'\xb6','\xf3'},{'\x00','\x00'},{'\xdc','\xe8'},
+ {'\x94','\x6d'},{'\xdc','\xf1'},{'\x95','\x62'},{'\x99','\x75'},{'\xe1','\x5d'},
+ {'\xb9','\xd0'},{'\xe1','\x63'},{'\x00','\x00'},{'\x00','\x00'},{'\xb9','\xd5'},
+ {'\xe1','\x5f'},{'\xe1','\x66'},{'\xe1','\x57'},{'\xb9','\xd7'},{'\xb9','\xd1'},
+ {'\xe1','\x5c'},{'\xbc','\x55'},{'\xe1','\x5b'},{'\xe1','\x64'},{'\xb9','\xd2'},
+ {'\x00','\x00'},{'\xb9','\xd6'},{'\xe1','\x5a'},{'\xe1','\x60'},{'\xe1','\x65'},
+ {'\xe1','\x56'},{'\xb9','\xd4'},{'\xe1','\x5e'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xe1','\x62'},{'\xe1','\x68'},{'\xe1','\x58'},{'\xe1','\x61'},{'\x81','\xc5'},
+ {'\xb9','\xd3'},{'\xe1','\x67'},{'\x00','\x00'},{'\x00','\x00'},{'\x93','\x5e'},
+ {'\xe1','\x59'},{'\x89','\xf5'},{'\x81','\xc6'},{'\x00','\x00'},{'\xbc','\x59'},
+ {'\xe5','\x4b'},{'\xbc','\x57'},{'\xbc','\x56'},{'\xe5','\x4d'},{'\xe5','\x52'},
+ {'\x00','\x00'},{'\xe5','\x4e'},{'\x00','\x00'},{'\xe5','\x51'},{'\xbc','\x5c'},
+ {'\x99','\x76'},{'\xbe','\xa5'},{'\xbc','\x5b'},{'\x99','\x77'},{'\xe5','\x4a'},
+ {'\xe5','\x50'},{'\x00','\x00'},{'\xbc','\x5a'},{'\xe5','\x4f'},{'\x99','\x78'},
+ {'\xe5','\x4c'},{'\x81','\xc7'},{'\xbc','\x58'},{'\x00','\x00'},{'\x99','\x79'},
+ {'\x99','\x7a'},{'\x00','\x00'},{'\x81','\xc8'},{'\x94','\x6e'},{'\xe9','\x4d'},
+ {'\xf9','\xd9'},{'\xe9','\x4f'},{'\xe9','\x4a'},{'\xbe','\xc1'},{'\xe9','\x4c'},
+ {'\x00','\x00'},{'\xbe','\xc0'},{'\xe9','\x4e'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xbe','\xc3'},{'\xe9','\x50'},{'\xbe','\xc2'},{'\xe9','\x49'},{'\xe9','\x4b'},
+ {'\x92','\x5c'},{'\x99','\x7b'},{'\x92','\xee'},{'\x00','\x00'},{'\xc0','\xa5'},
+ {'\xec','\xcc'},{'\x99','\x7c'},{'\xc0','\xa4'},{'\xec','\xcd'},{'\xc0','\xa3'},
+ {'\xec','\xcb'},{'\xc0','\xa2'},{'\xec','\xca'},{'\x94','\x6f'},{'\xc2','\x53'},
+ {'\xc2','\x52'},{'\xf1','\xf6'},{'\xf1','\xf8'},{'\xfb','\xf0'},{'\xf1','\xf7'},
+ {'\xc3','\x61'},{'\xc3','\x62'},{'\x99','\x7d'},{'\x00','\x00'},{'\xc3','\x63'},
+ {'\xf4','\x42'},{'\xc4','\x5b'},{'\x81','\xc9'},{'\x00','\x00'},{'\xf7','\xd3'},
+ {'\xf7','\xd2'},{'\xc5','\xf2'},{'\x00','\x00'},{'\xa4','\x68'},{'\xa4','\xd0'},
+ {'\x00','\x00'},{'\x83','\x47'},{'\xa7','\xa7'},{'\x8a','\x52'},{'\x92','\x45'},
+ {'\x93','\xb3'},{'\x84','\xea'},{'\xce','\x5f'},{'\x00','\x00'},{'\x84','\xd4'},
+ {'\x82','\x41'},{'\x00','\x00'},{'\xb3','\xfc'},{'\xb3','\xfd'},{'\x81','\xca'},
+ {'\xdc','\xf2'},{'\xb9','\xd8'},{'\xe1','\x69'},{'\xe5','\x53'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x81','\xcb'},{'\xc9','\x5a'},{'\x84','\x7a'},{'\x99','\x7e'},
+ {'\xca','\xb0'},{'\x84','\xc2'},{'\x00','\x00'},{'\x93','\xc4'},{'\xc6','\xca'},
+ {'\x81','\xcc'},{'\xcc','\x42'},{'\xce','\x60'},{'\xd1','\x59'},{'\xae','\x4c'},
+ {'\x81','\xcd'},{'\x99','\xa1'},{'\xf1','\xf9'},{'\x00','\x00'},{'\xc4','\xdc'},
+ {'\xa4','\x69'},{'\xa5','\x7e'},{'\xc9','\x70'},{'\x81','\xce'},{'\xa6','\x67'},
+ {'\xa6','\x68'},{'\x81','\xcf'},{'\xa9','\x5d'},{'\x9d','\x58'},{'\x00','\x00'},
+ {'\x83','\xfa'},{'\xb0','\xf7'},{'\x00','\x00'},{'\xb9','\xda'},{'\x00','\x00'},
+ {'\xb9','\xdb'},{'\xb9','\xd9'},{'\x00','\x00'},{'\xa4','\x6a'},{'\x00','\x00'},
+ {'\xa4','\xd1'},{'\xa4','\xd3'},{'\xa4','\xd2'},{'\xc9','\x5b'},{'\xa4','\xd4'},
+ {'\xa5','\xa1'},{'\xc9','\x71'},{'\x00','\x00'},{'\xa5','\xa2'},{'\x82','\xb5'},
+ {'\x00','\x00'},{'\x89','\xb3'},{'\x00','\x00'},{'\x00','\x00'},{'\xa6','\x69'},
+ {'\xa6','\x6a'},{'\x83','\x48'},{'\x86','\xbc'},{'\x00','\x00'},{'\xc9','\xcb'},
+ {'\x00','\x00'},{'\xa7','\xa8'},{'\x00','\x00'},{'\xca','\xb1'},{'\x86','\xbd'},
+ {'\x83','\x6b'},{'\x00','\x00'},{'\xa9','\x61'},{'\xcc','\x43'},{'\x00','\x00'},
+ {'\xa9','\x5f'},{'\xa9','\x60'},{'\xa9','\x5e'},{'\xd1','\x5a'},{'\x88','\xd2'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xab','\xb6'},{'\xab','\xb5'},{'\xab','\xb7'},
+ {'\xab','\xb4'},{'\x00','\x00'},{'\xce','\x61'},{'\xa9','\x62'},{'\xab','\xb3'},
+ {'\x87','\xf2'},{'\xae','\x4d'},{'\xae','\x4e'},{'\x00','\x00'},{'\xae','\x4f'},
+ {'\x82','\xb6'},{'\xd4','\xcd'},{'\x82','\xb7'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xb3','\xfe'},{'\xd8','\xb4'},{'\xb0','\xf8'},{'\x82','\xb8'},{'\x00','\x00'},
+ {'\x85','\xc4'},{'\x00','\x00'},{'\xb6','\xf8'},{'\x92','\xe6'},{'\xb9','\xdd'},
+ {'\xb9','\xdc'},{'\xe1','\x6a'},{'\x82','\xb9'},{'\xbc','\x5d'},{'\xbe','\xc4'},
+ {'\x00','\x00'},{'\xef','\xc0'},{'\xf6','\xda'},{'\xf7','\xd4'},{'\xa4','\x6b'},
+ {'\xa5','\xa3'},{'\xfe','\x66'},{'\xa5','\xa4'},{'\xc9','\xd1'},{'\xa6','\x6c'},
+ {'\xa6','\x6f'},{'\x00','\x00'},{'\xc9','\xcf'},{'\xc9','\xcd'},{'\xa6','\x6e'},
+ {'\xc9','\xd0'},{'\xc9','\xd2'},{'\xc9','\xcc'},{'\xa6','\x71'},{'\xa6','\x70'},
+ {'\xa6','\x6d'},{'\xa6','\x6b'},{'\xc9','\xce'},{'\x83','\x49'},{'\x83','\xfc'},
+ {'\x85','\xc5'},{'\x99','\xa2'},{'\xa7','\xb3'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xa7','\xb0'},{'\xca','\xb6'},{'\xca','\xb9'},{'\xca','\xb8'},{'\x00','\x00'},
+ {'\xa7','\xaa'},{'\xa7','\xb2'},{'\x99','\xa3'},{'\x00','\x00'},{'\xa7','\xaf'},
+ {'\xca','\xb5'},{'\xca','\xb3'},{'\xa7','\xae'},{'\x99','\xa4'},{'\x82','\xba'},
+ {'\x00','\x00'},{'\xa7','\xa9'},{'\xa7','\xac'},{'\x99','\xa5'},{'\xca','\xb4'},
+ {'\xca','\xbb'},{'\xca','\xb7'},{'\xa7','\xad'},{'\xa7','\xb1'},{'\xa7','\xb4'},
+ {'\xca','\xb2'},{'\xca','\xba'},{'\xa7','\xab'},{'\x87','\xbb'},{'\x86','\xbe'},
+ {'\x8d','\xdb'},{'\x95','\xa5'},{'\x00','\x00'},{'\xa9','\x67'},{'\xa9','\x6f'},
+ {'\x99','\xa6'},{'\xcc','\x4f'},{'\xcc','\x48'},{'\xa9','\x70'},{'\xcc','\x53'},
+ {'\xcc','\x44'},{'\xcc','\x4b'},{'\xfb','\xf1'},{'\x99','\xa7'},{'\xa9','\x66'},
+ {'\xcc','\x45'},{'\xa9','\x64'},{'\xcc','\x4c'},{'\xcc','\x50'},{'\xa9','\x63'},
+ {'\x9b','\x40'},{'\xcc','\x51'},{'\xcc','\x4a'},{'\x00','\x00'},{'\xcc','\x4d'},
+ {'\x99','\xa8'},{'\xa9','\x72'},{'\xa9','\x69'},{'\xcc','\x54'},{'\xcc','\x52'},
+ {'\x93','\xfc'},{'\xa9','\x6e'},{'\xa9','\x6c'},{'\xcc','\x49'},{'\xa9','\x6b'},
+ {'\xcc','\x47'},{'\xcc','\x46'},{'\xa9','\x6a'},{'\xa9','\x68'},{'\xa9','\x71'},
+ {'\xa9','\x6d'},{'\xa9','\x65'},{'\x00','\x00'},{'\xcc','\x4e'},{'\x82','\xbb'},
+ {'\xab','\xb9'},{'\xfb','\xf2'},{'\xab','\xc0'},{'\xce','\x6f'},{'\xab','\xb8'},
+ {'\xce','\x67'},{'\xce','\x63'},{'\x00','\x00'},{'\xce','\x73'},{'\xce','\x62'},
+ {'\x00','\x00'},{'\xab','\xbb'},{'\xce','\x6c'},{'\xab','\xbe'},{'\xab','\xc1'},
+ {'\x00','\x00'},{'\xab','\xbc'},{'\xce','\x70'},{'\xab','\xbf'},{'\x82','\xbc'},
+ {'\xae','\x56'},{'\xce','\x76'},{'\xce','\x64'},{'\x99','\xa9'},{'\x99','\xaa'},
+ {'\xce','\x66'},{'\xce','\x6d'},{'\xce','\x71'},{'\xce','\x75'},{'\xce','\x72'},
+ {'\xce','\x6b'},{'\xce','\x6e'},{'\x99','\xab'},{'\x95','\xc0'},{'\xce','\x68'},
+ {'\xab','\xc3'},{'\xce','\x6a'},{'\xce','\x69'},{'\xce','\x74'},{'\xab','\xba'},
+ {'\xce','\x65'},{'\xab','\xc2'},{'\x99','\xac'},{'\xab','\xbd'},{'\x83','\xfb'},
+ {'\x8d','\xcc'},{'\x87','\xbd'},{'\x87','\xbc'},{'\x90','\x55'},{'\xae','\x5c'},
+ {'\xd1','\x62'},{'\x99','\xad'},{'\xae','\x5b'},{'\x99','\xae'},{'\x00','\x00'},
+ {'\xd1','\x60'},{'\x00','\x00'},{'\xae','\x50'},{'\x99','\xaf'},{'\xae','\x55'},
+ {'\x00','\x00'},{'\xd1','\x5f'},{'\xd1','\x5c'},{'\xd1','\x61'},{'\xae','\x51'},
+ {'\xd1','\x5b'},{'\x82','\xbd'},{'\xae','\x54'},{'\xae','\x52'},{'\x00','\x00'},
+ {'\xd1','\x63'},{'\xae','\x53'},{'\xae','\x57'},{'\x99','\xb0'},{'\x00','\x00'},
+ {'\xae','\x58'},{'\x99','\xb1'},{'\xae','\x5a'},{'\x00','\x00'},{'\x99','\xb2'},
+ {'\x00','\x00'},{'\xae','\x59'},{'\x99','\xb3'},{'\x99','\xb4'},{'\x99','\xb5'},
+ {'\xd1','\x5d'},{'\xd1','\x5e'},{'\x92','\xbc'},{'\x00','\x00'},{'\x83','\xb1'},
+ {'\x84','\xd5'},{'\xd1','\x64'},{'\x87','\xb9'},{'\xd4','\xd4'},{'\xb0','\xf9'},
+ {'\xd8','\xc2'},{'\xd4','\xd3'},{'\xd4','\xe6'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xb1','\x40'},{'\x99','\xb6'},{'\xd4','\xe4'},{'\x00','\x00'},{'\xb0','\xfe'},
+ {'\xb0','\xfa'},{'\xd4','\xed'},{'\xd4','\xdd'},{'\xd4','\xe0'},{'\x99','\xb7'},
+ {'\xb1','\x43'},{'\xd4','\xea'},{'\xd4','\xe2'},{'\xb0','\xfb'},{'\xb1','\x44'},
+ {'\x00','\x00'},{'\xd4','\xe7'},{'\xd4','\xe5'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xd4','\xd6'},{'\xd4','\xeb'},{'\xd4','\xdf'},{'\xd4','\xda'},{'\x99','\xb8'},
+ {'\xd4','\xd0'},{'\xd4','\xec'},{'\xd4','\xdc'},{'\xd4','\xcf'},{'\x99','\xb9'},
+ {'\xb1','\x42'},{'\xd4','\xe1'},{'\xd4','\xee'},{'\xd4','\xde'},{'\xd4','\xd2'},
+ {'\xd4','\xd7'},{'\xd4','\xce'},{'\x99','\xba'},{'\xb1','\x41'},{'\x95','\x63'},
+ {'\xd4','\xdb'},{'\xd4','\xd8'},{'\xb0','\xfc'},{'\xd4','\xd1'},{'\x99','\xbb'},
+ {'\xd4','\xe9'},{'\xb0','\xfd'},{'\x99','\xbc'},{'\xd4','\xd9'},{'\xd4','\xd5'},
+ {'\x99','\xbd'},{'\x00','\x00'},{'\xd4','\xe8'},{'\x99','\xbe'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x89','\xcf'},{'\x87','\xba'},{'\x8a','\xc1'},{'\xb4','\x40'},
+ {'\xd8','\xbb'},{'\x99','\xbf'},{'\xd8','\xb8'},{'\xd8','\xc9'},{'\xd8','\xbd'},
+ {'\xd8','\xca'},{'\x99','\xc0'},{'\xb4','\x42'},{'\x00','\x00'},{'\x99','\xc1'},
+ {'\x99','\xc2'},{'\xd8','\xc6'},{'\xd8','\xc3'},{'\x00','\x00'},{'\x99','\xc3'},
+ {'\x00','\x00'},{'\x99','\xc4'},{'\x00','\x00'},{'\xd8','\xc4'},{'\xd8','\xc7'},
+ {'\xd8','\xcb'},{'\x00','\x00'},{'\xd4','\xe3'},{'\xd8','\xcd'},{'\xdd','\x47'},
+ {'\x99','\xc5'},{'\xb4','\x43'},{'\xd8','\xce'},{'\xd8','\xb6'},{'\xd8','\xc0'},
+ {'\xfe','\x78'},{'\xd8','\xc5'},{'\x00','\x00'},{'\x99','\xc6'},{'\xb4','\x41'},
+ {'\xb4','\x44'},{'\xd8','\xcc'},{'\xd8','\xcf'},{'\xd8','\xba'},{'\xd8','\xb7'},
+ {'\x99','\xc7'},{'\x99','\xc8'},{'\xd8','\xb9'},{'\x00','\x00'},{'\x9c','\x70'},
+ {'\xd8','\xbe'},{'\xd8','\xbc'},{'\xb4','\x45'},{'\x00','\x00'},{'\xd8','\xc8'},
+ {'\x82','\xbe'},{'\x99','\xc9'},{'\xd8','\xbf'},{'\x00','\x00'},{'\xd8','\xc1'},
+ {'\xd8','\xb5'},{'\xdc','\xfa'},{'\xdc','\xf8'},{'\xb7','\x42'},{'\xb7','\x40'},
+ {'\xdd','\x43'},{'\xdc','\xf9'},{'\xdd','\x44'},{'\xdd','\x40'},{'\xdc','\xf7'},
+ {'\xdd','\x46'},{'\xdc','\xf6'},{'\xdc','\xfd'},{'\xb6','\xfe'},{'\xb6','\xfd'},
+ {'\xb6','\xfc'},{'\xdc','\xfb'},{'\xdd','\x41'},{'\xb6','\xf9'},{'\xb7','\x41'},
+ {'\x99','\xca'},{'\xdc','\xf4'},{'\x00','\x00'},{'\xdc','\xfe'},{'\xdc','\xf3'},
+ {'\xdc','\xfc'},{'\xb6','\xfa'},{'\xdd','\x42'},{'\xdc','\xf5'},{'\xb6','\xfb'},
+ {'\xdd','\x45'},{'\x99','\xcb'},{'\x99','\xcc'},{'\x82','\xbf'},{'\x9d','\x67'},
+ {'\x8e','\xe5'},{'\x99','\xcd'},{'\x89','\xd0'},{'\xe1','\x6e'},{'\xb9','\xe2'},
+ {'\xb9','\xe1'},{'\xb9','\xe3'},{'\xe1','\x7a'},{'\xe1','\x70'},{'\xe1','\x76'},
+ {'\xe1','\x6b'},{'\xe1','\x79'},{'\xe1','\x78'},{'\xe1','\x7c'},{'\xe1','\x75'},
+ {'\xb9','\xde'},{'\xe1','\x74'},{'\xb9','\xe4'},{'\x99','\xce'},{'\xe1','\x6d'},
+ {'\xb9','\xdf'},{'\x00','\x00'},{'\xe1','\x7b'},{'\xb9','\xe0'},{'\xe1','\x6f'},
+ {'\xe1','\x72'},{'\xe1','\x77'},{'\xe1','\x71'},{'\xe1','\x6c'},{'\x00','\x00'},
+ {'\x99','\xcf'},{'\x82','\xc0'},{'\xfb','\x67'},{'\xe1','\x73'},{'\xe5','\x55'},
+ {'\xbc','\x61'},{'\xe5','\x58'},{'\xe5','\x57'},{'\xe5','\x5a'},{'\xe5','\x5c'},
+ {'\xf9','\xdc'},{'\xbc','\x5f'},{'\x00','\x00'},{'\xe5','\x56'},{'\x99','\xd0'},
+ {'\xe5','\x54'},{'\x00','\x00'},{'\xe5','\x5d'},{'\xe5','\x5b'},{'\xe5','\x59'},
+ {'\x00','\x00'},{'\xe5','\x5f'},{'\x00','\x00'},{'\xe5','\x5e'},{'\xbc','\x63'},
+ {'\xbc','\x5e'},{'\x00','\x00'},{'\xbc','\x60'},{'\xbc','\x62'},{'\x99','\xd1'},
+ {'\x00','\x00'},{'\xe5','\x60'},{'\xe9','\x57'},{'\x99','\xd2'},{'\x00','\x00'},
+ {'\xe9','\x56'},{'\xe9','\x55'},{'\x99','\xd3'},{'\xe9','\x58'},{'\xe9','\x51'},
+ {'\x00','\x00'},{'\xe9','\x52'},{'\xe9','\x5a'},{'\xe9','\x53'},{'\x00','\x00'},
+ {'\xbe','\xc5'},{'\xe9','\x5c'},{'\x99','\xd4'},{'\xe9','\x5b'},{'\xe9','\x54'},
+ {'\x92','\xef'},{'\xec','\xd1'},{'\xc0','\xa8'},{'\xec','\xcf'},{'\xec','\xd4'},
+ {'\xec','\xd3'},{'\xe9','\x59'},{'\x00','\x00'},{'\xc0','\xa7'},{'\x99','\xd5'},
+ {'\xec','\xd2'},{'\xec','\xce'},{'\xec','\xd6'},{'\xec','\xd5'},{'\xc0','\xa6'},
+ {'\x00','\x00'},{'\xec','\xd0'},{'\x00','\x00'},{'\xbe','\xc6'},{'\x00','\x00'},
+ {'\x82','\xc1'},{'\x89','\xd1'},{'\xc2','\x54'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xef','\xc1'},{'\xf1','\xfa'},{'\xf1','\xfb'},{'\xf1','\xfc'},
+ {'\xc4','\x5c'},{'\x99','\xd6'},{'\x00','\x00'},{'\xc4','\x5d'},{'\x99','\xd7'},
+ {'\xf4','\x43'},{'\x99','\xd8'},{'\xf5','\xc8'},{'\xf5','\xc7'},{'\x00','\x00'},
+ {'\x99','\xd9'},{'\xf6','\xdb'},{'\xf6','\xdc'},{'\xf7','\xd5'},{'\xf8','\xa7'},
+ {'\x99','\xda'},{'\xa4','\x6c'},{'\xa4','\x6d'},{'\x00','\x00'},{'\xa4','\x6e'},
+ {'\xa4','\xd5'},{'\xa5','\xa5'},{'\xc9','\xd3'},{'\xa6','\x72'},{'\xa6','\x73'},
+ {'\x83','\xb2'},{'\xa7','\xb7'},{'\xa7','\xb8'},{'\xa7','\xb6'},{'\xa7','\xb5'},
+ {'\x00','\x00'},{'\xa9','\x73'},{'\x00','\x00'},{'\x00','\x00'},{'\xcc','\x55'},
+ {'\xa9','\x75'},{'\xa9','\x74'},{'\xcc','\x56'},{'\x88','\xd4'},{'\x00','\x00'},
+ {'\x99','\xdb'},{'\xab','\xc4'},{'\x8c','\xcb'},{'\xae','\x5d'},{'\xd1','\x65'},
+ {'\xa0','\x41'},{'\xd4','\xf0'},{'\x00','\x00'},{'\xb1','\x45'},{'\xb4','\x47'},
+ {'\xd4','\xef'},{'\xb4','\x46'},{'\x99','\xdc'},{'\xb9','\xe5'},{'\x99','\xdd'},
+ {'\xe1','\x7d'},{'\xbe','\xc7'},{'\x00','\x00'},{'\xc0','\xa9'},{'\xec','\xd7'},
+ {'\x99','\xde'},{'\xc4','\x5e'},{'\x00','\x00'},{'\xc5','\x70'},{'\xc6','\xcb'},
+ {'\xc9','\x72'},{'\x99','\xdf'},{'\xa5','\xa6'},{'\xc9','\x73'},{'\xa6','\x76'},
+ {'\x00','\x00'},{'\xa6','\x74'},{'\xa6','\x75'},{'\xa6','\x77'},{'\x00','\x00'},
+ {'\xa7','\xba'},{'\xa7','\xb9'},{'\x93','\xfd'},{'\xca','\xbc'},{'\xa7','\xbb'},
+ {'\x99','\xe0'},{'\x00','\x00'},{'\xca','\xbd'},{'\xcc','\x57'},{'\x00','\x00'},
+ {'\xcc','\x58'},{'\x9a','\x40'},{'\xa9','\x76'},{'\xa9','\x78'},{'\xa9','\x7a'},
+ {'\xa9','\x77'},{'\xa9','\x7b'},{'\xa9','\x79'},{'\x8b','\xf3'},{'\x86','\xbf'},
+ {'\x92','\xd4'},{'\x8b','\x70'},{'\x87','\xbf'},{'\xab','\xc8'},{'\xab','\xc5'},
+ {'\xab','\xc7'},{'\xab','\xc9'},{'\xab','\xc6'},{'\xd1','\x66'},{'\xce','\x77'},
+ {'\x00','\x00'},{'\x88','\xd6'},{'\x90','\xb3'},{'\xd1','\x68'},{'\xd1','\x67'},
+ {'\xae','\x63'},{'\x00','\x00'},{'\xae','\x5f'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xae','\x60'},{'\xae','\x62'},{'\xae','\x64'},{'\xae','\x61'},{'\x9d','\x68'},
+ {'\xae','\x66'},{'\xae','\x65'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x87','\xbe'},{'\x87','\x59'},{'\xb1','\x4a'},{'\xd4','\xf2'},{'\xd4','\xf1'},
+ {'\xb1','\x49'},{'\xfc','\x43'},{'\xb1','\x48'},{'\xb1','\x47'},{'\xb1','\x4b'},
+ {'\xb1','\x46'},{'\x00','\x00'},{'\x82','\xc2'},{'\xd8','\xd5'},{'\xd8','\xd2'},
+ {'\xb4','\x49'},{'\xd8','\xd1'},{'\xd8','\xd6'},{'\x00','\x00'},{'\xb4','\x4b'},
+ {'\xd8','\xd4'},{'\xb4','\x48'},{'\xb4','\x4a'},{'\xd8','\xd3'},{'\x9a','\x55'},
+ {'\xdd','\x48'},{'\x9a','\x56'},{'\xdd','\x49'},{'\xdd','\x4a'},{'\x00','\x00'},
+ {'\x92','\x69'},{'\x00','\x00'},{'\x86','\xc0'},{'\xb9','\xe6'},{'\xb9','\xee'},
+ {'\xe1','\x7e'},{'\xb9','\xe8'},{'\xb9','\xec'},{'\xe1','\xa1'},{'\xb9','\xed'},
+ {'\xb9','\xe9'},{'\xb9','\xea'},{'\xb9','\xe7'},{'\xb9','\xeb'},{'\xbc','\x66'},
+ {'\xd8','\xd0'},{'\xbc','\x67'},{'\xbc','\x65'},{'\x00','\x00'},{'\xbc','\x64'},
+ {'\xe9','\x5d'},{'\xbe','\xc8'},{'\xec','\xd8'},{'\xec','\xd9'},{'\x82','\xc3'},
+ {'\x00','\x00'},{'\xc3','\x64'},{'\xc4','\x5f'},{'\x00','\x00'},{'\xa4','\x6f'},
+ {'\x86','\xc1'},{'\xa6','\x78'},{'\x84','\xd6'},{'\x88','\xd5'},{'\x00','\x00'},
+ {'\x93','\x66'},{'\x86','\xba'},{'\x00','\x00'},{'\xab','\xca'},{'\x93','\x47'},
+ {'\xd1','\x69'},{'\xae','\x67'},{'\x95','\x5b'},{'\x92','\xe2'},{'\xb1','\x4e'},
+ {'\xb1','\x4d'},{'\xb1','\x4c'},{'\xb4','\x4c'},{'\xb4','\x4d'},{'\xd8','\xd7'},
+ {'\xb9','\xef'},{'\xbe','\xc9'},{'\xa4','\x70'},{'\xc9','\x5c'},{'\xa4','\xd6'},
+ {'\xc9','\x74'},{'\x82','\xc4'},{'\x86','\xe0'},{'\xc9','\xd4'},{'\xa6','\x79'},
+ {'\x00','\x00'},{'\x86','\xb7'},{'\x00','\x00'},{'\xa9','\x7c'},{'\x00','\x00'},
+ {'\x82','\xc5'},{'\x86','\xaf'},{'\x82','\xc6'},{'\xdd','\x4b'},{'\xfb','\xf3'},
+ {'\x00','\x00'},{'\xa4','\x71'},{'\x9a','\x57'},{'\xa4','\xd7'},{'\xc9','\xd5'},
+ {'\x00','\x00'},{'\x84','\xd0'},{'\xca','\xbe'},{'\x00','\x00'},{'\xca','\xbf'},
+ {'\x00','\x00'},{'\xa7','\xbc'},{'\x82','\x59'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xd8','\xd8'},{'\xb4','\x4e'},{'\x00','\x00'},{'\xdd','\x4c'},{'\x89','\xd2'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc0','\xaa'},{'\xa4','\x72'},{'\xa4','\xa8'},
+ {'\xa4','\xd8'},{'\xc9','\x75'},{'\xa5','\xa7'},{'\x86','\xe9'},{'\xa7','\xc0'},
+ {'\xa7','\xbf'},{'\xa7','\xbd'},{'\xa7','\xbe'},{'\x87','\xc1'},{'\x00','\x00'},
+ {'\xcc','\x59'},{'\xa9','\x7e'},{'\xa9','\xa1'},{'\xcc','\x5a'},{'\xa9','\x7d'},
+ {'\x84','\x40'},{'\x83','\x57'},{'\xab','\xce'},{'\xce','\x78'},{'\xab','\xcd'},
+ {'\xab','\xcb'},{'\xab','\xcc'},{'\xae','\x6a'},{'\xae','\x68'},{'\x00','\x00'},
+ {'\x82','\xc7'},{'\xd1','\x6b'},{'\xae','\x69'},{'\xd1','\x6a'},{'\x00','\x00'},
+ {'\xae','\x5e'},{'\xd4','\xf3'},{'\x00','\x00'},{'\x00','\x00'},{'\xb1','\x50'},
+ {'\xb1','\x51'},{'\x8c','\x70'},{'\x00','\x00'},{'\xb1','\x4f'},{'\x86','\xc2'},
+ {'\xb9','\xf0'},{'\xe1','\xa2'},{'\xbc','\x68'},{'\xbc','\x69'},{'\x89','\xd3'},
+ {'\xe5','\x61'},{'\xc0','\xab'},{'\xef','\xc2'},{'\xef','\xc3'},{'\x00','\x00'},
+ {'\xc4','\xdd'},{'\xf8','\xa8'},{'\xc9','\x4b'},{'\xa4','\xd9'},{'\x00','\x00'},
+ {'\xa4','\x73'},{'\x00','\x00'},{'\xc9','\x77'},{'\xc9','\x76'},{'\x00','\x00'},
+ {'\x94','\x70'},{'\x00','\x00'},{'\x9d','\x64'},{'\xa6','\x7a'},{'\xc9','\xd7'},
+ {'\xc9','\xd8'},{'\xc9','\xd6'},{'\x00','\x00'},{'\xc9','\xd9'},{'\x89','\xd4'},
+ {'\x00','\x00'},{'\x85','\xd7'},{'\x83','\xdb'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x9a','\x58'},{'\xca','\xc7'},{'\x00','\x00'},{'\xca','\xc2'},{'\xca','\xc4'},
+ {'\xca','\xc6'},{'\xca','\xc3'},{'\xa7','\xc4'},{'\xca','\xc0'},{'\x00','\x00'},
+ {'\xca','\xc1'},{'\xa7','\xc1'},{'\xa7','\xc2'},{'\xca','\xc5'},{'\xca','\xc8'},
+ {'\xa7','\xc3'},{'\xca','\xc9'},{'\x86','\xc4'},{'\x84','\x42'},{'\x83','\xb5'},
+ {'\x82','\xc8'},{'\x84','\xd7'},{'\x83','\xb4'},{'\x82','\xc9'},{'\xcc','\x68'},
+ {'\x9a','\x59'},{'\xcc','\x62'},{'\xcc','\x5d'},{'\xa9','\xa3'},{'\xcc','\x65'},
+ {'\xcc','\x63'},{'\xcc','\x5c'},{'\xcc','\x69'},{'\xcc','\x6c'},{'\xcc','\x67'},
+ {'\xcc','\x60'},{'\xa9','\xa5'},{'\xcc','\x66'},{'\xa9','\xa6'},{'\xcc','\x61'},
+ {'\xcc','\x64'},{'\xcc','\x5b'},{'\xcc','\x5f'},{'\xcc','\x6b'},{'\xa9','\xa7'},
+ {'\x00','\x00'},{'\xa9','\xa8'},{'\x00','\x00'},{'\xcc','\x5e'},{'\xcc','\x6a'},
+ {'\xa9','\xa2'},{'\xa9','\xa4'},{'\x00','\x00'},{'\x82','\xca'},{'\x82','\xcb'},
+ {'\x94','\x71'},{'\x8d','\xcd'},{'\x94','\x73'},{'\x8f','\xfc'},{'\x00','\x00'},
+ {'\x82','\xcc'},{'\x9a','\x5a'},{'\x00','\x00'},{'\x8e','\xe6'},{'\x94','\x72'},
+ {'\xce','\xab'},{'\xce','\xa4'},{'\xce','\xaa'},{'\xce','\xa3'},{'\xce','\xa5'},
+ {'\xce','\x7d'},{'\xce','\x7b'},{'\x00','\x00'},{'\xce','\xac'},{'\xce','\xa9'},
+ {'\xce','\x79'},{'\xfb','\xf5'},{'\xab','\xd0'},{'\xce','\xa7'},{'\xce','\xa8'},
+ {'\x9d','\x71'},{'\xce','\xa6'},{'\xce','\x7c'},{'\xce','\x7a'},{'\xab','\xcf'},
+ {'\xce','\xa2'},{'\xce','\x7e'},{'\x00','\x00'},{'\x00','\x00'},{'\xce','\xa1'},
+ {'\xce','\xad'},{'\x94','\x50'},{'\x83','\xb3'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x8e','\xb4'},{'\x84','\x41'},{'\x8c','\xcd'},{'\x00','\x00'},{'\xae','\x6f'},
+ {'\xfb','\xf6'},{'\xae','\x6e'},{'\x00','\x00'},{'\xd1','\x6c'},{'\xae','\x6b'},
+ {'\xd1','\x6e'},{'\x95','\x5d'},{'\xae','\x70'},{'\xd1','\x6f'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xae','\x73'},{'\x82','\xcd'},{'\xae','\x71'},{'\xd1','\x70'},
+ {'\xce','\xae'},{'\xd1','\x72'},{'\x82','\xce'},{'\xae','\x6d'},{'\x9d','\x69'},
+ {'\xae','\x6c'},{'\x00','\x00'},{'\xd1','\x6d'},{'\xd1','\x71'},{'\xae','\x72'},
+ {'\x8e','\xb3'},{'\x8d','\xce'},{'\x00','\x00'},{'\x00','\x00'},{'\xb1','\x53'},
+ {'\xb1','\x52'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xd4','\xf5'},
+ {'\xd4','\xf9'},{'\xd4','\xfb'},{'\xb1','\x54'},{'\xd4','\xfe'},{'\x9a','\x5b'},
+ {'\xb1','\x58'},{'\xd5','\x41'},{'\x00','\x00'},{'\xb1','\x5a'},{'\x82','\xcf'},
+ {'\xb1','\x56'},{'\xb1','\x5e'},{'\x82','\xd0'},{'\xb1','\x5b'},{'\xd4','\xf7'},
+ {'\xb1','\x55'},{'\x00','\x00'},{'\xd4','\xf6'},{'\xd4','\xf4'},{'\xd5','\x43'},
+ {'\xd4','\xf8'},{'\x00','\x00'},{'\xb1','\x57'},{'\xd5','\x42'},{'\xb1','\x5c'},
+ {'\xd4','\xfd'},{'\xd4','\xfc'},{'\xb1','\x5d'},{'\xd4','\xfa'},{'\xb1','\x59'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x9a','\x5c'},{'\x86','\xc3'},{'\xd5','\x44'},
+ {'\x9a','\x5d'},{'\xd5','\x40'},{'\xd8','\xe7'},{'\xd8','\xee'},{'\xd8','\xe3'},
+ {'\xb4','\x51'},{'\xd8','\xdf'},{'\xd8','\xef'},{'\xd8','\xd9'},{'\xd8','\xec'},
+ {'\xd8','\xea'},{'\xd8','\xe4'},{'\x00','\x00'},{'\xd8','\xed'},{'\xd8','\xe6'},
+ {'\x82','\xd1'},{'\xd8','\xde'},{'\xd8','\xf0'},{'\xd8','\xdc'},{'\xd8','\xe9'},
+ {'\xd8','\xda'},{'\x00','\x00'},{'\xd8','\xf1'},{'\xfb','\xf7'},{'\xb4','\x52'},
+ {'\x9a','\x5e'},{'\xd8','\xeb'},{'\xdd','\x4f'},{'\xd8','\xdd'},{'\xb4','\x4f'},
+ {'\x00','\x00'},{'\xd8','\xe1'},{'\x00','\x00'},{'\xb4','\x50'},{'\xd8','\xe0'},
+ {'\xd8','\xe5'},{'\x82','\xd2'},{'\x00','\x00'},{'\xd8','\xe2'},{'\x9a','\x5f'},
+ {'\x95','\x65'},{'\x89','\xd5'},{'\xd8','\xe8'},{'\x00','\x00'},{'\x8d','\xdc'},
+ {'\x82','\xd3'},{'\x8e','\x67'},{'\xdd','\x53'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xdd','\x56'},{'\xdd','\x4e'},{'\x00','\x00'},{'\xdd','\x50'},
+ {'\x00','\x00'},{'\xdd','\x55'},{'\xdd','\x54'},{'\xb7','\x43'},{'\x00','\x00'},
+ {'\xd8','\xdb'},{'\xdd','\x52'},{'\x82','\xd4'},{'\x00','\x00'},{'\xb7','\x44'},
+ {'\x9a','\x60'},{'\xdd','\x4d'},{'\xdd','\x51'},{'\x82','\xd5'},{'\x82','\xd6'},
+ {'\xfe','\x7e'},{'\x94','\x74'},{'\xe1','\xa9'},{'\x9d','\x7a'},{'\xe1','\xb0'},
+ {'\xe1','\xa7'},{'\x9a','\x61'},{'\xe1','\xae'},{'\xe1','\xa5'},{'\xe1','\xad'},
+ {'\xe1','\xb1'},{'\xe1','\xa4'},{'\xe1','\xa8'},{'\xe1','\xa3'},{'\x00','\x00'},
+ {'\xb9','\xf1'},{'\x9a','\x62'},{'\xe1','\xa6'},{'\xb9','\xf2'},{'\xe1','\xac'},
+ {'\xe1','\xab'},{'\xe1','\xaa'},{'\x93','\xfe'},{'\x82','\xd7'},{'\xe1','\xaf'},
+ {'\xfb','\xf8'},{'\x00','\x00'},{'\x82','\xd8'},{'\x00','\x00'},{'\xe5','\x65'},
+ {'\xe5','\x67'},{'\xbc','\x6b'},{'\xe5','\x68'},{'\x00','\x00'},{'\xe5','\x63'},
+ {'\x00','\x00'},{'\xe5','\x62'},{'\xe5','\x6c'},{'\x00','\x00'},{'\xe5','\x6a'},
+ {'\xbc','\x6a'},{'\xe5','\x6d'},{'\xe5','\x64'},{'\xe5','\x69'},{'\xe5','\x6b'},
+ {'\xe5','\x66'},{'\x00','\x00'},{'\x9a','\x63'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xe9','\x61'},{'\xe9','\x66'},{'\xe9','\x60'},{'\xe9','\x65'},{'\x9a','\x64'},
+ {'\xe9','\x5e'},{'\xe9','\x68'},{'\xe9','\x64'},{'\xe9','\x69'},{'\xe9','\x63'},
+ {'\xe9','\x5f'},{'\xe9','\x67'},{'\x00','\x00'},{'\xe9','\x6a'},{'\xe9','\x62'},
+ {'\x9a','\x65'},{'\xec','\xda'},{'\xc0','\xaf'},{'\x82','\xd9'},{'\xc0','\xad'},
+ {'\x00','\x00'},{'\xc0','\xac'},{'\xc0','\xae'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xef','\xc4'},{'\x9a','\x66'},{'\xf1','\x72'},{'\xf1','\xfd'},{'\x00','\x00'},
+ {'\x8c','\xcc'},{'\xf4','\x44'},{'\xf4','\x45'},{'\x00','\x00'},{'\xc4','\x60'},
+ {'\x00','\x00'},{'\xf5','\xc9'},{'\x82','\x53'},{'\xc4','\xde'},{'\x00','\x00'},
+ {'\xf5','\xca'},{'\x82','\xda'},{'\xf6','\xde'},{'\xc5','\x72'},{'\x82','\xdb'},
+ {'\xc5','\x71'},{'\xf6','\xdd'},{'\xc5','\xc9'},{'\x9a','\x67'},{'\xf7','\xd6'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xcc'},{'\x00','\x00'},{'\xa4','\x74'},
+ {'\xa6','\x7b'},{'\xc9','\xda'},{'\xca','\xca'},{'\xa8','\xb5'},{'\xb1','\x5f'},
+ {'\x93','\x57'},{'\x00','\x00'},{'\xa4','\x75'},{'\xa5','\xaa'},{'\xa5','\xa9'},
+ {'\xa5','\xa8'},{'\x88','\xb2'},{'\x00','\x00'},{'\xa7','\xc5'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xae','\x74'},{'\x8e','\x43'},{'\xdd','\x57'},{'\xa4','\x76'},
+ {'\xa4','\x77'},{'\xa4','\x78'},{'\xa4','\xda'},{'\xfb','\xfa'},{'\x00','\x00'},
+ {'\xab','\xd1'},{'\x00','\x00'},{'\xce','\xaf'},{'\x00','\x00'},{'\x92','\x66'},
+ {'\x00','\x00'},{'\xb4','\x53'},{'\xa4','\x79'},{'\xc9','\x5d'},{'\x00','\x00'},
+ {'\x86','\xc5'},{'\xa5','\xab'},{'\xa5','\xac'},{'\xc9','\x78'},{'\x83','\x6c'},
+ {'\xa6','\x7c'},{'\x00','\x00'},{'\x83','\xb6'},{'\x9a','\x68'},{'\xca','\xcb'},
+ {'\xfb','\xfb'},{'\xa7','\xc6'},{'\x00','\x00'},{'\xca','\xcc'},{'\x84','\xd9'},
+ {'\x84','\x44'},{'\xa9','\xae'},{'\xfb','\xfc'},{'\x00','\x00'},{'\xcc','\x6e'},
+ {'\xa9','\xac'},{'\xa9','\xab'},{'\xcc','\x6d'},{'\xa9','\xa9'},{'\xcc','\x6f'},
+ {'\xa9','\xaa'},{'\xa9','\xad'},{'\x87','\xc3'},{'\xab','\xd2'},{'\x00','\x00'},
+ {'\xab','\xd4'},{'\xce','\xb3'},{'\xce','\xb0'},{'\xce','\xb1'},{'\xce','\xb2'},
+ {'\xce','\xb4'},{'\xab','\xd3'},{'\x84','\x43'},{'\x84','\xd8'},{'\xd1','\x74'},
+ {'\xd1','\x73'},{'\x00','\x00'},{'\xae','\x76'},{'\x00','\x00'},{'\xae','\x75'},
+ {'\x89','\xd6'},{'\x93','\x67'},{'\x92','\x6f'},{'\x8f','\x50'},{'\x00','\x00'},
+ {'\xb1','\x62'},{'\xd5','\x46'},{'\x00','\x00'},{'\xb1','\x61'},{'\xb1','\x63'},
+ {'\xb1','\x60'},{'\x00','\x00'},{'\x00','\x00'},{'\x8e','\x68'},{'\x86','\xc6'},
+ {'\xb4','\x55'},{'\xd5','\x45'},{'\x00','\x00'},{'\xb4','\x56'},{'\xd8','\xf3'},
+ {'\x88','\xcb'},{'\xb4','\x57'},{'\xd8','\xf2'},{'\xb4','\x54'},{'\x00','\x00'},
+ {'\x82','\xdc'},{'\x9a','\x69'},{'\x00','\x00'},{'\xdd','\x5a'},{'\xdd','\x5c'},
+ {'\xb7','\x45'},{'\xdd','\x5b'},{'\xdd','\x59'},{'\xdd','\x58'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xe1','\xb4'},{'\xb9','\xf7'},{'\xb9','\xf5'},
+ {'\x00','\x00'},{'\xb9','\xf6'},{'\xe1','\xb2'},{'\xe1','\xb3'},{'\x00','\x00'},
+ {'\xb9','\xf3'},{'\xe5','\x71'},{'\xe5','\x6f'},{'\xfb','\xfe'},{'\xbc','\x6d'},
+ {'\xe5','\x70'},{'\xbc','\x6e'},{'\xbc','\x6c'},{'\xb9','\xf4'},{'\x82','\xdd'},
+ {'\x00','\x00'},{'\xe9','\x6d'},{'\xe9','\x6b'},{'\xe9','\x6c'},{'\xe5','\x6e'},
+ {'\xec','\xdc'},{'\xc0','\xb0'},{'\xec','\xdb'},{'\xef','\xc5'},{'\xef','\xc6'},
+ {'\xe9','\x6e'},{'\xf1','\xfe'},{'\x00','\x00'},{'\xa4','\x7a'},{'\xa5','\xad'},
+ {'\xa6','\x7e'},{'\xc9','\xdb'},{'\xa6','\x7d'},{'\x00','\x00'},{'\xa9','\xaf'},
+ {'\xb7','\x46'},{'\xc6','\xcd'},{'\xa4','\xdb'},{'\xa5','\xae'},{'\xab','\xd5'},
+ {'\xb4','\x58'},{'\xc6','\xce'},{'\xc9','\x79'},{'\x93','\x75'},{'\xc9','\x7a'},
+ {'\x92','\xbe'},{'\xc9','\xdc'},{'\x00','\x00'},{'\x87','\xca'},{'\xa7','\xc8'},
+ {'\xca','\xd0'},{'\xca','\xce'},{'\xa7','\xc9'},{'\xca','\xcd'},{'\xca','\xcf'},
+ {'\xca','\xd1'},{'\x00','\x00'},{'\xa7','\xc7'},{'\x8b','\x72'},{'\x8e','\xb5'},
+ {'\x9a','\x6a'},{'\x83','\xb7'},{'\x89','\xd8'},{'\xa9','\xb3'},{'\xa9','\xb4'},
+ {'\xa9','\xb1'},{'\x00','\x00'},{'\x87','\xc6'},{'\xa9','\xb0'},{'\xce','\xb8'},
+ {'\xa9','\xb2'},{'\x00','\x00'},{'\x8b','\x71'},{'\x87','\xc4'},{'\xab','\xd6'},
+ {'\x00','\x00'},{'\xce','\xb7'},{'\xce','\xb9'},{'\xce','\xb6'},{'\xce','\xba'},
+ {'\xab','\xd7'},{'\xae','\x79'},{'\xd1','\x75'},{'\x00','\x00'},{'\xd1','\x77'},
+ {'\xae','\x77'},{'\xd1','\x78'},{'\xae','\x78'},{'\xd1','\x76'},{'\x00','\x00'},
+ {'\xce','\xb5'},{'\xd5','\x47'},{'\xd5','\x4a'},{'\xd5','\x4b'},{'\xd5','\x48'},
+ {'\xb1','\x67'},{'\xb1','\x66'},{'\xb1','\x64'},{'\xb1','\x65'},{'\xd5','\x49'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9a','\x6b'},{'\xb1','\x68'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xb4','\x5a'},{'\xb4','\x5b'},{'\x93','\xb2'},
+ {'\xb4','\x5c'},{'\xdd','\x5d'},{'\xdd','\x5f'},{'\xdd','\x61'},{'\xb7','\x48'},
+ {'\xb7','\x47'},{'\xb4','\x59'},{'\xdd','\x60'},{'\xdd','\x5e'},{'\xfe','\xa4'},
+ {'\xe1','\xb8'},{'\x82','\xde'},{'\x82','\xdf'},{'\xe1','\xb6'},{'\xe1','\xbc'},
+ {'\xb9','\xf8'},{'\xe1','\xbd'},{'\xe1','\xba'},{'\xb9','\xf9'},{'\xe1','\xb7'},
+ {'\xe1','\xb5'},{'\xe1','\xbb'},{'\xbc','\x70'},{'\xe5','\x73'},{'\xe1','\xb9'},
+ {'\xbc','\x72'},{'\xe5','\x74'},{'\xbc','\x71'},{'\xbc','\x74'},{'\xe5','\x75'},
+ {'\xbc','\x6f'},{'\xbc','\x73'},{'\x00','\x00'},{'\xe9','\x73'},{'\xe9','\x71'},
+ {'\xe9','\x70'},{'\xe9','\x72'},{'\xe9','\x6f'},{'\x82','\xe0'},{'\x00','\x00'},
+ {'\xc3','\x66'},{'\x00','\x00'},{'\xf4','\x46'},{'\xf4','\x47'},{'\x82','\xe1'},
+ {'\xf5','\xcb'},{'\xf6','\xdf'},{'\xc6','\x55'},{'\xc6','\xcf'},{'\x00','\x00'},
+ {'\xa9','\xb5'},{'\xa7','\xca'},{'\x95','\xa4'},{'\x95','\xa1'},{'\xab','\xd8'},
+ {'\x95','\xee'},{'\x95','\xfa'},{'\x00','\x00'},{'\xa4','\x7b'},{'\xa4','\xdc'},
+ {'\x85','\x7b'},{'\xa5','\xaf'},{'\xc9','\xdd'},{'\x84','\x56'},{'\xa7','\xcb'},
+ {'\xca','\xd2'},{'\x00','\x00'},{'\xce','\xbb'},{'\xab','\xd9'},{'\x82','\xe2'},
+ {'\xb9','\xfa'},{'\xa4','\x7c'},{'\x82','\xe3'},{'\x95','\xaa'},{'\x9a','\x6c'},
+ {'\xa6','\xa1'},{'\x93','\xae'},{'\x82','\xe4'},{'\xb7','\x49'},{'\xa4','\x7d'},
+ {'\xa4','\xdd'},{'\xa4','\xde'},{'\x94','\x75'},{'\xa5','\xb1'},{'\xa5','\xb0'},
+ {'\x00','\x00'},{'\xc9','\xde'},{'\xa6','\xa2'},{'\x00','\x00'},{'\xca','\xd3'},
+ {'\x00','\x00'},{'\xa7','\xcc'},{'\x84','\x45'},{'\x82','\xe5'},{'\xcc','\x71'},
+ {'\xcc','\x72'},{'\xcc','\x73'},{'\x93','\xf9'},{'\xa9','\xb6'},{'\xa9','\xb7'},
+ {'\xcc','\x70'},{'\xa9','\xb8'},{'\x8d','\xc3'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xab','\xda'},{'\xce','\xbc'},{'\x8c','\xce'},{'\xd1','\x7a'},{'\xae','\x7a'},
+ {'\x00','\x00'},{'\xd1','\x79'},{'\x82','\xe6'},{'\xb1','\x69'},{'\xd5','\x4c'},
+ {'\xb1','\x6a'},{'\xd5','\x4d'},{'\x87','\xc9'},{'\x84','\x46'},{'\x9d','\x7b'},
+ {'\xb4','\x5d'},{'\x00','\x00'},{'\x93','\x71'},{'\x00','\x00'},{'\xdd','\x62'},
+ {'\x82','\xe7'},{'\x00','\x00'},{'\xe1','\xbf'},{'\xe1','\xbe'},{'\x82','\xe8'},
+ {'\xb9','\xfb'},{'\x00','\x00'},{'\xbc','\x75'},{'\xe5','\x76'},{'\xbe','\xca'},
+ {'\xe9','\x74'},{'\xc0','\xb1'},{'\xfc','\x41'},{'\xc5','\x73'},{'\xf7','\xd8'},
+ {'\xc6','\xd0'},{'\x82','\xe9'},{'\x8a','\xd0'},{'\x85','\xe5'},{'\xcc','\x74'},
+ {'\x89','\xa3'},{'\xce','\xbd'},{'\xb1','\x6b'},{'\xd8','\xf4'},{'\xb7','\x4a'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x82','\xea'},{'\xc2','\x55'},{'\xc2','\x55'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xd1'},{'\xa7','\xce'},{'\xfe','\xa8'},
+ {'\xa7','\xcd'},{'\xab','\xdb'},{'\x82','\xeb'},{'\xd1','\x7b'},{'\x00','\x00'},
+ {'\xb1','\x6d'},{'\xb3','\x43'},{'\xb1','\x6e'},{'\xb1','\x6c'},{'\xb4','\x5e'},
+ {'\x00','\x00'},{'\xe1','\xc0'},{'\xb9','\xfc'},{'\xbc','\x76'},{'\x9a','\x6d'},
+ {'\xc9','\x4c'},{'\xc9','\xdf'},{'\x00','\x00'},{'\xca','\xd5'},{'\xa7','\xcf'},
+ {'\xca','\xd4'},{'\xa7','\xd0'},{'\x00','\x00'},{'\x86','\xc7'},{'\xa9','\xbc'},
+ {'\xcc','\x77'},{'\xcc','\x76'},{'\xa9','\xbb'},{'\xa9','\xb9'},{'\xa9','\xba'},
+ {'\xcc','\x75'},{'\x82','\xec'},{'\x92','\xa6'},{'\xab','\xdd'},{'\xce','\xbe'},
+ {'\xab','\xe0'},{'\xab','\xdc'},{'\xab','\xe2'},{'\xab','\xde'},{'\xab','\xdf'},
+ {'\xab','\xe1'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xae','\x7d'},
+ {'\xae','\x7c'},{'\xae','\x7b'},{'\x92','\xdc'},{'\x00','\x00'},{'\x84','\x48'},
+ {'\xd5','\x4f'},{'\xb1','\x6f'},{'\xb1','\x72'},{'\xb1','\x70'},{'\x00','\x00'},
+ {'\xd5','\x4e'},{'\xb1','\x75'},{'\x00','\x00'},{'\xb1','\x71'},{'\xd5','\x50'},
+ {'\xb1','\x74'},{'\xb1','\x73'},{'\x00','\x00'},{'\x00','\x00'},{'\xfc','\x47'},
+ {'\xd8','\xf6'},{'\xd8','\xf5'},{'\x95','\x5a'},{'\xb4','\x61'},{'\xb4','\x5f'},
+ {'\xb4','\x60'},{'\xd8','\xf7'},{'\xb7','\x4b'},{'\xdd','\x64'},{'\xb7','\x4c'},
+ {'\xdd','\x63'},{'\x00','\x00'},{'\x9a','\x6e'},{'\xe5','\x77'},{'\x93','\xa8'},
+ {'\x93','\x76'},{'\xbc','\x78'},{'\xe1','\xc1'},{'\xbc','\x77'},{'\x00','\x00'},
+ {'\xb9','\xfd'},{'\xfc','\x48'},{'\xec','\xde'},{'\xe9','\x75'},{'\xc0','\xb2'},
+ {'\xec','\xdd'},{'\xf2','\x40'},{'\xf4','\x48'},{'\xf4','\x49'},{'\x9a','\x6f'},
+ {'\xa4','\xdf'},{'\x9c','\xf5'},{'\xa5','\xb2'},{'\x88','\xda'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xc9','\x7b'},{'\x00','\x00'},{'\x00','\x00'},{'\xa7','\xd2'},
+ {'\xa7','\xd4'},{'\x00','\x00'},{'\xc9','\xe2'},{'\xca','\xd8'},{'\xca','\xd7'},
+ {'\xca','\xd6'},{'\x00','\x00'},{'\xc9','\xe1'},{'\xc9','\xe0'},{'\xa6','\xa4'},
+ {'\xa7','\xd3'},{'\xa7','\xd1'},{'\xa6','\xa3'},{'\x00','\x00'},{'\x9a','\x70'},
+ {'\x92','\x4e'},{'\xa9','\xbd'},{'\xcc','\x78'},{'\x9a','\x71'},{'\xa9','\xbe'},
+ {'\xca','\xdd'},{'\x00','\x00'},{'\xca','\xdf'},{'\xca','\xde'},{'\xcc','\x79'},
+ {'\x00','\x00'},{'\x87','\xcc'},{'\xca','\xda'},{'\x00','\x00'},{'\xa7','\xd8'},
+ {'\xa7','\xd6'},{'\x00','\x00'},{'\xca','\xd9'},{'\xca','\xdb'},{'\xca','\xe1'},
+ {'\x82','\xed'},{'\xa7','\xd5'},{'\x00','\x00'},{'\xca','\xdc'},{'\xca','\xe5'},
+ {'\xa9','\xc0'},{'\x00','\x00'},{'\xca','\xe2'},{'\xa7','\xd7'},{'\x00','\x00'},
+ {'\xca','\xe0'},{'\xca','\xe3'},{'\x00','\x00'},{'\xa9','\xbf'},{'\x85','\xc7'},
+ {'\xa9','\xc1'},{'\xca','\xe4'},{'\x86','\xc8'},{'\x87','\xcd'},{'\x87','\xd1'},
+ {'\x8e','\x6b'},{'\x84','\x4a'},{'\x85','\xc8'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xcc','\xaf'},{'\xcc','\xa2'},{'\xcc','\x7e'},{'\xcc','\xae'},{'\xcc','\xa9'},
+ {'\xab','\xe7'},{'\xa9','\xc2'},{'\xcc','\xaa'},{'\xcc','\xad'},{'\xab','\xe3'},
+ {'\xcc','\xac'},{'\xa9','\xc3'},{'\xa9','\xc8'},{'\xa9','\xc6'},{'\xcc','\xa3'},
+ {'\x00','\x00'},{'\xcc','\x7c'},{'\xcc','\xa5'},{'\xa9','\xcd'},{'\xcc','\xb0'},
+ {'\xab','\xe4'},{'\xcc','\xa6'},{'\x00','\x00'},{'\xab','\xe5'},{'\xa9','\xc9'},
+ {'\xcc','\xa8'},{'\x9a','\x72'},{'\xce','\xcd'},{'\xab','\xe6'},{'\xcc','\x7b'},
+ {'\xa9','\xca'},{'\xab','\xe8'},{'\xa9','\xcb'},{'\xa9','\xc7'},{'\xa9','\xcc'},
+ {'\xcc','\xa7'},{'\xcc','\x7a'},{'\xcc','\xab'},{'\xa9','\xc4'},{'\x00','\x00'},
+ {'\x95','\xa6'},{'\xcc','\x7d'},{'\xcc','\xa4'},{'\xcc','\xa1'},{'\xa9','\xc5'},
+ {'\x00','\x00'},{'\xce','\xbf'},{'\x00','\x00'},{'\xce','\xc0'},{'\x94','\x76'},
+ {'\x8a','\x4b'},{'\x8f','\x74'},{'\x00','\x00'},{'\x00','\x00'},{'\x8e','\xe7'},
+ {'\xce','\xca'},{'\xd1','\xa1'},{'\xce','\xcb'},{'\xab','\xee'},{'\xce','\xce'},
+ {'\xce','\xc4'},{'\xab','\xed'},{'\xce','\xc6'},{'\x00','\x00'},{'\xce','\xc7'},
+ {'\x82','\xee'},{'\x8c','\xf6'},{'\xce','\xc9'},{'\xab','\xe9'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xae','\xa3'},{'\x00','\x00'},{'\xf9','\xda'},{'\xce','\xc5'},
+ {'\xce','\xc1'},{'\xae','\xa4'},{'\x00','\x00'},{'\x00','\x00'},{'\xce','\xcf'},
+ {'\xae','\x7e'},{'\xd1','\x7d'},{'\xce','\xc8'},{'\x00','\x00'},{'\xd1','\x7c'},
+ {'\xce','\xc3'},{'\xce','\xcc'},{'\x82','\xef'},{'\x00','\x00'},{'\xab','\xec'},
+ {'\xae','\xa1'},{'\xab','\xf2'},{'\xae','\xa2'},{'\xce','\xd0'},{'\xd1','\x7e'},
+ {'\xab','\xeb'},{'\xae','\xa6'},{'\xab','\xf1'},{'\xab','\xf0'},{'\xab','\xef'},
+ {'\xae','\xa5'},{'\xce','\xd1'},{'\xae','\xa7'},{'\xab','\xea'},{'\x00','\x00'},
+ {'\xce','\xc2'},{'\x89','\xd9'},{'\x00','\x00'},{'\x92','\xa8'},{'\x84','\xdc'},
+ {'\xfc','\x4b'},{'\x86','\xca'},{'\x8f','\x51'},{'\x85','\xc9'},{'\x84','\xdf'},
+ {'\x84','\xe0'},{'\x8d','\xdd'},{'\x9a','\x73'},{'\xb1','\x76'},{'\xd1','\xa4'},
+ {'\xd1','\xa6'},{'\x00','\x00'},{'\xd1','\xa8'},{'\xae','\xa8'},{'\xae','\xae'},
+ {'\xd5','\x53'},{'\xd1','\xac'},{'\xd1','\xa3'},{'\xb1','\x78'},{'\xd5','\x51'},
+ {'\x82','\xf0'},{'\xae','\xad'},{'\xae','\xab'},{'\xd1','\xae'},{'\x00','\x00'},
+ {'\xd5','\x52'},{'\x00','\x00'},{'\xd1','\xa5'},{'\x00','\x00'},{'\xae','\xac'},
+ {'\xd1','\xa9'},{'\xae','\xaf'},{'\xd1','\xab'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xae','\xaa'},{'\xd1','\xaa'},{'\xd1','\xad'},{'\xd1','\xa7'},{'\xfb','\x64'},
+ {'\xae','\xa9'},{'\xb1','\x79'},{'\x00','\x00'},{'\xd1','\xa2'},{'\xb1','\x77'},
+ {'\xfc','\x4c'},{'\x00','\x00'},{'\x82','\xf1'},{'\xfe','\xa6'},{'\xb1','\x7a'},
+ {'\x93','\xaf'},{'\x92','\x41'},{'\x8e','\x69'},{'\x8b','\xf4'},{'\x8e','\x6a'},
+ {'\x00','\x00'},{'\x87','\xce'},{'\xd5','\x55'},{'\xd5','\x5e'},{'\xb4','\x64'},
+ {'\xfc','\x4d'},{'\xb1','\x7c'},{'\xb1','\xa3'},{'\xb4','\x65'},{'\xd5','\x60'},
+ {'\xb1','\xaa'},{'\xd8','\xf9'},{'\xd5','\x56'},{'\xb1','\xa2'},{'\xb1','\xa5'},
+ {'\xb1','\x7e'},{'\xd5','\x54'},{'\xd5','\x62'},{'\xd5','\x65'},{'\xd9','\x49'},
+ {'\x00','\x00'},{'\xd5','\x63'},{'\xd8','\xfd'},{'\xb1','\xa1'},{'\xb1','\xa8'},
+ {'\xb1','\xac'},{'\xd5','\x5d'},{'\xd8','\xf8'},{'\xd5','\x61'},{'\xb1','\x7b'},
+ {'\xd8','\xfa'},{'\xd5','\x64'},{'\xd8','\xfc'},{'\xd5','\x59'},{'\x00','\x00'},
+ {'\xb4','\x62'},{'\x00','\x00'},{'\xd5','\x57'},{'\xd5','\x58'},{'\xb1','\xa7'},
+ {'\x00','\x00'},{'\x9a','\x74'},{'\xb1','\xa6'},{'\xd5','\x5b'},{'\xb1','\xab'},
+ {'\xd5','\x5f'},{'\xb1','\xa4'},{'\xd5','\x5c'},{'\x82','\xf2'},{'\xb1','\xa9'},
+ {'\xb4','\x66'},{'\xb4','\x63'},{'\xd8','\xfb'},{'\x82','\xad'},{'\xd5','\x5a'},
+ {'\x00','\x00'},{'\xb1','\x7d'},{'\x8c','\x71'},{'\x86','\xcc'},{'\x8b','\x73'},
+ {'\x00','\x00'},{'\x88','\xd8'},{'\x84','\xde'},{'\x86','\xcb'},{'\x87','\xcf'},
+ {'\x86','\xc9'},{'\xb4','\x6b'},{'\xb4','\x6f'},{'\xd9','\x40'},{'\xb7','\x51'},
+ {'\xb4','\x6d'},{'\xd9','\x44'},{'\xb4','\x71'},{'\xdd','\x65'},{'\xd9','\x46'},
+ {'\xb7','\x53'},{'\xb4','\x69'},{'\xb4','\x6c'},{'\xd9','\x47'},{'\xfc','\x4e'},
+ {'\xd9','\x48'},{'\xd9','\x4e'},{'\xb4','\x73'},{'\xb7','\x54'},{'\x00','\x00'},
+ {'\xd9','\x4a'},{'\xd9','\x4f'},{'\xd9','\x43'},{'\xb7','\x5e'},{'\x9a','\x75'},
+ {'\xb7','\x55'},{'\xb4','\x72'},{'\xd9','\x41'},{'\xd9','\x50'},{'\x9a','\x76'},
+ {'\xb7','\x5d'},{'\xb4','\x70'},{'\xb7','\x4e'},{'\xd9','\x4d'},{'\x82','\xf3'},
+ {'\xb4','\x74'},{'\xd9','\x45'},{'\xd8','\xfe'},{'\xb4','\x6a'},{'\xd9','\x42'},
+ {'\x00','\x00'},{'\xd9','\x4b'},{'\x9a','\x77'},{'\xb7','\x4d'},{'\xb7','\x52'},
+ {'\xb4','\x67'},{'\xd9','\x4c'},{'\x00','\x00'},{'\xb7','\x50'},{'\x82','\xf4'},
+ {'\x82','\xf5'},{'\x9a','\x78'},{'\xb4','\x68'},{'\x87','\xd0'},{'\x00','\x00'},
+ {'\x8e','\xb6'},{'\xb7','\x5c'},{'\xe1','\xc3'},{'\xdd','\x70'},{'\x00','\x00'},
+ {'\xdd','\x68'},{'\xe1','\xc2'},{'\x00','\x00'},{'\xdd','\x6c'},{'\xdd','\x6e'},
+ {'\xfc','\x4f'},{'\x00','\x00'},{'\xdd','\x6b'},{'\x00','\x00'},{'\xb7','\x5b'},
+ {'\x00','\x00'},{'\xdd','\x6a'},{'\xb7','\x5f'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xe1','\xd2'},{'\x82','\xf6'},{'\x82','\xf7'},{'\xb7','\x5a'},
+ {'\xba','\x40'},{'\xdd','\x71'},{'\xe1','\xc4'},{'\xfc','\xc9'},{'\x00','\x00'},
+ {'\xb7','\x58'},{'\xdd','\x69'},{'\xdd','\x6d'},{'\xb9','\xfe'},{'\xb7','\x4f'},
+ {'\xdd','\x66'},{'\xdd','\x67'},{'\xba','\x41'},{'\xb7','\x57'},{'\xb7','\x59'},
+ {'\xb7','\x56'},{'\xdd','\x6f'},{'\x9a','\x79'},{'\x8c','\x72'},{'\xe1','\xc8'},
+ {'\xe1','\xc9'},{'\xe1','\xce'},{'\xbc','\x7d'},{'\xe1','\xd5'},{'\x00','\x00'},
+ {'\xba','\x47'},{'\xfc','\x52'},{'\xba','\x46'},{'\xe1','\xd0'},{'\xfc','\x54'},
+ {'\xbc','\x7c'},{'\xe1','\xc5'},{'\xba','\x45'},{'\x9a','\x7a'},{'\xe1','\xd4'},
+ {'\xba','\x43'},{'\xba','\x44'},{'\x95','\xad'},{'\xe1','\xd1'},{'\xe5','\xaa'},
+ {'\xbc','\x7a'},{'\xb4','\x6e'},{'\x00','\x00'},{'\xe1','\xd3'},{'\xbc','\xa3'},
+ {'\xe1','\xcb'},{'\x00','\x00'},{'\xbc','\x7b'},{'\x95','\x66'},{'\xbc','\xa2'},
+ {'\xe1','\xc6'},{'\xe1','\xca'},{'\xe1','\xc7'},{'\xe1','\xcd'},{'\xba','\x48'},
+ {'\xbc','\x79'},{'\xba','\x42'},{'\x00','\x00'},{'\xe5','\x7a'},{'\xe1','\xcf'},
+ {'\x00','\x00'},{'\xbc','\xa1'},{'\xfc','\x53'},{'\xbc','\xa4'},{'\x00','\x00'},
+ {'\xe1','\xcc'},{'\x9a','\x7b'},{'\xbc','\x7e'},{'\xe5','\x79'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x95','\xd1'},{'\x00','\x00'},{'\xe5','\x7e'},
+ {'\xbe','\xce'},{'\xe5','\x78'},{'\xe9','\xa3'},{'\xe5','\xa9'},{'\xbc','\xa8'},
+ {'\x00','\x00'},{'\xbc','\xa6'},{'\xbe','\xcc'},{'\xe5','\xa6'},{'\xe5','\xa2'},
+ {'\xbc','\xac'},{'\x9a','\x7c'},{'\xe9','\x78'},{'\x00','\x00'},{'\x82','\xf8'},
+ {'\xfe','\x74'},{'\xbc','\xaa'},{'\xe5','\xa1'},{'\xfc','\x51'},{'\xe9','\x76'},
+ {'\x00','\x00'},{'\xe5','\xa5'},{'\x00','\x00'},{'\xe5','\xa8'},{'\xe5','\x7d'},
+ {'\x00','\x00'},{'\xbc','\xab'},{'\x00','\x00'},{'\x00','\x00'},{'\xbc','\xa5'},
+ {'\xe9','\x77'},{'\xbe','\xcd'},{'\xe5','\xa7'},{'\xbc','\xa7'},{'\xbc','\xa9'},
+ {'\xe5','\xa4'},{'\xbc','\xad'},{'\xe5','\xa3'},{'\xe5','\x7c'},{'\xe5','\x7b'},
+ {'\xbe','\xcb'},{'\xe5','\xab'},{'\xe9','\x7a'},{'\xec','\xe0'},{'\xbe','\xd0'},
+ {'\x82','\xf9'},{'\xe9','\xa2'},{'\x9a','\x7d'},{'\xe9','\x7e'},{'\x00','\x00'},
+ {'\xec','\xe1'},{'\x00','\x00'},{'\xbe','\xd1'},{'\xe9','\xa1'},{'\x9a','\x7e'},
+ {'\xe9','\x7c'},{'\xc0','\xb4'},{'\xec','\xdf'},{'\x00','\x00'},{'\xe9','\x79'},
+ {'\xe9','\x7b'},{'\xc0','\xb5'},{'\xbe','\xd3'},{'\xc0','\xb3'},{'\xbe','\xd2'},
+ {'\xc0','\xb7'},{'\xe9','\x7d'},{'\xbe','\xcf'},{'\x00','\x00'},{'\x9a','\xa1'},
+ {'\x92','\x5d'},{'\x8a','\xc2'},{'\x8b','\x75'},{'\x9a','\xa2'},{'\x88','\xd9'},
+ {'\x00','\x00'},{'\xef','\xcf'},{'\x00','\x00'},{'\xef','\xc7'},{'\x00','\x00'},
+ {'\x9a','\xa3'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xec','\xe7'},
+ {'\xef','\xc8'},{'\xec','\xe3'},{'\x00','\x00'},{'\xfc','\x56'},{'\xc2','\x56'},
+ {'\xec','\xe5'},{'\xec','\xe4'},{'\xc0','\xb6'},{'\xec','\xe2'},{'\xec','\xe6'},
+ {'\xef','\xd0'},{'\xef','\xcc'},{'\xef','\xce'},{'\x00','\x00'},{'\xef','\xc9'},
+ {'\xef','\xca'},{'\x00','\x00'},{'\xef','\xcd'},{'\xef','\xcb'},{'\xc3','\x67'},
+ {'\x00','\x00'},{'\x82','\xfa'},{'\xc3','\x6a'},{'\xc3','\x69'},{'\xc3','\x68'},
+ {'\xc4','\x61'},{'\xf4','\x4a'},{'\xc4','\x62'},{'\xf2','\x41'},{'\xc4','\xdf'},
+ {'\xf5','\xcc'},{'\xc4','\xe0'},{'\xc5','\x74'},{'\xc5','\xca'},{'\xf7','\xd9'},
+ {'\x00','\x00'},{'\xf7','\xda'},{'\xf7','\xdb'},{'\x00','\x00'},{'\x90','\xab'},
+ {'\xf9','\xba'},{'\xa4','\xe0'},{'\xc9','\x7c'},{'\xa5','\xb3'},{'\x8d','\xb8'},
+ {'\xa6','\xa6'},{'\xa6','\xa7'},{'\xa6','\xa5'},{'\x89','\xda'},{'\xa6','\xa8'},
+ {'\xa7','\xda'},{'\xa7','\xd9'},{'\x82','\xfb'},{'\xcc','\xb1'},{'\xa9','\xcf'},
+ {'\xa9','\xce'},{'\x8e','\x6d'},{'\x88','\xdb'},{'\xd1','\xaf'},{'\xb1','\xad'},
+ {'\xb1','\xae'},{'\x00','\x00'},{'\x82','\xfc'},{'\x82','\xfd'},{'\xb4','\x75'},
+ {'\xdd','\x72'},{'\xb7','\x60'},{'\xb7','\x61'},{'\xdd','\x74'},{'\xdd','\x76'},
+ {'\xdd','\x75'},{'\x93','\x49'},{'\xe1','\xd7'},{'\x00','\x00'},{'\xe1','\xd6'},
+ {'\xba','\x49'},{'\xe1','\xd8'},{'\x8e','\x6c'},{'\xe5','\xac'},{'\xbc','\xae'},
+ {'\x92','\x70'},{'\xbe','\xd4'},{'\x00','\x00'},{'\xc0','\xb8'},{'\xc2','\x57'},
+ {'\xc0','\xb9'},{'\x00','\x00'},{'\xa4','\xe1'},{'\x82','\xfe'},{'\x90','\xbd'},
+ {'\xfc','\x58'},{'\xca','\xe6'},{'\x93','\xec'},{'\x00','\x00'},{'\xcc','\xb2'},
+ {'\xa9','\xd1'},{'\xa9','\xd0'},{'\xa9','\xd2'},{'\xab','\xf3'},{'\xce','\xd2'},
+ {'\xce','\xd3'},{'\x00','\x00'},{'\x00','\x00'},{'\xd1','\xb0'},{'\xae','\xb0'},
+ {'\xb1','\xaf'},{'\xb4','\x76'},{'\xd9','\x51'},{'\xa4','\xe2'},{'\x9c','\xf2'},
+ {'\xa4','\x7e'},{'\xa4','\xe3'},{'\x00','\x00'},{'\xc9','\x7d'},{'\xa5','\xb7'},
+ {'\xa5','\xb6'},{'\xa5','\xb4'},{'\xa5','\xb5'},{'\x93','\xc1'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa6','\xab'},{'\xc9','\xe9'},{'\xc9','\xeb'},{'\xa6','\xaa'},
+ {'\xc9','\xe3'},{'\x00','\x00'},{'\xc9','\xe4'},{'\x00','\x00'},{'\xc9','\xea'},
+ {'\xc9','\xe6'},{'\xc9','\xe8'},{'\xa6','\xa9'},{'\xc9','\xe5'},{'\xc9','\xec'},
+ {'\xc9','\xe7'},{'\x83','\xf9'},{'\xfc','\x59'},{'\x8a','\xc3'},{'\x84','\x4d'},
+ {'\x84','\x4b'},{'\x84','\xe4'},{'\xa7','\xe1'},{'\xa7','\xea'},{'\xa7','\xe8'},
+ {'\xca','\xf0'},{'\xca','\xed'},{'\xca','\xf5'},{'\xa7','\xe6'},{'\xca','\xf6'},
+ {'\x00','\x00'},{'\xa7','\xdf'},{'\xca','\xf3'},{'\x00','\x00'},{'\xa7','\xe5'},
+ {'\xca','\xef'},{'\xca','\xee'},{'\xa7','\xe3'},{'\xca','\xf4'},{'\xa7','\xe4'},
+ {'\xa9','\xd3'},{'\xa7','\xde'},{'\xca','\xf1'},{'\xfc','\x5b'},{'\xca','\xe7'},
+ {'\xa7','\xdb'},{'\xfc','\x5a'},{'\xa7','\xee'},{'\xca','\xec'},{'\xca','\xf2'},
+ {'\xa7','\xe0'},{'\xa7','\xe2'},{'\x00','\x00'},{'\xca','\xe8'},{'\x00','\x00'},
+ {'\xca','\xe9'},{'\xca','\xea'},{'\x9a','\xa4'},{'\xa7','\xed'},{'\xa7','\xe7'},
+ {'\xa7','\xec'},{'\xca','\xeb'},{'\xa7','\xeb'},{'\xa7','\xdd'},{'\xa7','\xdc'},
+ {'\xa7','\xe9'},{'\x00','\x00'},{'\x87','\xd7'},{'\x90','\xbe'},{'\x93','\xbb'},
+ {'\xfd','\x57'},{'\x93','\x6a'},{'\x8e','\x6e'},{'\x8e','\x6f'},{'\x84','\x4e'},
+ {'\x85','\xcb'},{'\x00','\x00'},{'\x8c','\xa8'},{'\x84','\xd2'},{'\xfc','\x5c'},
+ {'\x00','\x00'},{'\xa9','\xe1'},{'\xcc','\xbe'},{'\xcc','\xb7'},{'\xa9','\xdc'},
+ {'\xa9','\xef'},{'\xcc','\xb3'},{'\xcc','\xba'},{'\xcc','\xbc'},{'\xcc','\xbf'},
+ {'\xa9','\xea'},{'\x00','\x00'},{'\xcc','\xbb'},{'\xcc','\xb4'},{'\xa9','\xe8'},
+ {'\xcc','\xb8'},{'\x00','\x00'},{'\xcc','\xc0'},{'\xa9','\xd9'},{'\x00','\x00'},
+ {'\xcc','\xbd'},{'\xa9','\xe3'},{'\xa9','\xe2'},{'\xcc','\xb6'},{'\xa9','\xd7'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa9','\xd8'},{'\xfb','\x46'},{'\xa9','\xd6'},
+ {'\x88','\xe3'},{'\xa9','\xee'},{'\xa9','\xe6'},{'\xa9','\xe0'},{'\xa9','\xd4'},
+ {'\xcc','\xb9'},{'\xa9','\xdf'},{'\xa9','\xd5'},{'\xa9','\xe7'},{'\xa9','\xf0'},
+ {'\xce','\xd4'},{'\xa9','\xe4'},{'\xcc','\xb5'},{'\xa9','\xda'},{'\xa9','\xdd'},
+ {'\xa9','\xde'},{'\xfc','\x5d'},{'\xa9','\xec'},{'\xa9','\xed'},{'\xa9','\xeb'},
+ {'\xa9','\xe5'},{'\xa9','\xe9'},{'\xa9','\xdb'},{'\xab','\xf4'},{'\x93','\xb1'},
+ {'\x00','\x00'},{'\x89','\xde'},{'\x92','\x75'},{'\x92','\x5e'},{'\x8b','\x76'},
+ {'\x84','\xe1'},{'\x00','\x00'},{'\x88','\xdc'},{'\x8b','\xf6'},{'\x89','\xdd'},
+ {'\x87','\xd5'},{'\x88','\xe1'},{'\x00','\x00'},{'\xce','\xda'},{'\xac','\x41'},
+ {'\xab','\xf8'},{'\xab','\xfa'},{'\xac','\x40'},{'\xce','\xe6'},{'\xab','\xfd'},
+ {'\xd1','\xb1'},{'\xae','\xb1'},{'\xac','\x43'},{'\xce','\xd7'},{'\xce','\xdf'},
+ {'\xab','\xfe'},{'\xce','\xde'},{'\xce','\xdb'},{'\xce','\xe3'},{'\xce','\xe5'},
+ {'\xab','\xf7'},{'\xab','\xfb'},{'\xac','\x42'},{'\xae','\xb3'},{'\xce','\xe0'},
+ {'\xab','\xf9'},{'\xac','\x45'},{'\xce','\xd9'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xab','\xfc'},{'\xae','\xb2'},{'\xab','\xf6'},{'\x00','\x00'},
+ {'\xce','\xd6'},{'\xce','\xdd'},{'\xce','\xd5'},{'\xce','\xd8'},{'\xce','\xdc'},
+ {'\xd1','\xb2'},{'\xac','\x44'},{'\x00','\x00'},{'\xce','\xe1'},{'\xce','\xe2'},
+ {'\xce','\xe4'},{'\xab','\xf5'},{'\x00','\x00'},{'\x94','\xf4'},{'\x92','\x76'},
+ {'\x87','\xd2'},{'\x8c','\xf7'},{'\x00','\x00'},{'\x88','\xe4'},{'\x88','\xde'},
+ {'\x83','\xb9'},{'\x87','\xd6'},{'\x88','\xdd'},{'\x8e','\xb7'},{'\x84','\x4f'},
+ {'\x89','\xdc'},{'\x84','\xe2'},{'\x00','\x00'},{'\x90','\xbf'},{'\xae','\xc1'},
+ {'\xd1','\xbe'},{'\xae','\xbf'},{'\xae','\xc0'},{'\xd1','\xb4'},{'\xd1','\xc4'},
+ {'\xa0','\x5e'},{'\xae','\xb6'},{'\x00','\x00'},{'\x9a','\xa5'},{'\xd5','\x66'},
+ {'\xd1','\xc6'},{'\xd1','\xc0'},{'\xfc','\x5f'},{'\xd1','\xb7'},{'\x9a','\xa7'},
+ {'\xd1','\xc9'},{'\xd1','\xba'},{'\xae','\xbc'},{'\xd5','\x7d'},{'\xd1','\xbd'},
+ {'\xae','\xbe'},{'\xae','\xb5'},{'\x93','\x56'},{'\xd1','\xcb'},{'\xd1','\xbf'},
+ {'\xae','\xb8'},{'\xd1','\xb8'},{'\xd1','\xb5'},{'\xd1','\xb6'},{'\xae','\xb9'},
+ {'\xd1','\xc5'},{'\xd1','\xcc'},{'\xae','\xbb'},{'\xd1','\xbc'},{'\xd1','\xbb'},
+ {'\xae','\xc3'},{'\xae','\xc2'},{'\xae','\xb4'},{'\xae','\xba'},{'\xae','\xbd'},
+ {'\xd1','\xc8'},{'\x00','\x00'},{'\x00','\x00'},{'\xd1','\xc2'},{'\xae','\xb7'},
+ {'\xd1','\xb3'},{'\xd1','\xca'},{'\xd1','\xc1'},{'\xd1','\xc3'},{'\xd1','\xc7'},
+ {'\x00','\x00'},{'\x93','\x55'},{'\x00','\x00'},{'\x87','\xd4'},{'\x85','\xca'},
+ {'\x00','\x00'},{'\x88','\xe2'},{'\x84','\xe3'},{'\x85','\xcc'},{'\xfc','\x5e'},
+ {'\xd5','\x67'},{'\x00','\x00'},{'\xb1','\xb7'},{'\xb1','\xcb'},{'\xb1','\xca'},
+ {'\x00','\x00'},{'\xb1','\xbf'},{'\x95','\x59'},{'\xd5','\x79'},{'\xd5','\x75'},
+ {'\xd5','\x72'},{'\xd5','\xa6'},{'\xb1','\xba'},{'\xb1','\xb2'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xd5','\x77'},{'\xb4','\xa8'},{'\xb1','\xb6'},{'\xd5','\xa1'},
+ {'\x9a','\xa8'},{'\xb1','\xcc'},{'\xb1','\xc9'},{'\xd5','\x7b'},{'\xd5','\x6a'},
+ {'\x00','\x00'},{'\xfc','\x55'},{'\xb1','\xc8'},{'\xd5','\xa3'},{'\xd5','\x69'},
+ {'\xb1','\xbd'},{'\xb1','\xc1'},{'\xd5','\xa2'},{'\x00','\x00'},{'\xd5','\x73'},
+ {'\xb1','\xc2'},{'\xb1','\xbc'},{'\xd5','\x68'},{'\x9a','\xa9'},{'\xb4','\x78'},
+ {'\xd5','\xa5'},{'\xd5','\x71'},{'\xb1','\xc7'},{'\xd5','\x74'},{'\xd5','\xa4'},
+ {'\xb1','\xc6'},{'\x00','\x00'},{'\xd9','\x52'},{'\x00','\x00'},{'\xb1','\xb3'},
+ {'\xd5','\x6f'},{'\xb1','\xb8'},{'\xb1','\xc3'},{'\x00','\x00'},{'\xb1','\xbe'},
+ {'\xd5','\x78'},{'\xd5','\x6e'},{'\xd5','\x6c'},{'\xd5','\x7e'},{'\xb1','\xb0'},
+ {'\xb1','\xc4'},{'\xb1','\xb4'},{'\xb4','\x77'},{'\xd5','\x7c'},{'\xb1','\xb5'},
+ {'\x00','\x00'},{'\xb1','\xb1'},{'\xb1','\xc0'},{'\xb1','\xbb'},{'\xb1','\xb9'},
+ {'\xd5','\x70'},{'\xb1','\xc5'},{'\xd5','\x6d'},{'\xd5','\x7a'},{'\xd5','\x76'},
+ {'\xd9','\x54'},{'\xd9','\x53'},{'\x92','\xa9'},{'\x88','\xe0'},{'\x86','\xce'},
+ {'\x94','\x77'},{'\x00','\x00'},{'\x8a','\xc4'},{'\x87','\xd8'},{'\xfb','\x57'},
+ {'\x86','\xcf'},{'\x90','\xc0'},{'\x8e','\x70'},{'\xd5','\x6b'},{'\xd9','\x64'},
+ {'\x00','\x00'},{'\xb4','\x7a'},{'\x9a','\xaa'},{'\xd9','\x6a'},{'\xd9','\x59'},
+ {'\xd9','\x67'},{'\xdd','\x77'},{'\xb4','\x7d'},{'\xd9','\x6b'},{'\xd9','\x6e'},
+ {'\xb4','\x7c'},{'\xd9','\x5c'},{'\xd9','\x6d'},{'\xd9','\x6c'},{'\xb4','\x7e'},
+ {'\xd9','\x55'},{'\xb4','\x79'},{'\xb4','\xa3'},{'\xfd','\x6c'},{'\xb4','\xa1'},
+ {'\xd9','\x69'},{'\x00','\x00'},{'\xd9','\x5f'},{'\xb4','\xa5'},{'\xd9','\x70'},
+ {'\xd9','\x68'},{'\xd9','\x71'},{'\xb4','\xad'},{'\xb4','\xab'},{'\xd9','\x66'},
+ {'\xd9','\x65'},{'\x90','\xc1'},{'\xd9','\x63'},{'\xd9','\x5d'},{'\xb4','\xa4'},
+ {'\x9a','\xab'},{'\xb4','\xa2'},{'\xd1','\xb9'},{'\xd9','\x56'},{'\x9a','\xac'},
+ {'\xdd','\xb7'},{'\xd9','\x57'},{'\xb4','\x7b'},{'\xb4','\xaa'},{'\xdd','\x79'},
+ {'\x00','\x00'},{'\xb4','\xa6'},{'\xb4','\xa7'},{'\xd9','\x58'},{'\xd9','\x6f'},
+ {'\xdd','\x78'},{'\xd9','\x60'},{'\xd9','\x5b'},{'\xb4','\xa9'},{'\xd9','\x61'},
+ {'\xd9','\x5e'},{'\x00','\x00'},{'\xa0','\x5f'},{'\xb4','\xae'},{'\x90','\xc2'},
+ {'\x9a','\xad'},{'\xfb','\x5d'},{'\x8d','\x53'},{'\x9a','\xae'},{'\x87','\xd9'},
+ {'\x8b','\xf7'},{'\x89','\xdf'},{'\x86','\xcd'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x8c','\xf8'},{'\xb7','\x70'},{'\x9a','\xaf'},{'\x00','\x00'},{'\xdd','\x7c'},
+ {'\xdd','\xb1'},{'\xdd','\xb6'},{'\xdd','\xaa'},{'\xb7','\x6c'},{'\xdd','\xbb'},
+ {'\xb7','\x69'},{'\xdd','\x7a'},{'\x00','\x00'},{'\xdd','\x7b'},{'\xb7','\x62'},
+ {'\xb7','\x6b'},{'\xdd','\xa4'},{'\xb7','\x6e'},{'\xb7','\x6f'},{'\xdd','\xa5'},
+ {'\x00','\x00'},{'\xdd','\xb2'},{'\xdd','\xb8'},{'\xb7','\x6a'},{'\x00','\x00'},
+ {'\xb7','\x64'},{'\xdd','\xa3'},{'\xdd','\x7d'},{'\xdd','\xba'},{'\xdd','\xa8'},
+ {'\xdd','\xa9'},{'\xdd','\x7e'},{'\xdd','\xb4'},{'\xdd','\xab'},{'\xdd','\xb5'},
+ {'\xdd','\xad'},{'\x00','\x00'},{'\xb7','\x65'},{'\xe1','\xd9'},{'\xb7','\x68'},
+ {'\xb7','\x66'},{'\xdd','\xb9'},{'\xdd','\xb0'},{'\xdd','\xac'},{'\x00','\x00'},
+ {'\x9a','\xb0'},{'\xdd','\xa1'},{'\xba','\x53'},{'\xdd','\xaf'},{'\xb7','\x6d'},
+ {'\xdd','\xa7'},{'\x9a','\xb1'},{'\xdd','\xa6'},{'\x8c','\x74'},{'\x9a','\xb2'},
+ {'\x00','\x00'},{'\xb7','\x67'},{'\xb7','\x63'},{'\xe1','\xee'},{'\xdd','\xb3'},
+ {'\xdd','\xae'},{'\x93','\x45'},{'\xdd','\xa2'},{'\x8c','\x73'},{'\x8f','\x75'},
+ {'\x8a','\xc7'},{'\x93','\xda'},{'\x8f','\x52'},{'\x00','\x00'},{'\x8c','\xcf'},
+ {'\xe1','\xe9'},{'\x00','\x00'},{'\xe1','\xda'},{'\xe1','\xe5'},{'\x00','\x00'},
+ {'\xe1','\xec'},{'\xba','\x51'},{'\xb4','\xac'},{'\xe1','\xea'},{'\xba','\x4c'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xba','\x4b'},{'\xe1','\xf1'},
+ {'\x9a','\xb3'},{'\xe1','\xdb'},{'\xe1','\xe8'},{'\xe1','\xdc'},{'\xe1','\xe7'},
+ {'\xba','\x4f'},{'\xe1','\xeb'},{'\xd9','\x62'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xe1','\xf2'},{'\xe1','\xe3'},{'\xba','\x52'},{'\xe5','\xba'},
+ {'\xbc','\xaf'},{'\x00','\x00'},{'\xe1','\xf0'},{'\xe1','\xef'},{'\xba','\x54'},
+ {'\xe5','\xad'},{'\xbc','\xb0'},{'\xe5','\xae'},{'\x9a','\xb4'},{'\xe1','\xdf'},
+ {'\xe1','\xe0'},{'\xe1','\xdd'},{'\xe1','\xe2'},{'\xe1','\xde'},{'\xe1','\xf3'},
+ {'\xba','\x4e'},{'\xbc','\xb1'},{'\xba','\x50'},{'\xba','\x55'},{'\x9a','\xb5'},
+ {'\xe1','\xe1'},{'\x00','\x00'},{'\xe1','\xed'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xe1','\xe6'},{'\x92','\xb0'},{'\x8f','\xda'},{'\xe5','\xb1'},{'\x00','\x00'},
+ {'\xba','\x4a'},{'\xbc','\xb4'},{'\xe9','\xaa'},{'\xe5','\xb6'},{'\xe5','\xb5'},
+ {'\xe5','\xb7'},{'\x9a','\xb6'},{'\x00','\x00'},{'\xe5','\xb4'},{'\xbc','\xb5'},
+ {'\x90','\xc3'},{'\xbc','\xbb'},{'\xbc','\xb8'},{'\x00','\x00'},{'\xbc','\xb9'},
+ {'\xe5','\xaf'},{'\xe5','\xb2'},{'\xe5','\xbc'},{'\xbc','\xc1'},{'\xbc','\xbf'},
+ {'\x00','\x00'},{'\xe5','\xb3'},{'\xd9','\x5a'},{'\xbc','\xb2'},{'\xe5','\xb9'},
+ {'\xe5','\xb0'},{'\x00','\x00'},{'\xbc','\xc2'},{'\xe5','\xb8'},{'\xba','\x4d'},
+ {'\xbc','\xb7'},{'\xe1','\xe4'},{'\x00','\x00'},{'\x00','\x00'},{'\xbc','\xba'},
+ {'\x00','\x00'},{'\xbc','\xbe'},{'\xbc','\xc0'},{'\xbc','\xbd'},{'\xbc','\xbc'},
+ {'\x9a','\xb7'},{'\xbc','\xb6'},{'\xe5','\xbb'},{'\xbc','\xb3'},{'\xbc','\xc3'},
+ {'\x9a','\xb8'},{'\x8a','\xc6'},{'\x9a','\xb9'},{'\x8a','\xc9'},{'\x8f','\x76'},
+ {'\x82','\x4d'},{'\x8f','\xfe'},{'\xbe','\xd8'},{'\xbe','\xd9'},{'\xe9','\xa9'},
+ {'\xbe','\xe2'},{'\xbe','\xdf'},{'\x90','\xc4'},{'\xbe','\xd6'},{'\xbe','\xdd'},
+ {'\xe9','\xab'},{'\xbe','\xdb'},{'\xbe','\xd5'},{'\x00','\x00'},{'\xbe','\xdc'},
+ {'\x00','\x00'},{'\xe9','\xa8'},{'\xc0','\xbb'},{'\xbe','\xd7'},{'\x00','\x00'},
+ {'\xbe','\xde'},{'\xc0','\xba'},{'\xe9','\xa7'},{'\xe9','\xa6'},{'\x00','\x00'},
+ {'\xbe','\xe0'},{'\xa0','\x5d'},{'\xbe','\xe1'},{'\x00','\x00'},{'\xe9','\xa5'},
+ {'\xe9','\xa4'},{'\xc0','\xbc'},{'\xe9','\xae'},{'\xbe','\xda'},{'\xe9','\xac'},
+ {'\x00','\x00'},{'\x9a','\xba'},{'\x8a','\xc8'},{'\x00','\x00'},{'\xc0','\xbd'},
+ {'\x90','\xc5'},{'\xc0','\xc2'},{'\xec','\xea'},{'\xec','\xec'},{'\x9a','\xbb'},
+ {'\xc0','\xbf'},{'\xfb','\xa3'},{'\xec','\xed'},{'\xec','\xe9'},{'\x95','\xc8'},
+ {'\xec','\xeb'},{'\xc0','\xc0'},{'\xc0','\xc3'},{'\x00','\x00'},{'\xec','\xe8'},
+ {'\xc0','\xbe'},{'\xc0','\xc1'},{'\xc2','\x59'},{'\xe9','\xad'},{'\xc2','\x58'},
+ {'\x00','\x00'},{'\x90','\xc6'},{'\xc2','\x5e'},{'\xef','\xd4'},{'\x00','\x00'},
+ {'\xc2','\x5c'},{'\xc2','\x5d'},{'\xef','\xd7'},{'\xef','\xd3'},{'\xc2','\x5a'},
+ {'\xef','\xd1'},{'\xc3','\x6b'},{'\xef','\xd5'},{'\x00','\x00'},{'\xef','\xd6'},
+ {'\xef','\xd2'},{'\x90','\xc7'},{'\xc2','\x5b'},{'\xf2','\x42'},{'\x00','\x00'},
+ {'\xf2','\x45'},{'\x9a','\xbc'},{'\x00','\x00'},{'\xf2','\x46'},{'\xf2','\x44'},
+ {'\xf2','\x47'},{'\xc3','\x6c'},{'\xf2','\x43'},{'\x9a','\xbd'},{'\x90','\x57'},
+ {'\xf4','\x4e'},{'\xc4','\x64'},{'\xf4','\x4d'},{'\xf4','\x4c'},{'\xf4','\x4b'},
+ {'\xc4','\x63'},{'\xc4','\x65'},{'\x00','\x00'},{'\xf5','\xcd'},{'\xc4','\xe2'},
+ {'\xc4','\xe1'},{'\xa0','\x60'},{'\x9a','\xbe'},{'\xf6','\xe1'},{'\xf6','\xe0'},
+ {'\xf6','\xe3'},{'\xc5','\xcb'},{'\xc5','\x75'},{'\xf7','\xdd'},{'\xf6','\xe2'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xf7','\xdc'},{'\xc5','\xcd'},{'\xc5','\xcc'},
+ {'\xc5','\xf3'},{'\xf8','\xa9'},{'\xf8','\xef'},{'\xa4','\xe4'},{'\xfe','\x5b'},
+ {'\x00','\x00'},{'\xd9','\x72'},{'\xe9','\xaf'},{'\xc6','\xd2'},{'\x90','\xc8'},
+ {'\xa6','\xac'},{'\xca','\xf7'},{'\xa7','\xf1'},{'\xa7','\xef'},{'\x00','\x00'},
+ {'\xa7','\xf0'},{'\x00','\x00'},{'\xcc','\xc1'},{'\xa9','\xf1'},{'\xac','\x46'},
+ {'\x00','\x00'},{'\xce','\xe7'},{'\x00','\x00'},{'\xce','\xe8'},{'\x00','\x00'},
+ {'\xac','\x47'},{'\xd1','\xce'},{'\x00','\x00'},{'\xae','\xc4'},{'\xae','\xc5'},
+ {'\xd1','\xcd'},{'\x00','\x00'},{'\x87','\xda'},{'\x95','\xb4'},{'\x90','\xc9'},
+ {'\xb1','\xd3'},{'\x00','\x00'},{'\xb1','\xcf'},{'\x00','\x00'},{'\xd5','\xa7'},
+ {'\xb1','\xd6'},{'\xb1','\xd5'},{'\xb1','\xce'},{'\xb1','\xd1'},{'\xb1','\xd4'},
+ {'\xb1','\xd0'},{'\x00','\x00'},{'\x89','\xe0'},{'\xd9','\x76'},{'\xb1','\xcd'},
+ {'\xb4','\xaf'},{'\x9a','\xbf'},{'\x00','\x00'},{'\x00','\x00'},{'\xb4','\xb1'},
+ {'\xb4','\xb2'},{'\xd9','\x75'},{'\xd9','\x78'},{'\xb4','\xb0'},{'\xd9','\x73'},
+ {'\xd9','\x77'},{'\x00','\x00'},{'\xd9','\x74'},{'\x90','\xca'},{'\xb7','\x71'},
+ {'\x9a','\xc0'},{'\x00','\x00'},{'\xdd','\xbc'},{'\x87','\xdb'},{'\x00','\x00'},
+ {'\xba','\x56'},{'\xe1','\xf4'},{'\xbe','\xe3'},{'\xbc','\xc4'},{'\xe5','\xbd'},
+ {'\xbc','\xc5'},{'\xbc','\xc6'},{'\xe5','\xbf'},{'\xe5','\xbe'},{'\xe5','\xc0'},
+ {'\xe9','\xb1'},{'\x00','\x00'},{'\x00','\x00'},{'\xe9','\xb0'},{'\xec','\xef'},
+ {'\xec','\xee'},{'\xc0','\xc4'},{'\xc0','\xc5'},{'\xf2','\x48'},{'\xfc','\xb7'},
+ {'\x9a','\xc1'},{'\xa4','\xe5'},{'\x90','\xcb'},{'\x93','\x42'},{'\x00','\x00'},
+ {'\x8a','\xbc'},{'\xd9','\x79'},{'\x00','\x00'},{'\x92','\xc7'},{'\x00','\x00'},
+ {'\xb4','\xb4'},{'\xb4','\xb3'},{'\xdd','\xbd'},{'\x8c','\x75'},{'\xef','\xd8'},
+ {'\xc4','\xe3'},{'\xf7','\xde'},{'\xa4','\xe6'},{'\x00','\x00'},{'\xae','\xc6'},
+ {'\x00','\x00'},{'\xb1','\xd8'},{'\xb1','\xd7'},{'\xd9','\x7a'},{'\xd9','\x7b'},
+ {'\xb7','\x72'},{'\xe1','\xf5'},{'\xba','\x57'},{'\xe9','\xb2'},{'\x00','\x00'},
+ {'\xa4','\xe7'},{'\xa5','\xb8'},{'\x00','\x00'},{'\xa9','\xf2'},{'\xcc','\xc2'},
+ {'\x84','\x53'},{'\xce','\xe9'},{'\xac','\x48'},{'\xb1','\xd9'},{'\x8a','\xca'},
+ {'\xd9','\x7c'},{'\xb4','\xb5'},{'\xb7','\x73'},{'\x00','\x00'},{'\xe5','\xc1'},
+ {'\xe5','\xc2'},{'\x00','\x00'},{'\x9a','\xc2'},{'\xec','\xf0'},{'\xc2','\x5f'},
+ {'\xf8','\xf0'},{'\xa4','\xe8'},{'\x00','\x00'},{'\xcc','\xc3'},{'\xa9','\xf3'},
+ {'\xac','\x49'},{'\x9a','\xc3'},{'\xce','\xea'},{'\x00','\x00'},{'\xae','\xc7'},
+ {'\xd1','\xd2'},{'\xd1','\xd0'},{'\xd1','\xd1'},{'\xae','\xc8'},{'\xd1','\xcf'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xb1','\xdb'},
+ {'\xb1','\xdc'},{'\xd5','\xa8'},{'\xb1','\xdd'},{'\xb1','\xda'},{'\xd9','\x7d'},
+ {'\x9a','\xc4'},{'\xd9','\x7e'},{'\xdd','\xbe'},{'\x9a','\xc5'},{'\x00','\x00'},
+ {'\xba','\x59'},{'\xba','\x58'},{'\x00','\x00'},{'\x90','\xcc'},{'\xec','\xf1'},
+ {'\xef','\xd9'},{'\x00','\x00'},{'\xf2','\x4a'},{'\xf2','\x49'},{'\xf4','\x4f'},
+ {'\xc6','\xd3'},{'\xc9','\x5e'},{'\xac','\x4a'},{'\x9a','\xc6'},{'\x00','\x00'},
+ {'\xa4','\xe9'},{'\xa5','\xb9'},{'\x8a','\xf6'},{'\xa6','\xae'},{'\xa6','\xad'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa6','\xaf'},{'\xa6','\xb0'},{'\xc9','\xee'},
+ {'\xc9','\xed'},{'\xca','\xf8'},{'\xa7','\xf2'},{'\xca','\xfb'},{'\xca','\xfa'},
+ {'\xca','\xf9'},{'\xca','\xfc'},{'\x83','\xba'},{'\x8b','\x77'},{'\x85','\xd0'},
+ {'\x00','\x00'},{'\xa9','\xf4'},{'\xcc','\xc9'},{'\xcc','\xc5'},{'\xcc','\xce'},
+ {'\x00','\x00'},{'\x9a','\xc7'},{'\xa9','\xfb'},{'\x00','\x00'},{'\xa9','\xf9'},
+ {'\xcc','\xca'},{'\xcc','\xc6'},{'\xcc','\xcd'},{'\xa9','\xf8'},{'\xaa','\x40'},
+ {'\xcc','\xc8'},{'\xcc','\xc4'},{'\xa9','\xfe'},{'\xcc','\xcb'},{'\xa9','\xf7'},
+ {'\xcc','\xcc'},{'\xa9','\xfa'},{'\xa9','\xfc'},{'\xcc','\xd0'},{'\xcc','\xcf'},
+ {'\xcc','\xc7'},{'\xa9','\xf6'},{'\xa9','\xf5'},{'\xa9','\xfd'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x9a','\xc8'},{'\x88','\xe8'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xce','\xef'},{'\xce','\xf5'},{'\x90','\xcd'},{'\xac','\x50'},{'\xac','\x4d'},
+ {'\xce','\xec'},{'\xce','\xf1'},{'\x9a','\xc9'},{'\xac','\x53'},{'\xac','\x4b'},
+ {'\xce','\xf0'},{'\xac','\x4e'},{'\xac','\x51'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xce','\xf3'},{'\x00','\x00'},{'\xac','\x4c'},{'\xce','\xf8'},{'\xac','\x4f'},
+ {'\x95','\xfe'},{'\xac','\x52'},{'\xce','\xed'},{'\xce','\xf2'},{'\xce','\xf6'},
+ {'\xce','\xee'},{'\xce','\xeb'},{'\x00','\x00'},{'\x00','\x00'},{'\xce','\xf7'},
+ {'\xce','\xf4'},{'\x90','\xce'},{'\x84','\x54'},{'\x00','\x00'},{'\x8d','\x46'},
+ {'\x90','\xcf'},{'\x00','\x00'},{'\xae','\xd0'},{'\xae','\xc9'},{'\xae','\xcc'},
+ {'\x90','\xd0'},{'\xae','\xcf'},{'\x00','\x00'},{'\xd1','\xd5'},{'\xfc','\x62'},
+ {'\xae','\xca'},{'\xd1','\xd3'},{'\x83','\xbb'},{'\xae','\xce'},{'\x9d','\x59'},
+ {'\x00','\x00'},{'\xae','\xcb'},{'\x00','\x00'},{'\xd1','\xd6'},{'\xae','\xcd'},
+ {'\x88','\xe6'},{'\x88','\xe7'},{'\x85','\xcf'},{'\x85','\xce'},{'\x90','\xd1'},
+ {'\x00','\x00'},{'\xd5','\xac'},{'\xb1','\xdf'},{'\xd5','\xab'},{'\xd5','\xad'},
+ {'\xb1','\xde'},{'\xb1','\xe3'},{'\xd1','\xd4'},{'\x00','\x00'},{'\xd5','\xaa'},
+ {'\xd5','\xae'},{'\x9a','\xca'},{'\xb1','\xe0'},{'\xd5','\xa9'},{'\xb1','\xe2'},
+ {'\xfc','\x63'},{'\xb1','\xe1'},{'\x90','\xd2'},{'\xd9','\xa7'},{'\x9a','\xcb'},
+ {'\xd9','\xa2'},{'\x00','\x00'},{'\xb4','\xb6'},{'\xb4','\xba'},{'\xb4','\xb7'},
+ {'\xd9','\xa5'},{'\xd9','\xa8'},{'\x90','\xd3'},{'\xb4','\xb8'},{'\x00','\x00'},
+ {'\xb4','\xb9'},{'\xb4','\xbe'},{'\xdd','\xc7'},{'\xd9','\xa6'},{'\xb4','\xbc'},
+ {'\xd9','\xa3'},{'\xd9','\xa1'},{'\x9a','\xcc'},{'\xb4','\xbd'},{'\x00','\x00'},
+ {'\xd9','\xa4'},{'\x92','\x7d'},{'\x87','\xdc'},{'\x90','\xd4'},{'\xb7','\x79'},
+ {'\x9a','\xcd'},{'\xdd','\xbf'},{'\xb7','\x76'},{'\xb7','\x77'},{'\xb7','\x75'},
+ {'\xdd','\xc4'},{'\xdd','\xc3'},{'\xdd','\xc0'},{'\xb7','\x7b'},{'\xfe','\x7a'},
+ {'\x00','\x00'},{'\xdd','\xc2'},{'\xb4','\xbb'},{'\x9a','\xce'},{'\x00','\x00'},
+ {'\xdd','\xc6'},{'\xdd','\xc1'},{'\xb7','\x78'},{'\xb7','\x74'},{'\xb7','\x7a'},
+ {'\xdd','\xc5'},{'\x9a','\xcf'},{'\x00','\x00'},{'\x00','\x00'},{'\xba','\x5c'},
+ {'\x00','\x00'},{'\xe1','\xf8'},{'\xe1','\xf7'},{'\xe1','\xf6'},{'\xba','\x5a'},
+ {'\x00','\x00'},{'\x9a','\xd0'},{'\x00','\x00'},{'\x93','\xef'},{'\x89','\xe2'},
+ {'\xba','\x5b'},{'\xe5','\xc5'},{'\xe5','\xc8'},{'\xbc','\xc8'},{'\x00','\x00'},
+ {'\x9a','\xd1'},{'\xbc','\xc7'},{'\xe5','\xc9'},{'\xe5','\xc4'},{'\xbc','\xca'},
+ {'\xe5','\xc6'},{'\x9a','\xd2'},{'\xbc','\xc9'},{'\xe5','\xc3'},{'\x9a','\xd3'},
+ {'\xe5','\xc7'},{'\xbe','\xe9'},{'\xbe','\xe6'},{'\xe9','\xbb'},{'\xe9','\xba'},
+ {'\x90','\xd5'},{'\xe9','\xb9'},{'\xe9','\xb4'},{'\x90','\xd6'},{'\xe9','\xb5'},
+ {'\x90','\xd7'},{'\x00','\x00'},{'\x00','\x00'},{'\xbe','\xe7'},{'\x00','\x00'},
+ {'\xbe','\xe4'},{'\xbe','\xe8'},{'\xe9','\xb3'},{'\xbe','\xe5'},{'\xe9','\xb6'},
+ {'\xe9','\xb7'},{'\xe9','\xbc'},{'\x9a','\xd4'},{'\x9a','\xd5'},{'\xe9','\xb8'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xec','\xf2'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xc0','\xc7'},{'\x00','\x00'},{'\xef','\xdc'},{'\xc0','\xc6'},
+ {'\xef','\xda'},{'\xef','\xdb'},{'\xc2','\x60'},{'\xc3','\x6e'},{'\xf2','\x4b'},
+ {'\x00','\x00'},{'\xc3','\x6d'},{'\x00','\x00'},{'\x00','\x00'},{'\xf4','\x51'},
+ {'\xf4','\x52'},{'\x00','\x00'},{'\xc4','\x66'},{'\x9d','\xca'},{'\xf4','\x50'},
+ {'\xc4','\xe4'},{'\x00','\x00'},{'\xf7','\xdf'},{'\xc5','\xce'},{'\xf8','\xaa'},
+ {'\xf8','\xab'},{'\x00','\x00'},{'\xa4','\xea'},{'\xa0','\x58'},{'\xa6','\xb1'},
+ {'\xa6','\xb2'},{'\xa7','\xf3'},{'\x90','\xd8'},{'\xcc','\xd1'},{'\xac','\x54'},
+ {'\xae','\xd1'},{'\xb1','\xe4'},{'\x90','\xd9'},{'\x90','\xda'},{'\xb0','\xd2'},
+ {'\x93','\xfb'},{'\xb4','\xbf'},{'\xb4','\xc0'},{'\xb3','\xcc'},{'\xd9','\xa9'},
+ {'\x9a','\xd6'},{'\xb7','\x7c'},{'\xe1','\xfa'},{'\xe1','\xf9'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa4','\xeb'},{'\xa6','\xb3'},{'\xcc','\xd2'},{'\xaa','\x42'},
+ {'\x9a','\xd7'},{'\xaa','\x41'},{'\x90','\xdb'},{'\xce','\xf9'},{'\xce','\xfa'},
+ {'\x00','\x00'},{'\xd1','\xd7'},{'\xd1','\xd8'},{'\xae','\xd2'},{'\xae','\xd3'},
+ {'\x90','\xdc'},{'\xae','\xd4'},{'\xd5','\xaf'},{'\x9a','\xd8'},{'\x00','\x00'},
+ {'\xb1','\xe6'},{'\x00','\x00'},{'\xb4','\xc2'},{'\xfc','\x64'},{'\xb4','\xc1'},
+ {'\xdd','\xc8'},{'\xdf','\x7a'},{'\xe1','\xfb'},{'\xe9','\xbd'},{'\x00','\x00'},
+ {'\xfe','\x5e'},{'\xc2','\x61'},{'\xc4','\x67'},{'\xa4','\xec'},{'\x91','\xd1'},
+ {'\xa5','\xbc'},{'\xa5','\xbd'},{'\xa5','\xbb'},{'\xa5','\xbe'},{'\xa5','\xba'},
+ {'\x84','\x7b'},{'\x00','\x00'},{'\xa6','\xb6'},{'\x00','\x00'},{'\xc9','\xf6'},
+ {'\xa6','\xb5'},{'\xa6','\xb7'},{'\x95','\x7c'},{'\x90','\xdd'},{'\xc9','\xf1'},
+ {'\xc9','\xf0'},{'\xc9','\xf3'},{'\xc9','\xf2'},{'\xc9','\xf5'},{'\xa6','\xb4'},
+ {'\xc9','\xef'},{'\xc9','\xf4'},{'\x84','\x59'},{'\x94','\x78'},{'\x8b','\x59'},
+ {'\x8c','\xd0'},{'\x9a','\xd9'},{'\xca','\xfd'},{'\xa7','\xfd'},{'\xca','\xfe'},
+ {'\xcb','\x43'},{'\xa7','\xfc'},{'\x00','\x00'},{'\xcb','\x47'},{'\xcb','\x42'},
+ {'\xcb','\x45'},{'\xa7','\xf5'},{'\xa7','\xf6'},{'\xa7','\xf7'},{'\xa7','\xf8'},
+ {'\x00','\x00'},{'\xa8','\x40'},{'\x00','\x00'},{'\xcb','\x41'},{'\xa7','\xfa'},
+ {'\xa8','\x41'},{'\x00','\x00'},{'\xcb','\x40'},{'\xcb','\x46'},{'\x00','\x00'},
+ {'\xa7','\xf9'},{'\xcb','\x44'},{'\xa7','\xfb'},{'\xa7','\xf4'},{'\xa7','\xfe'},
+ {'\x84','\x57'},{'\x94','\x5c'},{'\x94','\x79'},{'\x90','\xde'},{'\x83','\x53'},
+ {'\x90','\xdf'},{'\xfb','\xa6'},{'\x85','\xd4'},{'\x8e','\x72'},{'\xaa','\x57'},
+ {'\x9a','\xda'},{'\xcc','\xd4'},{'\xaa','\x43'},{'\x9d','\x72'},{'\xaa','\x4d'},
+ {'\xaa','\x4e'},{'\xaa','\x46'},{'\xaa','\x58'},{'\xaa','\x48'},{'\xcc','\xdc'},
+ {'\xaa','\x53'},{'\xcc','\xd7'},{'\xaa','\x49'},{'\xcc','\xe6'},{'\xcc','\xe7'},
+ {'\xcc','\xdf'},{'\xcc','\xd8'},{'\xaa','\x56'},{'\xcc','\xe4'},{'\xaa','\x51'},
+ {'\xaa','\x4f'},{'\x00','\x00'},{'\xcc','\xe5'},{'\x00','\x00'},{'\xcc','\xe3'},
+ {'\xcc','\xdb'},{'\xcc','\xd3'},{'\xcc','\xda'},{'\xaa','\x4a'},{'\x00','\x00'},
+ {'\xaa','\x50'},{'\x00','\x00'},{'\xaa','\x44'},{'\xcc','\xde'},{'\xcc','\xdd'},
+ {'\xcc','\xd5'},{'\x9a','\xdb'},{'\xaa','\x52'},{'\xcc','\xe1'},{'\xcc','\xd6'},
+ {'\xaa','\x55'},{'\xcc','\xe8'},{'\xaa','\x45'},{'\x00','\x00'},{'\xaa','\x4c'},
+ {'\xcc','\xd9'},{'\xcc','\xe2'},{'\xaa','\x54'},{'\x00','\x00'},{'\xaa','\x47'},
+ {'\xaa','\x4b'},{'\x87','\xe5'},{'\xcc','\xe0'},{'\x94','\xfd'},{'\x94','\x7a'},
+ {'\x87','\xe0'},{'\x84','\xe5'},{'\x9a','\xdc'},{'\x8f','\xdc'},{'\x90','\xe0'},
+ {'\x90','\xe1'},{'\x8d','\xdf'},{'\x90','\xe2'},{'\x86','\xd2'},{'\x85','\xd6'},
+ {'\xfc','\x66'},{'\x84','\x58'},{'\xcf','\x5b'},{'\xac','\x5c'},{'\xac','\x69'},
+ {'\x95','\x45'},{'\xcf','\x56'},{'\xcf','\x4c'},{'\xac','\x62'},{'\xcf','\x4a'},
+ {'\xac','\x5b'},{'\xcf','\x45'},{'\xac','\x65'},{'\xcf','\x52'},{'\xce','\xfe'},
+ {'\xcf','\x41'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9a','\xdd'},
+ {'\xcf','\x44'},{'\xce','\xfb'},{'\xcf','\x51'},{'\xcf','\x61'},{'\xac','\x60'},
+ {'\xcf','\x46'},{'\xcf','\x58'},{'\x00','\x00'},{'\xce','\xfd'},{'\xcf','\x5f'},
+ {'\xcf','\x60'},{'\xcf','\x63'},{'\xcf','\x5a'},{'\xcf','\x4b'},{'\xcf','\x53'},
+ {'\xac','\x66'},{'\xac','\x59'},{'\xac','\x61'},{'\xac','\x6d'},{'\xac','\x56'},
+ {'\xac','\x58'},{'\x00','\x00'},{'\x9a','\xde'},{'\x9a','\xdf'},{'\xcf','\x43'},
+ {'\xac','\x6a'},{'\xac','\x63'},{'\xcf','\x5d'},{'\xcf','\x40'},{'\xac','\x6c'},
+ {'\xac','\x67'},{'\xcf','\x49'},{'\x8a','\xce'},{'\x00','\x00'},{'\xac','\x6b'},
+ {'\xcf','\x50'},{'\xcf','\x48'},{'\xac','\x64'},{'\xcf','\x5c'},{'\xcf','\x54'},
+ {'\x00','\x00'},{'\xac','\x5e'},{'\xcf','\x62'},{'\xcf','\x47'},{'\xac','\x5a'},
+ {'\xcf','\x59'},{'\xcf','\x4f'},{'\xac','\x5f'},{'\xcf','\x55'},{'\xac','\x57'},
+ {'\xce','\xfc'},{'\xac','\x68'},{'\xae','\xe3'},{'\xac','\x5d'},{'\xcf','\x4e'},
+ {'\xcf','\x4d'},{'\xcf','\x42'},{'\xfc','\x67'},{'\xcf','\x5e'},{'\x90','\xe3'},
+ {'\xcf','\x57'},{'\x90','\xe4'},{'\x94','\x5a'},{'\xac','\x55'},{'\x90','\xe5'},
+ {'\x90','\xe6'},{'\x94','\x4d'},{'\x94','\x51'},{'\x92','\x48'},{'\x90','\xe7'},
+ {'\x00','\x00'},{'\x87','\xe1'},{'\x84','\xe7'},{'\x89','\xe6'},{'\x8f','\xdb'},
+ {'\x84','\xe6'},{'\x8f','\xdd'},{'\x9a','\xe1'},{'\x8f','\xba'},{'\x8c','\x77'},
+ {'\x9a','\xe2'},{'\x88','\xeb'},{'\xd1','\xec'},{'\xae','\xea'},{'\xd1','\xed'},
+ {'\x00','\x00'},{'\xd1','\xe1'},{'\xae','\xdf'},{'\xae','\xeb'},{'\x00','\x00'},
+ {'\xd1','\xda'},{'\x9a','\xe3'},{'\xd1','\xe3'},{'\xd1','\xeb'},{'\x90','\xe8'},
+ {'\xd1','\xd9'},{'\xd1','\xf4'},{'\xae','\xd5'},{'\xfe','\x45'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xd1','\xf3'},{'\xd1','\xee'},{'\x00','\x00'},{'\xd1','\xef'},
+ {'\xae','\xdd'},{'\xae','\xe8'},{'\xd1','\xe5'},{'\x00','\x00'},{'\xd1','\xe6'},
+ {'\xd1','\xf0'},{'\xd1','\xe7'},{'\x00','\x00'},{'\xd1','\xe2'},{'\xd1','\xdc'},
+ {'\xd1','\xdd'},{'\xd1','\xea'},{'\xd1','\xe4'},{'\x9a','\xe4'},{'\x87','\xde'},
+ {'\xae','\xd6'},{'\xae','\xda'},{'\xd1','\xf2'},{'\xd1','\xde'},{'\xae','\xe6'},
+ {'\xae','\xe2'},{'\x90','\x6a'},{'\x00','\x00'},{'\xae','\xe5'},{'\xae','\xec'},
+ {'\xae','\xdb'},{'\xae','\xe7'},{'\xd1','\xe9'},{'\xae','\xe9'},{'\xae','\xd8'},
+ {'\x9a','\xe5'},{'\xae','\xd7'},{'\xd1','\xdb'},{'\x90','\xe9'},{'\xd1','\xdf'},
+ {'\xae','\xe0'},{'\xd1','\xf1'},{'\xd1','\xe8'},{'\xd1','\xe0'},{'\xae','\xe4'},
+ {'\xae','\xe1'},{'\x90','\xea'},{'\xae','\xd9'},{'\xae','\xdc'},{'\x90','\xeb'},
+ {'\x9a','\xe6'},{'\x00','\x00'},{'\x00','\x00'},{'\x90','\xec'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x92','\x51'},{'\x82','\x7c'},{'\x00','\x00'},{'\x92','\xcc'},
+ {'\x8d','\xde'},{'\x88','\xef'},{'\x85','\xd5'},{'\x89','\xe3'},{'\x8e','\x71'},
+ {'\x88','\xed'},{'\x88','\xe9'},{'\x89','\xe5'},{'\x87','\xe3'},{'\x87','\xdf'},
+ {'\x00','\x00'},{'\xd5','\xc4'},{'\x00','\x00'},{'\xd5','\xb4'},{'\xd5','\xb5'},
+ {'\xd5','\xb9'},{'\x00','\x00'},{'\xd5','\xc8'},{'\xd5','\xc5'},{'\x00','\x00'},
+ {'\xd5','\xbe'},{'\xd5','\xbd'},{'\xb1','\xed'},{'\xd5','\xc1'},{'\xd5','\xd0'},
+ {'\xd5','\xb0'},{'\x00','\x00'},{'\xd5','\xd1'},{'\xd5','\xc3'},{'\xd5','\xd5'},
+ {'\xd5','\xc9'},{'\xb1','\xec'},{'\xd5','\xc7'},{'\xb1','\xe7'},{'\xb1','\xfc'},
+ {'\xb1','\xf2'},{'\x9a','\xe7'},{'\xb1','\xf6'},{'\xb1','\xf5'},{'\xd5','\xb1'},
+ {'\x9a','\xe8'},{'\xd5','\xce'},{'\xd5','\xd4'},{'\xd5','\xcc'},{'\xd5','\xd3'},
+ {'\x90','\xed'},{'\x00','\x00'},{'\xd5','\xc0'},{'\xd5','\xb2'},{'\xd5','\xd2'},
+ {'\xd5','\xc2'},{'\xb1','\xea'},{'\xb1','\xf7'},{'\x00','\x00'},{'\xd5','\xcb'},
+ {'\xb1','\xf0'},{'\xfb','\x58'},{'\x00','\x00'},{'\x00','\x00'},{'\xd5','\xca'},
+ {'\xd5','\xb3'},{'\xb1','\xf8'},{'\x00','\x00'},{'\xb1','\xfa'},{'\xd5','\xcd'},
+ {'\xb1','\xfb'},{'\xb1','\xe9'},{'\xd5','\xba'},{'\xd5','\xcf'},{'\x00','\x00'},
+ {'\x86','\xbb'},{'\xb1','\xef'},{'\xb1','\xf9'},{'\xd5','\xbc'},{'\xd5','\xc6'},
+ {'\xd5','\xb7'},{'\xd5','\xbb'},{'\xb1','\xf4'},{'\xd5','\xb6'},{'\xb1','\xe8'},
+ {'\xb1','\xf1'},{'\xb1','\xee'},{'\xd5','\xbf'},{'\xae','\xde'},{'\xd9','\xc0'},
+ {'\xb1','\xeb'},{'\xfc','\x68'},{'\x00','\x00'},{'\x00','\x00'},{'\x90','\xee'},
+ {'\x94','\x7b'},{'\x00','\x00'},{'\x82','\x6f'},{'\x9a','\xe9'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x89','\xe4'},{'\x00','\x00'},{'\x8c','\x78'},{'\x9a','\xea'},
+ {'\xb1','\xf3'},{'\x9a','\xeb'},{'\xd9','\xc3'},{'\xd9','\xd9'},{'\xd9','\xce'},
+ {'\xb4','\xd6'},{'\xfc','\x6c'},{'\xb4','\xd1'},{'\xd9','\xbd'},{'\xb4','\xd2'},
+ {'\xd9','\xcd'},{'\x90','\xef'},{'\xd9','\xc6'},{'\xd9','\xd3'},{'\xb4','\xce'},
+ {'\xd9','\xab'},{'\xd9','\xd5'},{'\xb4','\xc4'},{'\xd9','\xb3'},{'\xb4','\xc7'},
+ {'\xb4','\xc6'},{'\x00','\x00'},{'\xb4','\xd7'},{'\x00','\x00'},{'\xd9','\xad'},
+ {'\xd9','\xcf'},{'\xd9','\xd0'},{'\xb4','\xc9'},{'\xb4','\xc5'},{'\xd9','\xbb'},
+ {'\x00','\x00'},{'\xb4','\xd0'},{'\xd9','\xb6'},{'\x00','\x00'},{'\xd9','\xd1'},
+ {'\xb4','\xcc'},{'\xd9','\xc9'},{'\xd9','\xd6'},{'\xd9','\xb0'},{'\xd9','\xb5'},
+ {'\xd9','\xaf'},{'\x00','\x00'},{'\xb4','\xcb'},{'\xd9','\xc2'},{'\xdd','\xde'},
+ {'\xd9','\xb1'},{'\xb4','\xcf'},{'\xd9','\xba'},{'\xd9','\xd2'},{'\xb4','\xca'},
+ {'\xd9','\xb7'},{'\xd9','\xb4'},{'\xd9','\xc5'},{'\xb4','\xcd'},{'\xb4','\xc3'},
+ {'\xb4','\xd9'},{'\xd9','\xc8'},{'\xd9','\xc7'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xfc','\x6b'},{'\xfc','\x6a'},{'\x9a','\xec'},{'\x9a','\xed'},{'\xd9','\xac'},
+ {'\xb4','\xc8'},{'\xd9','\xd4'},{'\xd9','\xbc'},{'\xd9','\xbe'},{'\x9a','\xee'},
+ {'\xd9','\xcb'},{'\xd9','\xca'},{'\xd9','\xaa'},{'\xb4','\xd3'},{'\xb4','\xd5'},
+ {'\xd9','\xb2'},{'\xd9','\xb9'},{'\xd9','\xc1'},{'\xb4','\xd4'},{'\xd9','\xb8'},
+ {'\xd9','\xc4'},{'\xd9','\xd7'},{'\x00','\x00'},{'\xd9','\xcc'},{'\x9a','\xef'},
+ {'\x94','\x49'},{'\xfe','\x4f'},{'\x94','\x41'},{'\x92','\xb6'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x8b','\x79'},{'\x8e','\xb8'},{'\x94','\xa2'},{'\x90','\xf3'},
+ {'\x94','\xa1'},{'\x90','\x6b'},{'\xd9','\xd8'},{'\x90','\xf4'},{'\x00','\x00'},
+ {'\x94','\x7d'},{'\x00','\x00'},{'\xd9','\xae'},{'\x00','\x00'},{'\xfc','\x69'},
+ {'\x88','\xec'},{'\x00','\x00'},{'\xdd','\xf2'},{'\xb7','\xa6'},{'\x00','\x00'},
+ {'\xdd','\xf0'},{'\xdd','\xdb'},{'\xdd','\xe0'},{'\xdd','\xd9'},{'\x90','\xfd'},
+ {'\xdd','\xec'},{'\xdd','\xcb'},{'\xdd','\xd2'},{'\x00','\x00'},{'\xdd','\xea'},
+ {'\xdd','\xf4'},{'\xdd','\xdc'},{'\xfc','\x6f'},{'\xdd','\xcf'},{'\xdd','\xe2'},
+ {'\xdd','\xe7'},{'\xdd','\xd3'},{'\x9a','\xf0'},{'\xdd','\xe4'},{'\xdd','\xd0'},
+ {'\x9a','\xf1'},{'\x00','\x00'},{'\xdd','\xd7'},{'\xdd','\xd8'},{'\xb7','\xa8'},
+ {'\xdd','\xeb'},{'\xdd','\xe9'},{'\x00','\x00'},{'\xdd','\xcc'},{'\xdd','\xee'},
+ {'\x00','\x00'},{'\xdd','\xef'},{'\xdd','\xf1'},{'\xb7','\xac'},{'\xb7','\xa4'},
+ {'\x82','\x6c'},{'\xd5','\xb8'},{'\xdd','\xd4'},{'\xdd','\xe6'},{'\xdd','\xd5'},
+ {'\xb7','\xa1'},{'\xb7','\xb1'},{'\xdd','\xed'},{'\xb7','\xaf'},{'\xb7','\xab'},
+ {'\xdd','\xca'},{'\xb7','\xa3'},{'\x90','\xfe'},{'\xdd','\xcd'},{'\xb7','\xb0'},
+ {'\x9a','\xf2'},{'\xdd','\xdd'},{'\xdd','\xc9'},{'\x9a','\xf3'},{'\xb7','\xa9'},
+ {'\xdd','\xe1'},{'\xdd','\xd1'},{'\xb7','\xaa'},{'\xdd','\xda'},{'\xb7','\x7e'},
+ {'\xb4','\xd8'},{'\xdd','\xe3'},{'\xd9','\xbf'},{'\xdd','\xce'},{'\x9a','\xf4'},
+ {'\xfc','\x6d'},{'\xdd','\xe8'},{'\xb7','\xa5'},{'\xdd','\xe5'},{'\xb7','\xa2'},
+ {'\xdd','\xdf'},{'\xb7','\xad'},{'\xdd','\xd6'},{'\xdd','\xf3'},{'\x87','\xe2'},
+ {'\x92','\x62'},{'\x94','\xa3'},{'\x00','\x00'},{'\xfc','\x6e'},{'\x94','\xa4'},
+ {'\xb7','\xa7'},{'\xde','\xc6'},{'\x8d','\x6e'},{'\x9a','\xf5'},{'\xb7','\xae'},
+ {'\x8b','\xf9'},{'\x8b','\x7a'},{'\x90','\x40'},{'\x94','\x45'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xe2','\x4a'},{'\xe2','\x48'},{'\x00','\x00'},{'\xe2','\x5e'},
+ {'\xe2','\x46'},{'\x00','\x00'},{'\xe2','\x58'},{'\xb7','\x7d'},{'\xba','\x5f'},
+ {'\xe2','\x42'},{'\xe2','\x5d'},{'\x95','\x67'},{'\xe2','\x47'},{'\xe2','\x55'},
+ {'\xba','\x64'},{'\xba','\x5d'},{'\x00','\x00'},{'\xe2','\x5b'},{'\x9a','\xf6'},
+ {'\xe2','\x40'},{'\xe2','\x5a'},{'\x9a','\xf7'},{'\xba','\x6f'},{'\xe2','\x51'},
+ {'\xe2','\x61'},{'\xba','\x6d'},{'\xe2','\x49'},{'\xba','\x5e'},{'\xe2','\x4b'},
+ {'\xe2','\x59'},{'\xba','\x67'},{'\xe2','\x44'},{'\xba','\x6b'},{'\xba','\x61'},
+ {'\xe2','\x4d'},{'\xe2','\x43'},{'\xe1','\xfc'},{'\xfc','\x71'},{'\xe2','\x57'},
+ {'\xba','\x68'},{'\xe2','\x60'},{'\xe1','\xfd'},{'\xba','\x65'},{'\x00','\x00'},
+ {'\xe2','\x53'},{'\x00','\x00'},{'\xba','\x66'},{'\xe2','\x45'},{'\xe2','\x50'},
+ {'\xe2','\x4c'},{'\xe2','\x4e'},{'\xfc','\x72'},{'\xba','\x60'},{'\xe2','\x5f'},
+ {'\xba','\x6e'},{'\xe2','\x4f'},{'\x00','\x00'},{'\xe2','\x62'},{'\x91','\xee'},
+ {'\x00','\x00'},{'\xe1','\xfe'},{'\xe2','\x54'},{'\xba','\x63'},{'\xba','\x6c'},
+ {'\xba','\x6a'},{'\xe2','\x41'},{'\xe2','\x56'},{'\xba','\x69'},{'\x9a','\xf8'},
+ {'\x00','\x00'},{'\xba','\x62'},{'\xe2','\x52'},{'\x9a','\xf9'},{'\x9a','\xfa'},
+ {'\x00','\x00'},{'\x93','\xdb'},{'\xe2','\x5c'},{'\x00','\x00'},{'\x8a','\xcd'},
+ {'\x00','\x00'},{'\x94','\xa5'},{'\x96','\x7d'},{'\x8a','\xcb'},{'\x8f','\xb9'},
+ {'\x9b','\x41'},{'\xe5','\xd5'},{'\x00','\x00'},{'\xe5','\xd1'},{'\xe5','\xcd'},
+ {'\xe5','\xe1'},{'\xe5','\xde'},{'\xbc','\xcd'},{'\xfc','\x75'},{'\x00','\x00'},
+ {'\xe5','\xe5'},{'\xe5','\xd4'},{'\xbc','\xd8'},{'\xe5','\xdb'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xe5','\xd0'},{'\xe5','\xda'},{'\xbc','\xd5'},{'\xe5','\xee'},
+ {'\x00','\x00'},{'\xe5','\xeb'},{'\xe5','\xdd'},{'\xe5','\xce'},{'\x96','\x7e'},
+ {'\xfc','\x74'},{'\xe5','\xe2'},{'\xe5','\xe4'},{'\xbc','\xd1'},{'\xe5','\xd8'},
+ {'\xe5','\xd3'},{'\xe5','\xca'},{'\xbc','\xce'},{'\xbc','\xd6'},{'\x9b','\x42'},
+ {'\xe5','\xe7'},{'\xbc','\xd7'},{'\xe5','\xcb'},{'\xe5','\xed'},{'\xe5','\xe0'},
+ {'\xe5','\xe6'},{'\xbc','\xd4'},{'\xfe','\x54'},{'\x96','\xce'},{'\xe5','\xe3'},
+ {'\x00','\x00'},{'\xe5','\xea'},{'\x00','\x00'},{'\xbc','\xd9'},{'\x96','\xeb'},
+ {'\xbc','\xd3'},{'\xe5','\xdc'},{'\xe5','\xcf'},{'\xe5','\xef'},{'\xe5','\xcc'},
+ {'\xe5','\xe8'},{'\xbc','\xd0'},{'\x9b','\x43'},{'\xe5','\xd6'},{'\x9b','\x44'},
+ {'\xe5','\xd7'},{'\xbc','\xcf'},{'\xbc','\xcc'},{'\xe5','\xd2'},{'\xbc','\xd2'},
+ {'\x96','\xec'},{'\xbc','\xcb'},{'\x00','\x00'},{'\xe5','\xe9'},{'\xe5','\xec'},
+ {'\xe5','\xd9'},{'\xe9','\xca'},{'\x92','\xb7'},{'\x88','\xea'},{'\x94','\x40'},
+ {'\x9b','\x45'},{'\x9b','\x46'},{'\x94','\xa6'},{'\x89','\xe7'},{'\x96','\xed'},
+ {'\x8c','\x76'},{'\xe9','\xc2'},{'\x9b','\x47'},{'\xe9','\xbe'},{'\xbe','\xf6'},
+ {'\x96','\xee'},{'\x00','\x00'},{'\xbe','\xeb'},{'\xbe','\xf0'},{'\xbe','\xec'},
+ {'\xe9','\xcc'},{'\xe9','\xd7'},{'\xbe','\xea'},{'\xe9','\xc4'},{'\xe9','\xcd'},
+ {'\xe5','\xdf'},{'\xe9','\xce'},{'\x00','\x00'},{'\x9b','\x48'},{'\xbe','\xf1'},
+ {'\x9b','\x49'},{'\xe9','\xdd'},{'\xbe','\xf5'},{'\xbe','\xf8'},{'\xe9','\xc0'},
+ {'\x00','\x00'},{'\xbe','\xf4'},{'\x9b','\x4a'},{'\xe9','\xdb'},{'\xe9','\xdc'},
+ {'\xe9','\xd2'},{'\xe9','\xd1'},{'\xe9','\xc9'},{'\xfc','\x77'},{'\x9b','\x4b'},
+ {'\xe9','\xd3'},{'\xe9','\xda'},{'\xe9','\xd9'},{'\x9b','\x4c'},{'\xbe','\xef'},
+ {'\xbe','\xed'},{'\xe9','\xcb'},{'\xe9','\xc8'},{'\x00','\x00'},{'\xe9','\xc5'},
+ {'\xe9','\xd8'},{'\xbe','\xf7'},{'\xe9','\xd6'},{'\xbe','\xf3'},{'\xbe','\xf2'},
+ {'\x9b','\x4d'},{'\xe9','\xd0'},{'\x96','\xef'},{'\xe9','\xbf'},{'\xe9','\xc1'},
+ {'\xe9','\xc3'},{'\xe9','\xd5'},{'\xe9','\xcf'},{'\xbe','\xee'},{'\x00','\x00'},
+ {'\xe9','\xc6'},{'\x00','\x00'},{'\xe9','\xd4'},{'\x00','\x00'},{'\x8b','\x78'},
+ {'\x94','\xa7'},{'\x96','\xf8'},{'\x9b','\x4e'},{'\x00','\x00'},{'\xe9','\xc7'},
+ {'\x00','\x00'},{'\x96','\xf9'},{'\x8b','\x7b'},{'\x94','\x7e'},{'\x00','\x00'},
+ {'\x96','\xfc'},{'\x00','\x00'},{'\xc0','\xcf'},{'\xed','\x45'},{'\xc0','\xc8'},
+ {'\xec','\xf5'},{'\x9b','\x4f'},{'\xed','\x41'},{'\xc0','\xca'},{'\xed','\x48'},
+ {'\x00','\x00'},{'\xec','\xfc'},{'\x00','\x00'},{'\xec','\xf7'},{'\x9b','\x50'},
+ {'\x00','\x00'},{'\xed','\x49'},{'\xec','\xf3'},{'\xec','\xfe'},{'\x9b','\x51'},
+ {'\xc0','\xd1'},{'\xed','\x44'},{'\xed','\x4a'},{'\xec','\xfd'},{'\xc0','\xc9'},
+ {'\xed','\x40'},{'\xec','\xf4'},{'\xc0','\xd0'},{'\x00','\x00'},{'\x9b','\x52'},
+ {'\xed','\x47'},{'\xec','\xf9'},{'\xc0','\xcc'},{'\xfc','\x78'},{'\xec','\xfb'},
+ {'\xec','\xf8'},{'\xc0','\xd2'},{'\xec','\xfa'},{'\xc0','\xcb'},{'\xc0','\xce'},
+ {'\xed','\x43'},{'\xec','\xf6'},{'\xed','\x46'},{'\x9b','\x53'},{'\xed','\x42'},
+ {'\x96','\xfd'},{'\x96','\xfe'},{'\x99','\xfe'},{'\xc2','\x63'},{'\xef','\xe7'},
+ {'\xc2','\x68'},{'\xc2','\x69'},{'\x00','\x00'},{'\x9b','\x54'},{'\xfc','\x76'},
+ {'\xc2','\x62'},{'\xef','\xe6'},{'\x9b','\x55'},{'\xef','\xe3'},{'\xef','\xe4'},
+ {'\xc2','\x66'},{'\xef','\xde'},{'\xef','\xe2'},{'\xc2','\x65'},{'\x00','\x00'},
+ {'\xef','\xdf'},{'\x9b','\x56'},{'\x00','\x00'},{'\x00','\x00'},{'\x9a','\xfe'},
+ {'\xc2','\x67'},{'\xc2','\x64'},{'\x00','\x00'},{'\xef','\xdd'},{'\xef','\xe1'},
+ {'\xef','\xe5'},{'\x95','\xe3'},{'\x9b','\x57'},{'\xfb','\xdc'},{'\xf2','\x51'},
+ {'\xf2','\x4e'},{'\xf2','\x57'},{'\x00','\x00'},{'\xf2','\x56'},{'\xf2','\x54'},
+ {'\xf2','\x4f'},{'\x00','\x00'},{'\xc3','\x72'},{'\x9b','\x58'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x9b','\x59'},{'\xf2','\x50'},{'\xc3','\x71'},
+ {'\xc0','\xcd'},{'\xf2','\x53'},{'\xc3','\x70'},{'\xf2','\x58'},{'\xf2','\x52'},
+ {'\xf2','\x4d'},{'\xef','\xe0'},{'\x9c','\xf9'},{'\x00','\x00'},{'\x9d','\xe1'},
+ {'\xc3','\x6f'},{'\x00','\x00'},{'\xf2','\x4c'},{'\xf4','\x56'},{'\x00','\x00'},
+ {'\xf4','\x55'},{'\xf2','\x55'},{'\xc4','\x68'},{'\x00','\x00'},{'\xf4','\x59'},
+ {'\xf4','\x5a'},{'\xf4','\x54'},{'\xf4','\x58'},{'\x00','\x00'},{'\xf4','\x53'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x9b','\x5a'},{'\x00','\x00'},{'\xf5','\xd1'},
+ {'\xf4','\x57'},{'\xc4','\xe7'},{'\xc4','\xe5'},{'\xf5','\xcf'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xf5','\xd2'},{'\x00','\x00'},{'\xf5','\xce'},
+ {'\xf5','\xd0'},{'\xc4','\xe6'},{'\x9d','\xfe'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xf6','\xe5'},{'\xf6','\xe6'},{'\xc5','\x76'},{'\xf6','\xe4'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xf7','\xe2'},{'\xc5','\xcf'},{'\xf7','\xe0'},
+ {'\xf7','\xe1'},{'\xf8','\xac'},{'\x00','\x00'},{'\x00','\x00'},{'\xc6','\x56'},
+ {'\xf8','\xf3'},{'\xf8','\xf1'},{'\xf8','\xf2'},{'\xf8','\xf4'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xfc','\x79'},{'\xf9','\xbb'},{'\x94','\xa8'},{'\xa4','\xed'},
+ {'\xa6','\xb8'},{'\x8c','\xd1'},{'\xaa','\x59'},{'\x8a','\xcf'},{'\xcc','\xe9'},
+ {'\x00','\x00'},{'\x87','\xe6'},{'\xcf','\x64'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xd1','\xf5'},{'\xd1','\xf7'},{'\x00','\x00'},{'\xd1','\xf6'},
+ {'\x00','\x00'},{'\xd1','\xf8'},{'\xb1','\xfd'},{'\xd5','\xd7'},{'\xd1','\xf9'},
+ {'\x95','\xb9'},{'\xd5','\xd6'},{'\xd5','\xd8'},{'\xd5','\xd9'},{'\xd9','\xda'},
+ {'\xb4','\xdb'},{'\xd9','\xdb'},{'\xd9','\xdd'},{'\xb4','\xdc'},{'\xb4','\xda'},
+ {'\xd9','\xdc'},{'\x00','\x00'},{'\xdd','\xfa'},{'\xdd','\xf8'},{'\xdd','\xf7'},
+ {'\x00','\x00'},{'\xdd','\xf6'},{'\xdd','\xf5'},{'\xb7','\xb2'},{'\xdd','\xf9'},
+ {'\xba','\x70'},{'\xe2','\x63'},{'\xe2','\x65'},{'\xba','\x71'},{'\xe2','\x64'},
+ {'\xbc','\xdb'},{'\x00','\x00'},{'\xbc','\xda'},{'\xe5','\xf0'},{'\xfc','\x7a'},
+ {'\x92','\x6c'},{'\xe9','\xdf'},{'\xe9','\xde'},{'\xe9','\xe0'},{'\x9b','\x5b'},
+ {'\x00','\x00'},{'\xbe','\xf9'},{'\x00','\x00'},{'\xed','\x4b'},{'\xc0','\xd3'},
+ {'\x00','\x00'},{'\xef','\xe8'},{'\xc2','\x6a'},{'\xf2','\x59'},{'\xc5','\x77'},
+ {'\xa4','\xee'},{'\xa5','\xbf'},{'\xa6','\xb9'},{'\xa8','\x42'},{'\xaa','\x5a'},
+ {'\xaa','\x5b'},{'\x00','\x00'},{'\x93','\xc5'},{'\xac','\x6e'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xd1','\xfa'},{'\x00','\x00'},{'\x92','\xd0'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xb7','\xb3'},{'\x92','\xc8'},{'\x93','\xf0'},{'\x00','\x00'},
+ {'\xe6','\xd1'},{'\xbe','\xfa'},{'\xc2','\x6b'},{'\xa4','\xef'},{'\x9b','\x5c'},
+ {'\xa6','\xba'},{'\x8c','\x79'},{'\x00','\x00'},{'\xcc','\xeb'},{'\xaa','\x5c'},
+ {'\xcc','\xea'},{'\x9f','\x4e'},{'\xcf','\x65'},{'\xac','\x6f'},{'\xcf','\x66'},
+ {'\x00','\x00'},{'\xac','\x70'},{'\x87','\xe7'},{'\xd1','\xfc'},{'\xae','\xee'},
+ {'\xae','\xed'},{'\x92','\xcf'},{'\xd5','\xde'},{'\xd5','\xdc'},{'\xd5','\xdd'},
+ {'\xd5','\xdb'},{'\x00','\x00'},{'\xd5','\xda'},{'\x8d','\xb5'},{'\x89','\xe8'},
+ {'\xd9','\xde'},{'\xd9','\xe1'},{'\xb4','\xde'},{'\xd9','\xdf'},{'\xb4','\xdd'},
+ {'\xd9','\xe0'},{'\x8e','\xe8'},{'\xdd','\xfb'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xe2','\x66'},{'\xe2','\x67'},{'\xe2','\x68'},{'\x8a','\xd1'},{'\xe5','\xf3'},
+ {'\xe5','\xf2'},{'\xbc','\xdc'},{'\xe5','\xf1'},{'\xe5','\xf4'},{'\xe9','\xe1'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xe9','\xe2'},{'\xe9','\xe3'},{'\x00','\x00'},
+ {'\xed','\x4c'},{'\xc0','\xd4'},{'\xc2','\x6c'},{'\xf2','\x5a'},{'\x9f','\x4f'},
+ {'\xc4','\xe8'},{'\xc9','\x5f'},{'\x87','\xe8'},{'\xac','\x71'},{'\xcf','\x67'},
+ {'\xae','\xef'},{'\x00','\x00'},{'\x00','\x00'},{'\xb1','\xfe'},{'\x92','\x5f'},
+ {'\xb4','\xdf'},{'\xd9','\xe2'},{'\x00','\x00'},{'\xb7','\xb5'},{'\xb7','\xb4'},
+ {'\x90','\xb5'},{'\x8a','\x75'},{'\xe2','\x69'},{'\xe2','\x6a'},{'\xbc','\xdd'},
+ {'\xbc','\xde'},{'\xe9','\xe5'},{'\xe9','\xe4'},{'\xef','\xe9'},{'\xf7','\xe3'},
+ {'\xa4','\xf0'},{'\xc9','\x60'},{'\xa5','\xc0'},{'\x93','\xd1'},{'\xa8','\x43'},
+ {'\xcb','\x48'},{'\x00','\x00'},{'\xac','\x72'},{'\xb7','\xb6'},{'\xa4','\xf1'},
+ {'\x84','\x65'},{'\xcf','\x68'},{'\xac','\x73'},{'\xcf','\x69'},{'\x89','\xe1'},
+ {'\xc0','\xd5'},{'\xa4','\xf2'},{'\x9b','\x5d'},{'\x00','\x00'},{'\xcc','\xec'},
+ {'\x94','\xa9'},{'\xcf','\x6a'},{'\x89','\xe9'},{'\xd2','\x42'},{'\xd2','\x41'},
+ {'\xd1','\xfe'},{'\x00','\x00'},{'\xd1','\xfd'},{'\xd2','\x43'},{'\xd2','\x40'},
+ {'\x00','\x00'},{'\xa0','\x62'},{'\xb2','\x40'},{'\xb2','\x41'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xb4','\xe0'},{'\xd9','\xe3'},{'\x00','\x00'},{'\xd9','\xe4'},
+ {'\xd9','\xe5'},{'\x00','\x00'},{'\x8e','\xb9'},{'\x00','\x00'},{'\xde','\x41'},
+ {'\xde','\x42'},{'\xde','\x40'},{'\xfc','\x7b'},{'\xdd','\xfd'},{'\xdd','\xfe'},
+ {'\xb7','\xb7'},{'\xe2','\x6b'},{'\xe5','\xf7'},{'\xe5','\xf6'},{'\xe5','\xf5'},
+ {'\xe5','\xf8'},{'\xe9','\xe7'},{'\xe9','\xe6'},{'\xbe','\xfb'},{'\xe9','\xe8'},
+ {'\x8f','\xbb'},{'\xc0','\xd6'},{'\xed','\x4d'},{'\x00','\x00'},{'\xef','\xea'},
+ {'\xf2','\x5b'},{'\xf6','\xe7'},{'\x00','\x00'},{'\xa4','\xf3'},{'\xa5','\xc2'},
+ {'\xa5','\xc1'},{'\x00','\x00'},{'\xaa','\x5d'},{'\xc9','\x61'},{'\xc9','\x7e'},
+ {'\xa6','\xbb'},{'\x92','\x6e'},{'\xc9','\xf7'},{'\xcb','\x49'},{'\xcb','\x4a'},
+ {'\xaa','\x5e'},{'\x9b','\x5e'},{'\xcc','\xed'},{'\x00','\x00'},{'\xac','\x74'},
+ {'\xcf','\x6b'},{'\xcf','\x6c'},{'\x84','\x5a'},{'\xae','\xf0'},{'\xae','\xf4'},
+ {'\xd2','\x44'},{'\xae','\xf3'},{'\xae','\xf1'},{'\xae','\xf2'},{'\x84','\xec'},
+ {'\xd5','\xdf'},{'\xb2','\x42'},{'\xb4','\xe3'},{'\x00','\x00'},{'\xb4','\xe1'},
+ {'\xb4','\xe2'},{'\xd9','\xe6'},{'\x9b','\x5f'},{'\xa0','\x63'},{'\xba','\x72'},
+ {'\xa4','\xf4'},{'\x9c','\xf3'},{'\xc9','\xa1'},{'\x95','\xeb'},{'\xa5','\xc3'},
+ {'\xfe','\x40'},{'\x91','\xd2'},{'\xc9','\xa4'},{'\x00','\x00'},{'\xa0','\x64'},
+ {'\xa5','\xc6'},{'\xc9','\xa3'},{'\xa5','\xc5'},{'\xa5','\xc4'},{'\xa8','\x44'},
+ {'\xc9','\xa2'},{'\x00','\x00'},{'\x00','\x00'},{'\xc9','\xf8'},{'\x85','\xb9'},
+ {'\x00','\x00'},{'\x86','\xd5'},{'\xc9','\xfc'},{'\xc9','\xfe'},{'\xca','\x40'},
+ {'\xa6','\xc5'},{'\xa6','\xc6'},{'\xc9','\xfb'},{'\xa6','\xc1'},{'\x00','\x00'},
+ {'\xc9','\xf9'},{'\x00','\x00'},{'\xc9','\xfd'},{'\xa6','\xc2'},{'\x00','\x00'},
+ {'\xa6','\xbd'},{'\x9b','\x60'},{'\xa6','\xbe'},{'\x95','\xea'},{'\xa6','\xc4'},
+ {'\xc9','\xfa'},{'\xa6','\xbc'},{'\xa8','\x45'},{'\xa6','\xbf'},{'\xa6','\xc0'},
+ {'\xa6','\xc3'},{'\xa0','\x65'},{'\x00','\x00'},{'\x84','\xf1'},{'\xcb','\x5b'},
+ {'\xcb','\x59'},{'\xcb','\x4c'},{'\xa8','\x51'},{'\xcb','\x53'},{'\xa8','\x4c'},
+ {'\xcb','\x4d'},{'\x00','\x00'},{'\xcb','\x55'},{'\x9b','\x61'},{'\xcb','\x52'},
+ {'\xa8','\x4f'},{'\xcb','\x51'},{'\xa8','\x56'},{'\xcb','\x5a'},{'\xa8','\x58'},
+ {'\x9b','\x62'},{'\xa8','\x5a'},{'\x00','\x00'},{'\xcb','\x4b'},{'\x83','\x6e'},
+ {'\xa8','\x4d'},{'\xcb','\x5c'},{'\x00','\x00'},{'\xa8','\x54'},{'\xa8','\x57'},
+ {'\x9b','\x63'},{'\xcd','\x45'},{'\xa8','\x47'},{'\xa8','\x5e'},{'\xa8','\x55'},
+ {'\xcb','\x4e'},{'\xa8','\x4a'},{'\xa8','\x59'},{'\xcb','\x56'},{'\xa8','\x48'},
+ {'\xa8','\x49'},{'\xcd','\x43'},{'\xcb','\x4f'},{'\xa8','\x50'},{'\xa8','\x5b'},
+ {'\xcb','\x5d'},{'\xcb','\x50'},{'\xa8','\x4e'},{'\x00','\x00'},{'\xa8','\x53'},
+ {'\xcc','\xee'},{'\xa8','\x5c'},{'\xcb','\x57'},{'\xa8','\x52'},{'\x00','\x00'},
+ {'\xa8','\x5d'},{'\xa8','\x46'},{'\xcb','\x54'},{'\xa8','\x4b'},{'\xcb','\x58'},
+ {'\xcd','\x44'},{'\x00','\x00'},{'\x85','\xd8'},{'\x00','\x00'},{'\x95','\xca'},
+ {'\x93','\x6b'},{'\x88','\xf4'},{'\x8e','\x75'},{'\x8b','\x7e'},{'\x84','\x5f'},
+ {'\x85','\xdc'},{'\x00','\x00'},{'\x8d','\xe0'},{'\x86','\xdb'},{'\xaa','\x6a'},
+ {'\xaa','\x7a'},{'\xcc','\xf5'},{'\xaa','\x71'},{'\x9b','\x64'},{'\xcd','\x4b'},
+ {'\xaa','\x62'},{'\xa0','\x66'},{'\xaa','\x65'},{'\xcd','\x42'},{'\x00','\x00'},
+ {'\xcc','\xf3'},{'\xcc','\xf7'},{'\xaa','\x6d'},{'\xaa','\x6f'},{'\xcc','\xfa'},
+ {'\xaa','\x76'},{'\xaa','\x68'},{'\xaa','\x66'},{'\xaa','\x67'},{'\xaa','\x75'},
+ {'\xcd','\x47'},{'\xaa','\x70'},{'\xcc','\xf9'},{'\xcc','\xfb'},{'\xaa','\x6e'},
+ {'\xaa','\x73'},{'\xcc','\xfc'},{'\xcd','\x4a'},{'\x00','\x00'},{'\xac','\x75'},
+ {'\xaa','\x79'},{'\x9b','\x65'},{'\xaa','\x63'},{'\xcd','\x49'},{'\xfc','\x7d'},
+ {'\xcd','\x4d'},{'\xcc','\xf8'},{'\xcd','\x4f'},{'\xcd','\x40'},{'\xaa','\x6c'},
+ {'\xcc','\xf4'},{'\xaa','\x6b'},{'\xaa','\x7d'},{'\xaa','\x72'},{'\x00','\x00'},
+ {'\xcc','\xf2'},{'\xcf','\x75'},{'\xaa','\x78'},{'\xaa','\x7c'},{'\xcd','\x41'},
+ {'\xcd','\x46'},{'\x9b','\x66'},{'\xaa','\x7e'},{'\xaa','\x77'},{'\xaa','\x69'},
+ {'\xaa','\x5f'},{'\x00','\x00'},{'\xaa','\x64'},{'\x00','\x00'},{'\xcc','\xf6'},
+ {'\xaa','\x60'},{'\xcd','\x4e'},{'\x84','\x5e'},{'\xcc','\xf0'},{'\xcc','\xef'},
+ {'\xcc','\xfd'},{'\xcc','\xf1'},{'\xaa','\x7b'},{'\xae','\xf5'},{'\xaa','\x74'},
+ {'\xcc','\xfe'},{'\xaa','\x61'},{'\x00','\x00'},{'\xac','\xa6'},{'\x8f','\x54'},
+ {'\x8f','\xbc'},{'\x8b','\xa2'},{'\xcd','\x4c'},{'\x8f','\x77'},{'\x8a','\xd2'},
+ {'\x87','\xea'},{'\x88','\xf2'},{'\x83','\xbd'},{'\x9b','\x67'},{'\xcf','\x7c'},
+ {'\xcf','\xa1'},{'\x9b','\x68'},{'\xcf','\xa4'},{'\xcf','\x77'},{'\x9b','\x69'},
+ {'\x9b','\x6a'},{'\xcf','\xa7'},{'\xcf','\xaa'},{'\xcf','\xac'},{'\xcf','\x74'},
+ {'\xac','\x76'},{'\xac','\x7b'},{'\xd2','\x49'},{'\xac','\xad'},{'\xcf','\xa5'},
+ {'\xcf','\xad'},{'\xcf','\x7b'},{'\xcf','\x73'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xd2','\x64'},{'\xac','\x7e'},{'\xcf','\xa2'},{'\xcf','\x78'},
+ {'\xcf','\x7a'},{'\xac','\xa5'},{'\x00','\x00'},{'\xcf','\x7d'},{'\xac','\x7d'},
+ {'\xcf','\x70'},{'\xcf','\xa8'},{'\x00','\x00'},{'\xcf','\xab'},{'\x00','\x00'},
+ {'\x95','\xb0'},{'\xac','\x7a'},{'\x9b','\x6b'},{'\xac','\xa8'},{'\xcf','\x6d'},
+ {'\xac','\xaa'},{'\xac','\x78'},{'\xac','\xae'},{'\xcf','\xa9'},{'\xcf','\x6f'},
+ {'\xac','\xab'},{'\xd2','\x5e'},{'\xcd','\x48'},{'\xac','\x7c'},{'\xac','\x77'},
+ {'\xcf','\x76'},{'\xcf','\x6e'},{'\xac','\xac'},{'\xac','\xa4'},{'\xcf','\xa3'},
+ {'\xac','\xa9'},{'\xac','\xa7'},{'\xcf','\x79'},{'\xac','\xa1'},{'\xcf','\x71'},
+ {'\xac','\xa2'},{'\xac','\xa3'},{'\xcf','\x72'},{'\xcf','\xa6'},{'\xac','\x79'},
+ {'\xcf','\x7e'},{'\x83','\xbe'},{'\x92','\xea'},{'\x93','\x48'},{'\x87','\xe9'},
+ {'\x87','\xec'},{'\x8d','\xe1'},{'\x00','\x00'},{'\x88','\xf3'},{'\x84','\xf2'},
+ {'\x00','\x00'},{'\x8e','\xe9'},{'\x89','\xec'},{'\x8a','\xd7'},{'\x00','\x00'},
+ {'\x84','\xf3'},{'\x8e','\x74'},{'\x88','\xf1'},{'\x87','\xf0'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x9b','\x6c'},{'\xd2','\x4c'},{'\xae','\xfd'},{'\xaf','\x43'},
+ {'\x9b','\x6d'},{'\x93','\xbd'},{'\x00','\x00'},{'\xd2','\x55'},{'\xd2','\x5b'},
+ {'\xd2','\x57'},{'\xd2','\x4a'},{'\xd2','\x4d'},{'\xd2','\x46'},{'\xd2','\x47'},
+ {'\xaf','\x4a'},{'\xae','\xfa'},{'\xd2','\x56'},{'\xd2','\x5f'},{'\xaf','\x45'},
+ {'\xae','\xf6'},{'\x00','\x00'},{'\xaf','\x40'},{'\xd2','\x4e'},{'\xaf','\x42'},
+ {'\xd2','\x4f'},{'\xd2','\x59'},{'\x9b','\x6e'},{'\xfb','\xa7'},{'\x00','\x00'},
+ {'\xaf','\x44'},{'\xd2','\x68'},{'\xd2','\x48'},{'\xae','\xfc'},{'\xae','\xfb'},
+ {'\xaf','\x48'},{'\xd2','\x45'},{'\xd2','\x66'},{'\xd2','\x5a'},{'\xd2','\x67'},
+ {'\xd2','\x61'},{'\xd2','\x53'},{'\xd2','\x62'},{'\x9b','\x6f'},{'\xd2','\x5c'},
+ {'\xd2','\x65'},{'\xd2','\x63'},{'\xaf','\x49'},{'\xd2','\x54'},{'\xae','\xf9'},
+ {'\xae','\xf8'},{'\xaf','\x41'},{'\xaf','\x47'},{'\xd2','\x60'},{'\xaf','\x46'},
+ {'\xd2','\x51'},{'\xb2','\x43'},{'\x9b','\x70'},{'\xd2','\x69'},{'\xd2','\x50'},
+ {'\xd2','\x4b'},{'\xae','\xfe'},{'\xaf','\x4b'},{'\xae','\xf7'},{'\xfe','\x5c'},
+ {'\xd2','\x58'},{'\xd2','\x5d'},{'\x93','\xe8'},{'\x00','\x00'},{'\x89','\xed'},
+ {'\x82','\x71'},{'\x8e','\xbb'},{'\x8d','\xcf'},{'\x86','\xda'},{'\x8e','\xbd'},
+ {'\x84','\xf0'},{'\x00','\x00'},{'\x84','\xf4'},{'\x86','\xde'},{'\x9b','\x71'},
+ {'\x87','\xee'},{'\x87','\xef'},{'\x86','\xd9'},{'\x89','\xef'},{'\xb2','\x65'},
+ {'\xd5','\xe1'},{'\xd5','\xe5'},{'\x00','\x00'},{'\xb2','\x52'},{'\xb2','\x50'},
+ {'\x00','\x00'},{'\x9b','\x72'},{'\xb2','\x47'},{'\xd5','\xe3'},{'\xd5','\xe2'},
+ {'\xb2','\x5b'},{'\x00','\x00'},{'\xd5','\xe8'},{'\xb2','\x55'},{'\xfc','\xa1'},
+ {'\xd5','\xfa'},{'\xd6','\x47'},{'\xb2','\x44'},{'\xd5','\xf7'},{'\xd5','\xf0'},
+ {'\xb2','\x67'},{'\xd5','\xe0'},{'\x00','\x00'},{'\xd5','\xfc'},{'\x00','\x00'},
+ {'\xb2','\x64'},{'\xb2','\x58'},{'\xb2','\x63'},{'\xb2','\x4e'},{'\xd5','\xec'},
+ {'\xd5','\xfe'},{'\xd5','\xf6'},{'\xb2','\x4f'},{'\xb2','\x49'},{'\xd6','\x45'},
+ {'\x00','\x00'},{'\xd5','\xfd'},{'\xd6','\x40'},{'\xb2','\x51'},{'\xb2','\x59'},
+ {'\xd6','\x42'},{'\xd5','\xea'},{'\xd5','\xfb'},{'\xd5','\xef'},{'\xd6','\x44'},
+ {'\xb2','\x5e'},{'\xb2','\x46'},{'\xb2','\x5c'},{'\xd5','\xf4'},{'\xd5','\xf2'},
+ {'\xd5','\xf3'},{'\xb2','\x53'},{'\xd5','\xee'},{'\xd5','\xed'},{'\xb2','\x48'},
+ {'\xd5','\xe7'},{'\xd6','\x46'},{'\xb2','\x4a'},{'\xd5','\xf1'},{'\xb2','\x68'},
+ {'\x00','\x00'},{'\xb2','\x62'},{'\xd5','\xe6'},{'\xb2','\x5f'},{'\xb2','\x5d'},
+ {'\xb2','\x66'},{'\xd5','\xf8'},{'\xb2','\x61'},{'\xd2','\x52'},{'\xd5','\xf9'},
+ {'\xb2','\x60'},{'\xd6','\x41'},{'\xb2','\x45'},{'\xd5','\xf5'},{'\xb2','\x57'},
+ {'\xd5','\xe9'},{'\xb2','\x56'},{'\xa0','\x67'},{'\xb2','\x54'},{'\xb2','\x4c'},
+ {'\xb2','\x4b'},{'\xd9','\xe7'},{'\xd6','\x43'},{'\x9b','\x73'},{'\x00','\x00'},
+ {'\xd5','\xeb'},{'\x00','\x00'},{'\x9b','\x74'},{'\xd9','\xfc'},{'\x9b','\x75'},
+ {'\xb2','\x4d'},{'\x00','\x00'},{'\x92','\x64'},{'\x92','\xc6'},{'\x92','\xe4'},
+ {'\x84','\x5d'},{'\x92','\xdd'},{'\x8d','\xd0'},{'\x86','\xd4'},{'\x8a','\xd5'},
+ {'\x9b','\x76'},{'\x86','\xd8'},{'\x88','\xf6'},{'\x00','\x00'},{'\x92','\xaa'},
+ {'\x86','\xdc'},{'\x94','\xaa'},{'\x8a','\xd3'},{'\x86','\xdd'},{'\x9b','\x77'},
+ {'\xb5','\x41'},{'\xb2','\x5a'},{'\xb4','\xee'},{'\xd9','\xf6'},{'\xb4','\xfc'},
+ {'\x00','\x00'},{'\xd9','\xea'},{'\xb4','\xeb'},{'\xb4','\xe7'},{'\xda','\x49'},
+ {'\xb4','\xed'},{'\xb4','\xf1'},{'\xb4','\xec'},{'\xb4','\xf5'},{'\xda','\x4d'},
+ {'\xda','\x44'},{'\xa0','\x68'},{'\x9b','\x78'},{'\xd9','\xf1'},{'\xb4','\xfa'},
+ {'\xb4','\xf4'},{'\xd9','\xfd'},{'\xb4','\xe4'},{'\xda','\x4a'},{'\xda','\x43'},
+ {'\xb4','\xe8'},{'\xd9','\xf7'},{'\xb4','\xf7'},{'\xda','\x55'},{'\xda','\x56'},
+ {'\x00','\x00'},{'\xb4','\xe5'},{'\xda','\x48'},{'\xb4','\xf9'},{'\xd9','\xfb'},
+ {'\xd9','\xed'},{'\xd9','\xee'},{'\xb4','\xfd'},{'\xd9','\xf2'},{'\xd9','\xf9'},
+ {'\xd9','\xf3'},{'\x00','\x00'},{'\xb4','\xfb'},{'\xb5','\x44'},{'\xd9','\xef'},
+ {'\xd9','\xe8'},{'\xd9','\xe9'},{'\x00','\x00'},{'\xd9','\xeb'},{'\xb4','\xea'},
+ {'\xd9','\xf8'},{'\x00','\x00'},{'\xb4','\xf8'},{'\xb5','\x42'},{'\xfc','\x7e'},
+ {'\x9b','\x79'},{'\xd9','\xfa'},{'\xda','\x53'},{'\xda','\x4b'},{'\xb4','\xe6'},
+ {'\xda','\x51'},{'\xb4','\xf2'},{'\x9d','\xcb'},{'\xb4','\xf0'},{'\x9b','\x7a'},
+ {'\xda','\x57'},{'\xb4','\xef'},{'\xda','\x41'},{'\xd9','\xf4'},{'\xd9','\xfe'},
+ {'\xb5','\x47'},{'\xda','\x45'},{'\xda','\x42'},{'\xd9','\xf0'},{'\xb5','\x43'},
+ {'\xda','\x4f'},{'\xda','\x4c'},{'\xda','\x54'},{'\xb4','\xe9'},{'\xda','\x40'},
+ {'\xb5','\x46'},{'\x00','\x00'},{'\xda','\x47'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xb4','\xf3'},{'\xb4','\xf6'},{'\x00','\x00'},{'\xda','\x46'},{'\xb5','\x45'},
+ {'\xd9','\xf5'},{'\xd5','\xe4'},{'\x00','\x00'},{'\xa0','\x69'},{'\xda','\x50'},
+ {'\xda','\x4e'},{'\xda','\x52'},{'\x00','\x00'},{'\x00','\x00'},{'\x95','\xcb'},
+ {'\x00','\x00'},{'\x8d','\x6f'},{'\x85','\xda'},{'\x93','\xd2'},{'\x00','\x00'},
+ {'\xa0','\x6a'},{'\x87','\xed'},{'\x00','\x00'},{'\x8a','\xd6'},{'\xa0','\x6b'},
+ {'\x00','\x00'},{'\xd9','\xec'},{'\xb5','\x40'},{'\x00','\x00'},{'\xfe','\x6a'},
+ {'\x82','\x78'},{'\xde','\x61'},{'\xde','\x60'},{'\xde','\x46'},{'\xb7','\xbd'},
+ {'\x00','\x00'},{'\xde','\x5f'},{'\xde','\x49'},{'\xde','\x4a'},{'\x00','\x00'},
+ {'\xb7','\xc7'},{'\xde','\x68'},{'\xb7','\xc2'},{'\xde','\x5e'},{'\x9b','\x7b'},
+ {'\xde','\x43'},{'\xb7','\xc8'},{'\xb7','\xbe'},{'\xde','\x52'},{'\xde','\x48'},
+ {'\xde','\x4b'},{'\xde','\x63'},{'\xb7','\xb8'},{'\xde','\x6a'},{'\xde','\x62'},
+ {'\xb7','\xc1'},{'\xde','\x57'},{'\xb7','\xcc'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xb7','\xcb'},{'\xb7','\xc5'},{'\x00','\x00'},{'\x00','\x00'},{'\xde','\x69'},
+ {'\xb7','\xb9'},{'\xde','\x55'},{'\xde','\x4c'},{'\xde','\x59'},{'\xde','\x65'},
+ {'\xb7','\xcd'},{'\x9b','\x7c'},{'\xb7','\xbb'},{'\xde','\x54'},{'\x9b','\x7d'},
+ {'\xde','\x4d'},{'\xb7','\xc4'},{'\xa0','\x6c'},{'\xb7','\xc3'},{'\xde','\x50'},
+ {'\xde','\x5a'},{'\xde','\x64'},{'\xde','\x47'},{'\xde','\x51'},{'\xb7','\xbc'},
+ {'\xde','\x5b'},{'\xb7','\xc9'},{'\xb7','\xc0'},{'\xde','\x4e'},{'\xb7','\xbf'},
+ {'\xde','\x45'},{'\xde','\x53'},{'\xde','\x67'},{'\xb4','\xfe'},{'\xba','\xb0'},
+ {'\xde','\x56'},{'\xe2','\x6c'},{'\xde','\x58'},{'\xde','\x66'},{'\xb7','\xc6'},
+ {'\xde','\x4f'},{'\xb7','\xba'},{'\xb7','\xca'},{'\xbc','\xf0'},{'\xde','\x44'},
+ {'\x8e','\xbe'},{'\xde','\x5d'},{'\x95','\x50'},{'\x86','\xd3'},{'\x9b','\x7e'},
+ {'\xde','\x5c'},{'\x93','\x69'},{'\x86','\xd7'},{'\xa0','\x6d'},{'\x90','\x41'},
+ {'\x86','\xd6'},{'\xa0','\x6e'},{'\x00','\x00'},{'\x8a','\xd4'},{'\x89','\xee'},
+ {'\x8d','\x7b'},{'\x00','\x00'},{'\x89','\xeb'},{'\x8c','\xd2'},{'\x00','\x00'},
+ {'\xe2','\xaa'},{'\xba','\xad'},{'\xe2','\x7d'},{'\xe2','\xa4'},{'\xba','\xa2'},
+ {'\x00','\x00'},{'\xe2','\x6e'},{'\xba','\xaf'},{'\x00','\x00'},{'\xba','\x77'},
+ {'\xe2','\x6d'},{'\xe2','\xb0'},{'\xba','\xb1'},{'\xe2','\x71'},{'\xe2','\xa3'},
+ {'\x9b','\xa1'},{'\xe2','\x73'},{'\xe2','\xb3'},{'\xe2','\xaf'},{'\xba','\x75'},
+ {'\xba','\xa1'},{'\xe6','\x53'},{'\xba','\xae'},{'\xba','\x7d'},{'\xe2','\x6f'},
+ {'\x9b','\xa2'},{'\xe2','\xae'},{'\xba','\xa3'},{'\xe2','\xab'},{'\xe2','\xb8'},
+ {'\xe2','\x75'},{'\xe2','\x7e'},{'\x9b','\xa3'},{'\x9b','\xa4'},{'\xe2','\xb6'},
+ {'\xe2','\xac'},{'\xba','\x7c'},{'\x00','\x00'},{'\xa0','\x6f'},{'\xe2','\x7c'},
+ {'\xba','\x76'},{'\xba','\x74'},{'\xba','\xa8'},{'\x9b','\xa5'},{'\x9b','\xa6'},
+ {'\xe2','\x7a'},{'\xe2','\x77'},{'\xe2','\x78'},{'\x00','\x00'},{'\xe2','\xb2'},
+ {'\x00','\x00'},{'\xe2','\xb7'},{'\xe2','\xb5'},{'\xba','\x7a'},{'\xe2','\xb9'},
+ {'\xba','\x7e'},{'\xba','\xa7'},{'\xa0','\x70'},{'\xe2','\x70'},{'\xe5','\xfa'},
+ {'\xe2','\x79'},{'\x00','\x00'},{'\xba','\x78'},{'\xba','\xac'},{'\xba','\xa9'},
+ {'\xba','\x7b'},{'\xe2','\xa5'},{'\xe2','\x74'},{'\xba','\xaa'},{'\xe2','\xa7'},
+ {'\xba','\xa4'},{'\xba','\xa6'},{'\xba','\x73'},{'\x9b','\xa7'},{'\xe2','\xa9'},
+ {'\xe2','\xa1'},{'\xe2','\x72'},{'\xba','\xa5'},{'\xe2','\xb1'},{'\xe2','\xb4'},
+ {'\xe2','\x7b'},{'\xe2','\xa8'},{'\x9b','\xa8'},{'\xba','\x79'},{'\xbc','\xdf'},
+ {'\xe2','\xa6'},{'\xe5','\xf9'},{'\x00','\x00'},{'\xe2','\xad'},{'\xfc','\xa2'},
+ {'\x82','\x50'},{'\x8f','\xbd'},{'\x8b','\x7c'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x8b','\xfb'},{'\x00','\x00'},{'\x89','\xf0'},{'\xe2','\x76'},
+ {'\xe6','\x44'},{'\xe6','\x4e'},{'\xbc','\xe2'},{'\xe6','\x4d'},{'\xe6','\x59'},
+ {'\xbc','\xe4'},{'\xe6','\x4b'},{'\x9b','\xa9'},{'\xe6','\x4f'},{'\xbc','\xef'},
+ {'\x00','\x00'},{'\xe6','\x46'},{'\xbc','\xe7'},{'\x90','\xb9'},{'\xe6','\x52'},
+ {'\xe9','\xf0'},{'\xbc','\xf3'},{'\xbc','\xf2'},{'\xe6','\x54'},{'\xe6','\x43'},
+ {'\xe6','\x5e'},{'\xbc','\xed'},{'\x00','\x00'},{'\xbc','\xe3'},{'\xe6','\x57'},
+ {'\x00','\x00'},{'\xe6','\x5b'},{'\xe6','\x60'},{'\xe6','\x55'},{'\xe6','\x49'},
+ {'\xbc','\xe6'},{'\xbc','\xe9'},{'\xbc','\xf1'},{'\xbc','\xec'},{'\x00','\x00'},
+ {'\xe6','\x4c'},{'\xe2','\xa2'},{'\xa0','\x71'},{'\x00','\x00'},{'\xe6','\x48'},
+ {'\xe6','\x5f'},{'\xbc','\xe8'},{'\x9b','\xaa'},{'\xbc','\xeb'},{'\xe6','\x61'},
+ {'\xbc','\xe0'},{'\xe6','\x56'},{'\xe5','\xfb'},{'\xe6','\x5c'},{'\xc0','\xdf'},
+ {'\x95','\x6b'},{'\xe6','\x4a'},{'\x00','\x00'},{'\xbc','\xe1'},{'\xe6','\x45'},
+ {'\xbc','\xe5'},{'\xe5','\xfc'},{'\xba','\xab'},{'\xe6','\x41'},{'\x9b','\xab'},
+ {'\xe6','\x5a'},{'\xe6','\x42'},{'\xe6','\x40'},{'\xbc','\xea'},{'\x00','\x00'},
+ {'\xe6','\x58'},{'\xa0','\x72'},{'\xe5','\xfe'},{'\xe6','\x51'},{'\xe6','\x50'},
+ {'\xe6','\x5d'},{'\xe6','\x47'},{'\xbc','\xee'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x8b','\xfa'},{'\x9b','\xac'},{'\xe9','\xf3'},
+ {'\x9b','\xad'},{'\xbf','\x49'},{'\xbe','\xfe'},{'\xea','\x40'},{'\xe9','\xeb'},
+ {'\xbf','\x41'},{'\xe9','\xf7'},{'\xbf','\x48'},{'\xbf','\x43'},{'\xe9','\xf5'},
+ {'\xed','\x4f'},{'\xe9','\xfb'},{'\xea','\x42'},{'\xe9','\xfa'},{'\xe9','\xe9'},
+ {'\xe9','\xf8'},{'\xea','\x44'},{'\xea','\x46'},{'\xbe','\xfd'},{'\xea','\x45'},
+ {'\xbf','\x44'},{'\xbf','\x4a'},{'\xa0','\x73'},{'\xbf','\x47'},{'\x00','\x00'},
+ {'\xe9','\xfe'},{'\xbf','\x46'},{'\xe9','\xf9'},{'\x9b','\xae'},{'\xe9','\xed'},
+ {'\xe9','\xf2'},{'\x9b','\xaf'},{'\xe9','\xfd'},{'\xbf','\x45'},{'\xbf','\x42'},
+ {'\xbe','\xfc'},{'\xbf','\x40'},{'\xe9','\xf1'},{'\x00','\x00'},{'\xe5','\xfd'},
+ {'\xe9','\xec'},{'\xe9','\xef'},{'\xea','\x41'},{'\xe9','\xf4'},{'\xe9','\xea'},
+ {'\xed','\x4e'},{'\xea','\x43'},{'\xe9','\xee'},{'\xe9','\xfc'},{'\x00','\x00'},
+ {'\x8b','\x7d'},{'\x8b','\xa1'},{'\x9b','\xb0'},{'\xed','\x51'},{'\xc0','\xe3'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc0','\xd7'},{'\x9b','\xb1'},{'\xfc','\xa4'},
+ {'\xc0','\xdb'},{'\xed','\x53'},{'\xed','\x59'},{'\xed','\x57'},{'\xc0','\xd9'},
+ {'\xc0','\xda'},{'\xc0','\xe1'},{'\xed','\x5a'},{'\xed','\x52'},{'\xc0','\xdc'},
+ {'\x00','\x00'},{'\xed','\x56'},{'\xed','\x55'},{'\xed','\x5b'},{'\xc0','\xe2'},
+ {'\x00','\x00'},{'\xc0','\xdd'},{'\xc0','\xe0'},{'\xed','\x54'},{'\xc0','\xe4'},
+ {'\xc0','\xde'},{'\xc0','\xe5'},{'\xc0','\xd8'},{'\xed','\x58'},{'\xa0','\x74'},
+ {'\xed','\x50'},{'\xa0','\x75'},{'\x95','\xc6'},{'\xef','\xf7'},{'\x9b','\xb2'},
+ {'\x00','\x00'},{'\xc2','\x71'},{'\xef','\xf4'},{'\xef','\xf6'},{'\x00','\x00'},
+ {'\xc2','\x6f'},{'\xef','\xf2'},{'\xef','\xf3'},{'\xef','\xee'},{'\x00','\x00'},
+ {'\x9b','\xb3'},{'\xe9','\xf6'},{'\xef','\xef'},{'\xc2','\x70'},{'\xef','\xeb'},
+ {'\x00','\x00'},{'\xc2','\x6d'},{'\xef','\xf8'},{'\xc2','\x6e'},{'\xef','\xec'},
+ {'\xef','\xed'},{'\xef','\xf1'},{'\xc2','\x73'},{'\x00','\x00'},{'\xc2','\x72'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xef','\xf0'},{'\xc3','\x78'},{'\xf2','\x5f'},
+ {'\xf2','\x65'},{'\xc3','\x79'},{'\xf2','\x5c'},{'\xc3','\x76'},{'\xc3','\x73'},
+ {'\xf2','\x67'},{'\xc3','\x77'},{'\xfe','\xa1'},{'\xc3','\x74'},{'\xf2','\x5e'},
+ {'\xf2','\x61'},{'\xf2','\x62'},{'\xf2','\x63'},{'\xf2','\x66'},{'\x00','\x00'},
+ {'\xef','\xf5'},{'\xf2','\x5d'},{'\xc3','\x75'},{'\xf2','\x64'},{'\xf2','\x68'},
+ {'\xf2','\x60'},{'\x93','\x40'},{'\x00','\x00'},{'\x00','\x00'},{'\xf4','\x5d'},
+ {'\xc4','\x6a'},{'\xf4','\x60'},{'\xc4','\x6b'},{'\xf4','\x68'},{'\xf4','\x5f'},
+ {'\xf4','\x5c'},{'\x00','\x00'},{'\xf4','\x5e'},{'\xf4','\x62'},{'\xf4','\x65'},
+ {'\xf4','\x64'},{'\xf4','\x67'},{'\xf4','\x5b'},{'\x00','\x00'},{'\xc4','\x69'},
+ {'\xf4','\x63'},{'\xf4','\x66'},{'\xf4','\x69'},{'\xf4','\x61'},{'\xf5','\xd3'},
+ {'\xf5','\xd4'},{'\xf5','\xd8'},{'\xf5','\xd9'},{'\x00','\x00'},{'\xf5','\xd6'},
+ {'\xf5','\xd7'},{'\xf5','\xd5'},{'\x9b','\xb4'},{'\xc4','\xe9'},{'\x9b','\xb5'},
+ {'\x00','\x00'},{'\x90','\x76'},{'\x9b','\xb6'},{'\xc5','\x78'},{'\xf6','\xeb'},
+ {'\x00','\x00'},{'\x9b','\xb7'},{'\xf6','\xe8'},{'\xf6','\xe9'},{'\xf6','\xea'},
+ {'\xc5','\x79'},{'\x00','\x00'},{'\xf7','\xe5'},{'\xf7','\xe4'},{'\x9b','\xb8'},
+ {'\xf8','\xaf'},{'\xc5','\xf4'},{'\xf8','\xad'},{'\xf8','\xb0'},{'\xf8','\xae'},
+ {'\xf8','\xf5'},{'\xc6','\x57'},{'\xc6','\x65'},{'\xf9','\xa3'},{'\xf9','\x6c'},
+ {'\x9b','\xb9'},{'\xf9','\xa2'},{'\xf9','\xd0'},{'\xf9','\xd1'},{'\xa4','\xf5'},
+ {'\x9c','\xf6'},{'\x85','\xd9'},{'\x00','\x00'},{'\x88','\xf9'},{'\xa6','\xc7'},
+ {'\xca','\x41'},{'\x00','\x00'},{'\x00','\x00'},{'\xcb','\x5e'},{'\x8d','\x5f'},
+ {'\xa8','\x5f'},{'\x9b','\xba'},{'\xa8','\x62'},{'\x9b','\xbb'},{'\xcb','\x5f'},
+ {'\x00','\x00'},{'\xa8','\x60'},{'\xa8','\x61'},{'\x83','\x4d'},{'\x89','\xf2'},
+ {'\x85','\xdf'},{'\xfc','\xa5'},{'\xcd','\x58'},{'\xcd','\x5a'},{'\xcd','\x55'},
+ {'\xcd','\x52'},{'\xcd','\x54'},{'\x00','\x00'},{'\x00','\x00'},{'\x93','\xf4'},
+ {'\xaa','\xa4'},{'\x9b','\xbc'},{'\x00','\x00'},{'\xfe','\xa3'},{'\xaa','\xa2'},
+ {'\x9b','\xbd'},{'\x00','\x00'},{'\xcd','\x56'},{'\xaa','\xa3'},{'\xcd','\x53'},
+ {'\xcd','\x50'},{'\xaa','\xa1'},{'\xcd','\x57'},{'\x00','\x00'},{'\xcd','\x51'},
+ {'\xaa','\xa5'},{'\xcd','\x59'},{'\x00','\x00'},{'\x8e','\x45'},{'\x8e','\x76'},
+ {'\x00','\x00'},{'\xcf','\xaf'},{'\x9b','\xbe'},{'\xcf','\xb3'},{'\x00','\x00'},
+ {'\x9b','\xbf'},{'\xac','\xb7'},{'\x9b','\xc0'},{'\x9b','\xc1'},{'\x9b','\xc2'},
+ {'\x00','\x00'},{'\xcf','\xb6'},{'\x00','\x00'},{'\xac','\xaf'},{'\xac','\xb2'},
+ {'\xac','\xb4'},{'\xac','\xb6'},{'\xac','\xb3'},{'\xcf','\xb2'},{'\xcf','\xb1'},
+ {'\x00','\x00'},{'\xac','\xb1'},{'\xcf','\xb4'},{'\xcf','\xb5'},{'\x00','\x00'},
+ {'\xcf','\xae'},{'\xac','\xb5'},{'\x8a','\xbb'},{'\xac','\xb0'},{'\xa0','\x76'},
+ {'\x85','\xde'},{'\x88','\xf7'},{'\xcf','\xb0'},{'\x00','\x00'},{'\xa0','\x77'},
+ {'\x8b','\xa3'},{'\x8c','\x7a'},{'\x8d','\xd1'},{'\x9b','\xc3'},{'\xd2','\x77'},
+ {'\xd2','\x78'},{'\xd2','\x79'},{'\xaf','\x50'},{'\x00','\x00'},{'\xaf','\x4c'},
+ {'\xd2','\x6e'},{'\x9b','\xc4'},{'\xd2','\x76'},{'\xd2','\x7b'},{'\xaf','\x51'},
+ {'\x9b','\xc5'},{'\xd2','\x6c'},{'\xd2','\x72'},{'\xd2','\x6b'},{'\xd2','\x75'},
+ {'\xfc','\x57'},{'\x9b','\xc6'},{'\xd2','\x71'},{'\xaf','\x4d'},{'\xaf','\x4f'},
+ {'\xd2','\x7a'},{'\x89','\xf3'},{'\xd2','\x6a'},{'\xd2','\x6d'},{'\xd2','\x73'},
+ {'\x95','\xaf'},{'\xd2','\x74'},{'\xd2','\x7c'},{'\xd2','\x70'},{'\x00','\x00'},
+ {'\xaf','\x4e'},{'\x00','\x00'},{'\x85','\xdd'},{'\x88','\xf8'},{'\x8e','\xea'},
+ {'\x89','\xf4'},{'\x00','\x00'},{'\x88','\xfa'},{'\x8a','\xd8'},{'\x87','\xf1'},
+ {'\x00','\x00'},{'\xb2','\x6d'},{'\xd6','\x4e'},{'\x95','\x49'},{'\x00','\x00'},
+ {'\xd6','\x50'},{'\xd6','\x4c'},{'\x9c','\x40'},{'\xd6','\x58'},{'\xd6','\x4a'},
+ {'\xd6','\x57'},{'\xb2','\x69'},{'\xd6','\x48'},{'\xda','\x5b'},{'\xd6','\x52'},
+ {'\xb2','\x6c'},{'\x9c','\x4b'},{'\xd6','\x53'},{'\xd6','\x56'},{'\x00','\x00'},
+ {'\xd6','\x5a'},{'\x00','\x00'},{'\xd6','\x4f'},{'\x9c','\x4c'},{'\xd6','\x54'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xb2','\x6a'},{'\xb2','\x6b'},{'\xd6','\x59'},
+ {'\xd6','\x4d'},{'\xd6','\x49'},{'\xd6','\x5b'},{'\xa0','\x78'},{'\xd6','\x51'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xd6','\x55'},{'\x82','\x44'},{'\x85','\xe0'},
+ {'\x88','\xfb'},{'\xd6','\x4b'},{'\x8a','\xd9'},{'\xb5','\x48'},{'\xb5','\x49'},
+ {'\xda','\x65'},{'\xb5','\x4f'},{'\x9c','\x4d'},{'\xda','\x59'},{'\xda','\x62'},
+ {'\xda','\x58'},{'\xb5','\x4c'},{'\xda','\x60'},{'\xda','\x5e'},{'\x00','\x00'},
+ {'\xda','\x5f'},{'\xb5','\x4a'},{'\x00','\x00'},{'\xda','\x63'},{'\x9c','\x4e'},
+ {'\x00','\x00'},{'\x9c','\x4f'},{'\x9c','\x50'},{'\x00','\x00'},{'\xda','\x5c'},
+ {'\xda','\x5a'},{'\xb5','\x4b'},{'\xda','\x5d'},{'\xda','\x61'},{'\x9c','\x51'},
+ {'\xfc','\xa7'},{'\x9c','\x52'},{'\xb5','\x4d'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xda','\x64'},{'\x9c','\x53'},{'\x92','\xe5'},{'\x00','\x00'},
+ {'\x9c','\x54'},{'\xfe','\x76'},{'\x9c','\x55'},{'\xde','\x70'},{'\xde','\x77'},
+ {'\xde','\x79'},{'\xde','\xa1'},{'\xfb','\x66'},{'\xb7','\xda'},{'\xde','\x6b'},
+ {'\x00','\x00'},{'\xb7','\xd2'},{'\x95','\x4f'},{'\xde','\x7a'},{'\xb7','\xd7'},
+ {'\xde','\xa2'},{'\xb7','\xce'},{'\x9c','\x56'},{'\xde','\x7d'},{'\x95','\x5f'},
+ {'\xde','\x6d'},{'\xde','\x7e'},{'\xde','\x6c'},{'\xa0','\x7a'},{'\xb7','\xdc'},
+ {'\x9d','\xcd'},{'\xde','\x78'},{'\xb7','\xcf'},{'\xde','\xa3'},{'\x00','\x00'},
+ {'\xb7','\xd4'},{'\xde','\x71'},{'\xb7','\xd9'},{'\xde','\x7c'},{'\xde','\x6f'},
+ {'\xde','\x76'},{'\xde','\x72'},{'\xde','\x6e'},{'\xb7','\xd1'},{'\xb7','\xd8'},
+ {'\xb7','\xd6'},{'\xb7','\xd3'},{'\xb7','\xdb'},{'\xb7','\xd0'},{'\xde','\x75'},
+ {'\x9c','\x57'},{'\xb7','\xd5'},{'\x00','\x00'},{'\xb5','\x4e'},{'\x00','\x00'},
+ {'\xde','\x7b'},{'\xfe','\x53'},{'\xde','\x73'},{'\xa0','\x7b'},{'\x00','\x00'},
+ {'\x9c','\x58'},{'\xfc','\xa9'},{'\x9c','\x59'},{'\xde','\x74'},{'\x00','\x00'},
+ {'\xa0','\x7c'},{'\xe2','\xc1'},{'\x9c','\x5a'},{'\xba','\xb4'},{'\x9c','\x5b'},
+ {'\x00','\x00'},{'\xe2','\xbd'},{'\xe2','\xc3'},{'\xe2','\xbf'},{'\x00','\x00'},
+ {'\xba','\xb6'},{'\xe2','\xbe'},{'\xe2','\xc2'},{'\xe2','\xba'},{'\xa0','\xd8'},
+ {'\xe2','\xbc'},{'\xba','\xb5'},{'\x00','\x00'},{'\x9c','\x5c'},{'\x00','\x00'},
+ {'\x9c','\x5d'},{'\xe2','\xc0'},{'\xe2','\xbb'},{'\x9c','\x5e'},{'\xba','\xb7'},
+ {'\x00','\x00'},{'\xba','\xb2'},{'\x94','\xab'},{'\x9c','\x5f'},{'\xe2','\xc4'},
+ {'\xa0','\xe7'},{'\xba','\xb3'},{'\xe6','\x67'},{'\xe6','\x64'},{'\xe6','\x70'},
+ {'\xe6','\x6a'},{'\xe6','\x6c'},{'\xbc','\xf4'},{'\xe6','\x66'},{'\xe6','\x6e'},
+ {'\x9c','\x60'},{'\x9c','\x61'},{'\xe6','\x6d'},{'\xe6','\x6b'},{'\x00','\x00'},
+ {'\xe6','\x71'},{'\xbc','\xf7'},{'\xe6','\x68'},{'\xe6','\x6f'},{'\x00','\x00'},
+ {'\xbc','\xf5'},{'\x9c','\x62'},{'\x00','\x00'},{'\xe6','\x63'},{'\xe6','\x65'},
+ {'\xbc','\xf6'},{'\xe6','\x62'},{'\xe6','\x72'},{'\x9c','\x63'},{'\xe6','\x69'},
+ {'\x00','\x00'},{'\x9c','\x64'},{'\xea','\x4a'},{'\xbf','\x51'},{'\x9c','\x65'},
+ {'\x00','\x00'},{'\xea','\x55'},{'\xea','\x53'},{'\xbf','\x4b'},{'\xea','\x49'},
+ {'\xea','\x4c'},{'\xea','\x4d'},{'\xea','\x48'},{'\xbf','\x55'},{'\xbf','\x56'},
+ {'\xea','\x47'},{'\xea','\x56'},{'\xea','\x51'},{'\xbf','\x4f'},{'\xbf','\x4c'},
+ {'\xea','\x50'},{'\xea','\x4e'},{'\x00','\x00'},{'\x00','\x00'},{'\xbf','\x52'},
+ {'\xea','\x52'},{'\xbf','\x4d'},{'\x9c','\x66'},{'\xbf','\x4e'},{'\x00','\x00'},
+ {'\xea','\x4f'},{'\xbf','\x50'},{'\xea','\x4b'},{'\xa0','\xe8'},{'\xea','\x54'},
+ {'\xbf','\x53'},{'\xea','\x57'},{'\xea','\x58'},{'\xbf','\x54'},{'\x9c','\x67'},
+ {'\x00','\x00'},{'\xc0','\xe7'},{'\xc0','\xee'},{'\xed','\x5c'},{'\xed','\x62'},
+ {'\x00','\x00'},{'\xed','\x60'},{'\xc0','\xea'},{'\xc0','\xe9'},{'\xc0','\xe6'},
+ {'\xed','\x5e'},{'\x00','\x00'},{'\x00','\x00'},{'\x9c','\x68'},{'\xc0','\xec'},
+ {'\xc0','\xeb'},{'\xc0','\xe8'},{'\x00','\x00'},{'\xed','\x61'},{'\xed','\x5d'},
+ {'\xed','\x5f'},{'\x00','\x00'},{'\xc0','\xed'},{'\xa0','\xf5'},{'\xfb','\x70'},
+ {'\x00','\x00'},{'\xc2','\x77'},{'\xef','\xfb'},{'\x00','\x00'},{'\xc2','\x74'},
+ {'\xc2','\x75'},{'\xef','\xfd'},{'\xc2','\x76'},{'\xef','\xfa'},{'\x9c','\x69'},
+ {'\xef','\xf9'},{'\xf2','\x6c'},{'\xef','\xfc'},{'\x00','\x00'},{'\xf2','\x6d'},
+ {'\xc3','\x7a'},{'\xf2','\x6b'},{'\x00','\x00'},{'\x9c','\x6a'},{'\xf2','\x6a'},
+ {'\x00','\x00'},{'\xf2','\x69'},{'\xc3','\x7b'},{'\x9c','\x6b'},{'\x9c','\x6c'},
+ {'\xc4','\x6c'},{'\x00','\x00'},{'\x00','\x00'},{'\xf4','\x6a'},{'\xf4','\x6b'},
+ {'\xfc','\xac'},{'\x9c','\x6d'},{'\x9c','\x6e'},{'\x00','\x00'},{'\xf5','\xdc'},
+ {'\xf5','\xdb'},{'\xc4','\xea'},{'\x00','\x00'},{'\xf5','\xda'},{'\xf6','\xec'},
+ {'\xf6','\xed'},{'\x00','\x00'},{'\x00','\x00'},{'\xf7','\xe6'},{'\xf8','\xb1'},
+ {'\x9c','\x6f'},{'\x9d','\x5a'},{'\xf8','\xf6'},{'\xf9','\xbc'},{'\xc6','\x79'},
+ {'\xf9','\xc6'},{'\xa4','\xf6'},{'\x91','\xc9'},{'\xaa','\xa6'},{'\xaa','\xa7'},
+ {'\x9c','\x71'},{'\x00','\x00'},{'\xac','\xb8'},{'\x85','\xc6'},{'\xfa','\x64'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc0','\xef'},{'\xa4','\xf7'},{'\x85','\xe1'},
+ {'\xaa','\xa8'},{'\xaf','\x52'},{'\xb7','\xdd'},{'\xa4','\xf8'},{'\xfa','\x65'},
+ {'\xb2','\x6e'},{'\xba','\xb8'},{'\xc9','\x62'},{'\x95','\xa7'},{'\xcf','\xb7'},
+ {'\xd2','\x7d'},{'\x00','\x00'},{'\xe2','\xc5'},{'\x00','\x00'},{'\xc0','\xf0'},
+ {'\xa4','\xf9'},{'\xaa','\xa9'},{'\xcf','\xb8'},{'\xcf','\xb9'},{'\xda','\x66'},
+ {'\xb5','\x50'},{'\x8b','\xa4'},{'\x00','\x00'},{'\xde','\xa4'},{'\xfc','\xad'},
+ {'\x00','\x00'},{'\xb7','\xde'},{'\xe2','\xc6'},{'\x00','\x00'},{'\x95','\x6e'},
+ {'\xbc','\xf8'},{'\x9c','\x73'},{'\xc3','\x7c'},{'\xa4','\xfa'},{'\xda','\x67'},
+ {'\xa4','\xfb'},{'\x9c','\x74'},{'\xa6','\xc9'},{'\xca','\x42'},{'\xa6','\xc8'},
+ {'\xa8','\x65'},{'\xa8','\x64'},{'\xa8','\x63'},{'\xcb','\x60'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xfa','\x66'},{'\xaa','\xaa'},{'\x00','\x00'},{'\xaa','\xab'},
+ {'\xcd','\x5b'},{'\x00','\x00'},{'\xcf','\xba'},{'\x00','\x00'},{'\xcf','\xbd'},
+ {'\xac','\xba'},{'\xcf','\xbb'},{'\x00','\x00'},{'\xac','\xb9'},{'\xcf','\xbc'},
+ {'\xac','\xbb'},{'\x84','\x61'},{'\xd2','\xa2'},{'\xd2','\xa1'},{'\xd2','\x7e'},
+ {'\xaf','\x53'},{'\x8c','\x7b'},{'\xd6','\x5d'},{'\xd6','\x5e'},{'\xb2','\x6f'},
+ {'\xd6','\x5c'},{'\xd6','\x5f'},{'\xb5','\x52'},{'\xb2','\x70'},{'\xfa','\x67'},
+ {'\x00','\x00'},{'\xb5','\x51'},{'\xda','\x6b'},{'\xda','\x6a'},{'\xfc','\xae'},
+ {'\xda','\x68'},{'\xda','\x69'},{'\x8b','\xa5'},{'\xda','\x6c'},{'\xde','\xa6'},
+ {'\xde','\xa5'},{'\xde','\xa9'},{'\xfa','\x68'},{'\xde','\xa8'},{'\xde','\xa7'},
+ {'\xba','\xb9'},{'\xe2','\xc9'},{'\x9c','\x75'},{'\xe2','\xc8'},{'\xba','\xba'},
+ {'\xe2','\xc7'},{'\xe6','\x73'},{'\x00','\x00'},{'\xe6','\x74'},{'\xbc','\xf9'},
+ {'\x00','\x00'},{'\xea','\x59'},{'\xea','\x5a'},{'\xfa','\x69'},{'\x92','\x71'},
+ {'\xf2','\x72'},{'\xc3','\x7d'},{'\xf2','\x71'},{'\xf2','\x70'},{'\xf2','\x6e'},
+ {'\xf2','\x6f'},{'\xc4','\xeb'},{'\xf4','\x6c'},{'\xf6','\xee'},{'\xf8','\xf7'},
+ {'\x00','\x00'},{'\xa4','\xfc'},{'\xfa','\x6a'},{'\xc9','\xa5'},{'\xa5','\xc7'},
+ {'\xc9','\xa6'},{'\xfa','\x6b'},{'\xfc','\xb0'},{'\x00','\x00'},{'\xca','\x43'},
+ {'\xca','\x44'},{'\x83','\x5d'},{'\x8a','\xda'},{'\xfa','\x6c'},{'\x84','\xf6'},
+ {'\xcb','\x66'},{'\x00','\x00'},{'\x00','\x00'},{'\xcb','\x62'},{'\xfa','\x6d'},
+ {'\xcb','\x61'},{'\xaa','\xac'},{'\xcb','\x65'},{'\xa8','\x67'},{'\xcb','\x63'},
+ {'\xa8','\x66'},{'\xcb','\x67'},{'\xcb','\x64'},{'\x00','\x00'},{'\x83','\xc1'},
+ {'\xcd','\x5f'},{'\xcf','\xbe'},{'\xcd','\x5d'},{'\xcd','\x64'},{'\xfa','\x6e'},
+ {'\xaa','\xad'},{'\x00','\x00'},{'\xaa','\xb0'},{'\xcd','\x65'},{'\xcd','\x61'},
+ {'\x00','\x00'},{'\xcd','\x62'},{'\x00','\x00'},{'\xcd','\x5c'},{'\xaa','\xaf'},
+ {'\xcd','\x5e'},{'\xaa','\xae'},{'\xcd','\x63'},{'\xfa','\x6f'},{'\xcd','\x60'},
+ {'\x00','\x00'},{'\x89','\xf6'},{'\xcf','\xc2'},{'\xac','\xbd'},{'\xac','\xbe'},
+ {'\xfc','\xb1'},{'\xcf','\xc5'},{'\xcf','\xbf'},{'\x00','\x00'},{'\xcf','\xc4'},
+ {'\x00','\x00'},{'\xcf','\xc0'},{'\xac','\xbc'},{'\xcf','\xc3'},{'\xcf','\xc1'},
+ {'\x88','\xfc'},{'\x83','\xc0'},{'\x85','\xe2'},{'\x8e','\xec'},{'\x84','\x62'},
+ {'\x86','\xe2'},{'\x8e','\x47'},{'\xd2','\xa8'},{'\xd2','\xa5'},{'\x00','\x00'},
+ {'\xd2','\xa7'},{'\xaf','\x58'},{'\xaf','\x57'},{'\xaf','\x55'},{'\xd2','\xa4'},
+ {'\xd2','\xa9'},{'\xaf','\x54'},{'\xaf','\x56'},{'\xd2','\xa6'},{'\xd6','\x67'},
+ {'\xd2','\xa3'},{'\xd2','\xaa'},{'\xfc','\xb2'},{'\x8e','\xeb'},{'\x9c','\x76'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xd6','\x62'},{'\xd6','\x66'},{'\x00','\x00'},
+ {'\xd6','\x65'},{'\xda','\x6e'},{'\xda','\x79'},{'\x00','\x00'},{'\x8a','\xdb'},
+ {'\xd6','\x68'},{'\x9c','\x77'},{'\xd6','\x63'},{'\xda','\x6d'},{'\xb2','\x74'},
+ {'\x00','\x00'},{'\x8f','\x55'},{'\xb2','\x73'},{'\xd6','\x61'},{'\xd6','\x64'},
+ {'\xb2','\x75'},{'\x00','\x00'},{'\xb2','\x72'},{'\xb2','\x71'},{'\xd6','\x60'},
+ {'\xd6','\x69'},{'\x93','\xe6'},{'\x00','\x00'},{'\x8c','\xd3'},{'\xda','\x70'},
+ {'\xda','\x77'},{'\xfa','\x70'},{'\xb5','\x54'},{'\xda','\x76'},{'\xda','\x73'},
+ {'\xfc','\xb4'},{'\xb5','\x56'},{'\x95','\xbd'},{'\x95','\xbc'},{'\xfc','\xaf'},
+ {'\xda','\x75'},{'\x95','\x52'},{'\xfa','\x71'},{'\xda','\x6f'},{'\xda','\x71'},
+ {'\xda','\x74'},{'\xda','\x72'},{'\xb5','\x55'},{'\xda','\x78'},{'\xb5','\x53'},
+ {'\xb7','\xdf'},{'\xfa','\x72'},{'\xfa','\x73'},{'\xde','\xad'},{'\xde','\xac'},
+ {'\xde','\xaa'},{'\x00','\x00'},{'\xb7','\xe2'},{'\xb7','\xe1'},{'\xde','\xae'},
+ {'\x9c','\x78'},{'\xde','\xab'},{'\xe2','\xca'},{'\xba','\xbb'},{'\xb7','\xe0'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xfc','\xb3'},{'\xde','\xb0'},{'\xde','\xaf'},
+ {'\x00','\x00'},{'\xe2','\xcd'},{'\xe2','\xcb'},{'\xbc','\xfa'},{'\xfc','\xb5'},
+ {'\xba','\xbc'},{'\xe2','\xcc'},{'\xe6','\x76'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xbc','\xfb'},{'\xe6','\x75'},{'\xe6','\x7e'},
+ {'\xe6','\x7d'},{'\xe6','\x7b'},{'\x00','\x00'},{'\xe6','\x7a'},{'\xe6','\x77'},
+ {'\xe6','\x78'},{'\xe6','\x79'},{'\xe6','\x7c'},{'\xe6','\xa1'},{'\x92','\xde'},
+ {'\x00','\x00'},{'\xea','\x5f'},{'\xea','\x5c'},{'\xea','\x5d'},{'\xbf','\x57'},
+ {'\xea','\x5b'},{'\xea','\x61'},{'\xea','\x60'},{'\xea','\x5e'},{'\x8b','\xa7'},
+ {'\xed','\x64'},{'\xed','\x65'},{'\xc0','\xf1'},{'\xfc','\xb6'},{'\xc0','\xf2'},
+ {'\xed','\x63'},{'\x9c','\x79'},{'\xc2','\x79'},{'\xef','\xfe'},{'\xc2','\x78'},
+ {'\xc3','\x7e'},{'\x00','\x00'},{'\xc3','\xa1'},{'\xc4','\x6d'},{'\xf4','\x6e'},
+ {'\xf4','\x6d'},{'\xf5','\xdd'},{'\xf6','\xef'},{'\xc5','\x7a'},{'\xf7','\xe8'},
+ {'\xf7','\xe7'},{'\xf7','\xe9'},{'\xa5','\xc8'},{'\xcf','\xc6'},{'\xaf','\x59'},
+ {'\xb2','\x76'},{'\xd6','\x6a'},{'\xa5','\xc9'},{'\xc9','\xa7'},{'\xa4','\xfd'},
+ {'\x9c','\x7a'},{'\x00','\x00'},{'\xca','\x45'},{'\x9c','\x7b'},{'\x00','\x00'},
+ {'\x88','\xfd'},{'\xcb','\x6c'},{'\xcb','\x6a'},{'\xcb','\x6b'},{'\xcb','\x68'},
+ {'\xa8','\x68'},{'\xcb','\x69'},{'\x9c','\x7c'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x86','\xe4'},{'\x9c','\x7d'},{'\xcd','\x6d'},{'\x9c','\x7e'},{'\xaa','\xb3'},
+ {'\xcd','\x6b'},{'\xcd','\x67'},{'\xcd','\x6a'},{'\x00','\x00'},{'\xcd','\x66'},
+ {'\xaa','\xb5'},{'\xcd','\x69'},{'\x9c','\xa1'},{'\xaa','\xb2'},{'\xaa','\xb1'},
+ {'\x9c','\xa2'},{'\xaa','\xb4'},{'\xcd','\x6c'},{'\xcd','\x68'},{'\x8e','\x48'},
+ {'\x89','\xf8'},{'\x84','\x63'},{'\x00','\x00'},{'\xac','\xc2'},{'\xac','\xc5'},
+ {'\xcf','\xce'},{'\xcf','\xcd'},{'\xcf','\xcc'},{'\xac','\xbf'},{'\xcf','\xd5'},
+ {'\xcf','\xcb'},{'\x8b','\xa8'},{'\xac','\xc1'},{'\xd2','\xaf'},{'\xfa','\x74'},
+ {'\xcf','\xd2'},{'\xcf','\xd0'},{'\xac','\xc4'},{'\x00','\x00'},{'\xcf','\xc8'},
+ {'\xcf','\xd3'},{'\x00','\x00'},{'\xcf','\xca'},{'\xcf','\xd4'},{'\xcf','\xd1'},
+ {'\xcf','\xc9'},{'\x95','\xbe'},{'\xac','\xc0'},{'\xcf','\xd6'},{'\xcf','\xc7'},
+ {'\xac','\xc3'},{'\xfa','\x75'},{'\x95','\xb6'},{'\x90','\xb2'},{'\x8b','\xfd'},
+ {'\xd2','\xb4'},{'\xd2','\xab'},{'\xd2','\xb6'},{'\x9c','\xa3'},{'\xd2','\xae'},
+ {'\xd2','\xb9'},{'\xd2','\xba'},{'\xd2','\xac'},{'\xd2','\xb8'},{'\xd2','\xb5'},
+ {'\xd2','\xb3'},{'\xd2','\xb7'},{'\xaf','\x5f'},{'\x00','\x00'},{'\xaf','\x5d'},
+ {'\x9c','\xa4'},{'\x9c','\xa5'},{'\xd2','\xb1'},{'\x9c','\xa6'},{'\xd2','\xad'},
+ {'\x9c','\xa7'},{'\xd2','\xb0'},{'\xd2','\xbb'},{'\xd2','\xb2'},{'\xaf','\x5e'},
+ {'\xcf','\xcf'},{'\x00','\x00'},{'\xaf','\x5a'},{'\xaf','\x5c'},{'\x9c','\xa8'},
+ {'\x00','\x00'},{'\xfa','\x76'},{'\x85','\xe4'},{'\x9c','\xa9'},{'\xd6','\x78'},
+ {'\xd6','\x6d'},{'\xd6','\x6b'},{'\xfe','\xaa'},{'\xd6','\x6c'},{'\x9c','\xab'},
+ {'\xd6','\x73'},{'\x9c','\xac'},{'\xd6','\x74'},{'\xd6','\x70'},{'\xb2','\x7b'},
+ {'\xd6','\x75'},{'\xd6','\x72'},{'\xd6','\x6f'},{'\x9c','\xad'},{'\xb2','\x79'},
+ {'\xd6','\x6e'},{'\xb2','\x77'},{'\xb2','\x7a'},{'\xd6','\x71'},{'\xd6','\x79'},
+ {'\xaf','\x5b'},{'\xb2','\x78'},{'\xd6','\x77'},{'\xd6','\x76'},{'\xb2','\x7c'},
+ {'\x00','\x00'},{'\x8e','\xbf'},{'\x86','\xe3'},{'\x9c','\xae'},{'\x9c','\xaf'},
+ {'\x00','\x00'},{'\x9c','\xb0'},{'\x9c','\xb1'},{'\xda','\x7e'},{'\x9c','\xb2'},
+ {'\x00','\x00'},{'\x9c','\xb3'},{'\xda','\xa1'},{'\xb5','\x60'},{'\x9c','\xb4'},
+ {'\xda','\xa7'},{'\x9c','\xb5'},{'\x9c','\xb6'},{'\xda','\xa9'},{'\xda','\xa2'},
+ {'\xb5','\x5a'},{'\xda','\xa6'},{'\xda','\xa5'},{'\xb5','\x5b'},{'\xb5','\x61'},
+ {'\x00','\x00'},{'\xb5','\x62'},{'\xda','\xa8'},{'\xb5','\x58'},{'\xda','\x7d'},
+ {'\xda','\x7b'},{'\xda','\xa3'},{'\xda','\x7a'},{'\xb5','\x5f'},{'\xda','\x7c'},
+ {'\xda','\xa4'},{'\xda','\xaa'},{'\xb5','\x59'},{'\xb5','\x5e'},{'\xb5','\x5c'},
+ {'\xb5','\x5d'},{'\x9c','\xb7'},{'\x9c','\xb8'},{'\x9c','\xb9'},{'\xb5','\x57'},
+ {'\x00','\x00'},{'\x8b','\xa9'},{'\x00','\x00'},{'\x00','\x00'},{'\xb7','\xe9'},
+ {'\xde','\xb7'},{'\xb7','\xe8'},{'\xde','\xbb'},{'\x9c','\xba'},{'\xde','\xb1'},
+ {'\x9c','\xbb'},{'\xde','\xbc'},{'\x9c','\xbc'},{'\x9c','\xbd'},{'\x9c','\xbe'},
+ {'\xde','\xb2'},{'\xde','\xb3'},{'\x00','\x00'},{'\xde','\xbd'},{'\xde','\xba'},
+ {'\xde','\xb8'},{'\xde','\xb9'},{'\xde','\xb5'},{'\xde','\xb4'},{'\x9c','\xbf'},
+ {'\xde','\xbe'},{'\xb7','\xe5'},{'\x9c','\xc0'},{'\xde','\xb6'},{'\x00','\x00'},
+ {'\xb7','\xea'},{'\xb7','\xe4'},{'\xb7','\xeb'},{'\xb7','\xec'},{'\xfc','\xb9'},
+ {'\xb7','\xe7'},{'\xb7','\xe6'},{'\xfe','\x75'},{'\x9d','\x73'},{'\xe2','\xce'},
+ {'\xba','\xbe'},{'\xba','\xbd'},{'\x9c','\xc1'},{'\x00','\x00'},{'\xe2','\xd3'},
+ {'\xfe','\xac'},{'\xbc','\xfc'},{'\xba','\xbf'},{'\x9c','\xc2'},{'\x9c','\xc3'},
+ {'\xba','\xc1'},{'\xe2','\xd4'},{'\xb7','\xe3'},{'\xba','\xc0'},{'\xe2','\xd0'},
+ {'\xe2','\xd2'},{'\xe2','\xcf'},{'\x9c','\xc4'},{'\xe2','\xd1'},{'\xfa','\x77'},
+ {'\x89','\xf9'},{'\x00','\x00'},{'\xe6','\xab'},{'\x9c','\xc5'},{'\x00','\x00'},
+ {'\xe6','\xaa'},{'\xe6','\xa7'},{'\xbd','\x40'},{'\xea','\x62'},{'\xbd','\x41'},
+ {'\xe6','\xa6'},{'\x9c','\xc6'},{'\xbc','\xfe'},{'\x00','\x00'},{'\xe6','\xa8'},
+ {'\xe6','\xa5'},{'\xe6','\xa2'},{'\xe6','\xa9'},{'\xe6','\xa3'},{'\xe6','\xa4'},
+ {'\xbc','\xfd'},{'\x81','\xd0'},{'\x81','\xd1'},{'\x8c','\x7d'},{'\x00','\x00'},
+ {'\xed','\x69'},{'\x00','\x00'},{'\xea','\x66'},{'\x00','\x00'},{'\xea','\x65'},
+ {'\xea','\x67'},{'\x00','\x00'},{'\xed','\x66'},{'\xbf','\x5a'},{'\x81','\xd2'},
+ {'\xea','\x63'},{'\x81','\xd3'},{'\xbf','\x58'},{'\x9d','\x74'},{'\xbf','\x5c'},
+ {'\xbf','\x5b'},{'\xea','\x64'},{'\xea','\x68'},{'\xfa','\x78'},{'\xbf','\x59'},
+ {'\x81','\xd4'},{'\xed','\x6d'},{'\xc0','\xf5'},{'\xc2','\x7a'},{'\xc0','\xf6'},
+ {'\xc0','\xf3'},{'\xed','\x6a'},{'\xed','\x68'},{'\x00','\x00'},{'\xed','\x6b'},
+ {'\x00','\x00'},{'\xed','\x6e'},{'\xc0','\xf4'},{'\xed','\x6c'},{'\xed','\x67'},
+ {'\x00','\x00'},{'\x81','\xd5'},{'\xf0','\x42'},{'\xf0','\x45'},{'\xf2','\x75'},
+ {'\xf0','\x40'},{'\x81','\xd6'},{'\xf4','\x6f'},{'\xf0','\x46'},{'\x00','\x00'},
+ {'\xc3','\xa2'},{'\xf0','\x44'},{'\xc2','\x7b'},{'\xf0','\x41'},{'\xf0','\x43'},
+ {'\xf0','\x47'},{'\xf2','\x76'},{'\x00','\x00'},{'\xf2','\x74'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x81','\xd7'},{'\x00','\x00'},{'\xc3','\xa3'},{'\xf2','\x73'},
+ {'\x81','\xd8'},{'\x00','\x00'},{'\x00','\x00'},{'\xc4','\x6e'},{'\x81','\xd9'},
+ {'\x00','\x00'},{'\x8c','\xf9'},{'\x81','\xda'},{'\xc4','\xed'},{'\xf6','\xf1'},
+ {'\xc4','\xec'},{'\xf6','\xf3'},{'\xf6','\xf0'},{'\xf6','\xf2'},{'\xc5','\xd0'},
+ {'\xf8','\xb2'},{'\xa5','\xca'},{'\xcd','\x6e'},{'\xd2','\xbc'},{'\xd2','\xbd'},
+ {'\xb2','\x7d'},{'\xde','\xbf'},{'\xbf','\x5d'},{'\xc3','\xa4'},{'\xc5','\x7b'},
+ {'\xf8','\xb3'},{'\xa5','\xcb'},{'\x94','\xac'},{'\xcd','\x6f'},{'\xa2','\x60'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xcf','\xd7'},{'\x00','\x00'},{'\xcf','\xd8'},
+ {'\x88','\xfe'},{'\x94','\xae'},{'\x94','\xaf'},{'\x94','\xad'},{'\x00','\x00'},
+ {'\xd2','\xbe'},{'\xd2','\xbf'},{'\xb2','\x7e'},{'\xb2','\xa1'},{'\x94','\xb0'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xda','\xab'},{'\x00','\x00'},{'\xde','\xc2'},
+ {'\xde','\xc1'},{'\xde','\xc0'},{'\xe2','\xd5'},{'\xfa','\x79'},{'\xe2','\xd6'},
+ {'\xe2','\xd7'},{'\xba','\xc2'},{'\x94','\xb1'},{'\x00','\x00'},{'\xe6','\xad'},
+ {'\xe6','\xac'},{'\x00','\x00'},{'\x00','\x00'},{'\xea','\x69'},{'\xbf','\x5e'},
+ {'\xbf','\x5f'},{'\x95','\xc2'},{'\xed','\x72'},{'\xed','\x6f'},{'\xed','\x70'},
+ {'\xed','\x71'},{'\xf0','\x49'},{'\xf0','\x48'},{'\xc2','\x7c'},{'\xf2','\x77'},
+ {'\xf5','\xde'},{'\xa5','\xcc'},{'\xfa','\x7a'},{'\xac','\xc6'},{'\x00','\x00'},
+ {'\xb2','\xa2'},{'\xde','\xc3'},{'\xfc','\xbb'},{'\xa5','\xcd'},{'\x00','\x00'},
+ {'\xd2','\xc0'},{'\xb2','\xa3'},{'\xfa','\x7b'},{'\x00','\x00'},{'\xb5','\x63'},
+ {'\xb5','\x64'},{'\x00','\x00'},{'\xa5','\xce'},{'\xa5','\xcf'},{'\xca','\x46'},
+ {'\xa8','\x6a'},{'\xa8','\x69'},{'\xac','\xc7'},{'\xcf','\xd9'},{'\xda','\xac'},
+ {'\xa5','\xd0'},{'\xa5','\xd1'},{'\xa5','\xd2'},{'\xa5','\xd3'},{'\xa0','\x59'},
+ {'\x86','\x7a'},{'\x00','\x00'},{'\xa8','\x6b'},{'\xa8','\x6c'},{'\xcb','\x6e'},
+ {'\xcb','\x6d'},{'\x84','\xf8'},{'\xfa','\x7c'},{'\xaa','\xb6'},{'\xcd','\x72'},
+ {'\xcd','\x70'},{'\xcd','\x71'},{'\x00','\x00'},{'\x81','\xdb'},{'\x00','\x00'},
+ {'\xfa','\x7d'},{'\x86','\xd0'},{'\xfb','\xd1'},{'\xcf','\xda'},{'\xcf','\xdb'},
+ {'\xfa','\x7e'},{'\x95','\xbf'},{'\xac','\xcb'},{'\xac','\xc9'},{'\xfa','\xa1'},
+ {'\xac','\xca'},{'\xac','\xc8'},{'\x00','\x00'},{'\x94','\x55'},{'\x00','\x00'},
+ {'\xfc','\xbc'},{'\xaf','\x60'},{'\x81','\xdc'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xaf','\x64'},{'\xaf','\x63'},{'\xd2','\xc1'},{'\xaf','\x62'},
+ {'\xaf','\x61'},{'\x00','\x00'},{'\xd2','\xc2'},{'\x94','\x56'},{'\x00','\x00'},
+ {'\xb2','\xa6'},{'\xd6','\x7b'},{'\xd6','\x7a'},{'\xb2','\xa4'},{'\xb2','\xa5'},
+ {'\x95','\xcc'},{'\x00','\x00'},{'\x94','\xb2'},{'\xb5','\x66'},{'\xb5','\x65'},
+ {'\xda','\xae'},{'\xfa','\xa2'},{'\x81','\xdd'},{'\xda','\xad'},{'\xb2','\xa7'},
+ {'\x00','\x00'},{'\x8d','\xe2'},{'\x92','\xec'},{'\x8b','\xaa'},{'\x00','\x00'},
+ {'\xb7','\xed'},{'\xde','\xc5'},{'\xb7','\xee'},{'\xde','\xc4'},{'\xfc','\xbd'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xe2','\xd8'},{'\xe6','\xae'},{'\xbd','\x42'},
+ {'\xea','\x6a'},{'\x00','\x00'},{'\xfa','\xa3'},{'\xfa','\xa4'},{'\xed','\x73'},
+ {'\x00','\x00'},{'\xc3','\xa6'},{'\xc3','\xa5'},{'\x00','\x00'},{'\xfa','\xa5'},
+ {'\xc5','\x7c'},{'\xa5','\xd4'},{'\xcd','\x73'},{'\x81','\xde'},{'\x93','\x51'},
+ {'\xb2','\xa8'},{'\xe2','\xd9'},{'\xba','\xc3'},{'\xc6','\xd4'},{'\x00','\x00'},
+ {'\xcb','\x6f'},{'\xcb','\x70'},{'\x8f','\x78'},{'\x89','\xfb'},{'\xcd','\x74'},
+ {'\xaa','\xb8'},{'\xaa','\xb9'},{'\x00','\x00'},{'\x00','\x00'},{'\xaa','\xb7'},
+ {'\x81','\xdf'},{'\x86','\xe5'},{'\x8a','\xdd'},{'\x86','\xe6'},{'\xac','\xcf'},
+ {'\xac','\xd0'},{'\xac','\xcd'},{'\xac','\xce'},{'\x00','\x00'},{'\xcf','\xdc'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xcf','\xdd'},{'\xac','\xcc'},{'\xfa','\xa6'},
+ {'\x00','\x00'},{'\x87','\xf4'},{'\x86','\xe7'},{'\xd2','\xc3'},{'\xfe','\x51'},
+ {'\xaf','\x68'},{'\xaf','\x69'},{'\xfb','\x5c'},{'\xb2','\xab'},{'\xd2','\xc9'},
+ {'\x00','\x00'},{'\xaf','\x6e'},{'\xaf','\x6c'},{'\xd2','\xca'},{'\xd2','\xc5'},
+ {'\xaf','\x6b'},{'\xaf','\x6a'},{'\xaf','\x65'},{'\xd2','\xc8'},{'\xd2','\xc7'},
+ {'\xd2','\xc4'},{'\xaf','\x6d'},{'\xfc','\xd3'},{'\xd2','\xc6'},{'\xaf','\x66'},
+ {'\x00','\x00'},{'\xaf','\x67'},{'\x8f','\xfd'},{'\x84','\xf9'},{'\xb2','\xac'},
+ {'\xd6','\xa1'},{'\xd6','\xa2'},{'\xb2','\xad'},{'\xd6','\x7c'},{'\xd6','\x7e'},
+ {'\xd6','\xa4'},{'\xd6','\xa3'},{'\xd6','\x7d'},{'\x00','\x00'},{'\xb2','\xa9'},
+ {'\xb2','\xaa'},{'\xfa','\xa7'},{'\xda','\xb6'},{'\xb5','\x6b'},{'\xb5','\x6a'},
+ {'\xda','\xb0'},{'\xb5','\x68'},{'\x81','\xe0'},{'\xda','\xb3'},{'\xb5','\x6c'},
+ {'\xda','\xb4'},{'\xb5','\x6d'},{'\xda','\xb1'},{'\xb5','\x67'},{'\xb5','\x69'},
+ {'\xda','\xb5'},{'\x00','\x00'},{'\xda','\xb2'},{'\xda','\xaf'},{'\x89','\xfa'},
+ {'\xfa','\xa8'},{'\x86','\xe8'},{'\x8f','\x58'},{'\x00','\x00'},{'\xde','\xd2'},
+ {'\x00','\x00'},{'\xde','\xc7'},{'\xb7','\xf0'},{'\xb7','\xf3'},{'\xb7','\xf2'},
+ {'\xb7','\xf7'},{'\xb7','\xf6'},{'\xde','\xd3'},{'\xde','\xd1'},{'\xde','\xca'},
+ {'\xde','\xce'},{'\xde','\xcd'},{'\xb7','\xf4'},{'\xde','\xd0'},{'\xde','\xcc'},
+ {'\xde','\xd4'},{'\xde','\xcb'},{'\xb7','\xf5'},{'\xb7','\xef'},{'\xb7','\xf1'},
+ {'\xfc','\xd5'},{'\xde','\xc9'},{'\x00','\x00'},{'\x8f','\x57'},{'\x00','\x00'},
+ {'\xfc','\xd4'},{'\xe2','\xdb'},{'\xba','\xc7'},{'\xe2','\xdf'},{'\xba','\xc6'},
+ {'\xe2','\xdc'},{'\xba','\xc5'},{'\x00','\x00'},{'\xde','\xc8'},{'\xde','\xcf'},
+ {'\xe2','\xde'},{'\x00','\x00'},{'\xba','\xc8'},{'\xe2','\xe0'},{'\xe2','\xdd'},
+ {'\xe2','\xda'},{'\x8e','\xc1'},{'\x89','\x40'},{'\xe6','\xb1'},{'\xe6','\xb5'},
+ {'\xe6','\xb7'},{'\xe6','\xb3'},{'\xe6','\xb2'},{'\xe6','\xb0'},{'\xbd','\x45'},
+ {'\xbd','\x43'},{'\xbd','\x48'},{'\xbd','\x49'},{'\xe6','\xb4'},{'\xbd','\x46'},
+ {'\xe6','\xaf'},{'\xbd','\x47'},{'\xba','\xc4'},{'\xe6','\xb6'},{'\xbd','\x44'},
+ {'\x8b','\xab'},{'\x8d','\x54'},{'\x81','\xe1'},{'\xea','\x6c'},{'\x00','\x00'},
+ {'\xea','\x6b'},{'\xea','\x73'},{'\xea','\x6d'},{'\xea','\x72'},{'\xea','\x6f'},
+ {'\xbf','\x60'},{'\xea','\x71'},{'\x00','\x00'},{'\x00','\x00'},{'\xbf','\x61'},
+ {'\x00','\x00'},{'\xbf','\x62'},{'\x95','\xa9'},{'\xea','\x70'},{'\xea','\x6e'},
+ {'\x8c','\xd5'},{'\x90','\x58'},{'\xfa','\xa9'},{'\x00','\x00'},{'\xc0','\xf8'},
+ {'\xed','\x74'},{'\x00','\x00'},{'\x00','\x00'},{'\xc0','\xf7'},{'\xed','\x77'},
+ {'\xed','\x75'},{'\xed','\x76'},{'\x00','\x00'},{'\x00','\x00'},{'\xc0','\xf9'},
+ {'\xfa','\xaa'},{'\x95','\x6f'},{'\x81','\xe2'},{'\xf0','\x4d'},{'\x81','\xe3'},
+ {'\xc2','\xa1'},{'\xf0','\x4e'},{'\xfa','\xab'},{'\x00','\x00'},{'\xc2','\x7d'},
+ {'\xf0','\x4f'},{'\xc2','\x7e'},{'\xf0','\x4c'},{'\xf0','\x50'},{'\x00','\x00'},
+ {'\xf0','\x4a'},{'\x00','\x00'},{'\x8c','\x7e'},{'\xc3','\xa7'},{'\xf2','\x78'},
+ {'\xc3','\xa8'},{'\xc4','\x6f'},{'\x8c','\xd6'},{'\xf0','\x4b'},{'\xc4','\x70'},
+ {'\xfb','\x76'},{'\xfc','\xd7'},{'\xfa','\xac'},{'\xc4','\xee'},{'\xf5','\xdf'},
+ {'\x8d','\x55'},{'\xc5','\x7e'},{'\xf6','\xf4'},{'\xc5','\x7d'},{'\xfc','\xd8'},
+ {'\xf7','\xea'},{'\xc5','\xf5'},{'\xc5','\xf6'},{'\x81','\xe4'},{'\x81','\xe5'},
+ {'\xf9','\xcc'},{'\xc6','\xd5'},{'\x00','\x00'},{'\xac','\xd1'},{'\xcf','\xde'},
+ {'\x93','\xb9'},{'\xb5','\x6e'},{'\xb5','\x6f'},{'\xa5','\xd5'},{'\xa6','\xca'},
+ {'\xca','\x47'},{'\xfa','\xad'},{'\xcb','\x71'},{'\xa8','\x6d'},{'\xfa','\xae'},
+ {'\xaa','\xba'},{'\x00','\x00'},{'\xac','\xd2'},{'\xac','\xd3'},{'\xac','\xd4'},
+ {'\xd6','\xa6'},{'\xd2','\xcb'},{'\xaf','\x6f'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xb2','\xae'},{'\xd6','\xa5'},{'\xfa','\xaf'},{'\x87','\xf5'},{'\xda','\xb8'},
+ {'\xb5','\x71'},{'\x00','\x00'},{'\xda','\xb7'},{'\xb5','\x70'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xde','\xd5'},{'\xbd','\x4a'},{'\xe6','\xbb'},{'\xe6','\xb8'},
+ {'\xe6','\xb9'},{'\xe6','\xba'},{'\x00','\x00'},{'\x00','\x00'},{'\xfc','\xbe'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xed','\x78'},{'\x81','\xe6'},{'\xf0','\x51'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xf4','\x71'},{'\xf4','\x70'},
+ {'\x00','\x00'},{'\xf6','\xf5'},{'\xa5','\xd6'},{'\xcd','\x75'},{'\xaf','\x70'},
+ {'\x87','\xf6'},{'\x8e','\x77'},{'\x00','\x00'},{'\xb5','\x72'},{'\xde','\xd6'},
+ {'\x00','\x00'},{'\xfa','\xb0'},{'\xe2','\xe1'},{'\xfa','\xb1'},{'\xbd','\x4b'},
+ {'\xea','\x74'},{'\x00','\x00'},{'\xf0','\x52'},{'\xf4','\x72'},{'\xa5','\xd7'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xaa','\xbb'},{'\xac','\xd7'},{'\xcf','\xdf'},
+ {'\xac','\xd8'},{'\xac','\xd6'},{'\x00','\x00'},{'\xac','\xd5'},{'\xd2','\xcc'},
+ {'\xaf','\x71'},{'\x00','\x00'},{'\xfc','\xbf'},{'\xaf','\x72'},{'\xaf','\x73'},
+ {'\x85','\xe6'},{'\x8d','\x69'},{'\x86','\xea'},{'\xb2','\xb0'},{'\xd6','\xa7'},
+ {'\xb2','\xaf'},{'\x00','\x00'},{'\x87','\x49'},{'\x84','\xfb'},{'\x87','\xf7'},
+ {'\x81','\xe7'},{'\xda','\xb9'},{'\xb2','\xb1'},{'\xb5','\x73'},{'\xde','\xd7'},
+ {'\xb7','\xf8'},{'\xb7','\xf9'},{'\x00','\x00'},{'\xba','\xc9'},{'\x00','\x00'},
+ {'\xba','\xca'},{'\xbd','\x4c'},{'\xbf','\x64'},{'\xea','\x75'},{'\xbf','\x63'},
+ {'\x00','\x00'},{'\xed','\x79'},{'\xc0','\xfa'},{'\x00','\x00'},{'\xf0','\x53'},
+ {'\xf4','\x73'},{'\xa5','\xd8'},{'\xa8','\x6e'},{'\xcd','\x78'},{'\xcd','\x77'},
+ {'\xaa','\xbc'},{'\xcd','\x76'},{'\xaa','\xbd'},{'\xcd','\x79'},{'\x00','\x00'},
+ {'\xcf','\xe5'},{'\xac','\xdb'},{'\xac','\xda'},{'\xcf','\xe7'},{'\xcf','\xe6'},
+ {'\xac','\xdf'},{'\x00','\x00'},{'\xac','\xde'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xac','\xd9'},{'\x00','\x00'},{'\xcf','\xe1'},{'\xcf','\xe2'},{'\xcf','\xe3'},
+ {'\x00','\x00'},{'\xac','\xe0'},{'\xcf','\xe0'},{'\xac','\xdc'},{'\xcf','\xe4'},
+ {'\xac','\xdd'},{'\x92','\xb1'},{'\xfa','\xb2'},{'\x81','\xe8'},{'\x81','\xe9'},
+ {'\xd2','\xcf'},{'\xd2','\xd3'},{'\xd2','\xd1'},{'\xd2','\xd0'},{'\x00','\x00'},
+ {'\xd2','\xd4'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xd2','\xd5'},
+ {'\xd2','\xd6'},{'\xd2','\xce'},{'\x00','\x00'},{'\xd2','\xcd'},{'\xfa','\xb3'},
+ {'\xaf','\x75'},{'\xaf','\x76'},{'\x00','\x00'},{'\xd2','\xd7'},{'\xd2','\xd2'},
+ {'\xfc','\xc0'},{'\xd6','\xb0'},{'\x8d','\xd2'},{'\xd2','\xd8'},{'\xaf','\x77'},
+ {'\xaf','\x74'},{'\x00','\x00'},{'\xfc','\xc1'},{'\x00','\x00'},{'\xd6','\xaa'},
+ {'\x00','\x00'},{'\xd6','\xa9'},{'\x00','\x00'},{'\xd6','\xab'},{'\xd6','\xac'},
+ {'\xd6','\xae'},{'\xd6','\xad'},{'\xd6','\xb2'},{'\xb2','\xb5'},{'\xb2','\xb2'},
+ {'\xb2','\xb6'},{'\xd6','\xa8'},{'\xb2','\xb7'},{'\xd6','\xb1'},{'\xb2','\xb4'},
+ {'\xd6','\xaf'},{'\xb2','\xb3'},{'\x00','\x00'},{'\x95','\x4d'},{'\x85','\xe8'},
+ {'\x00','\x00'},{'\xfa','\xb4'},{'\xda','\xbc'},{'\xda','\xbe'},{'\xda','\xba'},
+ {'\xda','\xbb'},{'\x00','\x00'},{'\x00','\x00'},{'\xda','\xbf'},{'\xda','\xc1'},
+ {'\xda','\xc2'},{'\xda','\xbd'},{'\xda','\xc0'},{'\xb5','\x74'},{'\x85','\xe7'},
+ {'\x8a','\xde'},{'\xde','\xdb'},{'\x00','\x00'},{'\xde','\xe0'},{'\xde','\xd8'},
+ {'\xde','\xdc'},{'\x00','\x00'},{'\x81','\xea'},{'\xde','\xe1'},{'\xde','\xdd'},
+ {'\xb7','\xfa'},{'\xb8','\x43'},{'\x00','\x00'},{'\xb7','\xfd'},{'\xde','\xd9'},
+ {'\xde','\xda'},{'\xba','\xce'},{'\xb8','\x46'},{'\xb7','\xfe'},{'\x00','\x00'},
+ {'\xb8','\x44'},{'\xb7','\xfc'},{'\xde','\xdf'},{'\xb8','\x45'},{'\xde','\xde'},
+ {'\xb8','\x41'},{'\xb7','\xfb'},{'\xb8','\x42'},{'\xde','\xe2'},{'\xe2','\xe6'},
+ {'\xe2','\xe8'},{'\x00','\x00'},{'\x00','\x00'},{'\x81','\xeb'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x81','\xec'},{'\x81','\xed'},
+ {'\xb8','\x40'},{'\x81','\xee'},{'\x81','\xef'},{'\xe2','\xe3'},{'\xba','\xcc'},
+ {'\xe2','\xe9'},{'\xba','\xcd'},{'\xe2','\xe7'},{'\xe2','\xe2'},{'\xe2','\xe5'},
+ {'\xe2','\xea'},{'\xba','\xcb'},{'\xe2','\xe4'},{'\x00','\x00'},{'\xbd','\x4e'},
+ {'\xe6','\xbf'},{'\xe6','\xbe'},{'\x00','\x00'},{'\xbd','\x51'},{'\xbd','\x4f'},
+ {'\xe6','\xbc'},{'\xbd','\x4d'},{'\xe6','\xbd'},{'\x00','\x00'},{'\xbd','\x50'},
+ {'\x89','\x42'},{'\xfb','\x6b'},{'\x00','\x00'},{'\xea','\x7d'},{'\x00','\x00'},
+ {'\xea','\xa1'},{'\x81','\xf0'},{'\xea','\x7e'},{'\xea','\x76'},{'\xea','\x7a'},
+ {'\xea','\x79'},{'\xea','\x77'},{'\xbf','\x66'},{'\xbf','\x67'},{'\xbf','\x65'},
+ {'\xea','\x78'},{'\xea','\x7b'},{'\xea','\x7c'},{'\x00','\x00'},{'\xbf','\x68'},
+ {'\x00','\x00'},{'\xc1','\x40'},{'\xed','\xa3'},{'\x8d','\x7c'},{'\xc0','\xfc'},
+ {'\xed','\x7b'},{'\xc0','\xfe'},{'\xc1','\x41'},{'\x00','\x00'},{'\x81','\xf1'},
+ {'\xc0','\xfd'},{'\xed','\xa2'},{'\xed','\x7c'},{'\xc0','\xfb'},{'\xed','\xa1'},
+ {'\xed','\x7a'},{'\xed','\x7e'},{'\xed','\x7d'},{'\x00','\x00'},{'\xfe','\x5a'},
+ {'\xf0','\x55'},{'\xc2','\xa4'},{'\xc2','\xa5'},{'\xc2','\xa2'},{'\x81','\xf2'},
+ {'\xc2','\xa3'},{'\x00','\x00'},{'\x00','\x00'},{'\xf0','\x54'},{'\x81','\xf3'},
+ {'\xf2','\x7b'},{'\x81','\xf4'},{'\x00','\x00'},{'\xc3','\xa9'},{'\x00','\x00'},
+ {'\xf2','\x79'},{'\xf2','\x7a'},{'\x81','\xf5'},{'\xf4','\x74'},{'\xf4','\x77'},
+ {'\xf4','\x75'},{'\xf4','\x76'},{'\xf5','\xe0'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xc4','\xef'},{'\xf7','\xeb'},{'\xf8','\xb4'},{'\x00','\x00'},{'\xc5','\xf7'},
+ {'\xf8','\xf8'},{'\xf8','\xf9'},{'\xc6','\x66'},{'\xa5','\xd9'},{'\xac','\xe1'},
+ {'\x81','\xf6'},{'\xda','\xc3'},{'\x00','\x00'},{'\xde','\xe3'},{'\x00','\x00'},
+ {'\xa5','\xda'},{'\xa8','\x6f'},{'\x00','\x00'},{'\xaa','\xbe'},{'\x81','\xf7'},
+ {'\xcf','\xe8'},{'\xcf','\xe9'},{'\xaf','\x78'},{'\x00','\x00'},{'\x89','\xfc'},
+ {'\xda','\xc4'},{'\xb5','\x75'},{'\xb8','\x47'},{'\xc1','\x42'},{'\xed','\xa4'},
+ {'\xf2','\x7c'},{'\xf4','\x78'},{'\xa5','\xdb'},{'\x81','\xf8'},{'\x00','\x00'},
+ {'\x89','\xfe'},{'\xcd','\xa1'},{'\xcd','\x7a'},{'\xcd','\x7c'},{'\xcd','\x7e'},
+ {'\xcd','\x7d'},{'\xcd','\x7b'},{'\xaa','\xbf'},{'\x8c','\x41'},{'\x8b','\xfe'},
+ {'\x8e','\x78'},{'\x87','\xf9'},{'\xac','\xe2'},{'\xcf','\xf2'},{'\x00','\x00'},
+ {'\xcf','\xed'},{'\xcf','\xea'},{'\x00','\x00'},{'\x96','\x41'},{'\xcf','\xf1'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xac','\xe4'},{'\xac','\xe5'},{'\xcf','\xf0'},
+ {'\xcf','\xef'},{'\xcf','\xee'},{'\xcf','\xeb'},{'\xcf','\xec'},{'\xcf','\xf3'},
+ {'\xac','\xe3'},{'\x92','\xc5'},{'\x89','\x43'},{'\x8d','\xe3'},{'\xfa','\xb5'},
+ {'\x00','\x00'},{'\x84','\xfc'},{'\x00','\x00'},{'\xfa','\xb6'},{'\xaf','\x7c'},
+ {'\x81','\xf9'},{'\xaf','\xa4'},{'\xaf','\xa3'},{'\xd2','\xe1'},{'\xd2','\xdb'},
+ {'\xd2','\xd9'},{'\x00','\x00'},{'\xaf','\xa1'},{'\xd6','\xb9'},{'\xaf','\x7a'},
+ {'\xd2','\xde'},{'\xd2','\xe2'},{'\xd2','\xe4'},{'\xd2','\xe0'},{'\xd2','\xda'},
+ {'\xaf','\xa2'},{'\xd2','\xdf'},{'\xd2','\xdd'},{'\xaf','\x79'},{'\xd2','\xe5'},
+ {'\xaf','\xa5'},{'\xd2','\xe3'},{'\xaf','\x7d'},{'\xd2','\xdc'},{'\x00','\x00'},
+ {'\xaf','\x7e'},{'\xaf','\x7b'},{'\xfa','\xb7'},{'\x8c','\x40'},{'\x90','\x42'},
+ {'\xfa','\xb8'},{'\x81','\xfa'},{'\x8c','\x42'},{'\x82','\x5f'},{'\x8a','\xdf'},
+ {'\x00','\x00'},{'\x81','\xfb'},{'\xb2','\xb9'},{'\x81','\xfc'},{'\xd6','\xba'},
+ {'\x00','\x00'},{'\xfa','\xb9'},{'\xd6','\xb3'},{'\xd6','\xb5'},{'\xd6','\xb7'},
+ {'\x81','\xfd'},{'\xd6','\xb8'},{'\xd6','\xb6'},{'\xb2','\xba'},{'\x00','\x00'},
+ {'\xd6','\xbb'},{'\x81','\xfe'},{'\xd6','\xb4'},{'\xfc','\xc3'},{'\x96','\x4b'},
+ {'\x86','\xeb'},{'\xfa','\xba'},{'\x8f','\x59'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xda','\xc8'},{'\xb5','\x76'},{'\xda','\xd0'},
+ {'\x00','\x00'},{'\xda','\xc5'},{'\x00','\x00'},{'\xda','\xd1'},{'\x00','\x00'},
+ {'\xda','\xc6'},{'\xda','\xc7'},{'\x96','\x4c'},{'\x00','\x00'},{'\xda','\xcf'},
+ {'\xda','\xce'},{'\xda','\xcb'},{'\xb2','\xb8'},{'\xb5','\x77'},{'\xda','\xc9'},
+ {'\xda','\xcc'},{'\xb5','\x78'},{'\xda','\xcd'},{'\xda','\xca'},{'\x94','\x54'},
+ {'\x00','\x00'},{'\x94','\xb4'},{'\x00','\x00'},{'\x00','\x00'},{'\x8d','\x68'},
+ {'\x00','\x00'},{'\xde','\xee'},{'\xfa','\xbb'},{'\xde','\xf2'},{'\xb8','\x4e'},
+ {'\x00','\x00'},{'\xe2','\xf0'},{'\xb8','\x51'},{'\xde','\xf0'},{'\xf9','\xd6'},
+ {'\x00','\x00'},{'\xde','\xed'},{'\xde','\xe8'},{'\xde','\xea'},{'\xde','\xeb'},
+ {'\xde','\xe4'},{'\x96','\x4d'},{'\xb8','\x4d'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xb8','\x4c'},{'\x8b','\xac'},{'\xb8','\x48'},{'\xde','\xe7'},{'\x00','\x00'},
+ {'\xb8','\x4f'},{'\x00','\x00'},{'\xb8','\x50'},{'\xde','\xe6'},{'\xde','\xe9'},
+ {'\xde','\xf1'},{'\xb8','\x4a'},{'\xb8','\x4b'},{'\xde','\xef'},{'\xde','\xe5'},
+ {'\x89','\x44'},{'\x8e','\xed'},{'\x00','\x00'},{'\xe2','\xf2'},{'\xba','\xd0'},
+ {'\xe2','\xf4'},{'\xde','\xec'},{'\xe2','\xf6'},{'\xba','\xd4'},{'\xe2','\xf7'},
+ {'\xe2','\xf3'},{'\x00','\x00'},{'\xba','\xd1'},{'\xe2','\xef'},{'\xba','\xd3'},
+ {'\xe2','\xec'},{'\xe2','\xf1'},{'\xe2','\xf5'},{'\xe2','\xee'},{'\x00','\x00'},
+ {'\xfc','\xc7'},{'\xb8','\x49'},{'\x95','\xf0'},{'\xe2','\xeb'},{'\xba','\xd2'},
+ {'\xe2','\xed'},{'\xfa','\xbc'},{'\x96','\x4e'},{'\x00','\x00'},{'\x96','\xcd'},
+ {'\xfa','\xbd'},{'\xbd','\x54'},{'\xe6','\xc1'},{'\xbd','\x58'},{'\x00','\x00'},
+ {'\xbd','\x56'},{'\x00','\x00'},{'\x00','\x00'},{'\xba','\xcf'},{'\x00','\x00'},
+ {'\xe6','\xc8'},{'\xe6','\xc9'},{'\xbd','\x53'},{'\xfa','\xbe'},{'\x96','\x4f'},
+ {'\xe6','\xc7'},{'\xe6','\xca'},{'\xbd','\x55'},{'\xbd','\x52'},{'\xe6','\xc3'},
+ {'\xe6','\xc0'},{'\xe6','\xc5'},{'\xe6','\xc2'},{'\xbd','\x59'},{'\xe6','\xc4'},
+ {'\x96','\x50'},{'\xfc','\xc4'},{'\xe6','\xc6'},{'\xbd','\x57'},{'\x00','\x00'},
+ {'\x96','\x51'},{'\xfc','\xc5'},{'\xfa','\xbf'},{'\xbf','\x6a'},{'\xea','\xa8'},
+ {'\x00','\x00'},{'\xea','\xa2'},{'\xea','\xa6'},{'\xea','\xac'},{'\xea','\xad'},
+ {'\xea','\xa9'},{'\xea','\xaa'},{'\xea','\xa7'},{'\x96','\x54'},{'\xea','\xa4'},
+ {'\x00','\x00'},{'\xbf','\x6c'},{'\xbf','\x69'},{'\xea','\xa3'},{'\xea','\xa5'},
+ {'\x00','\x00'},{'\xbf','\x6b'},{'\xea','\xab'},{'\x96','\x55'},{'\xc1','\x46'},
+ {'\x96','\x56'},{'\x96','\x57'},{'\xed','\xaa'},{'\xed','\xa5'},{'\xc1','\x45'},
+ {'\x96','\x58'},{'\x00','\x00'},{'\xc1','\x43'},{'\x00','\x00'},{'\xed','\xac'},
+ {'\xc1','\x44'},{'\xed','\xa8'},{'\xed','\xa9'},{'\xed','\xa6'},{'\xed','\xad'},
+ {'\xf0','\x56'},{'\x00','\x00'},{'\xc1','\x47'},{'\xed','\xa7'},{'\x00','\x00'},
+ {'\xed','\xae'},{'\xed','\xab'},{'\xfb','\xa8'},{'\xfa','\xc0'},{'\x00','\x00'},
+ {'\xf0','\x5a'},{'\x00','\x00'},{'\x00','\x00'},{'\xf0','\x57'},{'\x00','\x00'},
+ {'\xc2','\xa6'},{'\x00','\x00'},{'\xf0','\x5b'},{'\xf0','\x5d'},{'\xf0','\x5c'},
+ {'\xf0','\x58'},{'\xf0','\x59'},{'\x00','\x00'},{'\x00','\x00'},{'\xf2','\xa3'},
+ {'\x00','\x00'},{'\xc3','\xaa'},{'\x00','\x00'},{'\xf2','\x7e'},{'\xf2','\xa2'},
+ {'\xf2','\x7d'},{'\xf2','\xa4'},{'\x00','\x00'},{'\x00','\x00'},{'\xf2','\xa1'},
+ {'\x00','\x00'},{'\xf4','\x7a'},{'\xf4','\x7d'},{'\xf4','\x79'},{'\xc4','\x71'},
+ {'\xf4','\x7b'},{'\xf4','\x7c'},{'\xf4','\x7e'},{'\xc4','\x72'},{'\xc4','\x74'},
+ {'\xc4','\x73'},{'\xf5','\xe1'},{'\xfe','\x77'},{'\xf5','\xe3'},{'\xfa','\xc1'},
+ {'\xf5','\xe2'},{'\x96','\x59'},{'\x96','\x5a'},{'\xfa','\xc2'},{'\xf6','\xf6'},
+ {'\x96','\x5b'},{'\x00','\x00'},{'\xf8','\xb5'},{'\xf8','\xfa'},{'\xa5','\xdc'},
+ {'\xfa','\xc3'},{'\x8a','\xe0'},{'\xcb','\x72'},{'\xaa','\xc0'},{'\xcd','\xa3'},
+ {'\xaa','\xc1'},{'\xaa','\xc2'},{'\xcd','\xa2'},{'\x00','\x00'},{'\xcf','\xf8'},
+ {'\xcf','\xf7'},{'\xac','\xe6'},{'\xac','\xe9'},{'\xac','\xe8'},{'\xac','\xe7'},
+ {'\xcf','\xf4'},{'\xcf','\xf6'},{'\xcf','\xf5'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xd2','\xe8'},{'\xaf','\xa7'},{'\xd2','\xec'},{'\xd2','\xeb'},{'\xd2','\xea'},
+ {'\xd2','\xe6'},{'\xaf','\xa6'},{'\xaf','\xaa'},{'\xaf','\xad'},{'\x96','\x5c'},
+ {'\x96','\x5e'},{'\xaf','\xae'},{'\xd2','\xe7'},{'\xd2','\xe9'},{'\xaf','\xac'},
+ {'\xaf','\xab'},{'\xaf','\xa9'},{'\xaf','\xa8'},{'\xd6','\xc2'},{'\x8f','\xbe'},
+ {'\xd6','\xc0'},{'\xd6','\xbc'},{'\xb2','\xbb'},{'\x00','\x00'},{'\xd6','\xbd'},
+ {'\xb2','\xbc'},{'\xd6','\xbe'},{'\xd6','\xbf'},{'\xd6','\xc1'},{'\x00','\x00'},
+ {'\xb2','\xbd'},{'\x00','\x00'},{'\x86','\xec'},{'\xda','\xd5'},{'\x96','\x5f'},
+ {'\xda','\xd4'},{'\xda','\xd3'},{'\xda','\xd2'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x82','\x70'},{'\x86','\xed'},{'\xde','\xf6'},{'\xb8','\x52'},{'\x00','\x00'},
+ {'\xde','\xf3'},{'\xde','\xf5'},{'\x96','\x60'},{'\xb8','\x53'},{'\xfa','\xc4'},
+ {'\xb8','\x54'},{'\xde','\xf4'},{'\x96','\x61'},{'\x82','\x77'},{'\x93','\x50'},
+ {'\x96','\x62'},{'\x96','\x63'},{'\xe3','\x41'},{'\x00','\x00'},{'\xe2','\xf9'},
+ {'\xe2','\xfa'},{'\x00','\x00'},{'\xba','\xd7'},{'\xba','\xd5'},{'\xba','\xd6'},
+ {'\xe3','\x43'},{'\x96','\x64'},{'\xe3','\x42'},{'\xe2','\xfe'},{'\xe2','\xfd'},
+ {'\xe2','\xfc'},{'\xe2','\xfb'},{'\xe3','\x40'},{'\xe2','\xf8'},{'\x96','\x65'},
+ {'\xe6','\xcb'},{'\xe6','\xd0'},{'\xe6','\xce'},{'\xfa','\xc5'},{'\x00','\x00'},
+ {'\x96','\x66'},{'\xe6','\xcd'},{'\xe6','\xcc'},{'\xe6','\xcf'},{'\x00','\x00'},
+ {'\xea','\xae'},{'\x96','\x67'},{'\xbf','\x6d'},{'\xc1','\x48'},{'\xed','\xb0'},
+ {'\xfc','\xca'},{'\xc1','\x49'},{'\xed','\xaf'},{'\xf0','\x5f'},{'\xf0','\x5e'},
+ {'\xc2','\xa7'},{'\x00','\x00'},{'\xf2','\xa5'},{'\xc3','\xab'},{'\xf4','\xa1'},
+ {'\xc5','\xa1'},{'\xf6','\xf7'},{'\x00','\x00'},{'\xf8','\xb7'},{'\xf8','\xb6'},
+ {'\xc9','\xa8'},{'\xac','\xea'},{'\xac','\xeb'},{'\xd6','\xc3'},{'\x00','\x00'},
+ {'\xb8','\x56'},{'\xa5','\xdd'},{'\xa8','\x72'},{'\xa8','\x71'},{'\xa8','\x70'},
+ {'\x00','\x00'},{'\xfa','\xc6'},{'\xfb','\xa9'},{'\xcd','\xa4'},{'\x84','\xfd'},
+ {'\x00','\x00'},{'\xaa','\xc4'},{'\xaa','\xc3'},{'\x9d','\xce'},{'\xac','\xee'},
+ {'\xfc','\xa6'},{'\xcf','\xfa'},{'\xcf','\xfd'},{'\xcf','\xfb'},{'\x00','\x00'},
+ {'\xac','\xec'},{'\xac','\xed'},{'\x00','\x00'},{'\xfc','\xcc'},{'\xcf','\xf9'},
+ {'\xcf','\xfc'},{'\x00','\x00'},{'\xaf','\xb5'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xd2','\xf3'},{'\xd2','\xf5'},{'\xd2','\xf4'},{'\xaf','\xb2'},
+ {'\xd2','\xef'},{'\xfa','\xc7'},{'\x96','\x68'},{'\xaf','\xb0'},{'\xaf','\xaf'},
+ {'\x00','\x00'},{'\xaf','\xb3'},{'\xaf','\xb1'},{'\x00','\x00'},{'\xaf','\xb4'},
+ {'\xd2','\xf2'},{'\xd2','\xed'},{'\xd2','\xee'},{'\xd2','\xf1'},{'\xd2','\xf0'},
+ {'\x85','\xb8'},{'\x86','\xef'},{'\x96','\x69'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x96','\x6a'},{'\x00','\x00'},{'\xd6','\xc6'},{'\xd6','\xc7'},{'\xd6','\xc5'},
+ {'\x00','\x00'},{'\xd6','\xc4'},{'\xb2','\xbe'},{'\x00','\x00'},{'\x8a','\xe2'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xb5','\x7d'},{'\x00','\x00'},{'\xda','\xd6'},
+ {'\xda','\xd8'},{'\xda','\xda'},{'\xb5','\x7c'},{'\xfa','\xc8'},{'\x00','\x00'},
+ {'\xb5','\x7a'},{'\x00','\x00'},{'\xda','\xd7'},{'\xb5','\x7b'},{'\xda','\xd9'},
+ {'\xb5','\x79'},{'\xfa','\xc9'},{'\x00','\x00'},{'\xdf','\x41'},{'\xde','\xf7'},
+ {'\xde','\xfa'},{'\xde','\xfe'},{'\xb8','\x5a'},{'\xde','\xfc'},{'\x00','\x00'},
+ {'\xde','\xfb'},{'\xde','\xf8'},{'\xde','\xf9'},{'\xb8','\x58'},{'\xdf','\x40'},
+ {'\xb8','\x57'},{'\x00','\x00'},{'\xb8','\x5c'},{'\xb8','\x5b'},{'\xb8','\x59'},
+ {'\x00','\x00'},{'\xde','\xfd'},{'\x89','\x47'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xe3','\x49'},{'\x00','\x00'},{'\xe3','\x48'},{'\x00','\x00'},{'\x96','\x6b'},
+ {'\xe3','\x44'},{'\x00','\x00'},{'\xfc','\xce'},{'\xba','\xd8'},{'\xe3','\x47'},
+ {'\xe3','\x46'},{'\xba','\xd9'},{'\x93','\xa6'},{'\x8b','\xae'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xbd','\x5e'},{'\x00','\x00'},{'\xe6','\xd2'},
+ {'\x96','\x6c'},{'\xbd','\x5f'},{'\xbd','\x5b'},{'\xbd','\x5d'},{'\xfc','\xcf'},
+ {'\xbd','\x5a'},{'\xbd','\x5c'},{'\x00','\x00'},{'\x92','\xf9'},{'\xfa','\xca'},
+ {'\xea','\xaf'},{'\x96','\x6d'},{'\xbf','\x70'},{'\xea','\xb1'},{'\xea','\xb0'},
+ {'\xfc','\xd0'},{'\xe3','\x45'},{'\xbf','\x72'},{'\xbf','\x71'},{'\xbf','\x6e'},
+ {'\xbf','\x6f'},{'\x92','\x53'},{'\xfa','\xcb'},{'\x8a','\xe1'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xed','\xb5'},{'\x00','\x00'},{'\xed','\xb3'},{'\xc1','\x4a'},
+ {'\xed','\xb4'},{'\x00','\x00'},{'\xed','\xb6'},{'\xed','\xb2'},{'\xed','\xb1'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xf0','\x60'},{'\xc2','\xaa'},{'\xc2','\xa8'},
+ {'\xc2','\xa9'},{'\x82','\x67'},{'\x00','\x00'},{'\x96','\x6e'},{'\x00','\x00'},
+ {'\xf2','\xa6'},{'\xf2','\xa7'},{'\xc3','\xad'},{'\x00','\x00'},{'\xc3','\xac'},
+ {'\xf4','\xa3'},{'\xf4','\xa4'},{'\xf4','\xa2'},{'\x00','\x00'},{'\xf6','\xf8'},
+ {'\xf6','\xf9'},{'\x00','\x00'},{'\x00','\x00'},{'\xa5','\xde'},{'\xca','\x48'},
+ {'\xa8','\x73'},{'\x87','\xfb'},{'\xcd','\xa5'},{'\xaa','\xc6'},{'\xaa','\xc5'},
+ {'\xcd','\xa6'},{'\x00','\x00'},{'\xfc','\x42'},{'\xd0','\x40'},{'\xac','\xef'},
+ {'\xcf','\xfe'},{'\xac','\xf0'},{'\x00','\x00'},{'\x8c','\xfa'},{'\xaf','\xb6'},
+ {'\xd2','\xf8'},{'\xd2','\xf6'},{'\xd2','\xfc'},{'\xaf','\xb7'},{'\xd2','\xf7'},
+ {'\xd2','\xfb'},{'\xd2','\xf9'},{'\xd2','\xfa'},{'\x8a','\xe4'},{'\x00','\x00'},
+ {'\xd6','\xc8'},{'\xd6','\xca'},{'\x87','\xfa'},{'\xb2','\xbf'},{'\x93','\x58'},
+ {'\xd6','\xc9'},{'\xb2','\xc0'},{'\xb5','\xa2'},{'\xb5','\xa1'},{'\xb5','\x7e'},
+ {'\xda','\xdb'},{'\x00','\x00'},{'\x00','\x00'},{'\x8a','\xe3'},{'\x86','\xf1'},
+ {'\xdf','\x44'},{'\xb8','\x5d'},{'\xb8','\x5e'},{'\x00','\x00'},{'\xdf','\x43'},
+ {'\xdf','\x42'},{'\x00','\x00'},{'\x89','\x48'},{'\x8c','\x43'},{'\x00','\x00'},
+ {'\xe3','\x4a'},{'\xba','\xdb'},{'\xba','\xda'},{'\xe3','\x4b'},{'\xe3','\x4c'},
+ {'\x8e','\xee'},{'\xbd','\x61'},{'\xbd','\x60'},{'\xfe','\xa7'},{'\xea','\xb5'},
+ {'\xe6','\xd3'},{'\xe6','\xd5'},{'\xe6','\xd4'},{'\xea','\xb4'},{'\xea','\xb2'},
+ {'\xea','\xb6'},{'\xea','\xb3'},{'\x00','\x00'},{'\xbf','\x73'},{'\xfc','\x44'},
+ {'\x96','\x6f'},{'\x00','\x00'},{'\xed','\xb7'},{'\xc1','\x4b'},{'\xed','\xb8'},
+ {'\xed','\xb9'},{'\x96','\x70'},{'\xfa','\xcc'},{'\xc2','\xab'},{'\xc2','\xac'},
+ {'\x00','\x00'},{'\xc4','\x75'},{'\xfd','\xe5'},{'\x96','\x71'},{'\xc5','\xd1'},
+ {'\xa5','\xdf'},{'\x00','\x00'},{'\x94','\xb5'},{'\x00','\x00'},{'\x94','\xb6'},
+ {'\x00','\x00'},{'\xd0','\x41'},{'\xfa','\xcd'},{'\x94','\xb8'},{'\x00','\x00'},
+ {'\x94','\xb7'},{'\x88','\x67'},{'\x00','\x00'},{'\xd2','\xfd'},{'\xaf','\xb8'},
+ {'\xfc','\xd2'},{'\x96','\x72'},{'\x93','\xe2'},{'\xfc','\xd1'},{'\x8c','\x44'},
+ {'\xb3','\xba'},{'\xb3','\xb9'},{'\x94','\xb9'},{'\xfa','\xce'},{'\xb5','\xa4'},
+ {'\xda','\xdd'},{'\xb5','\xa3'},{'\xda','\xdc'},{'\xfa','\xcf'},{'\x00','\x00'},
+ {'\x96','\x73'},{'\x82','\x6d'},{'\xdf','\x45'},{'\x00','\x00'},{'\xba','\xdc'},
+ {'\xe3','\x4d'},{'\xba','\xdd'},{'\x94','\xba'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xc4','\x76'},{'\xf4','\xa5'},
+ {'\xfa','\xd0'},{'\xa6','\xcb'},{'\xaa','\xc7'},{'\xcd','\xa7'},{'\x00','\x00'},
+ {'\xac','\xf2'},{'\x96','\x74'},{'\xac','\xf1'},{'\xd0','\x42'},{'\xd0','\x43'},
+ {'\x94','\xbb'},{'\x89','\x49'},{'\xd3','\x40'},{'\xd3','\x42'},{'\xaf','\xb9'},
+ {'\x00','\x00'},{'\xd3','\x44'},{'\xd3','\x47'},{'\xd3','\x45'},{'\x85','\x41'},
+ {'\x96','\x75'},{'\x00','\x00'},{'\xd3','\x46'},{'\xd3','\x43'},{'\xd2','\xfe'},
+ {'\xaf','\xba'},{'\xd3','\x48'},{'\xd3','\x41'},{'\x85','\x40'},{'\x85','\xec'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xd6','\xd3'},{'\xb2','\xc6'},{'\xd6','\xdc'},
+ {'\xb2','\xc3'},{'\x00','\x00'},{'\xd6','\xd5'},{'\xb2','\xc7'},{'\xfc','\xdc'},
+ {'\xb2','\xc1'},{'\x00','\x00'},{'\xd6','\xd0'},{'\xd6','\xdd'},{'\xd6','\xd1'},
+ {'\xd6','\xce'},{'\xb2','\xc5'},{'\x96','\x76'},{'\xb2','\xc2'},{'\x96','\x77'},
+ {'\xd6','\xd4'},{'\xd6','\xd7'},{'\xb2','\xc4'},{'\xd6','\xd8'},{'\xb2','\xc8'},
+ {'\xd6','\xd9'},{'\xd6','\xcf'},{'\xd6','\xd6'},{'\xd6','\xda'},{'\xd6','\xd2'},
+ {'\xd6','\xcd'},{'\xd6','\xcb'},{'\xfa','\xd1'},{'\x00','\x00'},{'\xd6','\xdb'},
+ {'\xfe','\x64'},{'\x86','\xf2'},{'\xda','\xdf'},{'\x8c','\xd7'},{'\x00','\x00'},
+ {'\x90','\x7a'},{'\x00','\x00'},{'\xda','\xe4'},{'\x00','\x00'},{'\x96','\x78'},
+ {'\x96','\x79'},{'\xda','\xe0'},{'\xda','\xe6'},{'\xb5','\xa7'},{'\xd6','\xcc'},
+ {'\xda','\xe1'},{'\xb5','\xa5'},{'\xda','\xde'},{'\xb5','\xac'},{'\xda','\xe2'},
+ {'\xb5','\xab'},{'\xda','\xe3'},{'\xb5','\xad'},{'\xb5','\xa8'},{'\xb5','\xae'},
+ {'\xb5','\xa9'},{'\x00','\x00'},{'\xb5','\xaa'},{'\x96','\x7a'},{'\xb5','\xa6'},
+ {'\x00','\x00'},{'\xda','\xe5'},{'\x00','\x00'},{'\x8f','\x5b'},{'\x89','\x4a'},
+ {'\x00','\x00'},{'\x86','\xf3'},{'\x00','\x00'},{'\x00','\x00'},{'\xb8','\x61'},
+ {'\xdf','\x50'},{'\xfa','\xd2'},{'\xdf','\x53'},{'\xdf','\x47'},{'\xdf','\x4c'},
+ {'\xdf','\x46'},{'\xb8','\x63'},{'\x00','\x00'},{'\xdf','\x4a'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xfa','\xd3'},{'\xdf','\x48'},{'\xb8','\x62'},{'\x96','\x7b'},
+ {'\xdf','\x4f'},{'\xdf','\x4e'},{'\xdf','\x4b'},{'\xdf','\x4d'},{'\xdf','\x49'},
+ {'\xba','\xe1'},{'\xdf','\x52'},{'\xb8','\x5f'},{'\xdf','\x51'},{'\x8c','\x45'},
+ {'\xfa','\xd4'},{'\xfa','\xd5'},{'\x00','\x00'},{'\x00','\x00'},{'\x8b','\xaf'},
+ {'\x00','\x00'},{'\x8a','\xe9'},{'\x00','\x00'},{'\xe3','\x5d'},{'\x00','\x00'},
+ {'\xba','\xe8'},{'\xe3','\x58'},{'\x82','\x7a'},{'\xba','\xe7'},{'\xe3','\x4e'},
+ {'\x00','\x00'},{'\xe3','\x50'},{'\xba','\xe0'},{'\xe3','\x55'},{'\xe3','\x54'},
+ {'\xe3','\x57'},{'\xba','\xe5'},{'\xe3','\x52'},{'\xe3','\x51'},{'\xfc','\xdd'},
+ {'\x00','\x00'},{'\xba','\xe4'},{'\xba','\xdf'},{'\xe3','\x53'},{'\xba','\xe2'},
+ {'\xe3','\x59'},{'\xe3','\x5b'},{'\xfa','\xd6'},{'\xe3','\x56'},{'\xe3','\x4f'},
+ {'\xba','\xe3'},{'\xfa','\xd7'},{'\xfa','\xd8'},{'\xbd','\x69'},{'\xba','\xde'},
+ {'\xfa','\xd9'},{'\xfc','\xde'},{'\xe3','\x5c'},{'\x00','\x00'},{'\x8f','\x5a'},
+ {'\xfa','\xda'},{'\x90','\x59'},{'\x8d','\x71'},{'\x8a','\xe7'},{'\x8a','\xe5'},
+ {'\xe6','\xd9'},{'\xbd','\x62'},{'\x00','\x00'},{'\xe6','\xdb'},{'\x00','\x00'},
+ {'\xbd','\x63'},{'\x96','\x7c'},{'\x00','\x00'},{'\xbd','\x65'},{'\xe6','\xde'},
+ {'\x00','\x00'},{'\xe6','\xd6'},{'\xba','\xe6'},{'\xe6','\xdc'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xe6','\xd8'},{'\x00','\x00'},
+ {'\xb8','\x60'},{'\xbd','\x68'},{'\x00','\x00'},{'\x00','\x00'},{'\xbd','\x64'},
+ {'\x00','\x00'},{'\xbd','\x66'},{'\xbd','\x67'},{'\x00','\x00'},{'\xbf','\x76'},
+ {'\xe6','\xdd'},{'\xe6','\xd7'},{'\xbd','\x6a'},{'\x00','\x00'},{'\xe6','\xda'},
+ {'\xfc','\xdf'},{'\x96','\xd0'},{'\x8a','\xe8'},{'\x00','\x00'},{'\x8a','\x40'},
+ {'\xea','\xc0'},{'\xea','\xbb'},{'\x00','\x00'},{'\x00','\x00'},{'\xea','\xc5'},
+ {'\xbf','\x74'},{'\xea','\xbd'},{'\xbf','\x78'},{'\xea','\xc3'},{'\xea','\xba'},
+ {'\xea','\xb7'},{'\xea','\xc6'},{'\xc1','\x51'},{'\xbf','\x79'},{'\xea','\xc2'},
+ {'\xea','\xb8'},{'\xbf','\x77'},{'\xea','\xbc'},{'\xbf','\x7b'},{'\xea','\xb9'},
+ {'\xea','\xbe'},{'\xbf','\x7a'},{'\xea','\xc1'},{'\xea','\xc4'},{'\x96','\xd1'},
+ {'\x82','\xa1'},{'\x8c','\x46'},{'\x00','\x00'},{'\xed','\xcb'},{'\xed','\xcc'},
+ {'\xed','\xbc'},{'\xed','\xc3'},{'\xed','\xc1'},{'\x00','\x00'},{'\xfa','\xdb'},
+ {'\xc1','\x4f'},{'\xed','\xc8'},{'\xea','\xbf'},{'\x96','\xd2'},{'\xed','\xbf'},
+ {'\xfc','\xe1'},{'\xed','\xc9'},{'\xc1','\x4e'},{'\xed','\xbe'},{'\xed','\xbd'},
+ {'\xed','\xc7'},{'\xed','\xc4'},{'\xed','\xc6'},{'\x00','\x00'},{'\xed','\xba'},
+ {'\xed','\xca'},{'\xc1','\x4c'},{'\x00','\x00'},{'\xed','\xc5'},{'\xed','\xce'},
+ {'\xed','\xc2'},{'\xc1','\x50'},{'\xc1','\x4d'},{'\xed','\xc0'},{'\xed','\xbb'},
+ {'\xed','\xcd'},{'\xbf','\x75'},{'\xfa','\xdc'},{'\x94','\xbc'},{'\xfa','\xdd'},
+ {'\x96','\xd3'},{'\x90','\x77'},{'\x94','\xbd'},{'\x00','\x00'},{'\xf0','\x63'},
+ {'\x00','\x00'},{'\x96','\xd4'},{'\xf0','\x61'},{'\xf0','\x67'},{'\xc2','\xb0'},
+ {'\xf0','\x65'},{'\xf0','\x64'},{'\xc2','\xb2'},{'\xf0','\x6a'},{'\xc2','\xb1'},
+ {'\x00','\x00'},{'\xf0','\x6b'},{'\xf0','\x68'},{'\xc2','\xae'},{'\xf0','\x69'},
+ {'\xf0','\x62'},{'\xc2','\xaf'},{'\xc2','\xad'},{'\xf2','\xab'},{'\xf0','\x66'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xf0','\x6c'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xf2','\xa8'},{'\x00','\x00'},{'\x96','\xd5'},{'\x00','\x00'},{'\xc3','\xb2'},
+ {'\xc3','\xb0'},{'\xf2','\xaa'},{'\x00','\x00'},{'\xf2','\xac'},{'\xf2','\xa9'},
+ {'\xc3','\xb1'},{'\xc3','\xae'},{'\xc3','\xaf'},{'\xc3','\xb3'},{'\x8c','\xd8'},
+ {'\xfc','\xe2'},{'\xc4','\x78'},{'\x96','\xd6'},{'\xf4','\xaa'},{'\x00','\x00'},
+ {'\xf4','\xa9'},{'\xf4','\xa7'},{'\xf4','\xa6'},{'\xf4','\xa8'},{'\x00','\x00'},
+ {'\xc4','\x77'},{'\xc4','\x79'},{'\x00','\x00'},{'\xfa','\xde'},{'\xc4','\xf0'},
+ {'\xfc','\xe3'},{'\x00','\x00'},{'\xf5','\xe5'},{'\xf5','\xe4'},{'\x00','\x00'},
+ {'\xfa','\xdf'},{'\xf6','\xfa'},{'\xfa','\xe0'},{'\xf6','\xfc'},{'\xf6','\xfe'},
+ {'\xf6','\xfd'},{'\xf6','\xfb'},{'\xfc','\xe4'},{'\x00','\x00'},{'\xc5','\xa3'},
+ {'\xc5','\xa2'},{'\x00','\x00'},{'\x00','\x00'},{'\xc5','\xd3'},{'\xc5','\xd2'},
+ {'\xc5','\xd4'},{'\xf7','\xed'},{'\xf7','\xec'},{'\x00','\x00'},{'\xf8','\xfb'},
+ {'\xf8','\xb8'},{'\xf8','\xfc'},{'\xc6','\x58'},{'\x96','\xd7'},{'\xc6','\x59'},
+ {'\xf9','\x6d'},{'\xfc','\xe5'},{'\x00','\x00'},{'\xc6','\x7e'},{'\xa6','\xcc'},
+ {'\x90','\x5a'},{'\xcd','\xa8'},{'\x00','\x00'},{'\x00','\x00'},{'\xd0','\x45'},
+ {'\xd0','\x46'},{'\xd0','\x44'},{'\x8b','\xdd'},{'\x83','\x5e'},{'\xac','\xf3'},
+ {'\xfc','\xe6'},{'\xd0','\x47'},{'\xd0','\x48'},{'\xd0','\x49'},{'\x94','\x43'},
+ {'\xfc','\xe8'},{'\xd3','\x49'},{'\xd3','\x4f'},{'\xfc','\xe7'},{'\x00','\x00'},
+ {'\xd3','\x4d'},{'\xaf','\xbb'},{'\xd3','\x4b'},{'\x92','\xf7'},{'\xd3','\x4c'},
+ {'\xd3','\x4e'},{'\x96','\xd8'},{'\x00','\x00'},{'\x94','\xbe'},{'\xd3','\x4a'},
+ {'\xb2','\xc9'},{'\x00','\x00'},{'\xd6','\xde'},{'\xb2','\xcb'},{'\xd6','\xe0'},
+ {'\xb2','\xca'},{'\xd6','\xdf'},{'\x00','\x00'},{'\x00','\x00'},{'\x92','\xe0'},
+ {'\x90','\x7b'},{'\x90','\x43'},{'\xda','\xe8'},{'\xb5','\xaf'},{'\x00','\x00'},
+ {'\xda','\xea'},{'\xda','\xe7'},{'\xd6','\xe1'},{'\x85','\xed'},{'\xb5','\xb0'},
+ {'\xfe','\x63'},{'\xf9','\xdb'},{'\xda','\xe9'},{'\x00','\x00'},{'\x8a','\x41'},
+ {'\xfa','\xe1'},{'\xfc','\xe9'},{'\x94','\xbf'},{'\x8a','\xea'},{'\xdf','\x56'},
+ {'\x00','\x00'},{'\xb8','\x64'},{'\xdf','\x54'},{'\xb8','\x65'},{'\xdf','\x55'},
+ {'\xb8','\x66'},{'\x00','\x00'},{'\x00','\x00'},{'\x96','\xd9'},{'\xba','\xe9'},
+ {'\xe3','\x61'},{'\xe3','\x5e'},{'\xe3','\x60'},{'\xba','\xea'},{'\xba','\xeb'},
+ {'\xe3','\x5f'},{'\x94','\xc0'},{'\x8a','\x43'},{'\xfc','\xeb'},{'\x96','\xda'},
+ {'\x00','\x00'},{'\xe6','\xdf'},{'\x00','\x00'},{'\xfc','\xea'},{'\xe6','\xe0'},
+ {'\x95','\xb2'},{'\xbd','\x6b'},{'\xe6','\xe2'},{'\xe6','\xe1'},{'\xa0','\x54'},
+ {'\xa2','\x61'},{'\x00','\x00'},{'\xea','\xca'},{'\xea','\xcb'},{'\xea','\xc7'},
+ {'\xfb','\x7e'},{'\xea','\xc8'},{'\xbf','\x7c'},{'\xbf','\x7d'},{'\xea','\xc9'},
+ {'\x94','\xc1'},{'\xc1','\x57'},{'\xfc','\xed'},{'\x00','\x00'},{'\xc1','\x53'},
+ {'\xc1','\x58'},{'\xc1','\x54'},{'\xc1','\x56'},{'\xc1','\x52'},{'\x00','\x00'},
+ {'\xc1','\x55'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x96','\xdb'},
+ {'\xc2','\xb3'},{'\xed','\xcf'},{'\x00','\x00'},{'\xf2','\xae'},{'\x00','\x00'},
+ {'\xf2','\xad'},{'\x96','\xdc'},{'\xf4','\xab'},{'\xc4','\x7a'},{'\xc4','\x7b'},
+ {'\xf7','\x41'},{'\xf5','\xe6'},{'\x96','\xdd'},{'\xf7','\x40'},{'\x96','\xde'},
+ {'\xf8','\xfd'},{'\xf9','\xa4'},{'\xa6','\xcd'},{'\x96','\xdf'},{'\xfa','\xe2'},
+ {'\xa8','\x74'},{'\x96','\xe1'},{'\xcd','\xa9'},{'\xaa','\xc8'},{'\x00','\x00'},
+ {'\xac','\xf6'},{'\xd0','\x4c'},{'\xac','\xf4'},{'\xd0','\x4a'},{'\xac','\xf9'},
+ {'\xac','\xf5'},{'\xac','\xfa'},{'\xac','\xf8'},{'\xd0','\x4b'},{'\xac','\xf7'},
+ {'\xaf','\xbf'},{'\xaf','\xbe'},{'\xd3','\x5a'},{'\xaf','\xc7'},{'\xd3','\x53'},
+ {'\xd3','\x59'},{'\xaf','\xc3'},{'\xd3','\x52'},{'\xd3','\x58'},{'\xd3','\x56'},
+ {'\xaf','\xc2'},{'\xaf','\xc4'},{'\xd3','\x55'},{'\xaf','\xbd'},{'\xd3','\x54'},
+ {'\xaf','\xc8'},{'\xaf','\xc5'},{'\xaf','\xc9'},{'\xaf','\xc6'},{'\xd3','\x51'},
+ {'\xd3','\x50'},{'\xd3','\x57'},{'\xaf','\xc0'},{'\xaf','\xbc'},{'\xaf','\xc1'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x95','\xe2'},{'\x00','\x00'},{'\x86','\xfa'},
+ {'\xd6','\xf0'},{'\xd6','\xe9'},{'\x00','\x00'},{'\xb5','\xb5'},{'\xd6','\xe8'},
+ {'\x00','\x00'},{'\xb2','\xcf'},{'\xb2','\xd6'},{'\xb2','\xd3'},{'\xb2','\xd9'},
+ {'\xb2','\xd8'},{'\xb2','\xd4'},{'\x00','\x00'},{'\xd6','\xe2'},{'\xd6','\xe5'},
+ {'\x00','\x00'},{'\xd6','\xe4'},{'\xb2','\xd0'},{'\xd6','\xe6'},{'\xd6','\xef'},
+ {'\xb2','\xd1'},{'\xd6','\xe3'},{'\xd6','\xec'},{'\xd6','\xed'},{'\xb2','\xd2'},
+ {'\xd6','\xea'},{'\xb2','\xd7'},{'\xb2','\xcd'},{'\xb2','\xd5'},{'\xd6','\xe7'},
+ {'\xb2','\xcc'},{'\xd6','\xeb'},{'\xfa','\xe3'},{'\x00','\x00'},{'\xd6','\xee'},
+ {'\xfa','\xe4'},{'\x92','\xab'},{'\xfc','\xef'},{'\xda','\xfb'},{'\xda','\xf2'},
+ {'\xb5','\xb2'},{'\xda','\xf9'},{'\xda','\xf6'},{'\xda','\xee'},{'\xda','\xf7'},
+ {'\xb5','\xb4'},{'\xda','\xef'},{'\x00','\x00'},{'\xda','\xeb'},{'\x00','\x00'},
+ {'\xfc','\xf0'},{'\xb8','\x6c'},{'\xda','\xf4'},{'\xfe','\x60'},{'\xb5','\xb1'},
+ {'\xda','\xfa'},{'\x00','\x00'},{'\xb5','\xb8'},{'\xb5','\xba'},{'\xda','\xed'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xb5','\xb9'},{'\xda','\xf0'},{'\xb5','\xb3'},
+ {'\xda','\xf8'},{'\xda','\xf1'},{'\xda','\xf5'},{'\x00','\x00'},{'\xda','\xf3'},
+ {'\xb5','\xb6'},{'\xda','\xec'},{'\xb5','\xbb'},{'\xb2','\xce'},{'\xb5','\xb7'},
+ {'\xb5','\xbc'},{'\x00','\x00'},{'\x92','\x5b'},{'\x93','\x46'},{'\xfa','\xe5'},
+ {'\x00','\x00'},{'\xb8','\x68'},{'\xdf','\x5d'},{'\xdf','\x5f'},{'\xdf','\x61'},
+ {'\xdf','\x65'},{'\x00','\x00'},{'\xdf','\x5b'},{'\xdf','\x59'},{'\xb8','\x6a'},
+ {'\x00','\x00'},{'\xdf','\x60'},{'\xdf','\x64'},{'\xdf','\x5c'},{'\xdf','\x58'},
+ {'\x00','\x00'},{'\xdf','\x57'},{'\x95','\x68'},{'\x00','\x00'},{'\x96','\xe2'},
+ {'\xdf','\x62'},{'\xdf','\x5a'},{'\xdf','\x5e'},{'\xb8','\x6b'},{'\x00','\x00'},
+ {'\xb8','\x69'},{'\xdf','\x66'},{'\xb8','\x67'},{'\xdf','\x63'},{'\x9d','\xb9'},
+ {'\xe3','\x72'},{'\x96','\xe3'},{'\x00','\x00'},{'\x92','\xae'},{'\x93','\x64'},
+ {'\x94','\xc2'},{'\xba','\xee'},{'\xe3','\x6a'},{'\xbd','\x78'},{'\xe3','\x74'},
+ {'\xba','\xf1'},{'\xe3','\x78'},{'\xba','\xf7'},{'\xe3','\x65'},{'\x96','\xe4'},
+ {'\x00','\x00'},{'\xe3','\x75'},{'\xe3','\x62'},{'\x96','\xe5'},{'\xe3','\x77'},
+ {'\xe3','\x66'},{'\x95','\x56'},{'\xba','\xfe'},{'\xba','\xfb'},{'\xe3','\x76'},
+ {'\xe3','\x70'},{'\xba','\xed'},{'\xba','\xf5'},{'\xba','\xf4'},{'\x95','\x6a'},
+ {'\xba','\xf3'},{'\xba','\xf9'},{'\x00','\x00'},{'\xe3','\x63'},{'\xba','\xfa'},
+ {'\xe3','\x71'},{'\xba','\xf6'},{'\xba','\xec'},{'\xe3','\x73'},{'\xba','\xef'},
+ {'\xba','\xf0'},{'\xba','\xf8'},{'\xe3','\x68'},{'\xe3','\x67'},{'\xe3','\x64'},
+ {'\x00','\x00'},{'\xe3','\x6c'},{'\xe3','\x69'},{'\xe3','\x6d'},{'\xba','\xfd'},
+ {'\x00','\x00'},{'\xe3','\x79'},{'\xba','\xf2'},{'\xe3','\x6e'},{'\xe3','\x6f'},
+ {'\x96','\xe6'},{'\xe3','\x6b'},{'\x93','\x5c'},{'\x96','\xe7'},{'\x93','\xe7'},
+ {'\xba','\xfc'},{'\x96','\xe8'},{'\xfa','\xe6'},{'\xfa','\xe7'},{'\xfa','\xe8'},
+ {'\xe6','\xe7'},{'\xbd','\x70'},{'\xbd','\x79'},{'\xbd','\x75'},{'\xe6','\xe4'},
+ {'\x95','\xc3'},{'\xbd','\x72'},{'\xbd','\x76'},{'\xe6','\xf0'},{'\xbd','\x6c'},
+ {'\xe6','\xe8'},{'\x00','\x00'},{'\xbd','\x74'},{'\xfa','\xe9'},{'\x96','\xe9'},
+ {'\xe6','\xeb'},{'\xe6','\xe6'},{'\xbd','\x73'},{'\xbd','\x77'},{'\xe6','\xe5'},
+ {'\x00','\x00'},{'\xbd','\x71'},{'\x00','\x00'},{'\xe6','\xef'},{'\xbd','\x6e'},
+ {'\xe6','\xee'},{'\xe6','\xed'},{'\xbd','\x7a'},{'\xe5','\x72'},{'\xbd','\x6d'},
+ {'\xfc','\xf1'},{'\xe6','\xec'},{'\xe6','\xe3'},{'\x00','\x00'},{'\xbd','\x7b'},
+ {'\xe6','\xea'},{'\xbd','\x6f'},{'\x00','\x00'},{'\x96','\xea'},{'\x9f','\x7e'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x92','\x4d'},{'\x00','\x00'},{'\xe6','\xe9'},
+ {'\x92','\xed'},{'\x94','\xc3'},{'\x00','\x00'},{'\x9f','\xa1'},{'\xbf','\xa2'},
+ {'\xbf','\xa7'},{'\xbf','\x7e'},{'\xea','\xd8'},{'\xea','\xcf'},{'\xea','\xdb'},
+ {'\xea','\xd3'},{'\xea','\xd9'},{'\xbf','\xa8'},{'\xbf','\xa1'},{'\xea','\xcc'},
+ {'\xea','\xd2'},{'\xea','\xdc'},{'\xea','\xd5'},{'\xea','\xda'},{'\xea','\xce'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xea','\xd6'},{'\xbf','\xa3'},{'\xea','\xd4'},
+ {'\xbf','\xa6'},{'\xbf','\xa5'},{'\xea','\xd0'},{'\xea','\xd1'},{'\xea','\xcd'},
+ {'\xea','\xd7'},{'\xbf','\xa4'},{'\xea','\xde'},{'\xea','\xdd'},{'\x92','\xdf'},
+ {'\xfc','\xf2'},{'\x00','\x00'},{'\xed','\xda'},{'\xed','\xd6'},{'\xc1','\x5f'},
+ {'\x00','\x00'},{'\xed','\xd0'},{'\xc1','\x59'},{'\xc1','\x69'},{'\xed','\xdc'},
+ {'\xc1','\x61'},{'\xc1','\x5d'},{'\xed','\xd3'},{'\xc1','\x64'},{'\xc1','\x67'},
+ {'\xed','\xde'},{'\xc1','\x5c'},{'\xed','\xd5'},{'\xc1','\x65'},{'\xed','\xe0'},
+ {'\xed','\xdd'},{'\xed','\xd1'},{'\xc1','\x60'},{'\xc1','\x5a'},{'\xc1','\x68'},
+ {'\xed','\xd8'},{'\xc1','\x63'},{'\xed','\xd2'},{'\xc1','\x5e'},{'\xed','\xdf'},
+ {'\xc1','\x62'},{'\xc1','\x5b'},{'\xed','\xd9'},{'\xc1','\x66'},{'\xed','\xd7'},
+ {'\x93','\x4f'},{'\x82','\x5a'},{'\xed','\xdb'},{'\xfa','\xea'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xf0','\x6e'},{'\xf0','\x74'},{'\xc2','\xb9'},{'\xf0','\x77'},
+ {'\xc2','\xb4'},{'\xc2','\xb5'},{'\xf0','\x6f'},{'\xf0','\x76'},{'\xf0','\x71'},
+ {'\xc2','\xba'},{'\xc2','\xb7'},{'\x9f','\xa2'},{'\xf0','\x6d'},{'\xfa','\xeb'},
+ {'\xc2','\xb6'},{'\xf0','\x73'},{'\xf0','\x75'},{'\xc2','\xb8'},{'\xf0','\x72'},
+ {'\xf0','\x70'},{'\x00','\x00'},{'\x9f','\xa3'},{'\x8a','\x50'},{'\x94','\xc4'},
+ {'\xf2','\xb8'},{'\xc3','\xb7'},{'\xc3','\xb8'},{'\xc3','\xb4'},{'\x9f','\xa4'},
+ {'\xc3','\xb5'},{'\x8c','\xe8'},{'\xf2','\xb4'},{'\xf2','\xb2'},{'\x00','\x00'},
+ {'\xf2','\xb6'},{'\xc3','\xba'},{'\xf2','\xb7'},{'\xf2','\xb0'},{'\xf2','\xaf'},
+ {'\xf2','\xb3'},{'\xf2','\xb1'},{'\xc3','\xb6'},{'\xf2','\xb5'},{'\xf4','\xac'},
+ {'\xc4','\x7e'},{'\xc4','\x7d'},{'\xf4','\xad'},{'\xfa','\xec'},{'\xf4','\xaf'},
+ {'\xf4','\xae'},{'\xc4','\xa1'},{'\x94','\xc5'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xf5','\xeb'},{'\xf5','\xe8'},{'\xf5','\xe9'},{'\xfa','\xed'},{'\xf5','\xe7'},
+ {'\xf5','\xea'},{'\xc4','\xf2'},{'\xf5','\xec'},{'\xfa','\xee'},{'\xc4','\xf1'},
+ {'\x94','\xc6'},{'\xf7','\x42'},{'\xfa','\xef'},{'\xc5','\xd5'},{'\xc5','\xd7'},
+ {'\xf7','\xee'},{'\xc5','\xd6'},{'\xf8','\xb9'},{'\xf9','\x40'},{'\xf9','\x42'},
+ {'\xf8','\xfe'},{'\xf9','\x41'},{'\xc6','\x6c'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x9c','\xeb'},{'\x83','\x5f'},{'\x83','\x76'},{'\x83','\x71'},{'\x83','\x70'},
+ {'\x8a','\x4e'},{'\x83','\x74'},{'\x83','\x75'},{'\x83','\xcb'},{'\x8d','\xbe'},
+ {'\x90','\x44'},{'\x83','\x72'},{'\x83','\x73'},{'\x87','\xfe'},{'\x83','\xcc'},
+ {'\x00','\x00'},{'\x83','\xc8'},{'\x83','\xca'},{'\x83','\xc6'},{'\x86','\xfc'},
+ {'\x83','\xcd'},{'\x00','\x00'},{'\x8a','\x4c'},{'\x87','\x41'},{'\x83','\xcf'},
+ {'\x83','\xce'},{'\x83','\xc7'},{'\x83','\xc5'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x83','\xc9'},{'\x8d','\xc5'},{'\x88','\x45'},{'\x8d','\xd3'},{'\x84','\x71'},
+ {'\x84','\x72'},{'\x87','\xfd'},{'\x84','\x6f'},{'\x84','\x6e'},{'\x84','\x6d'},
+ {'\x8a','\xeb'},{'\x84','\x70'},{'\x89','\x53'},{'\x84','\x68'},{'\x84','\x6b'},
+ {'\x84','\x6c'},{'\x84','\x6a'},{'\x8b','\xb1'},{'\x85','\xee'},{'\x8d','\xd4'},
+ {'\x85','\xf0'},{'\x85','\x44'},{'\x85','\x43'},{'\xfa','\xf0'},{'\x8a','\xed'},
+ {'\x85','\x4a'},{'\x8d','\xe4'},{'\x8b','\xb3'},{'\x85','\x48'},{'\x85','\x49'},
+ {'\x85','\x4b'},{'\x85','\x47'},{'\x85','\x45'},{'\x85','\x42'},{'\x84','\x69'},
+ {'\x8e','\x4a'},{'\x8e','\x4b'},{'\x85','\xef'},{'\x8a','\xef'},{'\x00','\x00'},
+ {'\x85','\xf1'},{'\x85','\xf2'},{'\x8c','\x49'},{'\x8e','\x49'},{'\x8a','\x45'},
+ {'\x87','\x43'},{'\x86','\xf8'},{'\x00','\x00'},{'\x8c','\xa2'},{'\x86','\xfd'},
+ {'\x8e','\x7b'},{'\x86','\xf7'},{'\xfa','\xf1'},{'\x8e','\x7a'},{'\x8b','\xb2'},
+ {'\x87','\x42'},{'\x87','\x40'},{'\x87','\x45'},{'\x8a','\x49'},{'\x86','\xfe'},
+ {'\x00','\x00'},{'\x8e','\x7c'},{'\x8e','\x79'},{'\x86','\xf6'},{'\x86','\xf4'},
+ {'\x86','\xf5'},{'\x86','\xf9'},{'\x86','\xfb'},{'\x87','\x44'},{'\x88','\x49'},
+ {'\x8e','\xc2'},{'\x88','\x40'},{'\x88','\x41'},{'\x8d','\xa3'},{'\x88','\x4b'},
+ {'\x88','\x4a'},{'\x88','\x42'},{'\x00','\x00'},{'\x8f','\x79'},{'\x8e','\xc4'},
+ {'\x88','\x48'},{'\x88','\x46'},{'\x8e','\xc5'},{'\x00','\x00'},{'\x8e','\xc6'},
+ {'\xfa','\xf2'},{'\x88','\x47'},{'\x87','\xfc'},{'\x8a','\x47'},{'\x88','\x43'},
+ {'\x8e','\xc3'},{'\x88','\x44'},{'\x89','\x52'},{'\x89','\x4e'},{'\x8e','\xf0'},
+ {'\x89','\x51'},{'\x8a','\x4a'},{'\x00','\x00'},{'\x89','\x50'},{'\x8c','\xa1'},
+ {'\x8f','\x5d'},{'\x89','\x4b'},{'\x89','\x4c'},{'\x8c','\x48'},{'\x8a','\x4f'},
+ {'\x8a','\x51'},{'\x8a','\x48'},{'\x8c','\xfb'},{'\x8a','\x44'},{'\x8a','\x46'},
+ {'\x8a','\x4d'},{'\x90','\x45'},{'\x8a','\xee'},{'\x8a','\xec'},{'\x8a','\xf0'},
+ {'\xfa','\xf3'},{'\x8f','\xde'},{'\x8f','\xbf'},{'\x8f','\xc0'},{'\x8b','\xb5'},
+ {'\x90','\x7c'},{'\xa6','\xce'},{'\x9f','\xa5'},{'\xac','\xfb'},{'\xd2','\x6f'},
+ {'\xaf','\xca'},{'\x00','\x00'},{'\x00','\x00'},{'\xb2','\xda'},{'\xda','\xfc'},
+ {'\xda','\xfd'},{'\x9f','\xa6'},{'\x9f','\xa7'},{'\x8c','\x4a'},{'\xea','\xdf'},
+ {'\xc1','\x6a'},{'\xed','\xe1'},{'\x00','\x00'},{'\x95','\x74'},{'\xc2','\xbb'},
+ {'\x9f','\xa8'},{'\xf2','\xba'},{'\xf2','\xb9'},{'\xc4','\xa2'},{'\xf5','\xed'},
+ {'\xfb','\xaa'},{'\xf7','\x43'},{'\xc5','\xf8'},{'\xca','\x49'},{'\x9f','\xa9'},
+ {'\x9d','\x75'},{'\xaa','\xc9'},{'\xa8','\x75'},{'\x00','\x00'},{'\x8b','\xb4'},
+ {'\xd0','\x4d'},{'\x00','\x00'},{'\x87','\x46'},{'\xd3','\x60'},{'\xd3','\x5b'},
+ {'\xd3','\x5f'},{'\xd3','\x5d'},{'\xaf','\xcb'},{'\xd3','\x5e'},{'\xd3','\x5c'},
+ {'\x88','\x4d'},{'\xd6','\xf1'},{'\x00','\x00'},{'\xda','\xfe'},{'\xdb','\x40'},
+ {'\xdf','\x69'},{'\xdf','\x6a'},{'\xb8','\x6e'},{'\xb8','\x6f'},{'\xdf','\x68'},
+ {'\xdf','\x6b'},{'\xdf','\x67'},{'\xb8','\x6d'},{'\x00','\x00'},{'\xbb','\x40'},
+ {'\xfa','\xf4'},{'\xb8','\x70'},{'\xe3','\x7a'},{'\x8f','\xc1'},{'\xbd','\x7c'},
+ {'\xe6','\xf1'},{'\xbd','\x7d'},{'\x95','\x64'},{'\xbf','\xa9'},{'\xea','\xe2'},
+ {'\xea','\xe0'},{'\xea','\xe1'},{'\xed','\xe4'},{'\xed','\xe3'},{'\xed','\xe2'},
+ {'\x00','\x00'},{'\x8d','\x56'},{'\xfa','\xf5'},{'\xf2','\xbb'},{'\x00','\x00'},
+ {'\xc3','\xb9'},{'\xf2','\xbc'},{'\xf7','\x44'},{'\xc5','\xf9'},{'\xf8','\xba'},
+ {'\xa6','\xcf'},{'\xaa','\xcb'},{'\xaa','\xca'},{'\xd0','\x4f'},{'\xac','\xfc'},
+ {'\x9f','\xaa'},{'\x00','\x00'},{'\xd0','\x4e'},{'\xd3','\x62'},{'\x9f','\xab'},
+ {'\xaf','\xcc'},{'\xd6','\xf2'},{'\xd3','\x61'},{'\x95','\xe0'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xb2','\xdc'},{'\xd6','\xf5'},{'\xd6','\xf3'},{'\xd6','\xf4'},
+ {'\xb2','\xdb'},{'\x8e','\x4c'},{'\xdb','\x42'},{'\xdb','\x43'},{'\xdb','\x41'},
+ {'\x95','\x55'},{'\xb8','\x73'},{'\xdf','\x6d'},{'\xdf','\x6c'},{'\xdf','\x6e'},
+ {'\xb8','\x72'},{'\xb8','\x71'},{'\x00','\x00'},{'\x00','\x00'},{'\xe6','\xf2'},
+ {'\xe6','\xf4'},{'\xfa','\xf6'},{'\xbd','\x7e'},{'\xe6','\xf3'},{'\xea','\xe3'},
+ {'\xbf','\xaa'},{'\xf0','\x79'},{'\x9f','\xac'},{'\xf0','\x78'},{'\xc3','\xbb'},
+ {'\xf2','\xbd'},{'\xc3','\xbd'},{'\xc3','\xbc'},{'\xf4','\xb0'},{'\xf5','\xee'},
+ {'\xc4','\xf3'},{'\xa6','\xd0'},{'\xd0','\x50'},{'\xac','\xfd'},{'\xd3','\x65'},
+ {'\xaf','\xce'},{'\xd3','\x64'},{'\xd3','\x63'},{'\x00','\x00'},{'\xaf','\xcd'},
+ {'\xfa','\xf7'},{'\xd6','\xfb'},{'\x00','\x00'},{'\xd6','\xfd'},{'\xd6','\xf6'},
+ {'\xd6','\xf7'},{'\xb2','\xdd'},{'\xd6','\xf8'},{'\xb2','\xde'},{'\xd6','\xfc'},
+ {'\xd6','\xf9'},{'\xd6','\xfa'},{'\xb2','\xdf'},{'\x00','\x00'},{'\xb5','\xbe'},
+ {'\xb5','\xbf'},{'\x00','\x00'},{'\xdb','\x44'},{'\x8a','\xf1'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xdf','\x6f'},{'\xdf','\x70'},{'\x9f','\xad'},{'\xe3','\x7e'},
+ {'\xbb','\x43'},{'\xbb','\x41'},{'\xbb','\x42'},{'\xe3','\x7b'},{'\xe3','\x7c'},
+ {'\x00','\x00'},{'\xe3','\x7d'},{'\xe6','\xf9'},{'\x9f','\xae'},{'\xe6','\xfa'},
+ {'\xbd','\xa1'},{'\xe6','\xf7'},{'\xe6','\xf6'},{'\xe6','\xf8'},{'\xe6','\xf5'},
+ {'\xbf','\xad'},{'\xea','\xe4'},{'\xbf','\xab'},{'\xbf','\xac'},{'\xed','\xe6'},
+ {'\xc1','\x6b'},{'\xed','\xe5'},{'\xef','\xa8'},{'\x00','\x00'},{'\xf0','\x7a'},
+ {'\xf0','\x7b'},{'\xc2','\xbc'},{'\x9f','\xaf'},{'\xc2','\xbd'},{'\xc1','\x6c'},
+ {'\xf2','\xbe'},{'\xf2','\xbf'},{'\xf4','\xb1'},{'\xc4','\xa3'},{'\xa6','\xd1'},
+ {'\x9f','\xb0'},{'\xa6','\xd2'},{'\xac','\xfe'},{'\xaa','\xcc'},{'\xaf','\xcf'},
+ {'\xd0','\x51'},{'\x9f','\xb1'},{'\x00','\x00'},{'\x00','\x00'},{'\xb5','\xc0'},
+ {'\xa6','\xd3'},{'\xad','\x41'},{'\xd0','\x52'},{'\xd0','\x53'},{'\xad','\x40'},
+ {'\xad','\x42'},{'\xa6','\xd4'},{'\x00','\x00'},{'\xd0','\x54'},{'\xaf','\xd1'},
+ {'\xd3','\x66'},{'\xaf','\xd3'},{'\xaf','\xd0'},{'\xaf','\xd2'},{'\x00','\x00'},
+ {'\xd7','\x41'},{'\xb2','\xe0'},{'\xfc','\xf6'},{'\xd7','\x40'},{'\xd6','\xfe'},
+ {'\xfa','\xf8'},{'\xdf','\x71'},{'\xfa','\xf9'},{'\x00','\x00'},{'\xe3','\xa1'},
+ {'\xfa','\xfa'},{'\xbd','\xa2'},{'\x8f','\x5e'},{'\xbf','\xae'},{'\xea','\xe6'},
+ {'\xea','\xe5'},{'\x00','\x00'},{'\xed','\xe7'},{'\x00','\x00'},{'\x9f','\xb2'},
+ {'\x9f','\xb3'},{'\xf5','\xef'},{'\xfa','\xfb'},{'\x00','\x00'},{'\xa6','\xd5'},
+ {'\xcb','\x73'},{'\xcd','\xaa'},{'\xad','\x43'},{'\xd0','\x55'},{'\x8a','\x55'},
+ {'\xd3','\x68'},{'\x00','\x00'},{'\x95','\x5c'},{'\x9f','\xb4'},{'\xaf','\xd4'},
+ {'\xd3','\x67'},{'\xaf','\xd5'},{'\x00','\x00'},{'\x00','\x00'},{'\x8a','\xf3'},
+ {'\xd7','\x43'},{'\x00','\x00'},{'\x00','\x00'},{'\xb2','\xe2'},{'\xd7','\x42'},
+ {'\xd7','\x44'},{'\x00','\x00'},{'\xb2','\xe1'},{'\x8c','\xd9'},{'\x8a','\xf2'},
+ {'\x8f','\xdf'},{'\x00','\x00'},{'\xdb','\x46'},{'\xdb','\x47'},{'\xdb','\x45'},
+ {'\xb5','\xc1'},{'\x00','\x00'},{'\x8a','\x54'},{'\x00','\x00'},{'\xb8','\x74'},
+ {'\x00','\x00'},{'\xb8','\x75'},{'\x00','\x00'},{'\xbb','\x45'},{'\xfc','\xfa'},
+ {'\xe3','\xa3'},{'\xe3','\xa2'},{'\xbb','\x44'},{'\xfa','\xfc'},{'\x00','\x00'},
+ {'\x82','\x6b'},{'\xfc','\xf7'},{'\xfc','\xf8'},{'\xe6','\xfb'},{'\x00','\x00'},
+ {'\xfc','\xf9'},{'\xe6','\xfc'},{'\xfa','\xfd'},{'\x8f','\x7a'},{'\x8a','\x53'},
+ {'\x00','\x00'},{'\xea','\xe7'},{'\x00','\x00'},{'\x00','\x00'},{'\xc1','\x70'},
+ {'\xc1','\x6f'},{'\xc1','\x6d'},{'\xc1','\x6e'},{'\xc1','\x71'},{'\x93','\x77'},
+ {'\xf0','\x7c'},{'\xc2','\xbf'},{'\xc2','\xbe'},{'\xf2','\xc0'},{'\xf4','\xb2'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xc5','\xa5'},{'\xc5','\xa4'},
+ {'\xa6','\xd6'},{'\x91','\xd5'},{'\x00','\x00'},{'\xd1','\xfb'},{'\x85','\x4c'},
+ {'\xb8','\x77'},{'\xb5','\xc2'},{'\xb8','\x76'},{'\xbb','\x46'},{'\x00','\x00'},
+ {'\xa6','\xd7'},{'\xc9','\xa9'},{'\xa6','\xd8'},{'\xa6','\xd9'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xcd','\xab'},{'\xcb','\x76'},{'\x00','\x00'},{'\xcb','\x77'},
+ {'\xa8','\x77'},{'\x00','\x00'},{'\xcb','\x74'},{'\xa8','\x76'},{'\x00','\x00'},
+ {'\xa8','\x79'},{'\xcb','\x75'},{'\xa8','\x7b'},{'\xa8','\x7a'},{'\xcb','\x78'},
+ {'\xa8','\x78'},{'\x00','\x00'},{'\x96','\xaf'},{'\x85','\xf6'},{'\xaa','\xd1'},
+ {'\xaa','\xcf'},{'\xcd','\xad'},{'\x88','\x4f'},{'\xaa','\xce'},{'\xfc','\xfb'},
+ {'\x9f','\xb5'},{'\x00','\x00'},{'\xaa','\xd3'},{'\xaa','\xd5'},{'\xaa','\xd2'},
+ {'\xfa','\xfe'},{'\xcd','\xb0'},{'\xcd','\xac'},{'\xaa','\xd6'},{'\x00','\x00'},
+ {'\xaa','\xd0'},{'\xa8','\x7c'},{'\x00','\x00'},{'\xaa','\xd4'},{'\xcd','\xaf'},
+ {'\xfb','\x4d'},{'\xfb','\x40'},{'\xcd','\xae'},{'\x00','\x00'},{'\xaa','\xcd'},
+ {'\x00','\x00'},{'\x96','\xcb'},{'\x96','\xa6'},{'\x85','\x4d'},{'\x85','\xf8'},
+ {'\x85','\x4e'},{'\x83','\xd0'},{'\xd0','\x5b'},{'\xad','\x47'},{'\xad','\x48'},
+ {'\xd0','\x5d'},{'\x8a','\x57'},{'\xd0','\x57'},{'\xd0','\x5a'},{'\xd0','\x63'},
+ {'\xd0','\x61'},{'\x00','\x00'},{'\xad','\x49'},{'\xd0','\x67'},{'\xad','\x4c'},
+ {'\xd0','\x64'},{'\xd0','\x5c'},{'\xd0','\x59'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xdb','\x49'},{'\xd0','\x62'},{'\xad','\x44'},{'\xd0','\x65'},{'\xd0','\x56'},
+ {'\xd0','\x5f'},{'\xad','\x46'},{'\xad','\x4b'},{'\xd0','\x60'},{'\xad','\x4f'},
+ {'\xad','\x4d'},{'\x00','\x00'},{'\xd0','\x58'},{'\xad','\x4a'},{'\x00','\x00'},
+ {'\xd0','\x5e'},{'\xad','\x4e'},{'\xad','\x45'},{'\xd0','\x66'},{'\x8b','\xf8'},
+ {'\xfd','\xfb'},{'\xfd','\xfc'},{'\x8c','\x4b'},{'\x8d','\xd5'},{'\xfd','\xfd'},
+ {'\xaf','\xda'},{'\x00','\x00'},{'\xaf','\xe3'},{'\xaf','\xd8'},{'\xaf','\xd6'},
+ {'\xd3','\x6a'},{'\xaf','\xde'},{'\xaf','\xdb'},{'\xd3','\x6c'},{'\x88','\x4e'},
+ {'\x00','\x00'},{'\xaf','\xdd'},{'\xd3','\x6b'},{'\xd3','\x69'},{'\xd3','\x6e'},
+ {'\xaf','\xe2'},{'\xaf','\xe0'},{'\xdb','\x48'},{'\x00','\x00'},{'\xd3','\x6f'},
+ {'\xd3','\x6d'},{'\xaf','\xd7'},{'\xfc','\xfc'},{'\x00','\x00'},{'\xaf','\xd9'},
+ {'\xaf','\xdc'},{'\xfe','\x48'},{'\xaf','\xdf'},{'\x83','\xd1'},{'\xaf','\xe1'},
+ {'\x00','\x00'},{'\x9f','\xb6'},{'\x8a','\x59'},{'\xfd','\xfe'},{'\x8c','\xda'},
+ {'\x8a','\xf4'},{'\x85','\xf9'},{'\xfe','\xee'},{'\x8a','\x56'},{'\x90','\x7d'},
+ {'\xd7','\x4e'},{'\xb2','\xe4'},{'\x95','\xa8'},{'\xd7','\x45'},{'\xd7','\x47'},
+ {'\x85','\xf7'},{'\xd7','\x48'},{'\x00','\x00'},{'\xd7','\x50'},{'\xd7','\x4c'},
+ {'\xd7','\x4a'},{'\x00','\x00'},{'\xd7','\x4d'},{'\xd7','\x51'},{'\xb2','\xe5'},
+ {'\xb2','\xe9'},{'\xd7','\x46'},{'\x00','\x00'},{'\xd7','\x4f'},{'\x00','\x00'},
+ {'\xb2','\xe7'},{'\x9f','\xb7'},{'\xb2','\xe6'},{'\xd7','\x4b'},{'\xd7','\x49'},
+ {'\x00','\x00'},{'\xb2','\xe3'},{'\xb2','\xe8'},{'\xfe','\xef'},{'\x96','\xa5'},
+ {'\x93','\xb0'},{'\x9f','\xb8'},{'\x00','\x00'},{'\xfe','\xf0'},{'\xa0','\x42'},
+ {'\x8a','\x58'},{'\xb5','\xc8'},{'\xdb','\x51'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xdb','\x4f'},{'\xb5','\xca'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x9f','\xb9'},{'\xdb','\x4a'},{'\xdf','\xa1'},{'\x00','\x00'},{'\xb5','\xc9'},
+ {'\xdb','\x4e'},{'\x96','\xab'},{'\x00','\x00'},{'\xdb','\x4b'},{'\xb5','\xc5'},
+ {'\xb5','\xcb'},{'\xdb','\x50'},{'\xb5','\xc7'},{'\xdb','\x4d'},{'\xbb','\x47'},
+ {'\xb5','\xc6'},{'\xdb','\x4c'},{'\xb5','\xcc'},{'\xb5','\xc4'},{'\xb5','\xc3'},
+ {'\x9f','\xba'},{'\x00','\x00'},{'\x00','\x00'},{'\x96','\xae'},{'\x96','\xa2'},
+ {'\xdf','\x77'},{'\xdf','\x75'},{'\x00','\x00'},{'\xdf','\x7b'},{'\xfe','\xf1'},
+ {'\xdf','\x73'},{'\xdf','\xa2'},{'\xdf','\x78'},{'\x00','\x00'},{'\xdf','\x72'},
+ {'\xb8','\x7b'},{'\xb8','\xa3'},{'\xdf','\x7d'},{'\x00','\x00'},{'\xdf','\x76'},
+ {'\x00','\x00'},{'\xb8','\x7e'},{'\x9d','\xd0'},{'\xfe','\xf2'},{'\xb8','\x7c'},
+ {'\xdf','\x7e'},{'\xb8','\x79'},{'\xb8','\x78'},{'\xdf','\x79'},{'\xb8','\x7d'},
+ {'\xb5','\xcd'},{'\x00','\x00'},{'\xdf','\x7c'},{'\xdf','\x74'},{'\xb8','\x7a'},
+ {'\xb8','\xa1'},{'\xb8','\xa2'},{'\x89','\x54'},{'\x89','\xae'},{'\xfe','\xf3'},
+ {'\x8c','\x65'},{'\xbb','\x4c'},{'\xbb','\x48'},{'\x00','\x00'},{'\xbb','\x4d'},
+ {'\xe3','\xa6'},{'\x9f','\xbb'},{'\x00','\x00'},{'\xe3','\xa5'},{'\xe3','\xa7'},
+ {'\xbb','\x4a'},{'\xe3','\xa4'},{'\xbb','\x4b'},{'\xe3','\xaa'},{'\xe3','\xa9'},
+ {'\xe3','\xa8'},{'\x00','\x00'},{'\xbb','\x49'},{'\x00','\x00'},{'\x8a','\xf5'},
+ {'\x00','\x00'},{'\xfe','\xf4'},{'\x00','\x00'},{'\xe7','\x41'},{'\x00','\x00'},
+ {'\xe7','\x44'},{'\xbd','\xa8'},{'\xe7','\x43'},{'\xbd','\xa7'},{'\xbd','\xa3'},
+ {'\xbd','\xa4'},{'\xbd','\xa5'},{'\xe7','\x40'},{'\xe6','\xfe'},{'\xbd','\xa6'},
+ {'\x00','\x00'},{'\xe7','\x42'},{'\xe6','\xfd'},{'\x94','\xc7'},{'\x9f','\xbc'},
+ {'\xea','\xe9'},{'\xea','\xf3'},{'\xbf','\xb1'},{'\xbf','\xb0'},{'\xfe','\xf5'},
+ {'\xea','\xed'},{'\xea','\xef'},{'\x00','\x00'},{'\xea','\xea'},{'\x00','\x00'},
+ {'\xea','\xee'},{'\xea','\xe8'},{'\xea','\xf1'},{'\xbf','\xaf'},{'\xea','\xf0'},
+ {'\xea','\xec'},{'\xfb','\x6e'},{'\xea','\xf2'},{'\xfe','\xf6'},{'\xea','\xeb'},
+ {'\xc1','\x74'},{'\xed','\xe8'},{'\xed','\xee'},{'\xc1','\x78'},{'\xc1','\x7a'},
+ {'\xc1','\x77'},{'\xc1','\x76'},{'\xfe','\xf7'},{'\xc1','\x75'},{'\xc1','\x73'},
+ {'\xed','\xe9'},{'\xed','\xec'},{'\xc1','\x72'},{'\xed','\xed'},{'\xfc','\xfe'},
+ {'\xc1','\x79'},{'\xed','\xeb'},{'\x00','\x00'},{'\xed','\xea'},{'\xc2','\xc0'},
+ {'\x00','\x00'},{'\xc2','\xc1'},{'\xf0','\xa1'},{'\xf0','\x7d'},{'\xf0','\x7e'},
+ {'\x93','\x62'},{'\x00','\x00'},{'\xf2','\xc2'},{'\x00','\x00'},{'\xf2','\xc1'},
+ {'\xc3','\xbe'},{'\xf4','\xb4'},{'\xc4','\xa4'},{'\xf4','\xb3'},{'\x00','\x00'},
+ {'\xf5','\xf0'},{'\xf7','\x45'},{'\xc5','\xa6'},{'\xf9','\x43'},{'\xf9','\x44'},
+ {'\xc5','\xd8'},{'\xa6','\xda'},{'\x9f','\xbd'},{'\xaa','\xd7'},{'\xdb','\x52'},
+ {'\xbb','\x4e'},{'\xc1','\x7b'},{'\xed','\xef'},{'\xa6','\xdb'},{'\x00','\x00'},
+ {'\xaf','\xe5'},{'\xaf','\xe4'},{'\xdb','\x53'},{'\x95','\xd3'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xea','\xf4'},{'\xa6','\xdc'},{'\xad','\x50'},{'\x00','\x00'},
+ {'\xfd','\x42'},{'\xdb','\x54'},{'\xdb','\x55'},{'\xdb','\x56'},{'\xbb','\x4f'},
+ {'\xbf','\xb2'},{'\xa6','\xdd'},{'\x00','\x00'},{'\xaa','\xd8'},{'\xd0','\x68'},
+ {'\xaf','\xe6'},{'\xd3','\x70'},{'\xb2','\xea'},{'\x00','\x00'},{'\xdb','\x57'},
+ {'\xb8','\xa4'},{'\x8a','\x77'},{'\xbb','\x50'},{'\xbf','\xb3'},{'\xc1','\x7c'},
+ {'\xc2','\xc2'},{'\xf4','\xb5'},{'\xa6','\xde'},{'\xaa','\xd9'},{'\x92','\xd6'},
+ {'\x00','\x00'},{'\xaf','\xe7'},{'\xd7','\x52'},{'\xb5','\xce'},{'\x00','\x00'},
+ {'\xbb','\x51'},{'\xe3','\xab'},{'\xe7','\x45'},{'\x93','\xc6'},{'\x95','\xec'},
+ {'\x00','\x00'},{'\xfd','\x43'},{'\xa6','\xdf'},{'\xb5','\xcf'},{'\xdf','\xa3'},
+ {'\xbb','\x52'},{'\xa6','\xe0'},{'\xcd','\xb1'},{'\xd0','\x69'},{'\xad','\x51'},
+ {'\x8f','\xc2'},{'\x00','\x00'},{'\xd3','\x72'},{'\xfb','\x53'},{'\x00','\x00'},
+ {'\xaf','\xea'},{'\xfe','\xf8'},{'\xaf','\xe8'},{'\xaf','\xe9'},{'\xaf','\xeb'},
+ {'\xfe','\xf9'},{'\xfe','\xfa'},{'\xd3','\x71'},{'\x8c','\x4c'},{'\x89','\x56'},
+ {'\xd7','\x57'},{'\xd7','\x54'},{'\xd7','\x56'},{'\xb2','\xeb'},{'\xb2','\xed'},
+ {'\xb2','\xec'},{'\xd7','\x53'},{'\xb2','\xee'},{'\xd7','\x55'},{'\x90','\x5b'},
+ {'\xdb','\x58'},{'\xdb','\x59'},{'\xfe','\xfb'},{'\xdb','\x5a'},{'\xdf','\xa6'},
+ {'\x00','\x00'},{'\xdf','\xa7'},{'\x00','\x00'},{'\xdf','\xa5'},{'\xdf','\xa8'},
+ {'\x00','\x00'},{'\xb8','\xa5'},{'\x00','\x00'},{'\xdf','\xa4'},{'\x00','\x00'},
+ {'\xbb','\x53'},{'\x00','\x00'},{'\x00','\x00'},{'\xe7','\x4a'},{'\xe7','\x46'},
+ {'\xe7','\x49'},{'\xe7','\x4b'},{'\xe7','\x48'},{'\xe7','\x47'},{'\x9f','\xbe'},
+ {'\xea','\xf5'},{'\xea','\xf6'},{'\xea','\xf7'},{'\xbf','\xb4'},{'\xbf','\xb5'},
+ {'\xed','\xf1'},{'\xed','\xf0'},{'\xed','\xf2'},{'\x94','\xc8'},{'\xf0','\xa3'},
+ {'\xf0','\xa2'},{'\x00','\x00'},{'\xf2','\xc4'},{'\xfe','\xfc'},{'\xf2','\xc5'},
+ {'\xf2','\xc3'},{'\x9f','\xbf'},{'\xc4','\xa5'},{'\x00','\x00'},{'\xf4','\xb6'},
+ {'\xf4','\xb7'},{'\xfe','\xfd'},{'\xf7','\x46'},{'\xf7','\xef'},{'\xf8','\xbb'},
+ {'\xa6','\xe1'},{'\xa8','\x7d'},{'\x8a','\x5c'},{'\xc1','\x7d'},{'\xa6','\xe2'},
+ {'\x8d','\x5b'},{'\xd7','\x58'},{'\xdb','\x5b'},{'\x82','\x45'},{'\xc6','\x41'},
+ {'\xca','\x4a'},{'\x9c','\xd2'},{'\x8b','\xb7'},{'\x9f','\xc0'},{'\xca','\x4b'},
+ {'\xca','\x4d'},{'\xa6','\xe3'},{'\xca','\x4e'},{'\xca','\x4c'},{'\x00','\x00'},
+ {'\x85','\xeb'},{'\xcb','\xa2'},{'\xcb','\xa3'},{'\xcb','\x7b'},{'\x00','\x00'},
+ {'\x9f','\xc1'},{'\xfe','\xfe'},{'\x00','\x00'},{'\xcb','\xa1'},{'\xa8','\xa1'},
+ {'\x00','\x00'},{'\xa8','\xa2'},{'\xcb','\x7c'},{'\xcb','\x7a'},{'\xcb','\x79'},
+ {'\xcb','\x7d'},{'\xa8','\x7e'},{'\xcb','\x7e'},{'\xd0','\x6a'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x8e','\xf6'},{'\xcd','\xb6'},{'\xaa','\xdc'},{'\xcd','\xb5'},
+ {'\xcd','\xb7'},{'\x89','\x59'},{'\xaa','\xdb'},{'\xcd','\xbc'},{'\xaa','\xdf'},
+ {'\xcd','\xb2'},{'\xcd','\xc0'},{'\xcd','\xc6'},{'\xaa','\xe6'},{'\xcd','\xc3'},
+ {'\xaa','\xe3'},{'\x8c','\x4f'},{'\xcd','\xb9'},{'\xcd','\xbf'},{'\xcd','\xc1'},
+ {'\xfb','\xa5'},{'\xcd','\xb4'},{'\xaa','\xe2'},{'\xaa','\xdd'},{'\xcd','\xba'},
+ {'\xaa','\xe4'},{'\xaa','\xe7'},{'\xaa','\xe1'},{'\x00','\x00'},{'\xaa','\xda'},
+ {'\xcd','\xbe'},{'\xcd','\xb8'},{'\xcd','\xc5'},{'\xaa','\xe9'},{'\xaa','\xe5'},
+ {'\xaa','\xe0'},{'\xcd','\xbd'},{'\xaf','\xec'},{'\xcd','\xbb'},{'\xaa','\xde'},
+ {'\xaa','\xe8'},{'\x9f','\xc2'},{'\xcd','\xb3'},{'\x8e','\xca'},{'\xcd','\xc2'},
+ {'\xcd','\xc4'},{'\x96','\xbe'},{'\x91','\x40'},{'\x00','\x00'},{'\x85','\xfb'},
+ {'\x8f','\xe1'},{'\x00','\x00'},{'\x91','\x41'},{'\x84','\x79'},{'\x85','\x51'},
+ {'\x87','\x4b'},{'\x83','\x78'},{'\x84','\xf7'},{'\xfd','\x5f'},{'\xad','\x62'},
+ {'\xad','\x5c'},{'\xad','\x64'},{'\xad','\x61'},{'\xd0','\x71'},{'\xd0','\x74'},
+ {'\xad','\x5d'},{'\x91','\x42'},{'\xd0','\x6b'},{'\x00','\x00'},{'\xad','\x56'},
+ {'\xad','\x60'},{'\x00','\x00'},{'\xad','\x63'},{'\xad','\x65'},{'\xd0','\xa2'},
+ {'\xd0','\x77'},{'\x9f','\xc3'},{'\xad','\x55'},{'\xd0','\xa1'},{'\xad','\x59'},
+ {'\xad','\x57'},{'\xad','\x52'},{'\xd0','\x6f'},{'\x00','\x00'},{'\xd0','\x7e'},
+ {'\xd0','\x73'},{'\xd0','\x76'},{'\xd0','\xa5'},{'\x9f','\xc4'},{'\xad','\x66'},
+ {'\xd0','\x7d'},{'\xad','\x5e'},{'\xd0','\x78'},{'\xd0','\xa4'},{'\xd0','\x75'},
+ {'\xd0','\x79'},{'\xd0','\x7c'},{'\x96','\xa3'},{'\x9f','\xc5'},{'\xd0','\x6d'},
+ {'\xd0','\xa3'},{'\xd0','\x7b'},{'\x9f','\xc6'},{'\xfd','\x5d'},{'\xd0','\x6c'},
+ {'\x9f','\xc7'},{'\xd0','\x70'},{'\xad','\x5f'},{'\xad','\x5a'},{'\xad','\x53'},
+ {'\xad','\x58'},{'\xad','\x54'},{'\xad','\x67'},{'\xd0','\x6e'},{'\xd3','\xa5'},
+ {'\xad','\x5b'},{'\x00','\x00'},{'\x9f','\xc8'},{'\xd0','\x7a'},{'\xce','\x41'},
+ {'\x92','\xa7'},{'\x8f','\xe0'},{'\x00','\x00'},{'\x8e','\xc9'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x85','\xc3'},{'\x8e','\x46'},{'\xd3','\xa8'},{'\xaf','\xfa'},
+ {'\x91','\x43'},{'\xd3','\x76'},{'\x91','\x44'},{'\xd3','\xa3'},{'\xd3','\x7d'},
+ {'\x9f','\xc9'},{'\xd3','\xb2'},{'\x00','\x00'},{'\xd3','\xaa'},{'\x00','\x00'},
+ {'\xd3','\x7e'},{'\x91','\x45'},{'\xd3','\xa9'},{'\xd3','\x78'},{'\xd3','\x7c'},
+ {'\xd3','\xb5'},{'\xaf','\xfd'},{'\xd3','\xad'},{'\xd3','\xa4'},{'\xaf','\xed'},
+ {'\xd3','\xb3'},{'\xd3','\x74'},{'\x00','\x00'},{'\xd3','\xac'},{'\x00','\x00'},
+ {'\xaf','\xfc'},{'\xaf','\xf7'},{'\xd3','\x73'},{'\xaf','\xf5'},{'\xaf','\xf4'},
+ {'\xaf','\xf9'},{'\xd3','\xab'},{'\xaf','\xf1'},{'\xaf','\xf8'},{'\xd0','\x72'},
+ {'\xdb','\x5c'},{'\xd3','\xa6'},{'\x9f','\xca'},{'\x00','\x00'},{'\xd3','\x7a'},
+ {'\xaf','\xfb'},{'\xd3','\x7b'},{'\xd3','\xa1'},{'\xaf','\xfe'},{'\xd3','\x75'},
+ {'\xd3','\xaf'},{'\x91','\x46'},{'\xd3','\xae'},{'\xd3','\xb6'},{'\xaf','\xf3'},
+ {'\xaf','\xf0'},{'\xd3','\xb4'},{'\xd3','\xb0'},{'\xd3','\xa7'},{'\xd3','\xa2'},
+ {'\xaf','\xf6'},{'\xaf','\xf2'},{'\xd3','\x77'},{'\xaf','\xee'},{'\xd3','\xb1'},
+ {'\xaf','\xef'},{'\x00','\x00'},{'\xd3','\x79'},{'\x9f','\xcb'},{'\x93','\x54'},
+ {'\x00','\x00'},{'\x84','\x75'},{'\x91','\x47'},{'\x8e','\xc7'},{'\x00','\x00'},
+ {'\x8e','\xf4'},{'\x8f','\x5f'},{'\x8a','\xf9'},{'\x89','\x57'},{'\x91','\x48'},
+ {'\x86','\xd1'},{'\x85','\xfa'},{'\x8e','\x73'},{'\x86','\xe1'},{'\x86','\xdf'},
+ {'\x8e','\xf2'},{'\x8f','\x7b'},{'\x87','\x4a'},{'\x88','\x51'},{'\x91','\x49'},
+ {'\x8e','\x4d'},{'\x91','\x4a'},{'\x8b','\xb9'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xd7','\x5e'},{'\xd7','\x60'},{'\xd7','\x65'},{'\xd7','\x79'},
+ {'\xb2','\xfc'},{'\xb2','\xf2'},{'\x00','\x00'},{'\xd7','\x5d'},{'\xb2','\xfd'},
+ {'\xb2','\xfe'},{'\xd7','\x68'},{'\xd7','\x6f'},{'\xd7','\x75'},{'\x00','\x00'},
+ {'\xd7','\x62'},{'\x00','\x00'},{'\xd7','\x69'},{'\x00','\x00'},{'\x87','\x48'},
+ {'\xb3','\x40'},{'\xd7','\x77'},{'\xd7','\x72'},{'\xb2','\xfa'},{'\xb2','\xf8'},
+ {'\xd7','\x6e'},{'\xd7','\x6a'},{'\xd7','\x5c'},{'\xb2','\xef'},{'\xd7','\x61'},
+ {'\xd7','\x59'},{'\x9f','\xcc'},{'\xb2','\xf7'},{'\xb2','\xf9'},{'\xd7','\x66'},
+ {'\xd7','\x63'},{'\xb2','\xf4'},{'\xd7','\x73'},{'\xb2','\xf1'},{'\xd7','\x64'},
+ {'\xd7','\x7a'},{'\xd7','\x6c'},{'\x91','\x4b'},{'\xd7','\x6b'},{'\xb2','\xf0'},
+ {'\x91','\x4c'},{'\xb2','\xfb'},{'\x00','\x00'},{'\xb2','\xf3'},{'\xd7','\x5a'},
+ {'\xd7','\x5f'},{'\xd7','\x70'},{'\xd7','\x76'},{'\xb3','\x41'},{'\xd7','\x5b'},
+ {'\xd7','\x67'},{'\xd7','\x6d'},{'\xb2','\xf6'},{'\x9f','\xcd'},{'\x00','\x00'},
+ {'\xd7','\x78'},{'\xd7','\x71'},{'\xd7','\x74'},{'\x85','\x50'},{'\x88','\x50'},
+ {'\x8e','\x7d'},{'\x85','\xfd'},{'\x91','\x4d'},{'\x8f','\x60'},{'\x89','\xf7'},
+ {'\x8e','\xf5'},{'\x87','\xf3'},{'\x8c','\xc2'},{'\x00','\x00'},{'\x91','\x4e'},
+ {'\xb2','\xf5'},{'\xfb','\xad'},{'\xdb','\x6c'},{'\xdb','\x60'},{'\xb5','\xd7'},
+ {'\xdb','\x7d'},{'\xdb','\xa7'},{'\xdb','\xaa'},{'\xb5','\xd5'},{'\xdb','\x68'},
+ {'\xdb','\xa3'},{'\xdb','\x69'},{'\xdb','\x77'},{'\xb5','\xe2'},{'\xdb','\x73'},
+ {'\xb5','\xdf'},{'\x9f','\xce'},{'\xdb','\x74'},{'\xdb','\x5d'},{'\x00','\x00'},
+ {'\xdb','\xa4'},{'\x00','\x00'},{'\xfe','\x52'},{'\xb5','\xe8'},{'\xdb','\xa1'},
+ {'\xdb','\x75'},{'\xdb','\xac'},{'\xdb','\x70'},{'\xdf','\xc8'},{'\x00','\x00'},
+ {'\xdb','\xaf'},{'\xb5','\xe6'},{'\xdb','\x6e'},{'\xdb','\x7a'},{'\xb5','\xe9'},
+ {'\xb5','\xd4'},{'\xdb','\x72'},{'\xdb','\xad'},{'\xdb','\x6b'},{'\xdb','\x64'},
+ {'\xdb','\x6f'},{'\x00','\x00'},{'\xdb','\x63'},{'\xdb','\x61'},{'\xb5','\xd0'},
+ {'\xdb','\xa5'},{'\xdb','\x6a'},{'\xdb','\xa8'},{'\x9f','\xcf'},{'\xdb','\xa9'},
+ {'\xb5','\xd8'},{'\xb5','\xdd'},{'\xb5','\xd9'},{'\xb5','\xe1'},{'\xdb','\x7e'},
+ {'\xb5','\xda'},{'\xdb','\x76'},{'\xdb','\x66'},{'\x91','\x4f'},{'\xb5','\xd2'},
+ {'\xdb','\x5e'},{'\xdb','\xa2'},{'\xdb','\xab'},{'\xdb','\x65'},{'\xb5','\xe0'},
+ {'\xdb','\xb0'},{'\xdb','\x71'},{'\x00','\x00'},{'\xdb','\x6d'},{'\x00','\x00'},
+ {'\xb5','\xd1'},{'\xb5','\xe5'},{'\x9f','\xd0'},{'\xdb','\x7c'},{'\xb5','\xe7'},
+ {'\x00','\x00'},{'\xdb','\x78'},{'\xb5','\xdc'},{'\xb5','\xd6'},{'\xb5','\xde'},
+ {'\xb5','\xd3'},{'\xb5','\xe4'},{'\xdb','\x79'},{'\xdb','\x67'},{'\xdb','\x7b'},
+ {'\xdb','\x62'},{'\xdb','\xa6'},{'\x9f','\xd1'},{'\x00','\x00'},{'\x9f','\xd2'},
+ {'\x00','\x00'},{'\x96','\xa7'},{'\x00','\x00'},{'\x00','\x00'},{'\xdb','\xae'},
+ {'\x96','\xbd'},{'\x8c','\xfd'},{'\x00','\x00'},{'\x00','\x00'},{'\xfd','\x63'},
+ {'\x9f','\xd3'},{'\x94','\xc9'},{'\xdb','\x5f'},{'\x89','\x5b'},{'\x89','\xf1'},
+ {'\x89','\x4d'},{'\x89','\x58'},{'\x8a','\xf7'},{'\xdf','\xc7'},{'\x91','\x50'},
+ {'\xdf','\xdd'},{'\xb8','\x55'},{'\xdf','\xcc'},{'\x9f','\xd4'},{'\xdf','\xca'},
+ {'\xdf','\xb5'},{'\xb8','\xa9'},{'\xdf','\xc5'},{'\xdf','\xd9'},{'\xdf','\xc1'},
+ {'\xb8','\xb1'},{'\xdf','\xd8'},{'\xdf','\xbf'},{'\xb5','\xe3'},{'\xdf','\xcf'},
+ {'\xdf','\xc0'},{'\xdf','\xd6'},{'\xb8','\xb0'},{'\xb8','\xa8'},{'\x9f','\xd5'},
+ {'\xdf','\xaa'},{'\xdf','\xb2'},{'\x00','\x00'},{'\xdf','\xcb'},{'\xdf','\xc3'},
+ {'\xdf','\xdc'},{'\xdf','\xc6'},{'\xb8','\xb6'},{'\xdf','\xd7'},{'\x91','\x51'},
+ {'\xb8','\xad'},{'\x9f','\xd6'},{'\xdf','\xc9'},{'\xdf','\xd1'},{'\xdf','\xb6'},
+ {'\xdf','\xd0'},{'\x00','\x00'},{'\xdf','\xe1'},{'\xdf','\xb1'},{'\xdf','\xd2'},
+ {'\x9f','\xd7'},{'\xdf','\xdf'},{'\x9f','\xd8'},{'\xdf','\xab'},{'\xb5','\xdb'},
+ {'\x9f','\xd9'},{'\xdf','\xb9'},{'\xdf','\xb8'},{'\xb8','\xaf'},{'\x91','\x52'},
+ {'\xdf','\xbc'},{'\xdf','\xbe'},{'\xdf','\xcd'},{'\xdf','\xde'},{'\xb8','\xb2'},
+ {'\x91','\x53'},{'\xb8','\xb3'},{'\x9f','\xda'},{'\xdf','\xb0'},{'\xb8','\xab'},
+ {'\xdf','\xb4'},{'\xdf','\xda'},{'\xb8','\xb4'},{'\x00','\x00'},{'\xb8','\xac'},
+ {'\xb8','\xae'},{'\xb8','\xb5'},{'\xdf','\xe0'},{'\xdf','\xd3'},{'\xdf','\xce'},
+ {'\x95','\xf5'},{'\x9f','\xdb'},{'\xdf','\xbb'},{'\xdf','\xba'},{'\xb8','\xaa'},
+ {'\xdf','\xac'},{'\xb8','\xa7'},{'\xdf','\xc4'},{'\xdf','\xad'},{'\xdf','\xc2'},
+ {'\x96','\xc0'},{'\x00','\x00'},{'\xdf','\xb7'},{'\xdf','\xdb'},{'\x9f','\xdc'},
+ {'\x9f','\xdd'},{'\x00','\x00'},{'\xb8','\xa6'},{'\x00','\x00'},{'\x91','\x54'},
+ {'\x00','\x00'},{'\xdf','\xb3'},{'\x8e','\xf1'},{'\x91','\x55'},{'\x8e','\xf3'},
+ {'\x00','\x00'},{'\x88','\x52'},{'\x8e','\xc8'},{'\xdf','\xaf'},{'\xdf','\xd5'},
+ {'\xdf','\xae'},{'\xbb','\x60'},{'\xe3','\xd3'},{'\x9f','\xde'},{'\x9f','\xdf'},
+ {'\xe3','\xc2'},{'\x00','\x00'},{'\x9f','\xe0'},{'\xe3','\xac'},{'\xe3','\xca'},
+ {'\xbb','\x58'},{'\xe3','\xbb'},{'\xe3','\xc5'},{'\xbb','\x5b'},{'\xe3','\xbe'},
+ {'\xbb','\x59'},{'\xe3','\xaf'},{'\xe3','\xcd'},{'\xe3','\xae'},{'\xe3','\xc1'},
+ {'\x9f','\xe1'},{'\xe3','\xad'},{'\x00','\x00'},{'\x00','\x00'},{'\xe3','\xbf'},
+ {'\xe3','\xc8'},{'\xe3','\xc6'},{'\xe3','\xba'},{'\xe3','\xb5'},{'\xe3','\xb3'},
+ {'\xfd','\x66'},{'\xe3','\xb4'},{'\xe3','\xc7'},{'\xe3','\xd2'},{'\xe3','\xbc'},
+ {'\xbb','\x5a'},{'\x00','\x00'},{'\xe3','\xb7'},{'\x00','\x00'},{'\xe3','\xcb'},
+ {'\x00','\x00'},{'\xbb','\x5d'},{'\xe3','\xb6'},{'\xe3','\xb0'},{'\xe3','\xc0'},
+ {'\xbb','\x61'},{'\x96','\xbc'},{'\x9f','\xe2'},{'\xbb','\x55'},{'\xbb','\x5e'},
+ {'\xe3','\xb8'},{'\xe3','\xb2'},{'\x00','\x00'},{'\xbb','\x57'},{'\xdf','\xd4'},
+ {'\xbb','\x56'},{'\xe3','\xc3'},{'\x00','\x00'},{'\xbb','\x54'},{'\xbb','\x63'},
+ {'\xbb','\x5c'},{'\xe3','\xc4'},{'\xe3','\xb9'},{'\xe3','\xb1'},{'\xe3','\xcc'},
+ {'\xe3','\xbd'},{'\xbb','\x62'},{'\xe3','\xd0'},{'\xbb','\x5f'},{'\xe3','\xcf'},
+ {'\x00','\x00'},{'\xe3','\xc9'},{'\xe3','\xce'},{'\x00','\x00'},{'\x94','\xca'},
+ {'\xfd','\x65'},{'\xe3','\xd1'},{'\x91','\x56'},{'\x8a','\xf8'},{'\x9f','\xe3'},
+ {'\x8a','\x5e'},{'\x90','\x6c'},{'\x9f','\xe4'},{'\x9f','\xe5'},{'\x91','\x57'},
+ {'\x9f','\xe6'},{'\x8f','\xaa'},{'\x8c','\xbd'},{'\xe7','\x73'},{'\xe7','\x74'},
+ {'\xe7','\x67'},{'\xe7','\x66'},{'\xe7','\x62'},{'\xbd','\xb4'},{'\x00','\x00'},
+ {'\xbd','\xac'},{'\xe7','\x76'},{'\xe7','\x75'},{'\xdf','\xa9'},{'\xe7','\x5f'},
+ {'\xe7','\x63'},{'\xe7','\x5d'},{'\x00','\x00'},{'\xe7','\x70'},{'\xe7','\x61'},
+ {'\x9f','\xe7'},{'\xe7','\x77'},{'\xe7','\x5a'},{'\xe7','\x58'},{'\xe7','\x64'},
+ {'\xe7','\x6e'},{'\xe7','\x69'},{'\xbd','\xb6'},{'\xe7','\x4f'},{'\x00','\x00'},
+ {'\xe7','\x6d'},{'\x9f','\xe8'},{'\x00','\x00'},{'\x9f','\xe9'},{'\xbd','\xb7'},
+ {'\xdf','\xbd'},{'\xe7','\x5b'},{'\xe7','\x52'},{'\xe7','\x55'},{'\xe7','\x7b'},
+ {'\xe7','\x5c'},{'\xe7','\x53'},{'\xe7','\x51'},{'\xe7','\x4e'},{'\x9f','\xea'},
+ {'\xbd','\xb0'},{'\xe7','\x65'},{'\xbd','\xaf'},{'\xbd','\xb3'},{'\xe7','\x60'},
+ {'\xe7','\x68'},{'\xbd','\xa9'},{'\xe7','\x78'},{'\xe7','\x7c'},{'\xbd','\xab'},
+ {'\x00','\x00'},{'\xe7','\x57'},{'\xe7','\x6b'},{'\xe7','\x6f'},{'\xe7','\x54'},
+ {'\xe7','\x79'},{'\xbd','\xb2'},{'\x00','\x00'},{'\xbd','\xb1'},{'\xe7','\x4c'},
+ {'\xbd','\xb5'},{'\xe7','\x72'},{'\xe7','\x56'},{'\xe7','\x6a'},{'\xe7','\x50'},
+ {'\xe7','\x5e'},{'\xe7','\x59'},{'\xbd','\xad'},{'\xbd','\xae'},{'\xe7','\x6c'},
+ {'\xe7','\x7d'},{'\xe7','\x7a'},{'\xe7','\x71'},{'\x00','\x00'},{'\x9f','\xeb'},
+ {'\xfe','\x4c'},{'\x93','\x60'},{'\x00','\x00'},{'\x8a','\x5d'},{'\x91','\x58'},
+ {'\x90','\x46'},{'\x8c','\x4e'},{'\xe7','\x4d'},{'\x8c','\x4d'},{'\xbd','\xaa'},
+ {'\xeb','\x49'},{'\x00','\x00'},{'\xeb','\x40'},{'\xeb','\x43'},{'\x9f','\xed'},
+ {'\xbf','\xbb'},{'\xeb','\x45'},{'\xea','\xf9'},{'\xeb','\x41'},{'\xeb','\x47'},
+ {'\xbf','\xb8'},{'\xbf','\xbc'},{'\xbf','\xb6'},{'\xfd','\x68'},{'\x9f','\xee'},
+ {'\xea','\xfb'},{'\xeb','\x4c'},{'\x00','\x00'},{'\x00','\x00'},{'\xeb','\x46'},
+ {'\x9f','\xef'},{'\xea','\xfc'},{'\xeb','\x55'},{'\xeb','\x4f'},{'\xea','\xf8'},
+ {'\xee','\x46'},{'\xea','\xfe'},{'\xbf','\xb7'},{'\x91','\x59'},{'\xeb','\x4a'},
+ {'\x00','\x00'},{'\xeb','\x54'},{'\xbf','\xbf'},{'\x9f','\xf0'},{'\xeb','\x51'},
+ {'\xea','\xfd'},{'\xeb','\x44'},{'\xeb','\x48'},{'\xeb','\x42'},{'\xeb','\x56'},
+ {'\xeb','\x53'},{'\xeb','\x50'},{'\xbf','\xb9'},{'\xbf','\xba'},{'\xbf','\xbe'},
+ {'\xea','\xfa'},{'\xeb','\x57'},{'\xbf','\xbd'},{'\xeb','\x4d'},{'\x9f','\xf1'},
+ {'\x9f','\xf2'},{'\xeb','\x4b'},{'\x8f','\xe2'},{'\x9f','\xf3'},{'\x8c','\x51'},
+ {'\xeb','\x4e'},{'\xee','\x53'},{'\xee','\x40'},{'\xee','\x45'},{'\xee','\x52'},
+ {'\xee','\x44'},{'\xed','\xfb'},{'\xee','\x41'},{'\x00','\x00'},{'\xc1','\xa2'},
+ {'\x00','\x00'},{'\xed','\xf4'},{'\xee','\x4d'},{'\xee','\x4f'},{'\xed','\xf3'},
+ {'\xc1','\xa1'},{'\xee','\x51'},{'\xee','\x49'},{'\xc1','\xa8'},{'\xee','\x50'},
+ {'\xee','\x42'},{'\xc1','\xaa'},{'\xed','\xf9'},{'\xeb','\x52'},{'\xee','\x4a'},
+ {'\xee','\x47'},{'\xed','\xf5'},{'\xee','\x55'},{'\xc1','\xa4'},{'\x00','\x00'},
+ {'\x9d','\x76'},{'\xc1','\xa5'},{'\xed','\xf7'},{'\xee','\x48'},{'\x91','\x5a'},
+ {'\xee','\x54'},{'\xee','\x4b'},{'\xed','\xfd'},{'\xc1','\xa7'},{'\xc1','\xa3'},
+ {'\xee','\x4c'},{'\xed','\xfe'},{'\xee','\x56'},{'\xed','\xf8'},{'\xee','\x43'},
+ {'\xee','\x4e'},{'\xed','\xfa'},{'\xed','\xfc'},{'\x00','\x00'},{'\xc2','\xcb'},
+ {'\xed','\xf6'},{'\xc1','\xa9'},{'\xc2','\xc4'},{'\xc1','\x7e'},{'\x91','\x5b'},
+ {'\x93','\xd6'},{'\x00','\x00'},{'\x82','\x7e'},{'\xc1','\xa6'},{'\xc2','\xc8'},
+ {'\xf0','\xb3'},{'\x00','\x00'},{'\xf0','\xa9'},{'\xf0','\xa4'},{'\xf0','\xaa'},
+ {'\xf0','\xb4'},{'\xf0','\xb8'},{'\xf0','\xb7'},{'\xc2','\xca'},{'\xc2','\xc9'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xf0','\xab'},{'\xf0','\xb9'},{'\xf0','\xae'},
+ {'\xf0','\xa6'},{'\x91','\x5c'},{'\xf0','\xa8'},{'\xf0','\xa7'},{'\xf0','\xad'},
+ {'\xf0','\xb2'},{'\xf0','\xa5'},{'\xf0','\xac'},{'\xf0','\xb1'},{'\xc2','\xc7'},
+ {'\x00','\x00'},{'\xf0','\xaf'},{'\x00','\x00'},{'\xc2','\xc5'},{'\xf0','\xb0'},
+ {'\xc2','\xc3'},{'\xc2','\xc6'},{'\xf2','\xd5'},{'\xf0','\xb5'},{'\x8c','\xa4'},
+ {'\x00','\x00'},{'\xc3','\xc2'},{'\x9f','\xf4'},{'\xf2','\xcd'},{'\xf2','\xd1'},
+ {'\xf2','\xc9'},{'\xf2','\xcc'},{'\x00','\x00'},{'\xf2','\xd4'},{'\xc3','\xc0'},
+ {'\xf2','\xd9'},{'\xf2','\xd2'},{'\x9f','\xf5'},{'\xf2','\xca'},{'\xf2','\xda'},
+ {'\xf2','\xd3'},{'\xc3','\xc3'},{'\xc3','\xc4'},{'\xf2','\xd7'},{'\x00','\x00'},
+ {'\xf2','\xcb'},{'\xc3','\xbf'},{'\xc3','\xc1'},{'\xf2','\xc6'},{'\xf2','\xce'},
+ {'\xf2','\xc8'},{'\x9f','\xf6'},{'\xf2','\xd8'},{'\xf2','\xd6'},{'\xf2','\xc7'},
+ {'\xf2','\xcf'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xf4','\xbe'},
+ {'\xc3','\xc5'},{'\xf2','\xd0'},{'\xc4','\xa7'},{'\xc4','\xa9'},{'\xc4','\xa6'},
+ {'\x9f','\xf7'},{'\xf4','\xc3'},{'\xf4','\xbb'},{'\xf4','\xb9'},{'\xf4','\xbd'},
+ {'\xf4','\xba'},{'\xfd','\x6a'},{'\x00','\x00'},{'\xf4','\xbf'},{'\xf4','\xc1'},
+ {'\xc4','\xaa'},{'\xc4','\xac'},{'\x00','\x00'},{'\xf4','\xc0'},{'\xc4','\xad'},
+ {'\xc4','\xab'},{'\xf4','\xc2'},{'\x9f','\xf8'},{'\x00','\x00'},{'\x9f','\xf9'},
+ {'\xfd','\x6b'},{'\xc4','\xa8'},{'\x00','\x00'},{'\x91','\x5d'},{'\x9f','\xfa'},
+ {'\x00','\x00'},{'\x91','\x5e'},{'\xc4','\xf4'},{'\xf5','\xf1'},{'\xf5','\xf7'},
+ {'\xc4','\xf6'},{'\xf4','\xbc'},{'\xf5','\xf6'},{'\x00','\x00'},{'\xf5','\xfd'},
+ {'\xf5','\xf4'},{'\xf5','\xfb'},{'\xf5','\xfa'},{'\xf4','\xb8'},{'\xf5','\xf5'},
+ {'\xf0','\xb6'},{'\xf5','\xfe'},{'\xf5','\xf3'},{'\xf5','\xf8'},{'\x9f','\xfb'},
+ {'\xf5','\xfc'},{'\xf5','\xf2'},{'\x00','\x00'},{'\xf7','\x4a'},{'\xc4','\xf5'},
+ {'\xf5','\xf9'},{'\xfb','\xae'},{'\x94','\xcb'},{'\xf7','\xf4'},{'\xf7','\x4b'},
+ {'\xf7','\x49'},{'\xf7','\x47'},{'\xf7','\x48'},{'\xf7','\x4c'},{'\x00','\x00'},
+ {'\xc5','\xd9'},{'\xf7','\xf2'},{'\xf7','\xf0'},{'\xf7','\xf5'},{'\xf7','\xf3'},
+ {'\x00','\x00'},{'\xf7','\xf6'},{'\xc5','\xda'},{'\xf7','\xf1'},{'\x00','\x00'},
+ {'\x9f','\xfc'},{'\xf8','\xbc'},{'\x00','\x00'},{'\x9f','\xfd'},{'\xf9','\x45'},
+ {'\xf9','\x46'},{'\xf9','\x47'},{'\x00','\x00'},{'\x00','\x00'},{'\xf9','\xc7'},
+ {'\xf9','\xbd'},{'\xca','\x4f'},{'\xaa','\xea'},{'\x86','\x40'},{'\xad','\x68'},
+ {'\x87','\xcb'},{'\xd3','\xb8'},{'\xd3','\xb7'},{'\xb0','\x40'},{'\xb3','\x42'},
+ {'\xd7','\x7c'},{'\x00','\x00'},{'\x00','\x00'},{'\xd7','\x7b'},{'\x85','\x52'},
+ {'\xb5','\xea'},{'\xb8','\xb8'},{'\x00','\x00'},{'\xb8','\xb7'},{'\xb8','\xb9'},
+ {'\x00','\x00'},{'\xe3','\xd4'},{'\xe7','\x7e'},{'\xeb','\x58'},{'\xeb','\x5a'},
+ {'\xeb','\x59'},{'\x00','\x00'},{'\xc1','\xab'},{'\xee','\x57'},{'\xf0','\xba'},
+ {'\xf9','\xa5'},{'\xa6','\xe4'},{'\x95','\x78'},{'\xcd','\xc9'},{'\xcd','\xca'},
+ {'\xcd','\xc8'},{'\xcd','\xc7'},{'\xaa','\xeb'},{'\x9f','\xfe'},{'\xd0','\xa9'},
+ {'\xd0','\xa7'},{'\x00','\x00'},{'\x00','\x00'},{'\xd0','\xa6'},{'\x00','\x00'},
+ {'\xad','\x69'},{'\xad','\x6b'},{'\xad','\x6a'},{'\xd0','\xa8'},{'\x8a','\xaf'},
+ {'\x88','\x53'},{'\x8f','\xc4'},{'\x87','\x4c'},{'\x8b','\xba'},{'\x89','\x5a'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xd3','\xc4'},{'\xd3','\xc1'},{'\xd3','\xbf'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xb0','\x41'},{'\xd3','\xc2'},{'\xb0','\x46'},
+ {'\xd3','\xbc'},{'\xd3','\xcb'},{'\x00','\x00'},{'\xd3','\xcd'},{'\xd3','\xbd'},
+ {'\xfe','\xbb'},{'\xb0','\x43'},{'\xd3','\xce'},{'\xd3','\xc9'},{'\xd3','\xbb'},
+ {'\xd3','\xc0'},{'\xd3','\xca'},{'\xd3','\xc6'},{'\xd3','\xc3'},{'\x00','\x00'},
+ {'\xb0','\x48'},{'\xd3','\xcc'},{'\xd3','\xbe'},{'\x00','\x00'},{'\xfe','\xbc'},
+ {'\xd3','\xc7'},{'\xd3','\xb9'},{'\xb0','\x47'},{'\xb0','\x44'},{'\xd3','\xc5'},
+ {'\x00','\x00'},{'\xd3','\xc8'},{'\xd3','\xba'},{'\xb0','\x45'},{'\xb0','\x42'},
+ {'\x94','\xcc'},{'\x86','\x43'},{'\xfe','\xbd'},{'\x00','\x00'},{'\xb3','\x4c'},
+ {'\xd7','\xa5'},{'\xb3','\x4b'},{'\xfe','\xbe'},{'\xd7','\xa8'},{'\xd7','\xab'},
+ {'\xb3','\x48'},{'\xb3','\x46'},{'\xd7','\x7e'},{'\xd7','\xa9'},{'\xd7','\xa7'},
+ {'\xd7','\xa4'},{'\xd7','\xac'},{'\xd7','\xad'},{'\xd7','\xaf'},{'\xd7','\xb0'},
+ {'\xd7','\x7d'},{'\xb3','\x45'},{'\xd7','\xa2'},{'\xd7','\xa1'},{'\xd7','\xae'},
+ {'\xb3','\x47'},{'\xd7','\xa3'},{'\xb3','\x49'},{'\xb3','\x44'},{'\xd7','\xa6'},
+ {'\xb3','\x4d'},{'\x8c','\xfe'},{'\xb3','\x4a'},{'\xd7','\xaa'},{'\x92','\xac'},
+ {'\x82','\x4c'},{'\x8f','\xc3'},{'\xb5','\xf1'},{'\xdb','\xbf'},{'\x00','\x00'},
+ {'\xdb','\xb4'},{'\xb5','\xee'},{'\x00','\x00'},{'\xdf','\xe7'},{'\xdb','\xbd'},
+ {'\xdb','\xb1'},{'\xb5','\xec'},{'\xdb','\xb6'},{'\xb5','\xef'},{'\xdb','\xba'},
+ {'\xdb','\xb8'},{'\xb5','\xf2'},{'\xb5','\xeb'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xdb','\xb2'},{'\xdb','\xb5'},{'\xb5','\xf0'},{'\x00','\x00'},{'\xdb','\xb3'},
+ {'\x00','\x00'},{'\xdb','\xbe'},{'\xdb','\xbc'},{'\xdb','\xb7'},{'\xdb','\xb9'},
+ {'\xdb','\xbb'},{'\xb5','\xed'},{'\x8d','\x72'},{'\x94','\xcd'},{'\x8f','\x61'},
+ {'\x8e','\x4e'},{'\x8a','\xfa'},{'\x8e','\xf7'},{'\x8f','\xe3'},{'\xdf','\xe8'},
+ {'\xdf','\xee'},{'\xdf','\xe4'},{'\xdf','\xea'},{'\xb8','\xba'},{'\xdf','\xe6'},
+ {'\xb8','\xc0'},{'\x00','\x00'},{'\x00','\x00'},{'\xb8','\xbf'},{'\x00','\x00'},
+ {'\xb8','\xbe'},{'\xdf','\xed'},{'\xb8','\xc1'},{'\xb8','\xc2'},{'\xdf','\xe3'},
+ {'\xdf','\xf0'},{'\xb8','\xc3'},{'\xb8','\xbd'},{'\xb8','\xbc'},{'\xdf','\xec'},
+ {'\xb8','\xc4'},{'\xdf','\xe2'},{'\xdf','\xe5'},{'\xdf','\xef'},{'\xdf','\xeb'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xe3','\xf4'},{'\xe3','\xe9'},{'\xb8','\xbb'},
+ {'\x00','\x00'},{'\x91','\x60'},{'\x00','\x00'},{'\x88','\x54'},{'\xbb','\x6a'},
+ {'\xe3','\xdd'},{'\xe3','\xf2'},{'\xe3','\xde'},{'\xbb','\x65'},{'\x00','\x00'},
+ {'\xe3','\xdb'},{'\x00','\x00'},{'\xe3','\xe4'},{'\xe3','\xdc'},{'\xbb','\x67'},
+ {'\xe3','\xd6'},{'\xe3','\xf1'},{'\xbb','\x68'},{'\xe3','\xee'},{'\xe3','\xef'},
+ {'\xe3','\xd7'},{'\xbb','\x6d'},{'\xe3','\xe6'},{'\x00','\x00'},{'\xe3','\xe0'},
+ {'\xe3','\xe7'},{'\xe3','\xda'},{'\x00','\x00'},{'\xe3','\xf3'},{'\xe3','\xeb'},
+ {'\xe3','\xe5'},{'\xe3','\xd5'},{'\xbb','\x69'},{'\xe3','\xec'},{'\x00','\x00'},
+ {'\xbb','\x6c'},{'\xe3','\xf0'},{'\x00','\x00'},{'\xe3','\xea'},{'\xbb','\x66'},
+ {'\xe3','\xe8'},{'\x00','\x00'},{'\xe3','\xe2'},{'\xbb','\x64'},{'\xe3','\xd9'},
+ {'\xe3','\xe1'},{'\xe3','\xed'},{'\xe3','\xdf'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xe3','\xe3'},{'\x8b','\xbb'},{'\x8a','\x61'},{'\x8a','\xfb'},{'\x00','\x00'},
+ {'\x82','\xa2'},{'\xbd','\xc1'},{'\xdf','\xe9'},{'\xe7','\xb2'},{'\xe7','\xbb'},
+ {'\xe7','\xb1'},{'\xe7','\xad'},{'\xe7','\xaa'},{'\xbd','\xc2'},{'\xe7','\xa8'},
+ {'\xbb','\x6b'},{'\xe7','\xa1'},{'\xbd','\xc0'},{'\xe7','\xa7'},{'\xbd','\xbf'},
+ {'\xe7','\xac'},{'\xe7','\xa9'},{'\xe7','\xb9'},{'\xe7','\xb4'},{'\xe7','\xae'},
+ {'\xe7','\xb3'},{'\xbd','\xbb'},{'\xe7','\xab'},{'\xe7','\xbe'},{'\xe7','\xa2'},
+ {'\xe7','\xa3'},{'\xe7','\xba'},{'\xbd','\xbc'},{'\xe7','\xbf'},{'\xbd','\xbe'},
+ {'\xe7','\xc0'},{'\xe7','\xb0'},{'\xe3','\xd8'},{'\xe7','\xb6'},{'\xe7','\xaf'},
+ {'\xe7','\xb8'},{'\xe7','\xb5'},{'\x91','\x61'},{'\xfd','\x45'},{'\x00','\x00'},
+ {'\xe7','\xa6'},{'\xbd','\xb9'},{'\xe7','\xbd'},{'\xbd','\xba'},{'\xe7','\xa4'},
+ {'\xbd','\xbd'},{'\xeb','\x64'},{'\xe7','\xb7'},{'\xe7','\xbc'},{'\x8a','\x60'},
+ {'\x91','\x62'},{'\x8f','\xe4'},{'\x82','\x75'},{'\x00','\x00'},{'\xeb','\x61'},
+ {'\xbd','\xb8'},{'\xbf','\xc0'},{'\xeb','\x6b'},{'\xeb','\x67'},{'\xfb','\x6c'},
+ {'\xeb','\x65'},{'\xeb','\x60'},{'\xeb','\x6f'},{'\x00','\x00'},{'\x91','\x63'},
+ {'\xfd','\x47'},{'\xbf','\xc4'},{'\x00','\x00'},{'\xeb','\x5c'},{'\xeb','\x68'},
+ {'\xeb','\x69'},{'\xeb','\x5f'},{'\xeb','\x5e'},{'\xeb','\x6c'},{'\x00','\x00'},
+ {'\xeb','\x62'},{'\xeb','\x5d'},{'\xeb','\x63'},{'\x00','\x00'},{'\xeb','\x6e'},
+ {'\xeb','\x5b'},{'\xeb','\x6d'},{'\xeb','\x6a'},{'\xbf','\xc2'},{'\xbf','\xc1'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xbf','\xc3'},{'\xeb','\x66'},{'\xf0','\xcb'},
+ {'\xfe','\xbf'},{'\x00','\x00'},{'\x00','\x00'},{'\x91','\x64'},{'\xfd','\x46'},
+ {'\xee','\x59'},{'\xc1','\xb1'},{'\xee','\x5d'},{'\xee','\x5a'},{'\xee','\x61'},
+ {'\xee','\x67'},{'\xee','\x5c'},{'\xfe','\xc0'},{'\xee','\x70'},{'\xc1','\xae'},
+ {'\xee','\x6a'},{'\xee','\x5f'},{'\xee','\x6b'},{'\xee','\x66'},{'\xee','\x6d'},
+ {'\xee','\x5e'},{'\xc1','\xb3'},{'\xc1','\xb2'},{'\xee','\x60'},{'\xee','\x6e'},
+ {'\xee','\x58'},{'\xee','\x6c'},{'\xc1','\xac'},{'\xfd','\x49'},{'\xee','\x64'},
+ {'\xee','\x63'},{'\xee','\x68'},{'\xee','\x5b'},{'\xc1','\xb0'},{'\x91','\x65'},
+ {'\xc1','\xb4'},{'\xee','\x62'},{'\xee','\x69'},{'\xc1','\xb5'},{'\xee','\x65'},
+ {'\x00','\x00'},{'\x96','\xc7'},{'\x00','\x00'},{'\x91','\x66'},{'\xc1','\xad'},
+ {'\xc1','\xaf'},{'\xf0','\xc7'},{'\xf0','\xc5'},{'\x00','\x00'},{'\xfd','\x4c'},
+ {'\xf0','\xcc'},{'\xf0','\xc9'},{'\xf0','\xcd'},{'\xfe','\xc5'},{'\xf0','\xbe'},
+ {'\xf0','\xc6'},{'\xf0','\xd1'},{'\xee','\x6f'},{'\xf0','\xc2'},{'\xc2','\xcf'},
+ {'\xe7','\xa5'},{'\xf0','\xbd'},{'\xf0','\xca'},{'\xf0','\xc4'},{'\xf0','\xc1'},
+ {'\xf0','\xbc'},{'\xf0','\xbb'},{'\xf0','\xd0'},{'\x00','\x00'},{'\xf0','\xc0'},
+ {'\xf0','\xbf'},{'\xc2','\xcd'},{'\xf0','\xc8'},{'\xfb','\xab'},{'\xc2','\xcc'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc2','\xce'},{'\xf0','\xc3'},{'\xf0','\xcf'},
+ {'\xfd','\x4d'},{'\xf2','\xde'},{'\xf2','\xdf'},{'\x00','\x00'},{'\xc3','\xc9'},
+ {'\xf2','\xdc'},{'\xc3','\xc6'},{'\xf2','\xe4'},{'\x00','\x00'},{'\xc3','\xca'},
+ {'\xf2','\xe6'},{'\xf2','\xdb'},{'\xf0','\xce'},{'\xf2','\xe8'},{'\xf2','\xdd'},
+ {'\xfb','\x72'},{'\xc3','\xc7'},{'\xf2','\xe3'},{'\x91','\x67'},{'\xf2','\xe5'},
+ {'\xf2','\xe0'},{'\xf2','\xe7'},{'\xf2','\xe2'},{'\xf2','\xe1'},{'\xc3','\xc8'},
+ {'\x91','\x68'},{'\xfd','\x4e'},{'\xf4','\xc5'},{'\xf4','\xc6'},{'\x00','\x00'},
+ {'\xf4','\xc8'},{'\xc4','\xae'},{'\xc4','\xaf'},{'\xf4','\xc9'},{'\xf4','\xc7'},
+ {'\xfd','\x4f'},{'\xf4','\xc4'},{'\x00','\x00'},{'\xf6','\x42'},{'\xf6','\x45'},
+ {'\xf6','\x41'},{'\x00','\x00'},{'\xc4','\xfa'},{'\xf6','\x43'},{'\xc4','\xf9'},
+ {'\xc4','\xf8'},{'\xc4','\xf7'},{'\xf6','\x44'},{'\xf7','\x51'},{'\xf7','\x4f'},
+ {'\x91','\x69'},{'\xf7','\x4e'},{'\xf6','\x40'},{'\xf7','\x50'},{'\xf6','\x46'},
+ {'\xf7','\x4d'},{'\xfd','\x50'},{'\xf7','\xf9'},{'\xf7','\xd7'},{'\xf7','\xf7'},
+ {'\xc5','\xdb'},{'\xf7','\xf8'},{'\xf7','\xfa'},{'\x00','\x00'},{'\xf8','\xbf'},
+ {'\xc5','\xfa'},{'\xf8','\xbe'},{'\xf8','\xbd'},{'\xc5','\xfb'},{'\x00','\x00'},
+ {'\xc6','\x5a'},{'\xf9','\x6e'},{'\xf9','\xa7'},{'\xf9','\xa6'},{'\xf9','\xa8'},
+ {'\xa6','\xe5'},{'\xd0','\xaa'},{'\xfd','\x51'},{'\xd3','\xcf'},{'\xd3','\xd0'},
+ {'\x8d','\x75'},{'\x92','\xdb'},{'\x00','\x00'},{'\xdb','\xc0'},{'\x00','\x00'},
+ {'\xf6','\x47'},{'\xf8','\xc0'},{'\xa6','\xe6'},{'\xad','\x6c'},{'\xd0','\xab'},
+ {'\xfe','\xc6'},{'\x00','\x00'},{'\x00','\x00'},{'\xd7','\xb1'},{'\xb3','\x4e'},
+ {'\x83','\xf5'},{'\xdb','\xc2'},{'\xdb','\xc1'},{'\xb5','\xf3'},{'\x00','\x00'},
+ {'\xb8','\xc5'},{'\xe7','\xc1'},{'\xbd','\xc3'},{'\x00','\x00'},{'\xbd','\xc4'},
+ {'\xfd','\x5b'},{'\x00','\x00'},{'\xfe','\xc7'},{'\xbf','\xc5'},{'\xc5','\xfc'},
+ {'\xa6','\xe7'},{'\x91','\xd6'},{'\x86','\x44'},{'\x00','\x00'},{'\xd0','\xac'},
+ {'\xaa','\xed'},{'\xd0','\xae'},{'\xd0','\xad'},{'\xad','\x6d'},{'\x8c','\xdc'},
+ {'\xd3','\xd1'},{'\x84','\x7c'},{'\xd3','\xd8'},{'\xb0','\x49'},{'\xd3','\xd6'},
+ {'\xd3','\xd4'},{'\x00','\x00'},{'\xd3','\xdb'},{'\xd3','\xd2'},{'\xd3','\xd3'},
+ {'\xb0','\x4a'},{'\x00','\x00'},{'\xb0','\x4e'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xd3','\xdc'},{'\xb0','\x4d'},{'\xd3','\xda'},{'\xd3','\xd7'},{'\xd3','\xd5'},
+ {'\xb0','\x4b'},{'\xb0','\x4c'},{'\xd3','\xd9'},{'\x8b','\xbd'},{'\x88','\xd3'},
+ {'\x00','\x00'},{'\xfe','\xc8'},{'\xb3','\x50'},{'\xd7','\xb2'},{'\x00','\x00'},
+ {'\xb3','\x55'},{'\xd7','\xc2'},{'\xb3','\x54'},{'\xd7','\xc4'},{'\xfe','\xc9'},
+ {'\xfe','\xca'},{'\xd7','\xb8'},{'\xb3','\x52'},{'\xd7','\xc3'},{'\x00','\x00'},
+ {'\xd7','\xb3'},{'\xb3','\x53'},{'\xd7','\xbf'},{'\xd7','\xbb'},{'\xd7','\xbd'},
+ {'\xd7','\xb7'},{'\xd7','\xbe'},{'\x90','\xba'},{'\x00','\x00'},{'\xb3','\x4f'},
+ {'\xd7','\xba'},{'\xfd','\x56'},{'\xd7','\xb9'},{'\xd7','\xb5'},{'\x00','\x00'},
+ {'\xd7','\xc0'},{'\x00','\x00'},{'\x00','\x00'},{'\xd7','\xbc'},{'\xd7','\xb4'},
+ {'\x00','\x00'},{'\xd7','\xb6'},{'\xb3','\x51'},{'\xd7','\xc1'},{'\x8c','\xdb'},
+ {'\x91','\x6a'},{'\x00','\x00'},{'\x94','\xce'},{'\xb5','\xf6'},{'\xdb','\xcd'},
+ {'\x00','\x00'},{'\x95','\xdd'},{'\x91','\x6c'},{'\xdb','\xc9'},{'\xdb','\xcb'},
+ {'\xdb','\xc6'},{'\xdb','\xc5'},{'\xdb','\xc3'},{'\x00','\x00'},{'\xdb','\xca'},
+ {'\xdb','\xcc'},{'\xdb','\xc8'},{'\x91','\x6d'},{'\xdb','\xc7'},{'\xb5','\xf4'},
+ {'\xb5','\xf5'},{'\x94','\xcf'},{'\x94','\xd0'},{'\x86','\x45'},{'\x8b','\xbc'},
+ {'\xfb','\x63'},{'\x00','\x00'},{'\xdb','\xcf'},{'\xb8','\xcd'},{'\xdf','\xf2'},
+ {'\xdf','\xf8'},{'\xdf','\xf3'},{'\xdf','\xf4'},{'\xf9','\xd8'},{'\xdf','\xf9'},
+ {'\x00','\x00'},{'\xb8','\xcf'},{'\x00','\x00'},{'\xb8','\xc7'},{'\xb8','\xce'},
+ {'\xdf','\xf1'},{'\xdb','\xc4'},{'\xb8','\xca'},{'\xb8','\xc8'},{'\xdf','\xf7'},
+ {'\xdf','\xf6'},{'\xb8','\xc9'},{'\xb8','\xcb'},{'\xdf','\xf5'},{'\xb8','\xc6'},
+ {'\x00','\x00'},{'\xb8','\xcc'},{'\x8f','\x62'},{'\x8f','\xc5'},{'\x89','\x5c'},
+ {'\x91','\x6e'},{'\xfe','\xcb'},{'\xe3','\xf6'},{'\xbb','\x74'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xe4','\x42'},{'\xe4','\x41'},{'\x00','\x00'},{'\xe3','\xfb'},
+ {'\xbb','\x76'},{'\xe4','\x40'},{'\xe3','\xf7'},{'\xe3','\xf8'},{'\xbb','\x6e'},
+ {'\xbb','\x70'},{'\x91','\x6f'},{'\xe3','\xfd'},{'\xe3','\xf5'},{'\xbb','\x72'},
+ {'\xbb','\x71'},{'\xe3','\xf9'},{'\xe3','\xfe'},{'\xe3','\xfc'},{'\xbb','\x73'},
+ {'\xe3','\xfa'},{'\xfe','\xcc'},{'\xfe','\xcd'},{'\xdb','\xce'},{'\xbb','\x6f'},
+ {'\x00','\x00'},{'\x94','\xd1'},{'\xe7','\xc2'},{'\xe7','\xc9'},{'\xbd','\xc6'},
+ {'\x00','\x00'},{'\xe7','\xcd'},{'\xbd','\xca'},{'\xe7','\xc5'},{'\xe7','\xc3'},
+ {'\x00','\x00'},{'\xe7','\xcc'},{'\x00','\x00'},{'\xbd','\xc5'},{'\xe7','\xcb'},
+ {'\xbd','\xc7'},{'\xbd','\xc8'},{'\xe7','\xc4'},{'\xbd','\xc9'},{'\xe7','\xca'},
+ {'\xe7','\xc6'},{'\xe7','\xc7'},{'\xe7','\xc8'},{'\xbb','\x75'},{'\x8a','\x63'},
+ {'\x91','\x70'},{'\x91','\x71'},{'\xeb','\x70'},{'\xeb','\x7c'},{'\x00','\x00'},
+ {'\xbf','\xca'},{'\xeb','\x77'},{'\xeb','\x79'},{'\xfe','\xce'},{'\xbf','\xc8'},
+ {'\xeb','\x71'},{'\xeb','\x75'},{'\x00','\x00'},{'\xeb','\x78'},{'\xbf','\xc6'},
+ {'\xbf','\xc9'},{'\xeb','\x7b'},{'\xeb','\x73'},{'\xeb','\x74'},{'\xeb','\x7a'},
+ {'\xeb','\x72'},{'\xeb','\x76'},{'\xbf','\xc7'},{'\xee','\x72'},{'\x8c','\x53'},
+ {'\xee','\x71'},{'\xc1','\xb7'},{'\xee','\x77'},{'\xc1','\xb9'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xc1','\xb6'},{'\xee','\x73'},{'\xc1','\xba'},{'\xee','\x74'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xee','\x75'},{'\xee','\x78'},{'\xfd','\x58'},
+ {'\xc1','\xb8'},{'\x00','\x00'},{'\xf0','\xd6'},{'\xfe','\xcf'},{'\x00','\x00'},
+ {'\xf0','\xd9'},{'\x00','\x00'},{'\xf0','\xd3'},{'\xf0','\xd5'},{'\xfd','\x59'},
+ {'\x00','\x00'},{'\xf0','\xd4'},{'\xf0','\xd7'},{'\xf0','\xd8'},{'\xee','\x76'},
+ {'\xf0','\xd2'},{'\xfe','\xd0'},{'\x00','\x00'},{'\xc3','\xcd'},{'\xf2','\xec'},
+ {'\xf2','\xef'},{'\xf2','\xf1'},{'\xf2','\xea'},{'\xf2','\xeb'},{'\xf2','\xee'},
+ {'\xf2','\xf0'},{'\xc3','\xce'},{'\xc3','\xcc'},{'\xc3','\xcb'},{'\xf2','\xed'},
+ {'\xf2','\xe9'},{'\xf4','\xca'},{'\xc4','\xb0'},{'\xfe','\xd1'},{'\xf4','\xcb'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xf6','\x49'},{'\xc4','\xfb'},{'\xf6','\x4b'},
+ {'\xc4','\xfc'},{'\xf6','\x48'},{'\xf6','\x4a'},{'\xc5','\xa8'},{'\x00','\x00'},
+ {'\xf7','\x52'},{'\xc5','\xa7'},{'\xf7','\xfd'},{'\xf7','\xfc'},{'\x00','\x00'},
+ {'\xf7','\xfb'},{'\x91','\x72'},{'\x00','\x00'},{'\xf9','\x48'},{'\xf9','\x49'},
+ {'\xf9','\x4b'},{'\xf9','\x4a'},{'\x00','\x00'},{'\xca','\x50'},{'\xa6','\xe8'},
+ {'\xfe','\xd2'},{'\xad','\x6e'},{'\xd7','\xc5'},{'\xb5','\xf7'},{'\x00','\x00'},
+ {'\xdf','\xfa'},{'\xc2','\xd0'},{'\x95','\xf6'},{'\xf2','\xf2'},{'\xfd','\x6d'},
+ {'\xfd','\x6e'},{'\xa8','\xa3'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xb3','\x57'},{'\x00','\x00'},{'\xfe','\xd3'},{'\x00','\x00'},{'\xb3','\x56'},
+ {'\xfd','\x6f'},{'\xdb','\xd0'},{'\xb5','\xf8'},{'\xdb','\xd2'},{'\xdb','\xd1'},
+ {'\x00','\x00'},{'\x92','\x60'},{'\xdf','\xfb'},{'\xb8','\xd0'},{'\xe4','\x43'},
+ {'\xe4','\x46'},{'\xe4','\x45'},{'\x00','\x00'},{'\xe4','\x44'},{'\xe7','\xce'},
+ {'\xe7','\xd0'},{'\xe7','\xcf'},{'\xfb','\xaf'},{'\xbf','\xcc'},{'\x93','\xe1'},
+ {'\x00','\x00'},{'\x95','\xc5'},{'\xbf','\xcb'},{'\x00','\x00'},{'\xc1','\xbb'},
+ {'\xee','\x79'},{'\xee','\x7b'},{'\xee','\x7a'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xc2','\xd1'},{'\x92','\x6d'},{'\x00','\x00'},{'\x00','\x00'},{'\xf2','\xf4'},
+ {'\xf2','\xf3'},{'\x00','\x00'},{'\xf4','\xcc'},{'\xc4','\xb1'},{'\x00','\x00'},
+ {'\xfd','\x71'},{'\xc4','\xfd'},{'\xf7','\x54'},{'\xf7','\x53'},{'\xc6','\x5b'},
+ {'\x83','\x4e'},{'\x8d','\x73'},{'\x00','\x00'},{'\x84','\x7e'},{'\x84','\x7d'},
+ {'\x85','\x53'},{'\x8d','\xe6'},{'\x8c','\xa6'},{'\x8c','\x54'},{'\x8a','\x64'},
+ {'\x8e','\x7e'},{'\x90','\x5c'},{'\x00','\x00'},{'\x89','\x5e'},{'\x8f','\x63'},
+ {'\x8a','\xfc'},{'\x8f','\xc6'},{'\xa8','\xa4'},{'\xd0','\xaf'},{'\xad','\x6f'},
+ {'\xd7','\xc8'},{'\xd7','\xc6'},{'\x00','\x00'},{'\x00','\x00'},{'\xd7','\xc7'},
+ {'\xdb','\xd4'},{'\xdb','\xd5'},{'\xe0','\x43'},{'\xdb','\xd3'},{'\x8a','\xfd'},
+ {'\xdf','\xfc'},{'\xe0','\x41'},{'\xe0','\x40'},{'\xe0','\x42'},{'\xb8','\xd1'},
+ {'\xdf','\xfe'},{'\xdf','\xfd'},{'\xe0','\x44'},{'\x91','\x73'},{'\xe4','\x49'},
+ {'\xe4','\x47'},{'\x00','\x00'},{'\xe4','\x48'},{'\xe7','\xd3'},{'\xe7','\xd1'},
+ {'\x00','\x00'},{'\x8f','\xc7'},{'\xe7','\xd2'},{'\xeb','\x7d'},{'\xee','\x7c'},
+ {'\xee','\x7d'},{'\xc2','\xd2'},{'\x00','\x00'},{'\xf2','\xf5'},{'\xf4','\xcd'},
+ {'\xc4','\xb2'},{'\x00','\x00'},{'\xf6','\x4c'},{'\xf7','\x55'},{'\xc5','\xa9'},
+ {'\x00','\x00'},{'\xf7','\xfe'},{'\xf9','\x4c'},{'\xa8','\xa5'},{'\x00','\x00'},
+ {'\xad','\x71'},{'\xad','\x72'},{'\xd0','\xb0'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xd0','\xb1'},{'\xad','\x70'},{'\x00','\x00'},{'\xb0','\x54'},{'\x00','\x00'},
+ {'\xb0','\x52'},{'\x00','\x00'},{'\xb0','\x51'},{'\xb0','\x58'},{'\xb0','\x50'},
+ {'\xb0','\x59'},{'\xd3','\xdd'},{'\xb0','\x56'},{'\x00','\x00'},{'\xb0','\x53'},
+ {'\xb0','\x57'},{'\xb0','\x55'},{'\xb0','\x4f'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xb3','\x5f'},{'\xfe','\xd4'},{'\xb3','\x59'},{'\xd7','\xcc'},{'\xb3','\x5e'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xb3','\x60'},{'\xb3','\x5a'},{'\x00','\x00'},
+ {'\xb3','\x5b'},{'\x00','\x00'},{'\xd7','\xca'},{'\x00','\x00'},{'\xfe','\xd5'},
+ {'\xb3','\x58'},{'\xfe','\xd6'},{'\xd7','\xcb'},{'\xb3','\x5d'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xd7','\xc9'},{'\xb3','\x5c'},{'\x00','\x00'},{'\x93','\xd5'},
+ {'\xb6','\x44'},{'\x00','\x00'},{'\xb6','\x46'},{'\x91','\x74'},{'\xfe','\xd7'},
+ {'\xdb','\xd8'},{'\xb6','\x45'},{'\xb5','\xf9'},{'\xb5','\xfd'},{'\xfe','\xd8'},
+ {'\xb8','\xe4'},{'\xe0','\x49'},{'\xdb','\xda'},{'\xb5','\xfe'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xdb','\xdd'},{'\xdb','\xde'},{'\xb6','\x43'},{'\x00','\x00'},
+ {'\xdb','\xe0'},{'\xfd','\x73'},{'\xdb','\xe2'},{'\x00','\x00'},{'\xdb','\xe3'},
+ {'\xdb','\xd7'},{'\xdb','\xd6'},{'\xdb','\xe4'},{'\xb6','\x42'},{'\xdb','\xe1'},
+ {'\xdb','\xdf'},{'\x00','\x00'},{'\xb6','\x40'},{'\xb5','\xfb'},{'\xb6','\x47'},
+ {'\xdb','\xdb'},{'\xdb','\xdc'},{'\xdb','\xd9'},{'\x00','\x00'},{'\xb6','\x41'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xb5','\xfc'},{'\x00','\x00'},{'\xb5','\xfa'},
+ {'\xe0','\x48'},{'\xb8','\xdf'},{'\xb8','\xda'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xb8','\xd5'},{'\xfc','\xda'},{'\xb8','\xe5'},{'\xb8','\xd6'},{'\x00','\x00'},
+ {'\xb8','\xd2'},{'\xb8','\xe1'},{'\xb8','\xde'},{'\xb8','\xe0'},{'\x00','\x00'},
+ {'\xb8','\xd7'},{'\xb8','\xdc'},{'\xb8','\xd3'},{'\xb8','\xd4'},{'\xe0','\x50'},
+ {'\xe0','\x4d'},{'\xe0','\x45'},{'\xe0','\x4a'},{'\x00','\x00'},{'\xb8','\xe2'},
+ {'\xe0','\x51'},{'\xb8','\xe3'},{'\xb8','\xd9'},{'\x00','\x00'},{'\xfd','\x72'},
+ {'\xe0','\x47'},{'\x00','\x00'},{'\xe0','\x4f'},{'\xe0','\x4b'},{'\xe0','\x4e'},
+ {'\xe0','\x4c'},{'\xb8','\xdd'},{'\xe0','\x46'},{'\xb8','\xd8'},{'\x00','\x00'},
+ {'\x8c','\xa9'},{'\x8a','\x6c'},{'\xe4','\x4c'},{'\xbb','\x78'},{'\xbb','\x7b'},
+ {'\x00','\x00'},{'\xe4','\x4e'},{'\xfe','\xda'},{'\xbb','\xa5'},{'\xe4','\x4d'},
+ {'\xbb','\x7d'},{'\xfe','\xdb'},{'\xbd','\xcf'},{'\xe4','\x4f'},{'\x00','\x00'},
+ {'\xbb','\xa4'},{'\xe4','\x4b'},{'\xbb','\xa6'},{'\x00','\x00'},{'\xfe','\xdc'},
+ {'\x00','\x00'},{'\xbb','\x79'},{'\x00','\x00'},{'\xb8','\xdb'},{'\xbb','\x7c'},
+ {'\x00','\x00'},{'\xbb','\x7a'},{'\xbb','\x7e'},{'\xbb','\xa2'},{'\xbb','\x77'},
+ {'\xbb','\xa7'},{'\xbb','\xa3'},{'\xfe','\xdd'},{'\xbb','\xa1'},{'\xe4','\x4a'},
+ {'\x91','\x75'},{'\x93','\xab'},{'\x00','\x00'},{'\xfe','\xde'},{'\xbd','\xd6'},
+ {'\x00','\x00'},{'\xbd','\xd2'},{'\x00','\x00'},{'\xfe','\xdf'},{'\x00','\x00'},
+ {'\xbd','\xd9'},{'\x00','\x00'},{'\xe7','\xd6'},{'\xbd','\xda'},{'\xe7','\xe2'},
+ {'\xe7','\xdb'},{'\xbd','\xcb'},{'\xe7','\xe3'},{'\xe7','\xdd'},{'\xbd','\xd5'},
+ {'\xe7','\xde'},{'\x00','\x00'},{'\xbd','\xd4'},{'\xe7','\xe1'},{'\xbd','\xce'},
+ {'\xe7','\xdf'},{'\xe7','\xd5'},{'\xbd','\xcd'},{'\xeb','\xaa'},{'\xbd','\xd3'},
+ {'\x00','\x00'},{'\xbd','\xd0'},{'\x82','\x51'},{'\xbd','\xd8'},{'\x00','\x00'},
+ {'\xe7','\xd4'},{'\x00','\x00'},{'\xe7','\xd8'},{'\xbd','\xcc'},{'\xe7','\xd7'},
+ {'\xe7','\xd9'},{'\xe7','\xda'},{'\xbd','\xd7'},{'\xe7','\xdc'},{'\xe7','\xe0'},
+ {'\xe7','\xe4'},{'\x91','\x76'},{'\xbd','\xdb'},{'\xbf','\xd2'},{'\xeb','\xa5'},
+ {'\xeb','\xab'},{'\xeb','\xa8'},{'\xeb','\x7e'},{'\xeb','\xac'},{'\xeb','\xa1'},
+ {'\x00','\x00'},{'\xeb','\xa7'},{'\x00','\x00'},{'\xbf','\xcd'},{'\xbf','\xd3'},
+ {'\xeb','\xad'},{'\x00','\x00'},{'\xfe','\xe0'},{'\xbf','\xcf'},{'\x00','\x00'},
+ {'\xbf','\xd9'},{'\xbf','\xd4'},{'\xeb','\xaf'},{'\xeb','\xa9'},{'\xbf','\xd0'},
+ {'\xeb','\xa2'},{'\xbf','\xda'},{'\xeb','\xa3'},{'\xeb','\xa4'},{'\xbf','\xdb'},
+ {'\xbf','\xd8'},{'\xbd','\xd1'},{'\x9d','\xd1'},{'\xbf','\xce'},{'\xeb','\xb0'},
+ {'\xbf','\xdc'},{'\x00','\x00'},{'\xbf','\xd5'},{'\xeb','\xae'},{'\xbf','\xd1'},
+ {'\xbf','\xd6'},{'\xbf','\xd7'},{'\x00','\x00'},{'\xc1','\xc3'},{'\xee','\xa4'},
+ {'\xee','\xad'},{'\xee','\xaa'},{'\xee','\xac'},{'\x00','\x00'},{'\xc1','\xc0'},
+ {'\xee','\xa5'},{'\xfd','\x74'},{'\xee','\xab'},{'\xc1','\xbc'},{'\xee','\xa7'},
+ {'\xc1','\xc4'},{'\xee','\xa3'},{'\xee','\xa8'},{'\xee','\xaf'},{'\xeb','\xa6'},
+ {'\xee','\xa9'},{'\xee','\xa2'},{'\xc1','\xbd'},{'\xee','\xa1'},{'\xc1','\xbe'},
+ {'\xee','\xb0'},{'\xc1','\xbf'},{'\xee','\xae'},{'\xc1','\xc2'},{'\xee','\x7e'},
+ {'\xfe','\xe1'},{'\xc1','\xc1'},{'\x93','\xdc'},{'\xee','\xa6'},{'\xf0','\xdc'},
+ {'\xf0','\xea'},{'\xf0','\xe5'},{'\xf0','\xe7'},{'\xf0','\xdb'},{'\xc2','\xd3'},
+ {'\x00','\x00'},{'\xf0','\xda'},{'\xc2','\xd6'},{'\xc2','\xd5'},{'\x96','\xc1'},
+ {'\xf0','\xe9'},{'\xf0','\xe1'},{'\xf0','\xde'},{'\xf0','\xe4'},{'\x00','\x00'},
+ {'\xf0','\xdd'},{'\x00','\x00'},{'\xf0','\xdf'},{'\xf0','\xe8'},{'\xf0','\xe6'},
+ {'\x00','\x00'},{'\xc2','\xd4'},{'\xf0','\xed'},{'\xf0','\xeb'},{'\xf0','\xe2'},
+ {'\xf0','\xec'},{'\xf0','\xe3'},{'\xfe','\xe3'},{'\xf2','\xf9'},{'\xc3','\xcf'},
+ {'\xf3','\x41'},{'\xfd','\x75'},{'\x00','\x00'},{'\xf6','\x4f'},{'\xc3','\xd6'},
+ {'\xf0','\xe0'},{'\xf2','\xf7'},{'\xc3','\xd2'},{'\xf2','\xf8'},{'\xf2','\xfd'},
+ {'\xfd','\x77'},{'\xfe','\xe4'},{'\xc3','\xd4'},{'\xc3','\xd5'},{'\xf2','\xf6'},
+ {'\xf3','\x40'},{'\xf3','\x42'},{'\xf2','\xfa'},{'\xf2','\xfc'},{'\xf2','\xfe'},
+ {'\xf2','\xfb'},{'\xf3','\x43'},{'\xc3','\xd1'},{'\xc3','\xd7'},{'\xc3','\xd3'},
+ {'\x91','\x77'},{'\xc3','\xd0'},{'\xf4','\xd0'},{'\xfe','\xe5'},{'\xc4','\xb7'},
+ {'\xf4','\xce'},{'\x00','\x00'},{'\xfe','\xe6'},{'\xf4','\xd2'},{'\x00','\x00'},
+ {'\xf4','\xd3'},{'\xc4','\xb5'},{'\xf4','\xd4'},{'\xf4','\xd1'},{'\xfe','\xe7'},
+ {'\xf4','\xcf'},{'\xc4','\xb8'},{'\xc4','\xb4'},{'\xf4','\xd5'},{'\x00','\x00'},
+ {'\xc4','\xb6'},{'\xc4','\xb3'},{'\x91','\x78'},{'\x92','\xf0'},{'\x00','\x00'},
+ {'\xc4','\xfe'},{'\x00','\x00'},{'\x00','\x00'},{'\xc5','\x40'},{'\xf6','\x4e'},
+ {'\xf6','\x4d'},{'\xf6','\x50'},{'\xf6','\x51'},{'\x00','\x00'},{'\xc5','\x41'},
+ {'\xf7','\x56'},{'\xf7','\x5b'},{'\xc5','\xaa'},{'\xfd','\x76'},{'\xf7','\x58'},
+ {'\x82','\x63'},{'\xf7','\x57'},{'\xf7','\x5a'},{'\xf7','\x59'},{'\x00','\x00'},
+ {'\xf8','\x43'},{'\x00','\x00'},{'\xc5','\xdc'},{'\xf8','\x42'},{'\xf8','\x40'},
+ {'\x00','\x00'},{'\xf8','\x41'},{'\x00','\x00'},{'\x95','\xf8'},{'\x00','\x00'},
+ {'\xc5','\xfe'},{'\xc5','\xfd'},{'\xf8','\xc1'},{'\xf8','\xc2'},{'\xc6','\x40'},
+ {'\x00','\x00'},{'\xf9','\x4d'},{'\xf9','\x4e'},{'\xc6','\x67'},{'\xfe','\xe8'},
+ {'\xc6','\x6d'},{'\x00','\x00'},{'\xf9','\xa9'},{'\xf9','\xc8'},{'\x9c','\xec'},
+ {'\x83','\x79'},{'\x83','\x7a'},{'\x83','\x7b'},{'\x87','\x50'},{'\x8b','\xc2'},
+ {'\x83','\xd4'},{'\x83','\xd6'},{'\x83','\xd5'},{'\x8d','\x58'},{'\x83','\xd7'},
+ {'\x83','\xda'},{'\x00','\x00'},{'\x83','\xd9'},{'\x8c','\x56'},{'\x83','\xd8'},
+ {'\x83','\xd3'},{'\x00','\x00'},{'\x8a','\x68'},{'\x89','\x62'},{'\x8f','\x7e'},
+ {'\x8d','\xe7'},{'\x84','\xa2'},{'\x84','\xa4'},{'\x84','\xa5'},{'\x84','\xa8'},
+ {'\x88','\x62'},{'\x00','\x00'},{'\x84','\xa7'},{'\x89','\x6a'},{'\x84','\xa6'},
+ {'\x84','\xa1'},{'\x84','\xa3'},{'\x85','\x56'},{'\x85','\x57'},{'\x85','\x5e'},
+ {'\x85','\x54'},{'\x85','\x59'},{'\x8b','\xbf'},{'\x00','\x00'},{'\x85','\x5a'},
+ {'\x85','\x5c'},{'\x85','\x5d'},{'\x85','\x5b'},{'\x8f','\x65'},{'\x85','\x55'},
+ {'\x8d','\xe8'},{'\x85','\x58'},{'\x00','\x00'},{'\x8c','\x57'},{'\x8d','\xe9'},
+ {'\x8e','\x4f'},{'\x8e','\x52'},{'\x86','\x49'},{'\x8e','\x50'},{'\x86','\x4a'},
+ {'\x86','\x4b'},{'\x86','\x4c'},{'\x86','\x4e'},{'\x86','\x50'},{'\x8e','\x53'},
+ {'\x86','\x4f'},{'\x88','\x5a'},{'\x86','\x54'},{'\x86','\x53'},{'\x86','\x51'},
+ {'\x86','\x52'},{'\x86','\x4d'},{'\x88','\x63'},{'\x86','\x47'},{'\x86','\x48'},
+ {'\x86','\x46'},{'\x8e','\xf8'},{'\x8e','\x51'},{'\x00','\x00'},{'\x87','\x51'},
+ {'\x87','\x4f'},{'\x87','\x4e'},{'\x87','\x58'},{'\x87','\x52'},{'\x87','\x54'},
+ {'\x87','\x56'},{'\x87','\x55'},{'\x87','\x57'},{'\x87','\x53'},{'\x87','\x4d'},
+ {'\x8e','\xa1'},{'\x88','\x5b'},{'\x88','\x5c'},{'\x8e','\xcb'},{'\x89','\x67'},
+ {'\x8c','\xdd'},{'\x8e','\xcc'},{'\x88','\x65'},{'\x88','\x5d'},{'\x88','\x5e'},
+ {'\x88','\x66'},{'\x88','\x61'},{'\x8e','\xcd'},{'\x88','\x60'},{'\x88','\x5f'},
+ {'\x88','\x57'},{'\x88','\x59'},{'\x88','\x64'},{'\x88','\x58'},{'\x00','\x00'},
+ {'\x88','\x56'},{'\x89','\x63'},{'\x89','\x6d'},{'\x89','\x64'},{'\x8a','\x69'},
+ {'\x89','\x61'},{'\x89','\x65'},{'\x8e','\xf9'},{'\x89','\x68'},{'\x89','\x69'},
+ {'\x8e','\xfa'},{'\x89','\x6b'},{'\x89','\x6e'},{'\x8d','\x59'},{'\x89','\x66'},
+ {'\x89','\x6c'},{'\x89','\x60'},{'\x89','\x5f'},{'\x8a','\x65'},{'\x8e','\xfb'},
+ {'\x00','\x00'},{'\x8a','\xfe'},{'\x8d','\xa4'},{'\x8f','\x64'},{'\x8a','\x6b'},
+ {'\x8a','\x6a'},{'\x8a','\x66'},{'\x8f','\x66'},{'\x8a','\x67'},{'\x8a','\x6d'},
+ {'\x8b','\x40'},{'\x8f','\xa1'},{'\x8b','\x42'},{'\x91','\x79'},{'\x8b','\x41'},
+ {'\x8b','\xc0'},{'\x8f','\xc8'},{'\x8b','\xc3'},{'\x90','\x78'},{'\x8b','\xbe'},
+ {'\x8b','\xc1'},{'\x90','\xa6'},{'\x8c','\xa7'},{'\x8c','\x58'},{'\x8d','\x5a'},
+ {'\xa8','\xa6'},{'\x00','\x00'},{'\xd7','\xcd'},{'\x91','\x7a'},{'\xd7','\xce'},
+ {'\xe0','\x52'},{'\xe4','\x50'},{'\xe7','\xe5'},{'\xc1','\xc6'},{'\x00','\x00'},
+ {'\xc1','\xc5'},{'\xf0','\xee'},{'\xf3','\x44'},{'\x00','\x00'},{'\xf8','\x44'},
+ {'\xa8','\xa7'},{'\xd3','\xde'},{'\xb0','\x5a'},{'\xb3','\x61'},{'\xe0','\x54'},
+ {'\xe0','\x53'},{'\xbd','\xdc'},{'\xe7','\xe6'},{'\xbd','\xdd'},{'\xee','\xb1'},
+ {'\xc2','\xd7'},{'\xfe','\xe9'},{'\x00','\x00'},{'\x00','\x00'},{'\xc6','\x76'},
+ {'\xa8','\xa8'},{'\xcd','\xcb'},{'\xd3','\xdf'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xb3','\x62'},{'\x00','\x00'},{'\xd7','\xcf'},{'\xd7','\xd0'},{'\x00','\x00'},
+ {'\xdb','\xe5'},{'\x00','\x00'},{'\xb6','\x48'},{'\xb8','\xe6'},{'\x00','\x00'},
+ {'\xe0','\x56'},{'\xe0','\x55'},{'\xe0','\x57'},{'\x00','\x00'},{'\xe4','\x51'},
+ {'\xe4','\x52'},{'\xbb','\xa8'},{'\xbf','\xdd'},{'\xbd','\xde'},{'\xbf','\xde'},
+ {'\x00','\x00'},{'\xee','\xb5'},{'\xee','\xb2'},{'\xee','\xb4'},{'\xee','\xb3'},
+ {'\xc1','\xc7'},{'\x00','\x00'},{'\xf0','\xef'},{'\xf3','\x46'},{'\xf3','\x45'},
+ {'\xcb','\xa4'},{'\xb0','\x5c'},{'\xb0','\x5b'},{'\xd3','\xe0'},{'\x91','\x7b'},
+ {'\xd7','\xd1'},{'\x00','\x00'},{'\x00','\x00'},{'\xdb','\xe7'},{'\xdb','\xe6'},
+ {'\xb6','\x49'},{'\x00','\x00'},{'\xe0','\x59'},{'\xe0','\x5a'},{'\xe0','\x58'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xb8','\xe8'},{'\xb8','\xe7'},{'\x00','\x00'},
+ {'\xbb','\xaa'},{'\xbb','\xa9'},{'\x91','\x7c'},{'\xe7','\xe7'},{'\xeb','\xb3'},
+ {'\xeb','\xb1'},{'\xeb','\xb2'},{'\xbf','\xdf'},{'\xee','\xb7'},{'\xee','\xb6'},
+ {'\x00','\x00'},{'\xf0','\xf2'},{'\xf0','\xf1'},{'\xf0','\xf0'},{'\xf3','\x47'},
+ {'\xfe','\xea'},{'\xf9','\xaa'},{'\xa8','\xa9'},{'\xad','\x73'},{'\xfe','\xeb'},
+ {'\xad','\x74'},{'\xb0','\x5d'},{'\xb0','\x5e'},{'\xd3','\xe2'},{'\xd3','\xe1'},
+ {'\xd7','\xd2'},{'\x00','\x00'},{'\xb3','\x68'},{'\xb3','\x66'},{'\xb3','\x63'},
+ {'\xb3','\x67'},{'\xb3','\x65'},{'\xb3','\x64'},{'\xfd','\x79'},{'\x91','\x7d'},
+ {'\xb6','\x4a'},{'\xdb','\xea'},{'\x00','\x00'},{'\xb8','\xed'},{'\xb6','\x4c'},
+ {'\xb6','\x51'},{'\xdb','\xec'},{'\xb6','\x53'},{'\xb6','\x52'},{'\xb6','\x55'},
+ {'\xdb','\xeb'},{'\xdb','\xe8'},{'\xb6','\x4f'},{'\xb6','\x4b'},{'\xb6','\x4d'},
+ {'\xdb','\xe9'},{'\xb6','\x54'},{'\xb6','\x50'},{'\xb6','\x4e'},{'\xb8','\xef'},
+ {'\xb8','\xee'},{'\xb8','\xec'},{'\xb8','\xf0'},{'\x00','\x00'},{'\xb8','\xea'},
+ {'\xb8','\xeb'},{'\x00','\x00'},{'\xb8','\xe9'},{'\x00','\x00'},{'\xe0','\x5b'},
+ {'\x95','\x60'},{'\x82','\x62'},{'\xe4','\x54'},{'\x00','\x00'},{'\xbb','\xac'},
+ {'\xbb','\xad'},{'\xbb','\xab'},{'\xfe','\xec'},{'\xe4','\x53'},{'\xfe','\xed'},
+ {'\xe4','\x55'},{'\x00','\x00'},{'\xe7','\xea'},{'\xe7','\xec'},{'\x92','\xce'},
+ {'\xbd','\xe7'},{'\xe7','\xed'},{'\xbd','\xe0'},{'\xe7','\xe9'},{'\xbd','\xdf'},
+ {'\xbd','\xe9'},{'\xbd','\xe5'},{'\xbd','\xe6'},{'\xbd','\xe2'},{'\xe7','\xe8'},
+ {'\xbd','\xe1'},{'\xe7','\xee'},{'\xe7','\xeb'},{'\x9e','\x40'},{'\xbd','\xe8'},
+ {'\xfd','\x7a'},{'\xbd','\xe3'},{'\xbd','\xe4'},{'\xeb','\xb5'},{'\x00','\x00'},
+ {'\xeb','\xb7'},{'\xeb','\xb6'},{'\x9e','\x41'},{'\xeb','\xb8'},{'\xbf','\xe0'},
+ {'\xeb','\xb4'},{'\x00','\x00'},{'\xfd','\x7b'},{'\xc1','\xcb'},{'\xee','\xb8'},
+ {'\xc1','\xc8'},{'\xc1','\xcc'},{'\xc1','\xca'},{'\xc1','\xc9'},{'\xf0','\xf3'},
+ {'\x00','\x00'},{'\xf0','\xf6'},{'\x00','\x00'},{'\xf0','\xf5'},{'\x9e','\x42'},
+ {'\xf0','\xf4'},{'\xc2','\xd8'},{'\xf3','\x48'},{'\xf3','\x49'},{'\xc3','\xd8'},
+ {'\xf3','\x4a'},{'\xc3','\xd9'},{'\x82','\x57'},{'\xfd','\x7c'},{'\xc4','\xba'},
+ {'\x00','\x00'},{'\xc4','\xb9'},{'\xf6','\x52'},{'\x9e','\x43'},{'\x91','\x7e'},
+ {'\xc5','\x42'},{'\xf6','\x53'},{'\xf7','\x5c'},{'\xc5','\xab'},{'\xc5','\xac'},
+ {'\x95','\x76'},{'\xf8','\x45'},{'\x00','\x00'},{'\xc6','\x42'},{'\x9e','\x44'},
+ {'\x83','\x50'},{'\x83','\x7c'},{'\x83','\x7d'},{'\x00','\x00'},{'\x83','\xdd'},
+ {'\x83','\xdc'},{'\x84','\xaa'},{'\x88','\x6e'},{'\x84','\x50'},{'\x88','\x6c'},
+ {'\x84','\xac'},{'\x88','\x71'},{'\x84','\xa9'},{'\x84','\xad'},{'\x84','\xae'},
+ {'\x85','\x68'},{'\x8a','\x70'},{'\x85','\x5f'},{'\x84','\xab'},{'\x85','\x61'},
+ {'\x88','\x6b'},{'\x85','\x63'},{'\x8d','\xeb'},{'\x85','\x60'},{'\x85','\x66'},
+ {'\x8d','\xea'},{'\x85','\x6a'},{'\x85','\x69'},{'\x85','\x64'},{'\x85','\x65'},
+ {'\x85','\x62'},{'\x86','\x55'},{'\x8f','\xa3'},{'\x86','\x57'},{'\x86','\x58'},
+ {'\x86','\x59'},{'\x86','\x5a'},{'\x86','\x5b'},{'\x8c','\xaa'},{'\x86','\x56'},
+ {'\x86','\x5c'},{'\x90','\x47'},{'\x8e','\xa2'},{'\x87','\x5a'},{'\x91','\xa1'},
+ {'\x87','\x5b'},{'\x88','\x6a'},{'\x88','\x6d'},{'\x91','\xa2'},{'\x8c','\xde'},
+ {'\x88','\x69'},{'\x88','\x70'},{'\x00','\x00'},{'\x00','\x00'},{'\x88','\x72'},
+ {'\x88','\x68'},{'\x8e','\xce'},{'\x89','\x6f'},{'\x00','\x00'},{'\x8b','\x43'},
+ {'\x8a','\x71'},{'\x8a','\x6e'},{'\x8a','\x6f'},{'\x8f','\xa2'},{'\x8c','\xdf'},
+ {'\x8b','\xc5'},{'\x00','\x00'},{'\x8b','\xc4'},{'\x8c','\x5a'},{'\x8c','\x59'},
+ {'\x8d','\x5c'},{'\xa8','\xaa'},{'\x00','\x00'},{'\xb3','\x6a'},{'\xb3','\x69'},
+ {'\xe0','\x5c'},{'\xe0','\x5d'},{'\x00','\x00'},{'\xbb','\xae'},{'\xeb','\xb9'},
+ {'\xbd','\xea'},{'\xeb','\xba'},{'\xee','\xb9'},{'\xa8','\xab'},{'\x91','\xa3'},
+ {'\xd0','\xb2'},{'\xad','\x76'},{'\xad','\x75'},{'\x87','\x5c'},{'\xd3','\xe3'},
+ {'\xb0','\x5f'},{'\xd3','\xe4'},{'\xd7','\xd5'},{'\x9e','\x45'},{'\xd7','\xd4'},
+ {'\x00','\x00'},{'\xd7','\xd3'},{'\x00','\x00'},{'\x00','\x00'},{'\xdb','\xee'},
+ {'\xb6','\x58'},{'\xfd','\x7d'},{'\x00','\x00'},{'\xdb','\xed'},{'\xb6','\x57'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xdb','\xef'},{'\xb6','\x56'},
+ {'\x8a','\x72'},{'\xe0','\x5f'},{'\xe0','\x62'},{'\xe0','\x60'},{'\xe0','\x61'},
+ {'\xe0','\x65'},{'\xe0','\x5e'},{'\xe0','\x66'},{'\xe0','\x63'},{'\xe0','\x64'},
+ {'\xbb','\xb0'},{'\xe4','\x56'},{'\x00','\x00'},{'\x00','\x00'},{'\xbb','\xaf'},
+ {'\x00','\x00'},{'\xe7','\xf2'},{'\xe7','\xf0'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xbd','\xeb'},{'\xe7','\xef'},{'\xe7','\xf1'},{'\x00','\x00'},{'\xbd','\xec'},
+ {'\x00','\x00'},{'\xeb','\xbb'},{'\xfd','\x7e'},{'\xeb','\xbc'},{'\xc1','\xcd'},
+ {'\x9e','\x46'},{'\xf3','\x4c'},{'\xf3','\x4e'},{'\xf3','\x4b'},{'\xf3','\x4d'},
+ {'\xf4','\xd6'},{'\xf6','\x54'},{'\x00','\x00'},{'\x90','\xa3'},{'\xf9','\x6f'},
+ {'\xa8','\xac'},{'\xad','\x77'},{'\xd3','\xe5'},{'\xd3','\xe7'},{'\xd3','\xe6'},
+ {'\x8c','\x5b'},{'\xd7','\xd8'},{'\xb3','\x6c'},{'\x00','\x00'},{'\xd7','\xd6'},
+ {'\x00','\x00'},{'\xb3','\x6b'},{'\xd7','\xd9'},{'\x9e','\x47'},{'\xd7','\xda'},
+ {'\xd7','\xd7'},{'\x8c','\xac'},{'\x8f','\x67'},{'\xdb','\xfb'},{'\xb6','\x60'},
+ {'\xdb','\xf3'},{'\xdb','\xf9'},{'\x00','\x00'},{'\x00','\x00'},{'\xb6','\x5b'},
+ {'\xb6','\x5e'},{'\xdb','\xf2'},{'\xb6','\x59'},{'\xdb','\xf6'},{'\xe0','\x6c'},
+ {'\xb6','\x5d'},{'\x00','\x00'},{'\xdb','\xf1'},{'\xfd','\xa1'},{'\xdb','\xf7'},
+ {'\xdb','\xf4'},{'\xdb','\xfa'},{'\xdb','\xf0'},{'\xdb','\xf8'},{'\xb6','\x5c'},
+ {'\xb6','\x5f'},{'\xdb','\xf5'},{'\xb6','\x5a'},{'\x90','\x5e'},{'\xb8','\xf2'},
+ {'\xe0','\x68'},{'\xb8','\xf1'},{'\xe0','\x6f'},{'\xe0','\x6e'},{'\xb8','\xf8'},
+ {'\x00','\x00'},{'\xb8','\xf9'},{'\xe0','\x70'},{'\xb8','\xf3'},{'\xe0','\x6d'},
+ {'\xb8','\xf7'},{'\xe0','\x72'},{'\xe0','\x69'},{'\x00','\x00'},{'\xe0','\x6b'},
+ {'\xb8','\xf4'},{'\xe0','\x67'},{'\xe0','\x6a'},{'\xe0','\x71'},{'\xb8','\xf5'},
+ {'\xe0','\x73'},{'\x88','\x73'},{'\x00','\x00'},{'\x8b','\xc6'},{'\x8b','\x46'},
+ {'\x90','\x5d'},{'\xb8','\xf6'},{'\x8c','\xad'},{'\xbb','\xb1'},{'\xe4','\x5b'},
+ {'\xe4','\x61'},{'\xe4','\x59'},{'\xe4','\x62'},{'\x9e','\x48'},{'\xe4','\x58'},
+ {'\xe4','\x5d'},{'\xe4','\x63'},{'\xe4','\x60'},{'\xe4','\x5f'},{'\xe4','\x5e'},
+ {'\x91','\xa4'},{'\xe4','\x57'},{'\xe4','\x5c'},{'\x00','\x00'},{'\x8c','\xab'},
+ {'\xe4','\x5a'},{'\x9e','\x49'},{'\xbd','\xf1'},{'\xbd','\xee'},{'\xe7','\xfb'},
+ {'\xe8','\x41'},{'\xe8','\x43'},{'\xe8','\x40'},{'\xe7','\xf8'},{'\xe7','\xfa'},
+ {'\xe8','\x45'},{'\xe8','\x42'},{'\xe7','\xfc'},{'\xe8','\x46'},{'\xe7','\xf9'},
+ {'\xe8','\x44'},{'\xbd','\xef'},{'\xbd','\xf5'},{'\xbd','\xf3'},{'\xe7','\xf3'},
+ {'\xbd','\xf4'},{'\xbd','\xf0'},{'\xe7','\xf4'},{'\xe7','\xf6'},{'\xe7','\xf5'},
+ {'\xe7','\xfd'},{'\xe7','\xfe'},{'\xfd','\xa2'},{'\xbd','\xf2'},{'\x95','\x57'},
+ {'\xbd','\xed'},{'\x8c','\xe1'},{'\xfb','\x6d'},{'\xe7','\xf7'},{'\x8c','\xe0'},
+ {'\xeb','\xc6'},{'\xbf','\xe2'},{'\x00','\x00'},{'\xeb','\xbd'},{'\xbf','\xe3'},
+ {'\xbf','\xe6'},{'\xeb','\xc2'},{'\x00','\x00'},{'\xeb','\xbf'},{'\xbf','\xe5'},
+ {'\x91','\xa5'},{'\x00','\x00'},{'\xeb','\xc3'},{'\xeb','\xc4'},{'\xeb','\xbe'},
+ {'\xeb','\xc7'},{'\xeb','\xc0'},{'\xeb','\xc5'},{'\xbf','\xe4'},{'\x00','\x00'},
+ {'\xbf','\xe1'},{'\xeb','\xc1'},{'\x9e','\x4a'},{'\xee','\xbf'},{'\xc1','\xd0'},
+ {'\xc1','\xce'},{'\xc1','\xd1'},{'\xc1','\xcf'},{'\xee','\xbe'},{'\xee','\xbb'},
+ {'\xee','\xba'},{'\xfd','\xa3'},{'\xee','\xbd'},{'\x8d','\x74'},{'\x8b','\x44'},
+ {'\xee','\xbc'},{'\xf1','\x45'},{'\xc2','\xde'},{'\xf0','\xfb'},{'\xf0','\xfa'},
+ {'\x00','\x00'},{'\xc2','\xd9'},{'\xf1','\x41'},{'\xf1','\x40'},{'\xf0','\xf7'},
+ {'\xf1','\x43'},{'\xf0','\xfc'},{'\xc2','\xdd'},{'\xf0','\xf9'},{'\xf1','\x42'},
+ {'\xf0','\xf8'},{'\xc2','\xda'},{'\xc2','\xdc'},{'\xf0','\xfd'},{'\xc2','\xdb'},
+ {'\xf0','\xfe'},{'\x9e','\x4b'},{'\xf1','\x44'},{'\xf3','\x52'},{'\x00','\x00'},
+ {'\xc3','\xde'},{'\xf3','\x4f'},{'\x00','\x00'},{'\xf3','\x53'},{'\x91','\xa6'},
+ {'\x9e','\x4c'},{'\xc3','\xdb'},{'\xf3','\x51'},{'\xc3','\xe0'},{'\xfd','\xa5'},
+ {'\xc3','\xdd'},{'\xfd','\xa4'},{'\xf3','\x50'},{'\x00','\x00'},{'\xc3','\xdf'},
+ {'\xf3','\x54'},{'\xc3','\xda'},{'\x00','\x00'},{'\x9e','\x4d'},{'\x90','\x7e'},
+ {'\x9e','\x4e'},{'\xc4','\xbc'},{'\xc4','\xbe'},{'\x00','\x00'},{'\xf4','\xd9'},
+ {'\xc4','\xbd'},{'\xf4','\xd7'},{'\xc3','\xdc'},{'\xf4','\xd8'},{'\xc4','\xbb'},
+ {'\xc5','\x43'},{'\xc5','\x45'},{'\xf6','\x56'},{'\xc5','\x44'},{'\xf6','\x55'},
+ {'\x8d','\xa5'},{'\xf7','\x61'},{'\xc5','\xad'},{'\xf7','\x60'},{'\xc5','\xae'},
+ {'\xf7','\x5e'},{'\xf7','\x5d'},{'\xf7','\x62'},{'\xf7','\x63'},{'\xf8','\x46'},
+ {'\x91','\xa7'},{'\xf7','\x5f'},{'\x00','\x00'},{'\x90','\xa4'},{'\xf8','\xc6'},
+ {'\xf8','\xc3'},{'\xf8','\xc4'},{'\xf8','\xc5'},{'\xc6','\x5c'},{'\x00','\x00'},
+ {'\xf9','\x51'},{'\xf9','\x50'},{'\xf9','\x4f'},{'\xf9','\x70'},{'\xfd','\xa6'},
+ {'\xf9','\xbe'},{'\xf9','\xab'},{'\xc6','\x6e'},{'\xa8','\xad'},{'\xb0','\x60'},
+ {'\x95','\xdf'},{'\x00','\x00'},{'\x82','\x49'},{'\x91','\xa8'},{'\x91','\xa9'},
+ {'\xb8','\xfa'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9e','\x4f'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x9e','\x50'},{'\xbd','\xf6'},{'\x00','\x00'},
+ {'\x9e','\x51'},{'\xeb','\xc8'},{'\x94','\xd3'},{'\x00','\x00'},{'\xc2','\xdf'},
+ {'\x00','\x00'},{'\xf3','\x55'},{'\x9e','\x52'},{'\x00','\x00'},{'\x91','\xaa'},
+ {'\x91','\xab'},{'\x00','\x00'},{'\x94','\xd4'},{'\xf9','\xac'},{'\xa8','\xae'},
+ {'\xaa','\xee'},{'\xad','\x79'},{'\xad','\x78'},{'\x91','\xac'},{'\xb0','\x63'},
+ {'\x00','\x00'},{'\xd3','\xe8'},{'\xb0','\x61'},{'\xd3','\xe9'},{'\xb0','\x62'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xd7','\xdf'},{'\xd7','\xdb'},{'\x00','\x00'},
+ {'\xfb','\xa1'},{'\xb3','\x6d'},{'\xd7','\xde'},{'\xd7','\xdd'},{'\xd7','\xdc'},
+ {'\xb3','\x6e'},{'\xd7','\xe0'},{'\xd7','\xe1'},{'\x93','\x7d'},{'\x91','\xad'},
+ {'\x9e','\x53'},{'\xdc','\x43'},{'\xdc','\x41'},{'\xdc','\x45'},{'\xdc','\x46'},
+ {'\xdc','\x4c'},{'\x00','\x00'},{'\xdc','\x48'},{'\xdc','\x4a'},{'\x9e','\x54'},
+ {'\xdc','\x42'},{'\xdb','\xfc'},{'\x00','\x00'},{'\xdc','\x49'},{'\x9e','\x55'},
+ {'\x00','\x00'},{'\xdc','\x4b'},{'\xdc','\x44'},{'\xdc','\x47'},{'\xdb','\xfd'},
+ {'\xb6','\x62'},{'\xdc','\x40'},{'\xdb','\xfe'},{'\xb6','\x61'},{'\xb6','\x63'},
+ {'\x92','\xad'},{'\xb8','\xfd'},{'\xe0','\x75'},{'\xe0','\x77'},{'\xe0','\x76'},
+ {'\xe0','\x7b'},{'\xb8','\xfb'},{'\x00','\x00'},{'\xe0','\x78'},{'\xe0','\x74'},
+ {'\xe0','\x79'},{'\xe0','\x7a'},{'\xb8','\xfc'},{'\xb8','\xfe'},{'\xe0','\x7c'},
+ {'\x91','\xae'},{'\xe4','\x67'},{'\xe4','\x66'},{'\x00','\x00'},{'\xe4','\x64'},
+ {'\xe4','\x65'},{'\xbb','\xb3'},{'\xbb','\xb5'},{'\xbb','\xb2'},{'\xbb','\xb4'},
+ {'\xe8','\x4d'},{'\xe8','\x4e'},{'\xe8','\x49'},{'\xfd','\xa7'},{'\xe8','\x4a'},
+ {'\xbd','\xf8'},{'\xbd','\xfd'},{'\xbd','\xf7'},{'\xbd','\xfe'},{'\xbd','\xf9'},
+ {'\xe8','\x4b'},{'\x00','\x00'},{'\x00','\x00'},{'\xe8','\x4c'},{'\xe8','\x48'},
+ {'\xbe','\x40'},{'\xbd','\xfb'},{'\x00','\x00'},{'\x00','\x00'},{'\xbd','\xfa'},
+ {'\xbd','\xfc'},{'\x00','\x00'},{'\xe8','\x47'},{'\x95','\x70'},{'\xeb','\xca'},
+ {'\xbf','\xe8'},{'\x9e','\x56'},{'\x00','\x00'},{'\xeb','\xcc'},{'\xbf','\xea'},
+ {'\xeb','\xcf'},{'\xeb','\xcb'},{'\xeb','\xc9'},{'\xeb','\xce'},{'\xbf','\xe9'},
+ {'\xeb','\xcd'},{'\x00','\x00'},{'\xbf','\xe7'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xc1','\xd3'},{'\xc1','\xd6'},{'\xee','\xc1'},{'\x9e','\x57'},{'\xc1','\xd4'},
+ {'\xee','\xc0'},{'\xc1','\xd2'},{'\xc1','\xd5'},{'\xf1','\x46'},{'\xf1','\x47'},
+ {'\xf1','\x48'},{'\xc2','\xe0'},{'\x9e','\x58'},{'\xf1','\x49'},{'\x94','\xd5'},
+ {'\xc2','\xe1'},{'\xc3','\xe2'},{'\xf3','\x58'},{'\xf3','\x59'},{'\xf3','\x57'},
+ {'\xf3','\x56'},{'\xf3','\x5a'},{'\xc3','\xe1'},{'\xf4','\xdd'},{'\xf4','\xdb'},
+ {'\xf4','\xdc'},{'\xf4','\xde'},{'\xf4','\xda'},{'\xf4','\xdf'},{'\xf6','\x58'},
+ {'\xfd','\xa9'},{'\xf6','\x59'},{'\xf6','\x57'},{'\xc5','\x46'},{'\xf7','\x64'},
+ {'\xc5','\xaf'},{'\xf7','\x65'},{'\xf8','\x48'},{'\xf8','\x47'},{'\x00','\x00'},
+ {'\x83','\x51'},{'\x83','\x61'},{'\x83','\xa1'},{'\x83','\xde'},{'\x00','\x00'},
+ {'\x83','\xdf'},{'\x8b','\x48'},{'\x84','\xaf'},{'\x88','\x79'},{'\x84','\xb0'},
+ {'\x8c','\xae'},{'\x91','\xaf'},{'\x85','\x6b'},{'\x90','\x6e'},{'\x85','\x6c'},
+ {'\x8d','\xed'},{'\x85','\x6d'},{'\x91','\xb0'},{'\x8d','\xee'},{'\x90','\x5f'},
+ {'\x8d','\xec'},{'\x87','\x60'},{'\x86','\x5f'},{'\x86','\x5e'},{'\x86','\x60'},
+ {'\x8b','\xc8'},{'\x00','\x00'},{'\x8e','\x56'},{'\x8e','\x55'},{'\x86','\x5d'},
+ {'\x87','\x5f'},{'\x87','\x5e'},{'\x88','\x75'},{'\x88','\x78'},{'\x88','\x77'},
+ {'\x88','\x74'},{'\x88','\x7c'},{'\x88','\x7b'},{'\x00','\x00'},{'\x88','\x76'},
+ {'\x88','\x7a'},{'\x89','\x73'},{'\x89','\x70'},{'\x89','\x71'},{'\x00','\x00'},
+ {'\x89','\x72'},{'\x8c','\xe2'},{'\x8a','\x76'},{'\x8a','\x73'},{'\x8a','\x74'},
+ {'\x8f','\xa4'},{'\x8b','\x49'},{'\x8b','\xc7'},{'\xa8','\xaf'},{'\xb6','\x64'},
+ {'\x00','\x00'},{'\x8b','\xc9'},{'\xb9','\x40'},{'\xfd','\x41'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xbb','\xb6'},{'\x00','\x00'},{'\x9e','\x59'},{'\xbf','\xec'},
+ {'\x91','\xb1'},{'\xbf','\xeb'},{'\x8c','\xaf'},{'\x00','\x00'},{'\x8c','\x47'},
+ {'\x00','\x00'},{'\xc3','\xe3'},{'\xc4','\x7c'},{'\xc5','\x47'},{'\xa8','\xb0'},
+ {'\xb0','\x64'},{'\xb9','\x41'},{'\x9e','\x5a'},{'\xf3','\x5b'},{'\xc6','\xd6'},
+ {'\x9c','\xe0'},{'\x94','\xd6'},{'\x9e','\x5b'},{'\x8b','\xca'},{'\x93','\xc3'},
+ {'\x94','\x4e'},{'\x94','\x44'},{'\x89','\x77'},{'\x86','\x63'},{'\xcb','\xa6'},
+ {'\x00','\x00'},{'\x88','\x7e'},{'\xa8','\xb1'},{'\x00','\x00'},{'\xa8','\xb4'},
+ {'\xa8','\xb3'},{'\xa8','\xb2'},{'\x86','\x65'},{'\x8a','\x79'},{'\xcb','\xa5'},
+ {'\x9e','\x5c'},{'\xcd','\xcd'},{'\xa0','\xa4'},{'\xcd','\xcf'},{'\xaa','\xef'},
+ {'\x9e','\x5d'},{'\x86','\x62'},{'\xaa','\xf1'},{'\xcd','\xcc'},{'\xcd','\xce'},
+ {'\xaa','\xf0'},{'\xcd','\xd1'},{'\xcd','\xd0'},{'\xcd','\xd2'},{'\x8a','\x78'},
+ {'\x84','\xb1'},{'\x94','\xd7'},{'\x85','\x6e'},{'\x87','\x61'},{'\x86','\x64'},
+ {'\x84','\xb2'},{'\x89','\x76'},{'\xd0','\xb6'},{'\xd0','\xb4'},{'\xad','\x7c'},
+ {'\xd0','\xb3'},{'\xad','\xa3'},{'\xad','\x7e'},{'\xad','\x7b'},{'\x00','\x00'},
+ {'\xad','\xa4'},{'\x8b','\x4a'},{'\xad','\x7d'},{'\xad','\xa2'},{'\x00','\x00'},
+ {'\xad','\xa1'},{'\xd0','\xb5'},{'\x91','\xb2'},{'\xad','\x7a'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x84','\xb3'},{'\xb0','\x6a'},{'\xd3','\xeb'},{'\xd3','\xf1'},
+ {'\xb0','\x67'},{'\xb0','\x6e'},{'\x95','\xd9'},{'\xb0','\x69'},{'\xd3','\xee'},
+ {'\xd3','\xf0'},{'\xb0','\x6c'},{'\xd3','\xea'},{'\xd3','\xed'},{'\xb0','\x68'},
+ {'\xb0','\x65'},{'\xd3','\xec'},{'\xb0','\x6b'},{'\xd3','\xef'},{'\xb0','\x6d'},
+ {'\xb0','\x66'},{'\x00','\x00'},{'\x9e','\x5e'},{'\x89','\x75'},{'\x87','\x62'},
+ {'\xd7','\xe3'},{'\xd7','\xe6'},{'\xb3','\x70'},{'\x91','\xb3'},{'\xb3','\x7a'},
+ {'\xb3','\x76'},{'\xd7','\xe4'},{'\x87','\x63'},{'\x93','\x7a'},{'\xb3','\x7e'},
+ {'\xb3','\x77'},{'\xb3','\x7c'},{'\xb3','\x72'},{'\x00','\x00'},{'\xb3','\x6f'},
+ {'\xb3','\x71'},{'\xb3','\x7d'},{'\xd7','\xe5'},{'\xb3','\x75'},{'\xb3','\x78'},
+ {'\xb3','\x74'},{'\xb3','\x79'},{'\xd7','\xe7'},{'\xb3','\x7b'},{'\xb3','\x73'},
+ {'\xd7','\xe2'},{'\x00','\x00'},{'\x8d','\x41'},{'\x94','\xd8'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xdc','\x4d'},
+ {'\xb6','\x65'},{'\xdc','\x4f'},{'\x00','\x00'},{'\xb6','\x67'},{'\xb6','\x69'},
+ {'\x9e','\x5f'},{'\xdc','\x4e'},{'\xb6','\x66'},{'\xb6','\x6a'},{'\x9e','\x60'},
+ {'\xb6','\x68'},{'\x91','\xb4'},{'\x00','\x00'},{'\x8d','\x42'},{'\xb9','\x47'},
+ {'\xe0','\xa3'},{'\xb9','\x4f'},{'\xe0','\x7e'},{'\x00','\x00'},{'\xb9','\x50'},
+ {'\xb9','\x45'},{'\x00','\x00'},{'\xe0','\xa1'},{'\x93','\x72'},{'\x00','\x00'},
+ {'\xb9','\x4a'},{'\x00','\x00'},{'\xe0','\xa2'},{'\xb9','\x43'},{'\xb9','\x42'},
+ {'\xfd','\xb6'},{'\xb9','\x4d'},{'\xb9','\x4c'},{'\xb9','\x4b'},{'\xb9','\x49'},
+ {'\xb9','\x4e'},{'\xe0','\x7d'},{'\xb9','\x44'},{'\xb9','\x46'},{'\xb9','\x48'},
+ {'\xfd','\xb5'},{'\x89','\x78'},{'\xbb','\xb8'},{'\xbb','\xbb'},{'\x00','\x00'},
+ {'\xbb','\xbf'},{'\xbb','\xb9'},{'\xbb','\xbe'},{'\xbb','\xbc'},{'\x00','\x00'},
+ {'\xbb','\xb7'},{'\xfe','\x61'},{'\xbb','\xbd'},{'\xbb','\xba'},{'\x9e','\x61'},
+ {'\x91','\xb5'},{'\x00','\x00'},{'\xe8','\x52'},{'\xbe','\x43'},{'\xbe','\x41'},
+ {'\x00','\x00'},{'\xe8','\x53'},{'\x9e','\x62'},{'\xbe','\x44'},{'\xbe','\x42'},
+ {'\xe8','\x51'},{'\xe8','\x50'},{'\x00','\x00'},{'\xbf','\xf0'},{'\xe8','\x4f'},
+ {'\xbf','\xee'},{'\xbf','\xed'},{'\xeb','\xd0'},{'\xbe','\x45'},{'\xbf','\xef'},
+ {'\xeb','\xd1'},{'\xbf','\xf2'},{'\xeb','\xd2'},{'\xbf','\xf1'},{'\xc1','\xd8'},
+ {'\xee','\xc3'},{'\xc1','\xd7'},{'\xc1','\xdc'},{'\xc1','\xda'},{'\xc1','\xdb'},
+ {'\xc2','\xe3'},{'\xc1','\xd9'},{'\xee','\xc2'},{'\xeb','\xd3'},{'\xc2','\xe2'},
+ {'\xc2','\xe4'},{'\x91','\xb6'},{'\xc3','\xe4'},{'\xc3','\xe5'},{'\x00','\x00'},
+ {'\xf4','\xe0'},{'\x00','\x00'},{'\xc5','\xde'},{'\xc5','\xdd'},{'\xa8','\xb6'},
+ {'\x00','\x00'},{'\x88','\xa3'},{'\xca','\x55'},{'\xb0','\x6f'},{'\x00','\x00'},
+ {'\xca','\x52'},{'\xca','\x53'},{'\xca','\x51'},{'\x00','\x00'},{'\xca','\x54'},
+ {'\x00','\x00'},{'\x8f','\xa5'},{'\xcb','\xaa'},{'\xcb','\xa7'},{'\xcb','\xac'},
+ {'\xcb','\xa8'},{'\xa8','\xb7'},{'\xa8','\xba'},{'\x00','\x00'},{'\xcb','\xa9'},
+ {'\xa8','\xb9'},{'\xcb','\xab'},{'\x95','\x40'},{'\x00','\x00'},{'\xa8','\xb8'},
+ {'\x00','\x00'},{'\x8e','\x57'},{'\x00','\x00'},{'\x85','\x6f'},{'\xcd','\xd5'},
+ {'\xcd','\xd7'},{'\xaa','\xf4'},{'\xcd','\xd3'},{'\xcd','\xd6'},{'\xcd','\xd4'},
+ {'\xaa','\xf2'},{'\xaa','\xf5'},{'\x00','\x00'},{'\xaa','\xf3'},{'\x86','\x66'},
+ {'\x89','\x79'},{'\x88','\xa1'},{'\x00','\x00'},{'\xd0','\xb8'},{'\xd0','\xbc'},
+ {'\xd0','\xb9'},{'\x00','\x00'},{'\xad','\xa7'},{'\x00','\x00'},{'\xad','\xa8'},
+ {'\xfd','\xab'},{'\xd0','\xbb'},{'\x00','\x00'},{'\xd0','\xbd'},{'\xd0','\xbf'},
+ {'\x00','\x00'},{'\xad','\xa5'},{'\xd0','\xbe'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xad','\xa6'},{'\x8d','\xc6'},{'\x8e','\xfc'},{'\x88','\xa2'},{'\x00','\x00'},
+ {'\x8d','\xf0'},{'\xd7','\xee'},{'\xd0','\xba'},{'\xd3','\xf2'},{'\xd3','\xfb'},
+ {'\xd3','\xf9'},{'\xd3','\xf4'},{'\xd3','\xf5'},{'\xd3','\xfa'},{'\xd3','\xfc'},
+ {'\xb0','\x71'},{'\x91','\xb7'},{'\xd3','\xf7'},{'\xd3','\xf3'},{'\xb0','\x70'},
+ {'\xb0','\x72'},{'\xd3','\xf6'},{'\xd3','\xfd'},{'\xd3','\xf8'},{'\x8c','\xe3'},
+ {'\x90','\xbb'},{'\xb3','\xa1'},{'\xd7','\xf1'},{'\xd7','\xe9'},{'\xd7','\xef'},
+ {'\xd7','\xf0'},{'\xb3','\xa2'},{'\x00','\x00'},{'\xd7','\xe8'},{'\xd7','\xea'},
+ {'\xd0','\xb7'},{'\xd7','\xec'},{'\xd7','\xed'},{'\xd7','\xeb'},{'\xb6','\x6c'},
+ {'\x00','\x00'},{'\x92','\x7b'},{'\x8e','\xcf'},{'\xdc','\x56'},{'\xeb','\xd4'},
+ {'\xdc','\x57'},{'\xdc','\x54'},{'\xb3','\xa3'},{'\xb6','\x6e'},{'\xdc','\x53'},
+ {'\xdc','\x59'},{'\xdc','\x58'},{'\xb6','\x6b'},{'\xdc','\x5c'},{'\xdc','\x52'},
+ {'\xdc','\x5b'},{'\xdc','\x50'},{'\xdc','\x5a'},{'\xdc','\x55'},{'\xb6','\x6d'},
+ {'\x00','\x00'},{'\xe0','\xaa'},{'\x00','\x00'},{'\xe0','\xa5'},{'\xe0','\xab'},
+ {'\xe0','\xa6'},{'\xe0','\xa4'},{'\xe0','\xa7'},{'\xb9','\x51'},{'\x00','\x00'},
+ {'\xe0','\xa9'},{'\x91','\xb8'},{'\xe0','\xa8'},{'\xb9','\x52'},{'\xbb','\xc1'},
+ {'\xbb','\xc0'},{'\xe4','\x6e'},{'\xe4','\x71'},{'\xe4','\x69'},{'\xe4','\x6d'},
+ {'\xbb','\xc2'},{'\xe4','\x6c'},{'\xe4','\x6a'},{'\xe4','\x70'},{'\xe4','\x6b'},
+ {'\xe4','\x68'},{'\xe4','\x6f'},{'\x00','\x00'},{'\xe8','\x59'},{'\xbe','\x48'},
+ {'\xf1','\x4a'},{'\xe8','\x56'},{'\xe8','\x57'},{'\xe8','\x55'},{'\xdc','\x51'},
+ {'\xbe','\x47'},{'\xe8','\x5a'},{'\xe8','\x54'},{'\xbe','\x46'},{'\xbe','\x49'},
+ {'\xe8','\x58'},{'\xeb','\xd5'},{'\xbf','\xf3'},{'\xeb','\xd6'},{'\xeb','\xd7'},
+ {'\x00','\x00'},{'\xee','\xc4'},{'\xc1','\xdd'},{'\xf1','\x4b'},{'\xf1','\x4c'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xf1','\x4d'},{'\xf3','\x5d'},{'\xf3','\x5c'},
+ {'\xf4','\xe2'},{'\x00','\x00'},{'\xf4','\xe1'},{'\xf6','\x5b'},{'\xf6','\x5c'},
+ {'\xf6','\x5a'},{'\xf7','\x66'},{'\xc5','\xb0'},{'\xa8','\xbb'},{'\xad','\xaa'},
+ {'\xad','\xa9'},{'\xb0','\x75'},{'\xb0','\x74'},{'\xd4','\x40'},{'\xd4','\x41'},
+ {'\xd3','\xfe'},{'\xfd','\xac'},{'\xb0','\x73'},{'\xd7','\xf5'},{'\x92','\xf8'},
+ {'\xd7','\xf6'},{'\xd7','\xf2'},{'\xb3','\xa4'},{'\xd7','\xf3'},{'\xfd','\xaf'},
+ {'\xd7','\xf4'},{'\x00','\x00'},{'\xfd','\xae'},{'\x8a','\x7a'},{'\x96','\xa8'},
+ {'\xdc','\x5f'},{'\xdc','\x61'},{'\xdc','\x5d'},{'\xdc','\x60'},{'\xb6','\x6f'},
+ {'\xdc','\x5e'},{'\xb6','\x70'},{'\x00','\x00'},{'\xfd','\xb0'},{'\xdd','\x73'},
+ {'\xb9','\x55'},{'\xb9','\x54'},{'\x00','\x00'},{'\xb9','\x53'},{'\x00','\x00'},
+ {'\xe0','\xac'},{'\xe0','\xad'},{'\x96','\xa9'},{'\x8b','\x4c'},{'\xe4','\x73'},
+ {'\xe4','\x75'},{'\xbb','\xc6'},{'\xbb','\xc3'},{'\x96','\xa1'},{'\xbb','\xc5'},
+ {'\xbb','\xc4'},{'\xe4','\x74'},{'\xe4','\x72'},{'\x00','\x00'},{'\xfd','\xb1'},
+ {'\x8d','\xa6'},{'\x90','\xa5'},{'\x8d','\x5d'},{'\xe8','\x61'},{'\xe8','\x5e'},
+ {'\xe8','\x5f'},{'\xbe','\x4d'},{'\xe8','\x60'},{'\xe8','\x5b'},{'\xe8','\x5c'},
+ {'\xbe','\x4a'},{'\x00','\x00'},{'\xbe','\x4b'},{'\xe8','\x5d'},{'\xbe','\x4c'},
+ {'\x96','\xaa'},{'\xeb','\xdb'},{'\xfd','\xb2'},{'\xeb','\xdc'},{'\xeb','\xd9'},
+ {'\xeb','\xda'},{'\xbf','\xf4'},{'\xeb','\xd8'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x82','\x79'},{'\x00','\x00'},{'\xee','\xc8'},{'\xee','\xc5'},
+ {'\xee','\xc7'},{'\xc1','\xe0'},{'\xee','\xcb'},{'\xc1','\xdf'},{'\xee','\xc9'},
+ {'\xee','\xcc'},{'\xee','\xca'},{'\xee','\xc6'},{'\xc1','\xde'},{'\x82','\x66'},
+ {'\xf1','\x4f'},{'\x00','\x00'},{'\xf1','\x50'},{'\xf1','\x4e'},{'\x9e','\x63'},
+ {'\xf1','\x52'},{'\xc2','\xe5'},{'\xc2','\xe6'},{'\xf3','\x5f'},{'\xc3','\xe7'},
+ {'\xf1','\x51'},{'\xf3','\x5e'},{'\xc3','\xe6'},{'\xf4','\xe5'},{'\xf4','\xe6'},
+ {'\xc4','\xbf'},{'\xf4','\xe4'},{'\x9e','\x64'},{'\xf4','\xe3'},{'\x92','\xf1'},
+ {'\xf6','\x5d'},{'\xc5','\x48'},{'\xfd','\xb3'},{'\xf8','\x49'},{'\xf8','\xc8'},
+ {'\xf8','\xc7'},{'\x00','\x00'},{'\xc6','\x43'},{'\xc6','\x5d'},{'\xf8','\xc9'},
+ {'\xf9','\x71'},{'\x9e','\x65'},{'\xc6','\x6f'},{'\xa8','\xbc'},{'\xaa','\xf6'},
+ {'\x92','\xd8'},{'\xb9','\x56'},{'\x8c','\x5c'},{'\xc4','\xc0'},{'\xa8','\xbd'},
+ {'\xad','\xab'},{'\xb3','\xa5'},{'\xb6','\x71'},{'\xc2','\xe7'},{'\xaa','\xf7'},
+ {'\x00','\x00'},{'\xd0','\xc1'},{'\xd0','\xc0'},{'\xd4','\x42'},{'\x91','\xb9'},
+ {'\xb0','\x78'},{'\xb0','\x76'},{'\xb0','\x7a'},{'\xd4','\x44'},{'\x91','\xba'},
+ {'\xb0','\x79'},{'\xb0','\x77'},{'\x91','\xbb'},{'\x96','\x49'},{'\x00','\x00'},
+ {'\x91','\xbc'},{'\xd4','\x43'},{'\xb3','\xa8'},{'\xd7','\xfc'},{'\x91','\xbd'},
+ {'\xb3','\xa7'},{'\xb3','\xa9'},{'\xd8','\x42'},{'\xb3','\xab'},{'\xd7','\xfe'},
+ {'\xd8','\x40'},{'\xd7','\xf7'},{'\xb3','\xaa'},{'\xd8','\x43'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xd7','\xf9'},{'\x00','\x00'},{'\xd7','\xfa'},{'\xd7','\xf8'},
+ {'\xb3','\xa6'},{'\x91','\xbe'},{'\xd8','\x41'},{'\xd7','\xfb'},{'\xd7','\xfd'},
+ {'\x9e','\x66'},{'\x00','\x00'},{'\x91','\xbf'},{'\xdc','\x6d'},{'\xfd','\xb7'},
+ {'\xdc','\x6c'},{'\xdc','\x6a'},{'\xdc','\x62'},{'\xdc','\x71'},{'\xdc','\x65'},
+ {'\xdc','\x6f'},{'\xdc','\x76'},{'\xdc','\x6e'},{'\xb6','\x79'},{'\x9e','\x67'},
+ {'\xb6','\x75'},{'\xdc','\x63'},{'\x00','\x00'},{'\xdc','\x69'},{'\xb6','\x77'},
+ {'\x95','\x4c'},{'\xdc','\x68'},{'\xb6','\x78'},{'\xb6','\x7a'},{'\xdc','\x6b'},
+ {'\x9e','\x68'},{'\xb6','\x72'},{'\xb6','\x73'},{'\xdc','\x77'},{'\xdc','\x75'},
+ {'\x00','\x00'},{'\xdc','\x74'},{'\xdc','\x66'},{'\x00','\x00'},{'\xdc','\x72'},
+ {'\x00','\x00'},{'\xb6','\x76'},{'\x00','\x00'},{'\x00','\x00'},{'\x9e','\x69'},
+ {'\x00','\x00'},{'\xb6','\x74'},{'\xdc','\x73'},{'\xdc','\x64'},{'\xdc','\x67'},
+ {'\xdc','\x70'},{'\x9e','\x6a'},{'\x91','\xc0'},{'\xfb','\x5f'},{'\x9e','\x6b'},
+ {'\x91','\xc1'},{'\xe4','\xba'},{'\xe0','\xb7'},{'\x00','\x00'},{'\xe0','\xb0'},
+ {'\xe0','\xc3'},{'\xe0','\xcc'},{'\xe0','\xb3'},{'\xb9','\x61'},{'\x9e','\x6c'},
+ {'\xe0','\xc0'},{'\xb9','\x57'},{'\xb9','\x59'},{'\xb9','\x65'},{'\xe0','\xb1'},
+ {'\x00','\x00'},{'\x9e','\x6d'},{'\xb9','\x5a'},{'\xb9','\x5c'},{'\xb9','\x66'},
+ {'\xb9','\x5b'},{'\x9e','\x6e'},{'\x00','\x00'},{'\x00','\x00'},{'\x93','\x7b'},
+ {'\xb9','\x64'},{'\xe0','\xb9'},{'\x00','\x00'},{'\xe0','\xae'},{'\xb9','\x62'},
+ {'\xe0','\xb8'},{'\xb9','\x5e'},{'\xe0','\xca'},{'\xb9','\x63'},{'\xe0','\xc8'},
+ {'\xe0','\xbc'},{'\xe0','\xc6'},{'\xb9','\x60'},{'\xe0','\xaf'},{'\xe0','\xc9'},
+ {'\xe0','\xc4'},{'\x96','\x40'},{'\xe0','\xcb'},{'\xb9','\x58'},{'\x9e','\x6f'},
+ {'\x91','\xc3'},{'\xb9','\x67'},{'\xb9','\x5d'},{'\x00','\x00'},{'\x9e','\x70'},
+ {'\xe0','\xb5'},{'\x9e','\x71'},{'\xe0','\xbd'},{'\xe0','\xc1'},{'\x95','\xf1'},
+ {'\xe0','\xc5'},{'\xb9','\x5f'},{'\xe0','\xb4'},{'\xe0','\xb2'},{'\xe0','\xbe'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9e','\x72'},{'\xe0','\xbb'},
+ {'\xe0','\xba'},{'\x9e','\x73'},{'\xe0','\xbf'},{'\xe0','\xc2'},{'\x92','\xc0'},
+ {'\xe0','\xc7'},{'\x96','\x43'},{'\x8c','\xe5'},{'\x00','\x00'},{'\xe4','\x78'},
+ {'\x91','\xc4'},{'\xbb','\xc7'},{'\xe4','\xa4'},{'\xe4','\x7a'},{'\xbb','\xcc'},
+ {'\xbb','\xd0'},{'\xe4','\xad'},{'\xe4','\xb5'},{'\xe4','\xa6'},{'\xbb','\xc8'},
+ {'\x9e','\x74'},{'\xe4','\xaa'},{'\xe0','\xb6'},{'\x9e','\x75'},{'\xbb','\xc9'},
+ {'\xe4','\xb1'},{'\xe4','\xb6'},{'\xe4','\xae'},{'\x9e','\x76'},{'\xe4','\xb0'},
+ {'\xe4','\xb9'},{'\xe4','\xb2'},{'\xe4','\x7e'},{'\xe4','\xa9'},{'\x9e','\x77'},
+ {'\x00','\x00'},{'\xbb','\xd1'},{'\x00','\x00'},{'\xbb','\xcd'},{'\xe4','\x7c'},
+ {'\xe4','\xab'},{'\xbb','\xcb'},{'\xe4','\xa5'},{'\xbb','\xca'},{'\xe4','\xb3'},
+ {'\xe4','\xa2'},{'\xe4','\x79'},{'\xbb','\xce'},{'\xe4','\xb8'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xe4','\x7b'},{'\xe4','\xaf'},{'\xe4','\xac'},{'\xe4','\xa7'},
+ {'\xe4','\x77'},{'\xe4','\x76'},{'\xe4','\xa1'},{'\xe4','\xb4'},{'\xbb','\xcf'},
+ {'\xe4','\xb7'},{'\xe4','\x7d'},{'\xe4','\xa3'},{'\xbe','\x52'},{'\x93','\x4b'},
+ {'\x8d','\xa8'},{'\x00','\x00'},{'\x00','\x00'},{'\x9e','\x78'},{'\xbe','\x5a'},
+ {'\xbe','\x55'},{'\xe8','\xa4'},{'\xe8','\xa1'},{'\xe8','\x67'},{'\xbe','\x50'},
+ {'\x00','\x00'},{'\xf9','\xd7'},{'\x9e','\x79'},{'\xbe','\x4f'},{'\xbe','\x56'},
+ {'\x00','\x00'},{'\xfd','\xb9'},{'\x9e','\x7a'},{'\xe8','\x65'},{'\xbe','\x54'},
+ {'\xe8','\x71'},{'\xe8','\x63'},{'\xe8','\x64'},{'\xbe','\x4e'},{'\xe8','\xa3'},
+ {'\xbe','\x58'},{'\xe8','\x74'},{'\xe8','\x79'},{'\xe8','\x73'},{'\xeb','\xee'},
+ {'\xe8','\x6f'},{'\xe8','\x77'},{'\xe8','\x75'},{'\xe8','\x68'},{'\xe8','\x62'},
+ {'\xe8','\x7d'},{'\xbe','\x57'},{'\xe8','\x7e'},{'\x9e','\x7b'},{'\xe8','\x78'},
+ {'\x00','\x00'},{'\xe8','\x6d'},{'\xe8','\x6b'},{'\xe8','\x66'},{'\x00','\x00'},
+ {'\x9e','\x7c'},{'\x00','\x00'},{'\xe8','\x6e'},{'\xe8','\x7b'},{'\xe8','\x6a'},
+ {'\xe8','\x7a'},{'\xe8','\xa2'},{'\x00','\x00'},{'\x9e','\x7d'},{'\xbe','\x53'},
+ {'\x9e','\x7e'},{'\xe8','\x76'},{'\xe8','\x7c'},{'\xe8','\x72'},{'\xe8','\x6c'},
+ {'\xbe','\x51'},{'\x9e','\xa1'},{'\x9e','\xa2'},{'\x91','\xc5'},{'\xe4','\xa8'},
+ {'\xe8','\x70'},{'\xbe','\x59'},{'\xe8','\x69'},{'\x94','\x58'},{'\x93','\x74'},
+ {'\x9e','\xa3'},{'\x00','\x00'},{'\x9e','\xa4'},{'\xeb','\xf4'},{'\xbf','\xf7'},
+ {'\xeb','\xf3'},{'\xeb','\xf0'},{'\xec','\x44'},{'\xbf','\xfb'},{'\x9e','\xa5'},
+ {'\xec','\x41'},{'\xeb','\xf8'},{'\xec','\x43'},{'\xeb','\xe9'},{'\xeb','\xf6'},
+ {'\x9e','\xa6'},{'\xbf','\xfd'},{'\x00','\x00'},{'\xeb','\xe1'},{'\x9e','\xa7'},
+ {'\xeb','\xdf'},{'\xec','\x42'},{'\x00','\x00'},{'\xec','\x40'},{'\xeb','\xfe'},
+ {'\xeb','\xed'},{'\xeb','\xec'},{'\xeb','\xe2'},{'\xc0','\x40'},{'\x00','\x00'},
+ {'\xeb','\xe8'},{'\xeb','\xf2'},{'\xeb','\xfd'},{'\xc0','\x43'},{'\xec','\x45'},
+ {'\x00','\x00'},{'\xc1','\xe8'},{'\xc0','\x45'},{'\xbf','\xfe'},{'\xeb','\xe6'},
+ {'\x00','\x00'},{'\xeb','\xef'},{'\xeb','\xde'},{'\xeb','\xe0'},{'\xbf','\xf5'},
+ {'\xc0','\x42'},{'\xbf','\xfa'},{'\xeb','\xe7'},{'\xeb','\xf7'},{'\xeb','\xf1'},
+ {'\xc0','\x41'},{'\xeb','\xdd'},{'\xc1','\xe3'},{'\xeb','\xf9'},{'\xeb','\xfc'},
+ {'\xbf','\xfc'},{'\x93','\xf3'},{'\xeb','\xeb'},{'\xc0','\x44'},{'\xbf','\xf9'},
+ {'\x9e','\xa8'},{'\x9e','\xa9'},{'\x93','\xf7'},{'\xbf','\xf8'},{'\xeb','\xf5'},
+ {'\xeb','\xfb'},{'\xbf','\xf6'},{'\x00','\x00'},{'\xeb','\xe4'},{'\xeb','\xfa'},
+ {'\x91','\xc6'},{'\x94','\xdb'},{'\xeb','\xe5'},{'\x00','\x00'},{'\x8b','\xd6'},
+ {'\x00','\x00'},{'\x9e','\xaa'},{'\xfe','\x7c'},{'\x9e','\xab'},{'\x9e','\xac'},
+ {'\x97','\x55'},{'\x96','\x42'},{'\xeb','\xea'},{'\xee','\xd2'},{'\xfe','\x79'},
+ {'\xee','\xd7'},{'\xc1','\xe5'},{'\xc1','\xe7'},{'\xee','\xdd'},{'\xc1','\xe1'},
+ {'\xee','\xec'},{'\xee','\xe3'},{'\xee','\xd8'},{'\xee','\xd9'},{'\xee','\xe2'},
+ {'\x00','\x00'},{'\xc1','\xee'},{'\xee','\xe1'},{'\xee','\xd1'},{'\xee','\xe0'},
+ {'\xee','\xd4'},{'\xee','\xed'},{'\xc1','\xed'},{'\xc1','\xeb'},{'\xee','\xd5'},
+ {'\x00','\x00'},{'\xee','\xe8'},{'\x9e','\xad'},{'\xee','\xda'},{'\xee','\xe7'},
+ {'\x9e','\xae'},{'\xee','\xe9'},{'\xee','\xd0'},{'\xc1','\xe6'},{'\x9e','\xaf'},
+ {'\xee','\xea'},{'\x9e','\xb0'},{'\x96','\x44'},{'\xee','\xde'},{'\xfd','\xba'},
+ {'\xc1','\xea'},{'\xee','\xdb'},{'\xfd','\xbb'},{'\x00','\x00'},{'\xc1','\xec'},
+ {'\xee','\xe4'},{'\x00','\x00'},{'\x9e','\xb1'},{'\x9e','\xb2'},{'\xc1','\xe4'},
+ {'\xee','\xd6'},{'\xee','\xe5'},{'\x9e','\xb3'},{'\xee','\xdf'},{'\xeb','\xe3'},
+ {'\xee','\xe6'},{'\xee','\xd3'},{'\x9e','\xb4'},{'\xc1','\xe9'},{'\x00','\x00'},
+ {'\xee','\xeb'},{'\x9e','\xb5'},{'\xc1','\xe2'},{'\xee','\xce'},{'\x9e','\xb6'},
+ {'\xfb','\x73'},{'\x9e','\xb7'},{'\x9e','\xb8'},{'\xf1','\x60'},{'\xf1','\x59'},
+ {'\xc2','\xe9'},{'\x00','\x00'},{'\xf1','\x54'},{'\xf1','\x63'},{'\xf1','\x5b'},
+ {'\xee','\xdc'},{'\x9e','\xb9'},{'\xf1','\x65'},{'\xf1','\x55'},{'\x00','\x00'},
+ {'\xc2','\xe8'},{'\xf1','\x5f'},{'\xc2','\xea'},{'\xc2','\xf2'},{'\xc2','\xf0'},
+ {'\xf1','\x61'},{'\xc2','\xf1'},{'\xf1','\x57'},{'\x9e','\xba'},{'\xf1','\x58'},
+ {'\xf1','\x5d'},{'\xf1','\x62'},{'\x9e','\xbb'},{'\xee','\xcd'},{'\xc2','\xeb'},
+ {'\xf1','\x6a'},{'\xf1','\x67'},{'\xf1','\x6b'},{'\xf1','\x5e'},{'\xf1','\x5a'},
+ {'\xf1','\x68'},{'\xf3','\x6a'},{'\xf1','\x5c'},{'\x00','\x00'},{'\xc2','\xee'},
+ {'\x97','\x56'},{'\xc2','\xed'},{'\xee','\xcf'},{'\xc2','\xef'},{'\xf1','\x64'},
+ {'\xf1','\x66'},{'\xc2','\xec'},{'\xf1','\x69'},{'\xf1','\x53'},{'\x00','\x00'},
+ {'\xf1','\x56'},{'\x9e','\xbc'},{'\x94','\xdc'},{'\xfd','\xbc'},{'\x9e','\xbd'},
+ {'\x00','\x00'},{'\x9e','\xbe'},{'\x00','\x00'},{'\x9e','\xbf'},{'\xf3','\x73'},
+ {'\x00','\x00'},{'\xf3','\x63'},{'\xc3','\xeb'},{'\xf3','\x71'},{'\x00','\x00'},
+ {'\x97','\x57'},{'\xf3','\x61'},{'\xc3','\xec'},{'\x00','\x00'},{'\xf3','\x6c'},
+ {'\x9e','\xc0'},{'\xf3','\x68'},{'\xc3','\xf1'},{'\xf3','\x72'},{'\xf3','\x62'},
+ {'\xf3','\x65'},{'\xc3','\xe9'},{'\xf3','\x74'},{'\x9e','\xc1'},{'\xf3','\x6d'},
+ {'\xf3','\x70'},{'\xc3','\xef'},{'\xc3','\xf4'},{'\xc3','\xf2'},{'\xf3','\x69'},
+ {'\xf3','\x64'},{'\x9e','\xc2'},{'\xc3','\xed'},{'\xc3','\xee'},{'\xf3','\x60'},
+ {'\xc3','\xea'},{'\x9e','\xc3'},{'\xc3','\xe8'},{'\xc3','\xf0'},{'\xf3','\x6f'},
+ {'\xc3','\xf3'},{'\x97','\x58'},{'\xf3','\x6b'},{'\xf3','\x75'},{'\xc3','\xf5'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xf3','\x67'},{'\x00','\x00'},
+ {'\xf3','\x6e'},{'\x00','\x00'},{'\x9e','\xc4'},{'\x9e','\xc5'},{'\x00','\x00'},
+ {'\x9e','\xc6'},{'\x9e','\xc7'},{'\xf4','\xf3'},{'\xf5','\x42'},{'\xf4','\xf5'},
+ {'\xf4','\xfc'},{'\xf3','\x66'},{'\xf4','\xfa'},{'\xf4','\xe9'},{'\xf5','\x40'},
+ {'\xc4','\xc3'},{'\xf4','\xed'},{'\xf4','\xfe'},{'\xf4','\xf4'},{'\x9e','\xc8'},
+ {'\x00','\x00'},{'\xc4','\xc2'},{'\x9e','\xc9'},{'\x00','\x00'},{'\xf5','\x44'},
+ {'\xf4','\xf6'},{'\x9e','\xca'},{'\xf4','\xfb'},{'\xf4','\xfd'},{'\xf4','\xe7'},
+ {'\xf5','\x41'},{'\xf4','\xf2'},{'\xf4','\xf7'},{'\xf4','\xeb'},{'\xf4','\xef'},
+ {'\xf5','\x43'},{'\xf4','\xf9'},{'\xf4','\xe8'},{'\xf4','\xec'},{'\xf4','\xee'},
+ {'\xf4','\xf8'},{'\x9e','\xcb'},{'\xc4','\xc1'},{'\xf4','\xf1'},{'\x97','\x59'},
+ {'\x9e','\xcc'},{'\x00','\x00'},{'\x9e','\xcd'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xf4','\xea'},{'\x97','\x5a'},{'\x00','\x00'},{'\x00','\x00'},{'\x9e','\xce'},
+ {'\x9e','\xcf'},{'\x9e','\xd0'},{'\xfd','\xbd'},{'\xf4','\xf0'},{'\xf6','\x61'},
+ {'\xf6','\x66'},{'\xc5','\x4f'},{'\xf6','\x68'},{'\x9e','\xd1'},{'\xc5','\x49'},
+ {'\x00','\x00'},{'\xf6','\x64'},{'\xf6','\x6a'},{'\xc5','\x4e'},{'\xc5','\x4a'},
+ {'\x00','\x00'},{'\xc5','\x4b'},{'\xf6','\x60'},{'\xf6','\x67'},{'\xc5','\x4d'},
+ {'\xf6','\x65'},{'\xc5','\x4c'},{'\xf6','\x5f'},{'\xf6','\x63'},{'\xf6','\x62'},
+ {'\x97','\x5b'},{'\xf6','\x5e'},{'\xf6','\x69'},{'\x97','\x5c'},{'\x9e','\xd2'},
+ {'\x9e','\xd3'},{'\xc5','\xb1'},{'\xf7','\x6d'},{'\xf7','\x70'},{'\xf7','\x6c'},
+ {'\xf7','\x6e'},{'\xf7','\x6f'},{'\xf7','\x69'},{'\xf7','\x6a'},{'\xf7','\x67'},
+ {'\x9e','\xd4'},{'\x00','\x00'},{'\xf7','\x6b'},{'\xf7','\x68'},{'\xc5','\xb2'},
+ {'\xc5','\xb3'},{'\x97','\x5d'},{'\x9e','\xd5'},{'\xf8','\x4b'},{'\x00','\x00'},
+ {'\xf8','\x4d'},{'\x9e','\xd6'},{'\x00','\x00'},{'\x97','\x5e'},{'\x95','\x58'},
+ {'\x00','\x00'},{'\xf8','\x4c'},{'\xf8','\x4e'},{'\x00','\x00'},{'\xc5','\xe0'},
+ {'\x00','\x00'},{'\xf8','\x4a'},{'\xc5','\xdf'},{'\xc5','\xe1'},{'\x9e','\xd7'},
+ {'\x00','\x00'},{'\x9e','\xd8'},{'\xf8','\xcb'},{'\xf8','\xcc'},{'\xc6','\x44'},
+ {'\xf8','\xca'},{'\x9e','\xd9'},{'\xf9','\x53'},{'\xf9','\x52'},{'\xf9','\x54'},
+ {'\xc6','\x5f'},{'\xf9','\x55'},{'\xc6','\x5e'},{'\xf9','\x56'},{'\xf9','\x72'},
+ {'\xf9','\x75'},{'\xf9','\x74'},{'\xc6','\x68'},{'\xf9','\x73'},{'\x9e','\xda'},
+ {'\x00','\x00'},{'\x9e','\xdb'},{'\xc6','\x72'},{'\xc6','\x70'},{'\xc6','\x71'},
+ {'\xc6','\x77'},{'\xf9','\xc0'},{'\xf9','\xc1'},{'\xf9','\xbf'},{'\xf9','\xc9'},
+ {'\x00','\x00'},{'\x9c','\xf0'},{'\x8d','\xc1'},{'\x8d','\xc0'},{'\x83','\xe1'},
+ {'\x83','\xe0'},{'\x83','\xe2'},{'\x83','\xe3'},{'\x8d','\xc7'},{'\x8d','\xd9'},
+ {'\x8d','\xd6'},{'\x84','\xb6'},{'\x8d','\xd7'},{'\x00','\x00'},{'\x84','\xb7'},
+ {'\x84','\xb5'},{'\x8f','\x46'},{'\x8d','\xd8'},{'\x00','\x00'},{'\x84','\xb4'},
+ {'\x00','\x00'},{'\x85','\x73'},{'\x97','\x5f'},{'\x8d','\xf4'},{'\x86','\x73'},
+ {'\x85','\x76'},{'\x85','\x71'},{'\x8c','\x5d'},{'\x85','\x74'},{'\x88','\xae'},
+ {'\x89','\xa1'},{'\x85','\x78'},{'\x85','\x77'},{'\x8d','\x76'},{'\x84','\xe8'},
+ {'\x85','\x75'},{'\x8b','\x4f'},{'\x86','\x6e'},{'\x8d','\xf7'},{'\x8d','\xf2'},
+ {'\x8d','\xf3'},{'\x8d','\xf6'},{'\x85','\x72'},{'\x8d','\xf5'},{'\x8e','\x5a'},
+ {'\x89','\x7e'},{'\x8e','\x5b'},{'\x86','\x68'},{'\x86','\x67'},{'\x84','\x73'},
+ {'\x8e','\x5c'},{'\x97','\x60'},{'\x86','\x6a'},{'\x86','\x69'},{'\x8d','\xb2'},
+ {'\x8d','\xa7'},{'\x8e','\x60'},{'\x8e','\x5f'},{'\x86','\x6b'},{'\x86','\x75'},
+ {'\x86','\x6c'},{'\x8c','\xb2'},{'\x86','\x6f'},{'\x86','\x70'},{'\x8d','\x44'},
+ {'\x86','\x6d'},{'\x86','\x76'},{'\x00','\x00'},{'\x8e','\x59'},{'\x86','\x71'},
+ {'\x8e','\x58'},{'\x86','\x72'},{'\x8e','\x5e'},{'\x86','\x74'},{'\x8c','\xb4'},
+ {'\x00','\x00'},{'\x88','\xa8'},{'\x8e','\xa5'},{'\x8e','\xa4'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x8e','\xa6'},{'\x8e','\xac'},{'\x8e','\xd1'},{'\x97','\x61'},
+ {'\x8c','\x5e'},{'\x00','\x00'},{'\x8c','\xb3'},{'\x87','\x66'},{'\x88','\xaa'},
+ {'\x97','\x62'},{'\x8e','\xa7'},{'\x8f','\xa7'},{'\x8f','\x6a'},{'\x87','\x68'},
+ {'\x87','\x6c'},{'\x8e','\xd5'},{'\x8e','\xad'},{'\x00','\x00'},{'\x8f','\xec'},
+ {'\x87','\x6a'},{'\x8f','\xcd'},{'\x8e','\xaa'},{'\x8e','\xa8'},{'\x87','\x69'},
+ {'\x87','\x67'},{'\x89','\xa4'},{'\x8e','\xa9'},{'\x87','\x64'},{'\x8e','\xa3'},
+ {'\x85','\xb6'},{'\x97','\x63'},{'\x8f','\xe5'},{'\x87','\x6b'},{'\x87','\x65'},
+ {'\x8e','\xab'},{'\x8c','\xe4'},{'\x8f','\xee'},{'\x88','\xa7'},{'\x00','\x00'},
+ {'\x8f','\x42'},{'\x8e','\xd2'},{'\x8b','\xce'},{'\x8b','\xd5'},{'\x88','\xa6'},
+ {'\x8b','\x4e'},{'\x88','\xaf'},{'\x97','\x64'},{'\x88','\xa9'},{'\x8a','\xa2'},
+ {'\x8e','\xd6'},{'\x8e','\xd7'},{'\x8c','\x5f'},{'\x88','\xac'},{'\x8e','\xd4'},
+ {'\x88','\xad'},{'\x88','\xa4'},{'\x8e','\x5d'},{'\x97','\x65'},{'\x97','\x66'},
+ {'\x88','\xab'},{'\x88','\xa5'},{'\x8e','\xd0'},{'\x8e','\xd3'},{'\x8e','\xd8'},
+ {'\x8f','\x44'},{'\x8f','\x40'},{'\x8f','\x41'},{'\x97','\x67'},{'\x89','\x7d'},
+ {'\x8a','\x7d'},{'\x8f','\x43'},{'\x00','\x00'},{'\x97','\x68'},{'\x8f','\x45'},
+ {'\x89','\xa7'},{'\x00','\x00'},{'\x89','\xa2'},{'\x89','\xa8'},{'\x8d','\xa9'},
+ {'\x8a','\xa3'},{'\x89','\xa5'},{'\x89','\xa6'},{'\x00','\x00'},{'\x90','\xf1'},
+ {'\x8e','\xfd'},{'\x97','\x69'},{'\x97','\x6a'},{'\x8e','\xfe'},{'\x89','\x7a'},
+ {'\x8a','\x7e'},{'\x89','\x7b'},{'\x89','\x7c'},{'\x89','\xa9'},{'\x8a','\xa1'},
+ {'\x00','\x00'},{'\x8f','\x69'},{'\x8b','\xd3'},{'\x8f','\x6b'},{'\x8a','\xa8'},
+ {'\x8f','\x68'},{'\x8a','\xa5'},{'\x8a','\xa4'},{'\x8a','\xa6'},{'\x8f','\xa8'},
+ {'\x00','\x00'},{'\x8a','\xa7'},{'\x97','\x6b'},{'\x8a','\x7b'},{'\x8a','\x7c'},
+ {'\x8b','\xd4'},{'\x00','\x00'},{'\x8f','\xea'},{'\x97','\x6c'},{'\x8a','\x42'},
+ {'\x8b','\x51'},{'\x00','\x00'},{'\x8b','\x54'},{'\x8d','\x7d'},{'\x00','\x00'},
+ {'\x8c','\xb6'},{'\x8b','\x50'},{'\x97','\x6d'},{'\x8f','\xa9'},{'\x8b','\x52'},
+ {'\x8b','\x4d'},{'\x8b','\x53'},{'\x8f','\xa6'},{'\x90','\x60'},{'\x00','\x00'},
+ {'\x8b','\xd1'},{'\x8b','\xcf'},{'\x8b','\xd0'},{'\x8b','\xd2'},{'\x00','\x00'},
+ {'\x8f','\xc9'},{'\x8b','\xcb'},{'\x8b','\xcc'},{'\x8b','\xcd'},{'\x8f','\xca'},
+ {'\x00','\x00'},{'\x8f','\xe8'},{'\x97','\x6e'},{'\x8f','\xe9'},{'\x8f','\xed'},
+ {'\x97','\x6f'},{'\x8f','\xe6'},{'\x90','\xa1'},{'\x8f','\xe7'},{'\x97','\x70'},
+ {'\x8f','\xcb'},{'\x8f','\xeb'},{'\x90','\x61'},{'\x8c','\xb1'},{'\x00','\x00'},
+ {'\x8c','\xb5'},{'\x8c','\xb0'},{'\x90','\x48'},{'\x97','\x71'},{'\x8d','\x43'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x8c','\x7c'},{'\xaa','\xf8'},{'\x9e','\xdc'},
+ {'\x00','\x00'},{'\xd8','\x44'},{'\xdc','\x78'},{'\xe8','\xa5'},{'\xf3','\x76'},
+ {'\x00','\x00'},{'\x83','\x63'},{'\xaa','\xf9'},{'\x00','\x00'},{'\xad','\xac'},
+ {'\xb0','\x7b'},{'\x00','\x00'},{'\x9e','\xdd'},{'\xd8','\x45'},{'\x97','\x72'},
+ {'\xd8','\x46'},{'\xb3','\xac'},{'\x94','\xdd'},{'\xb6','\x7d'},{'\xdc','\x7a'},
+ {'\xdc','\x79'},{'\xb6','\xa3'},{'\xb6','\x7c'},{'\xdc','\x7b'},{'\xb6','\x7e'},
+ {'\xb6','\xa2'},{'\xb6','\xa1'},{'\xb6','\x7b'},{'\x00','\x00'},{'\x94','\xde'},
+ {'\xfd','\xbe'},{'\xb9','\x68'},{'\x97','\x73'},{'\x00','\x00'},{'\xe0','\xd0'},
+ {'\xe0','\xce'},{'\x00','\x00'},{'\xe0','\xcf'},{'\xe0','\xcd'},{'\x97','\x74'},
+ {'\xbb','\xd2'},{'\x92','\x6b'},{'\xbb','\xd5'},{'\xbb','\xd7'},{'\xbb','\xd6'},
+ {'\x9e','\xde'},{'\xfd','\xbf'},{'\xbb','\xd3'},{'\xbb','\xd4'},{'\x9e','\xdf'},
+ {'\xe8','\xa7'},{'\xe8','\xa6'},{'\xbe','\x5b'},{'\xe8','\xa8'},{'\x00','\x00'},
+ {'\xe8','\xa9'},{'\xbe','\x5c'},{'\x97','\x75'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xec','\x4d'},{'\xec','\x4b'},{'\xee','\xf3'},{'\x00','\x00'},{'\xec','\x49'},
+ {'\xec','\x4a'},{'\xc0','\x46'},{'\xec','\x46'},{'\xec','\x4e'},{'\xec','\x48'},
+ {'\xec','\x4c'},{'\xee','\xef'},{'\x00','\x00'},{'\x00','\x00'},{'\xee','\xf1'},
+ {'\x00','\x00'},{'\xee','\xf2'},{'\xc1','\xf3'},{'\xee','\xee'},{'\xc1','\xf2'},
+ {'\xee','\xf0'},{'\xc1','\xef'},{'\xc1','\xf0'},{'\xc1','\xf1'},{'\xec','\x47'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc2','\xf5'},{'\xf1','\x6e'},{'\xf1','\x6c'},
+ {'\xf1','\x6d'},{'\xc2','\xf3'},{'\xc2','\xf6'},{'\xc2','\xf4'},{'\x00','\x00'},
+ {'\x93','\xa7'},{'\x00','\x00'},{'\xf3','\x77'},{'\xf3','\x78'},{'\xc3','\xf6'},
+ {'\x00','\x00'},{'\xf5','\x45'},{'\xf5','\x47'},{'\xf5','\x46'},{'\xc4','\xc4'},
+ {'\xc5','\x50'},{'\xf6','\x6d'},{'\xf6','\x6c'},{'\xf6','\x6b'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x83','\x64'},{'\x83','\xa2'},{'\x83','\xe4'},{'\x8d','\xda'},
+ {'\x00','\x00'},{'\x84','\xb8'},{'\x83','\xf4'},{'\x8b','\x56'},{'\x85','\x7a'},
+ {'\x8a','\xac'},{'\x85','\x7c'},{'\x85','\x7e'},{'\x85','\x7d'},{'\x85','\x79'},
+ {'\x8d','\xf8'},{'\x84','\xdd'},{'\x86','\x77'},{'\x88','\xc1'},{'\x87','\x6e'},
+ {'\x87','\x47'},{'\x90','\x49'},{'\x87','\x6f'},{'\x88','\xb0'},{'\x00','\x00'},
+ {'\x87','\x71'},{'\x87','\x70'},{'\x87','\x6d'},{'\x8e','\xda'},{'\x90','\xac'},
+ {'\x88','\xb1'},{'\x8e','\xd9'},{'\x00','\x00'},{'\x8f','\x48'},{'\x8f','\x49'},
+ {'\x8f','\x4a'},{'\x8f','\xb0'},{'\x8f','\x4b'},{'\x8f','\x4c'},{'\x89','\xaa'},
+ {'\x8f','\x47'},{'\x8c','\x60'},{'\x8a','\xab'},{'\x8f','\x6c'},{'\x00','\x00'},
+ {'\x8a','\xa9'},{'\x8a','\xaa'},{'\x8b','\x55'},{'\x8b','\x57'},{'\x00','\x00'},
+ {'\x8b','\x58'},{'\x8f','\xef'},{'\x00','\x00'},{'\xaa','\xfa'},{'\x9c','\xf1'},
+ {'\xc9','\xaa'},{'\x85','\xa1'},{'\xca','\x58'},{'\xa6','\xe9'},{'\xca','\x56'},
+ {'\xca','\x59'},{'\xca','\x57'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xcb','\xae'},{'\x00','\x00'},{'\xa8','\xc1'},{'\x00','\x00'},{'\xa8','\xc2'},
+ {'\xcb','\xb0'},{'\xa8','\xbf'},{'\xcb','\xaf'},{'\xcb','\xad'},{'\xa8','\xc0'},
+ {'\xa8','\xbe'},{'\x85','\xa3'},{'\x84','\xbb'},{'\x83','\xe5'},{'\x85','\xa2'},
+ {'\x00','\x00'},{'\xfd','\xc1'},{'\xcd','\xd8'},{'\xcd','\xdb'},{'\xaa','\xfd'},
+ {'\xcd','\xda'},{'\xcd','\xd9'},{'\x00','\x00'},{'\xaa','\xfc'},{'\xaa','\xfb'},
+ {'\xfe','\x42'},{'\xab','\x40'},{'\xcd','\xdc'},{'\xaa','\xfe'},{'\x87','\x72'},
+ {'\x84','\xba'},{'\x8b','\xd8'},{'\x84','\xb9'},{'\x83','\xe7'},{'\xd0','\xc6'},
+ {'\xad','\xae'},{'\xad','\xaf'},{'\xad','\xb0'},{'\xd0','\xc7'},{'\xd0','\xc3'},
+ {'\xad','\xad'},{'\xd0','\xc4'},{'\x00','\x00'},{'\xd0','\xc5'},{'\xd0','\xc2'},
+ {'\x83','\xe6'},{'\x9e','\xe0'},{'\x00','\x00'},{'\xb0','\xa4'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xb0','\xa1'},{'\xd4','\x45'},{'\xb0','\xa2'},{'\xb0','\xa5'},
+ {'\xd4','\x46'},{'\x00','\x00'},{'\xb0','\x7e'},{'\xb0','\x7c'},{'\xb0','\x7d'},
+ {'\xb0','\xa3'},{'\x92','\x67'},{'\x97','\x76'},{'\x8d','\xf9'},{'\x86','\x78'},
+ {'\x89','\xac'},{'\xb3','\xad'},{'\xd8','\x49'},{'\xb3','\xb5'},{'\xd8','\x48'},
+ {'\x00','\x00'},{'\xd8','\x4b'},{'\xb3','\xb1'},{'\xd8','\x4a'},{'\xb6','\xab'},
+ {'\xb3','\xaf'},{'\xb3','\xb2'},{'\xb3','\xae'},{'\xb3','\xb3'},{'\xb3','\xb4'},
+ {'\xb3','\xb0'},{'\x00','\x00'},{'\x92','\xb4'},{'\x9e','\xe1'},{'\xd8','\x47'},
+ {'\xb6','\xa7'},{'\xdc','\x7d'},{'\x00','\x00'},{'\xdc','\xa3'},{'\xfd','\xc5'},
+ {'\x00','\x00'},{'\xdc','\xa2'},{'\xb6','\xac'},{'\xb6','\xa8'},{'\xb6','\xa9'},
+ {'\xdc','\x7c'},{'\xdc','\x7e'},{'\xdc','\xa1'},{'\xb6','\xa4'},{'\xb6','\xa6'},
+ {'\x00','\x00'},{'\xb6','\xaa'},{'\xb6','\xa5'},{'\x92','\xfa'},{'\x8a','\xad'},
+ {'\xe0','\xd3'},{'\xe0','\xd1'},{'\xe0','\xd2'},{'\xb9','\x6a'},{'\xb9','\x6b'},
+ {'\xfd','\xc4'},{'\xe0','\xd4'},{'\xb9','\x69'},{'\xbb','\xd8'},{'\x00','\x00'},
+ {'\xbb','\xda'},{'\xbb','\xd9'},{'\x97','\x77'},{'\xe4','\xbb'},{'\x00','\x00'},
+ {'\x92','\x47'},{'\xe4','\xbc'},{'\xe8','\xab'},{'\x95','\xf9'},{'\xe8','\xaa'},
+ {'\x9e','\xe2'},{'\x00','\x00'},{'\xc0','\x47'},{'\xc0','\x48'},{'\xec','\x4f'},
+ {'\xc0','\x49'},{'\x00','\x00'},{'\xee','\xf6'},{'\x00','\x00'},{'\xee','\xf4'},
+ {'\x97','\x78'},{'\xee','\xf5'},{'\xc1','\xf4'},{'\x97','\x79'},{'\xf1','\x6f'},
+ {'\xc3','\xf7'},{'\x00','\x00'},{'\xc6','\xd7'},{'\x95','\xfb'},{'\xc1','\xf5'},
+ {'\xab','\x41'},{'\x00','\x00'},{'\xb0','\xa6'},{'\xd4','\x47'},{'\x86','\x79'},
+ {'\x8b','\xd9'},{'\xd8','\x4c'},{'\xb3','\xb6'},{'\xb6','\xad'},{'\xdc','\xa4'},
+ {'\xdc','\xa6'},{'\xb6','\xaf'},{'\xb6','\xae'},{'\xb6','\xb0'},{'\xb6','\xb1'},
+ {'\xdc','\xa5'},{'\xb9','\x6e'},{'\xb9','\x6f'},{'\xb9','\x6d'},{'\xbb','\xdb'},
+ {'\xb9','\x6c'},{'\xe0','\xd5'},{'\x8b','\x5b'},{'\x00','\x00'},{'\x92','\xca'},
+ {'\xbb','\xdc'},{'\xe8','\xac'},{'\xec','\x50'},{'\xc0','\x4a'},{'\xc1','\xf6'},
+ {'\xf1','\x70'},{'\xf1','\x74'},{'\xc2','\xf9'},{'\xf1','\x71'},{'\xc2','\xfa'},
+ {'\xc2','\xf8'},{'\xf1','\x75'},{'\xc2','\xfb'},{'\xf1','\x73'},{'\x90','\x6d'},
+ {'\xf3','\x79'},{'\xc2','\xf7'},{'\xc3','\xf8'},{'\x00','\x00'},{'\xf8','\xcd'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xab','\x42'},{'\xb3','\xb8'},{'\xb3','\xb7'},
+ {'\x94','\x48'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xb6','\xb2'},
+ {'\xdc','\xa8'},{'\xdc','\xa7'},{'\xb6','\xb3'},{'\x8d','\x5e'},{'\x9e','\xe3'},
+ {'\xe0','\xd9'},{'\xb9','\x73'},{'\xb9','\x70'},{'\xe0','\xd8'},{'\xb9','\x72'},
+ {'\xe0','\xd6'},{'\xb9','\x71'},{'\x00','\x00'},{'\xe0','\xd7'},{'\x8b','\xda'},
+ {'\xe4','\xbd'},{'\xbb','\xdd'},{'\x8c','\xe6'},{'\xe8','\xaf'},{'\xfd','\xc7'},
+ {'\xbe','\x5d'},{'\xe8','\xad'},{'\xbe','\x5e'},{'\xbe','\x5f'},{'\xe8','\xae'},
+ {'\xbe','\x60'},{'\x93','\xed'},{'\xec','\x51'},{'\x00','\x00'},{'\xc0','\x4e'},
+ {'\xc0','\x4b'},{'\xc0','\x50'},{'\xec','\x53'},{'\xc0','\x4c'},{'\xec','\x52'},
+ {'\xc0','\x4f'},{'\x00','\x00'},{'\x00','\x00'},{'\xc0','\x4d'},{'\x00','\x00'},
+ {'\xee','\xf9'},{'\xee','\xfb'},{'\x00','\x00'},{'\x9e','\xe4'},{'\xc1','\xf7'},
+ {'\xee','\xfa'},{'\xc1','\xf8'},{'\xee','\xf8'},{'\xee','\xf7'},{'\xfd','\xc8'},
+ {'\xf1','\x77'},{'\xf1','\x76'},{'\xc2','\xfc'},{'\xf1','\x78'},{'\xf3','\x7e'},
+ {'\xc3','\xfa'},{'\xf3','\x7d'},{'\xf3','\x7a'},{'\xc3','\xf9'},{'\xf3','\x7b'},
+ {'\xf3','\x7c'},{'\x8d','\x60'},{'\xf5','\x48'},{'\xf5','\x49'},{'\xc4','\xc5'},
+ {'\xfd','\xc9'},{'\xc5','\x53'},{'\x97','\x7a'},{'\x9d','\xbb'},{'\xf6','\x6e'},
+ {'\x9e','\xe5'},{'\x00','\x00'},{'\xc5','\x51'},{'\xc5','\x52'},{'\xf6','\x6f'},
+ {'\x97','\x7b'},{'\x00','\x00'},{'\xc5','\xb4'},{'\xc5','\xb5'},{'\xf7','\x71'},
+ {'\x9e','\xe6'},{'\x9e','\xe7'},{'\xc6','\x45'},{'\xf8','\xcf'},{'\xc6','\x47'},
+ {'\x00','\x00'},{'\xf8','\xce'},{'\xf8','\xd0'},{'\xc6','\x46'},{'\xf9','\x57'},
+ {'\x00','\x00'},{'\xf9','\xad'},{'\x00','\x00'},{'\x97','\x7c'},{'\x00','\x00'},
+ {'\x97','\x7d'},{'\x00','\x00'},{'\x97','\x7e'},{'\xab','\x43'},{'\x8e','\xdb'},
+ {'\x00','\x00'},{'\x97','\xa1'},{'\xb9','\x74'},{'\x9e','\xe8'},{'\xe4','\xbe'},
+ {'\x93','\x43'},{'\xe8','\xb0'},{'\xc0','\x51'},{'\xc0','\x52'},{'\xfe','\x6d'},
+ {'\xab','\x44'},{'\xfd','\xca'},{'\xbe','\x61'},{'\xc3','\xfb'},{'\xad','\xb1'},
+ {'\x00','\x00'},{'\x97','\xa2'},{'\x8d','\x45'},{'\xc0','\x53'},{'\x00','\x00'},
+ {'\xc5','\xe2'},{'\xad','\xb2'},{'\xd8','\x4d'},{'\x97','\xa3'},{'\xdc','\xa9'},
+ {'\x95','\xf7'},{'\xdc','\xab'},{'\x00','\x00'},{'\xdc','\xaa'},{'\x97','\xa4'},
+ {'\xe0','\xdd'},{'\xe0','\xda'},{'\xb9','\x75'},{'\x00','\x00'},{'\xb9','\x76'},
+ {'\xe0','\xdb'},{'\xe0','\xdc'},{'\x94','\xdf'},{'\xe4','\xc0'},{'\xe4','\xc5'},
+ {'\xbb','\xde'},{'\xe4','\xbf'},{'\xe4','\xc1'},{'\xe4','\xc8'},{'\xe4','\xc3'},
+ {'\xe4','\xc7'},{'\xe4','\xc4'},{'\xe4','\xc2'},{'\xe4','\xc6'},{'\xbb','\xdf'},
+ {'\x94','\xe0'},{'\x9e','\xe9'},{'\xe8','\xb3'},{'\x9e','\xea'},{'\xe8','\xb1'},
+ {'\xbe','\x63'},{'\x00','\x00'},{'\xbe','\x62'},{'\xe8','\xb2'},{'\xbe','\x64'},
+ {'\x94','\xe1'},{'\x8c','\xe7'},{'\x97','\xa5'},{'\x00','\x00'},{'\xec','\x56'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xec','\x55'},{'\xc0','\x54'},{'\xec','\x54'},
+ {'\xee','\xfc'},{'\x9e','\xeb'},{'\xee','\xfe'},{'\xef','\x41'},{'\xef','\x40'},
+ {'\xfd','\xcb'},{'\xc1','\xf9'},{'\xee','\xfd'},{'\xf1','\xa1'},{'\xc2','\xfd'},
+ {'\xf1','\x7d'},{'\xf1','\xa2'},{'\xc2','\xfe'},{'\x00','\x00'},{'\xf1','\x7b'},
+ {'\x00','\x00'},{'\xf1','\x7e'},{'\xf1','\x7c'},{'\xf1','\x79'},{'\xc3','\x40'},
+ {'\xf1','\x7a'},{'\x8d','\x7e'},{'\x00','\x00'},{'\x9e','\xec'},{'\x97','\xa6'},
+ {'\xf3','\xa1'},{'\xfd','\xcc'},{'\x00','\x00'},{'\xf3','\xa3'},{'\xf3','\xa2'},
+ {'\xfd','\xcd'},{'\xf5','\x4a'},{'\xfd','\xce'},{'\xf5','\x4b'},{'\x00','\x00'},
+ {'\x9e','\xed'},{'\xfd','\xcf'},{'\xf6','\x70'},{'\x9e','\xee'},{'\xc5','\xb7'},
+ {'\x9e','\xef'},{'\xc5','\xb6'},{'\xf8','\x4f'},{'\xf8','\x50'},{'\xc6','\x48'},
+ {'\xf8','\xd1'},{'\xfd','\xd0'},{'\xc6','\x69'},{'\x00','\x00'},{'\xad','\xb3'},
+ {'\xb6','\xb4'},{'\xe4','\xca'},{'\xe4','\xc9'},{'\xe8','\xb5'},{'\xe8','\xb4'},
+ {'\x00','\x00'},{'\x9e','\xf0'},{'\xc1','\xfa'},{'\xef','\x43'},{'\xef','\x42'},
+ {'\xf1','\xa5'},{'\xf1','\xa3'},{'\xf1','\xa6'},{'\xf1','\xa4'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xc3','\xfc'},{'\xf3','\xa4'},{'\xf3','\xa5'},{'\xf3','\xa6'},
+ {'\x9e','\xf1'},{'\xf6','\x71'},{'\x00','\x00'},{'\xf7','\x72'},{'\x00','\x00'},
+ {'\xf8','\xd2'},{'\x83','\xa3'},{'\x85','\xa4'},{'\x00','\x00'},{'\x8a','\xb0'},
+ {'\x8f','\xab'},{'\x8f','\xce'},{'\x8b','\xdb'},{'\xad','\xb4'},{'\x95','\x61'},
+ {'\x00','\x00'},{'\xec','\x57'},{'\xef','\x44'},{'\x97','\xa7'},{'\xad','\xb5'},
+ {'\x00','\x00'},{'\x8b','\xdc'},{'\xbb','\xe0'},{'\x00','\x00'},{'\xec','\x58'},
+ {'\xc3','\x41'},{'\xf1','\xa7'},{'\xc3','\xfd'},{'\x00','\x00'},{'\xf5','\x4c'},
+ {'\xf5','\x4d'},{'\xc5','\x54'},{'\xf8','\x51'},{'\xad','\xb6'},{'\xb3','\xbb'},
+ {'\xb3','\xbc'},{'\xd8','\x4e'},{'\xb6','\xb5'},{'\xb6','\xb6'},{'\xdc','\xac'},
+ {'\xb6','\xb7'},{'\x00','\x00'},{'\xb9','\x7a'},{'\x00','\x00'},{'\xb9','\x7c'},
+ {'\xe0','\xdf'},{'\xe0','\xe0'},{'\xe0','\xde'},{'\xb9','\x77'},{'\xb9','\x78'},
+ {'\xb9','\x7b'},{'\xb9','\x79'},{'\x9e','\xf2'},{'\x9e','\xf3'},{'\xe4','\xcb'},
+ {'\xbb','\xe1'},{'\xbb','\xe2'},{'\x00','\x00'},{'\x82','\x5b'},{'\xe8','\xbc'},
+ {'\xbe','\x67'},{'\xe8','\xb7'},{'\xe8','\xb6'},{'\xfd','\xd2'},{'\xe8','\xbb'},
+ {'\xbe','\x65'},{'\x00','\x00'},{'\x9e','\xf4'},{'\xc0','\x5b'},{'\x00','\x00'},
+ {'\xe8','\xb8'},{'\xe8','\xbd'},{'\xe8','\xba'},{'\xe8','\xb9'},{'\x00','\x00'},
+ {'\xbe','\x66'},{'\x82','\x7b'},{'\xc0','\x59'},{'\xfd','\xd3'},{'\xec','\x5a'},
+ {'\xc0','\x55'},{'\x00','\x00'},{'\xec','\x5b'},{'\x9e','\xf5'},{'\x82','\x42'},
+ {'\xec','\x59'},{'\x00','\x00'},{'\xc0','\x58'},{'\xc0','\x56'},{'\xc0','\x5a'},
+ {'\x00','\x00'},{'\xc0','\x57'},{'\x93','\xdf'},{'\x97','\xa8'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xef','\x45'},{'\x00','\x00'},{'\xef','\x4a'},
+ {'\xef','\x46'},{'\xef','\x49'},{'\xc1','\xfb'},{'\xfd','\xd5'},{'\xed','\xd4'},
+ {'\xef','\x48'},{'\xef','\x47'},{'\xfd','\xd6'},{'\xc3','\x44'},{'\xc3','\x42'},
+ {'\xc3','\x45'},{'\xc3','\x43'},{'\xf1','\xa8'},{'\xf1','\xa9'},{'\xf1','\xaa'},
+ {'\xc3','\x46'},{'\x97','\xa9'},{'\x92','\xb8'},{'\x9d','\xd2'},{'\xf3','\xaa'},
+ {'\xc4','\x40'},{'\xf3','\xa8'},{'\x00','\x00'},{'\xc4','\x41'},{'\xf3','\xa7'},
+ {'\xf3','\xa9'},{'\xc3','\xfe'},{'\xf5','\x51'},{'\xf5','\x4e'},{'\x00','\x00'},
+ {'\xf5','\x4f'},{'\xf5','\x50'},{'\xf6','\x72'},{'\xc5','\x56'},{'\xfd','\xd7'},
+ {'\xc5','\x55'},{'\x9e','\xf6'},{'\xf7','\x74'},{'\xf7','\x73'},{'\xc5','\xb8'},
+ {'\xfd','\xd8'},{'\x00','\x00'},{'\x00','\x00'},{'\xc5','\xe3'},{'\xc6','\x49'},
+ {'\xc6','\x60'},{'\xf9','\x58'},{'\xf9','\xae'},{'\xf9','\xaf'},{'\x83','\xa4'},
+ {'\x84','\xbc'},{'\x84','\xbd'},{'\x8d','\xfa'},{'\x85','\xa5'},{'\x85','\xa6'},
+ {'\x85','\xa7'},{'\x86','\x7e'},{'\x86','\x7c'},{'\x8c','\xb8'},{'\x86','\x7d'},
+ {'\x8e','\x62'},{'\x86','\xa1'},{'\x86','\xa2'},{'\x8e','\x61'},{'\x86','\x7b'},
+ {'\x8d','\x77'},{'\x87','\x74'},{'\x87','\x73'},{'\x89','\xb0'},{'\x88','\xb3'},
+ {'\x89','\xaf'},{'\x00','\x00'},{'\x88','\xb4'},{'\x8e','\xba'},{'\x00','\x00'},
+ {'\x8e','\xdc'},{'\x89','\xb5'},{'\x89','\xb1'},{'\x00','\x00'},{'\x89','\xb4'},
+ {'\x89','\xb2'},{'\x00','\x00'},{'\x89','\x46'},{'\x8a','\xb1'},{'\x8b','\x5f'},
+ {'\x00','\x00'},{'\x8b','\x60'},{'\x8b','\x61'},{'\x8b','\x5e'},{'\x8b','\x5d'},
+ {'\x90','\xa7'},{'\x8f','\xf0'},{'\x8b','\xde'},{'\x8f','\xcf'},{'\x8c','\xb9'},
+ {'\x00','\x00'},{'\x8c','\xe9'},{'\x97','\xaa'},{'\x8d','\x61'},{'\x90','\xa8'},
+ {'\xad','\xb7'},{'\xdc','\xad'},{'\x94','\xe2'},{'\x00','\x00'},{'\xe0','\xe1'},
+ {'\xe4','\xcc'},{'\xe4','\xcd'},{'\xbb','\xe3'},{'\x00','\x00'},{'\xbb','\xe4'},
+ {'\xe8','\xbe'},{'\xbe','\x68'},{'\xfd','\xd9'},{'\x00','\x00'},{'\xc1','\xfc'},
+ {'\x9e','\xf7'},{'\xf1','\xab'},{'\x9e','\xf8'},{'\xc3','\x47'},{'\xf3','\xad'},
+ {'\xc4','\x42'},{'\xf3','\xac'},{'\xf3','\xae'},{'\xf3','\xab'},{'\xf6','\x75'},
+ {'\xf5','\x52'},{'\xf5','\x53'},{'\x97','\xab'},{'\xc4','\xc6'},{'\x00','\x00'},
+ {'\xf6','\x74'},{'\x9e','\xf9'},{'\xfb','\xb2'},{'\xf6','\x73'},{'\x9e','\xfa'},
+ {'\xf7','\x75'},{'\xf9','\xb0'},{'\x00','\x00'},{'\x83','\xa5'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x8e','\xae'},{'\x87','\x75'},{'\x8a','\xb2'},{'\x00','\x00'},
+ {'\x8b','\xdf'},{'\x00','\x00'},{'\x00','\x00'},{'\x8c','\x61'},{'\x90','\x4a'},
+ {'\x97','\xac'},{'\xad','\xb8'},{'\xfd','\xdb'},{'\x00','\x00'},{'\x83','\xa6'},
+ {'\xad','\xb9'},{'\x9e','\xfb'},{'\x9e','\xfc'},{'\xb0','\xa7'},{'\xd4','\x48'},
+ {'\x00','\x00'},{'\xd8','\x4f'},{'\xfd','\xdc'},{'\xb6','\xb8'},{'\x8c','\xba'},
+ {'\xb6','\xbb'},{'\xb6','\xb9'},{'\xdc','\xae'},{'\x9e','\xfd'},{'\xb6','\xbd'},
+ {'\x97','\xad'},{'\xb6','\xba'},{'\x00','\x00'},{'\x95','\xda'},{'\xb6','\xbc'},
+ {'\x00','\x00'},{'\xb9','\x7e'},{'\x9e','\xfe'},{'\xe0','\xe2'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xe0','\xe3'},{'\xe8','\xc0'},{'\x00','\x00'},{'\xb9','\x7d'},
+ {'\xb9','\xa1'},{'\xb9','\xa2'},{'\x00','\x00'},{'\xe4','\xcf'},{'\x00','\x00'},
+ {'\xe4','\xce'},{'\xbb','\xe5'},{'\x00','\x00'},{'\xbb','\xe6'},{'\x00','\x00'},
+ {'\xe4','\xd0'},{'\xe8','\xbf'},{'\xbb','\xe8'},{'\xbe','\x69'},{'\x00','\x00'},
+ {'\xbb','\xe7'},{'\x8d','\x47'},{'\x9f','\x70'},{'\x00','\x00'},{'\xc0','\x5c'},
+ {'\xe8','\xc1'},{'\xbe','\x6b'},{'\xbe','\x6a'},{'\xe8','\xc2'},{'\xe8','\xc5'},
+ {'\xe8','\xc3'},{'\xe8','\xc4'},{'\xbe','\x6c'},{'\x9f','\x71'},{'\xc0','\x61'},
+ {'\xc0','\x5f'},{'\x9f','\x72'},{'\x97','\xae'},{'\xc0','\x5e'},{'\xec','\x5d'},
+ {'\x97','\xaf'},{'\xc0','\x60'},{'\x00','\x00'},{'\x00','\x00'},{'\xec','\x5c'},
+ {'\xef','\x4b'},{'\x00','\x00'},{'\xec','\x5e'},{'\xc0','\x5d'},{'\xec','\x5f'},
+ {'\xef','\x4e'},{'\xef','\x4c'},{'\xef','\x4d'},{'\xef','\x52'},{'\xc3','\x4b'},
+ {'\xef','\x51'},{'\xef','\x54'},{'\xef','\x53'},{'\xef','\x50'},{'\xef','\x4f'},
+ {'\x00','\x00'},{'\xc1','\xfd'},{'\x00','\x00'},{'\x9f','\x73'},{'\xa0','\x44'},
+ {'\xfd','\xde'},{'\xf1','\xae'},{'\xfd','\xdf'},{'\xf1','\xad'},{'\xc3','\x4a'},
+ {'\xc3','\x48'},{'\xc3','\x49'},{'\xfb','\xb3'},{'\xf1','\xac'},{'\xfd','\xdd'},
+ {'\xf3','\xb1'},{'\x00','\x00'},{'\xc4','\x43'},{'\x00','\x00'},{'\xf3','\xb0'},
+ {'\xf3','\xaf'},{'\xc4','\x44'},{'\xfd','\xe1'},{'\xf5','\x58'},{'\xf5','\x57'},
+ {'\xfb','\xb4'},{'\xf5','\x55'},{'\x00','\x00'},{'\xf5','\x54'},{'\xc4','\xc8'},
+ {'\xc4','\xc7'},{'\xf5','\x59'},{'\xf7','\x76'},{'\xc5','\xb9'},{'\xf6','\x77'},
+ {'\xc5','\x57'},{'\xf6','\x76'},{'\xf5','\x56'},{'\x00','\x00'},{'\xf7','\x77'},
+ {'\xc5','\xe4'},{'\x9f','\x74'},{'\xc6','\x61'},{'\xf9','\x59'},{'\x00','\x00'},
+ {'\xf9','\xb1'},{'\x9f','\x75'},{'\x97','\xb0'},{'\x00','\x00'},{'\x83','\xe8'},
+ {'\x00','\x00'},{'\x8f','\x6d'},{'\x85','\xaa'},{'\x8f','\xac'},{'\x85','\xa8'},
+ {'\x8d','\xfb'},{'\x85','\xac'},{'\x85','\xa9'},{'\x85','\xab'},{'\x89','\xb7'},
+ {'\x86','\xa6'},{'\x86','\xa5'},{'\x86','\xa3'},{'\x00','\x00'},{'\x86','\xa4'},
+ {'\x87','\x78'},{'\x8c','\x62'},{'\x87','\x79'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x87','\x76'},{'\x00','\x00'},{'\x87','\x77'},{'\x8e','\xdd'},{'\x00','\x00'},
+ {'\x88','\xb6'},{'\x97','\xb1'},{'\x88','\xb7'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x89','\xb8'},{'\x89','\xb9'},{'\x89','\xb6'},{'\x97','\xb2'},{'\x8b','\x64'},
+ {'\x00','\x00'},{'\x8b','\x63'},{'\x8d','\x78'},{'\x00','\x00'},{'\x97','\xb3'},
+ {'\x00','\x00'},{'\x8b','\x62'},{'\x8f','\xd0'},{'\x8b','\xe1'},{'\x8b','\xe0'},
+ {'\x97','\xb4'},{'\x8f','\xf1'},{'\x97','\xb5'},{'\xad','\xba'},{'\xd8','\x50'},
+ {'\xef','\x55'},{'\xad','\xbb'},{'\x00','\x00'},{'\x9f','\x76'},{'\xe4','\xd2'},
+ {'\xe4','\xd1'},{'\xec','\x60'},{'\x00','\x00'},{'\x00','\x00'},{'\xef','\x57'},
+ {'\x00','\x00'},{'\xef','\x56'},{'\x9f','\x77'},{'\xc3','\x4c'},{'\xf3','\xb2'},
+ {'\xf3','\xb3'},{'\xc4','\xc9'},{'\x00','\x00'},{'\x9f','\x78'},{'\xf9','\xb2'},
+ {'\xb0','\xa8'},{'\xb6','\xbf'},{'\xb6','\xbe'},{'\xe0','\xe4'},{'\xe0','\xe6'},
+ {'\xb9','\xa4'},{'\xe0','\xe5'},{'\xb9','\xa3'},{'\xb9','\xa5'},{'\xe0','\xe7'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x9f','\x79'},{'\xe4','\xd4'},{'\xe4','\xd6'},
+ {'\xe4','\xd5'},{'\x97','\xb6'},{'\xe4','\xd8'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xbb','\xe9'},{'\xe4','\xd7'},{'\xe4','\xd3'},{'\x94','\x4b'},
+ {'\x92','\x4a'},{'\x92','\xa3'},{'\xe4','\xd9'},{'\x97','\xb7'},{'\xe8','\xcc'},
+ {'\x00','\x00'},{'\xe8','\xcf'},{'\xe8','\xd1'},{'\xe8','\xc7'},{'\xe8','\xcb'},
+ {'\xe8','\xc8'},{'\xbe','\x6e'},{'\xbe','\x71'},{'\xbe','\x73'},{'\xe8','\xc9'},
+ {'\xe8','\xca'},{'\xbe','\x72'},{'\xe8','\xcd'},{'\xe8','\xd0'},{'\xe8','\xce'},
+ {'\xbe','\x74'},{'\xfd','\xe4'},{'\xbe','\x70'},{'\xe8','\xc6'},{'\xbe','\x6d'},
+ {'\x00','\x00'},{'\xbe','\x6f'},{'\x9f','\x7a'},{'\x95','\xc4'},{'\xc0','\x63'},
+ {'\xec','\x66'},{'\xec','\x64'},{'\xec','\x63'},{'\x9f','\x7b'},{'\xec','\x69'},
+ {'\x00','\x00'},{'\xec','\x68'},{'\xec','\x67'},{'\x00','\x00'},{'\xec','\x62'},
+ {'\xc0','\x62'},{'\xec','\x61'},{'\x00','\x00'},{'\xec','\x65'},{'\xc0','\x64'},
+ {'\x97','\xb8'},{'\x00','\x00'},{'\xef','\x5a'},{'\x9f','\x7c'},{'\xef','\x5e'},
+ {'\xef','\x5b'},{'\xef','\x5d'},{'\xef','\x5c'},{'\xef','\x59'},{'\xef','\x5f'},
+ {'\xef','\x62'},{'\xef','\x60'},{'\xef','\x61'},{'\xc2','\x40'},{'\x00','\x00'},
+ {'\xc1','\xfe'},{'\xef','\x58'},{'\xef','\x63'},{'\xf1','\xb3'},{'\xf1','\xb6'},
+ {'\xf1','\xb8'},{'\xf1','\xb7'},{'\x00','\x00'},{'\xf1','\xb1'},{'\xf1','\xb5'},
+ {'\xf1','\xb0'},{'\xfb','\xb5'},{'\xf1','\xb2'},{'\xc3','\x4d'},{'\xf1','\xaf'},
+ {'\x95','\xe1'},{'\xf1','\xb4'},{'\x93','\x5d'},{'\x92','\xb9'},{'\xf3','\xc0'},
+ {'\xf3','\xb5'},{'\xc4','\x45'},{'\x00','\x00'},{'\x00','\x00'},{'\xc4','\x46'},
+ {'\xf3','\xb4'},{'\xf3','\xb9'},{'\xf3','\xbf'},{'\xf3','\xb7'},{'\xf3','\xbe'},
+ {'\x9f','\x7d'},{'\xf3','\xbb'},{'\x9a','\xfb'},{'\xf3','\xba'},{'\xf3','\xbd'},
+ {'\xf3','\xb8'},{'\xf3','\xb6'},{'\x9a','\xfc'},{'\xf3','\xbc'},{'\x82','\x55'},
+ {'\xf5','\x60'},{'\xf5','\x5e'},{'\xc4','\xca'},{'\xf5','\x5d'},{'\xf5','\x63'},
+ {'\xf5','\x61'},{'\x9a','\xfd'},{'\xc4','\xcb'},{'\xf5','\x5c'},{'\xf5','\x5a'},
+ {'\x00','\x00'},{'\xf5','\x5b'},{'\xc4','\xcd'},{'\xf5','\x5f'},{'\xc4','\xcc'},
+ {'\xf5','\x62'},{'\xf6','\x78'},{'\xf6','\x7e'},{'\x9c','\xfa'},{'\x9c','\xfb'},
+ {'\xf6','\x79'},{'\xc5','\x5b'},{'\xf6','\xa1'},{'\xc5','\x5a'},{'\xf6','\x7d'},
+ {'\xf6','\x7c'},{'\xc5','\x59'},{'\xf6','\x7b'},{'\xc5','\x58'},{'\xf6','\x7a'},
+ {'\x00','\x00'},{'\xf7','\x7d'},{'\xf7','\xa1'},{'\xf7','\x7e'},{'\x00','\x00'},
+ {'\xf7','\x7b'},{'\xc5','\xbb'},{'\xf7','\x78'},{'\xf7','\x7c'},{'\xf7','\xa3'},
+ {'\x00','\x00'},{'\xf7','\xa2'},{'\xf7','\x79'},{'\xf7','\x7a'},{'\xc5','\xba'},
+ {'\xf8','\x52'},{'\xc5','\xe7'},{'\x9c','\xfc'},{'\xf8','\x53'},{'\xc5','\xe5'},
+ {'\xc5','\xe6'},{'\x9c','\xfd'},{'\x00','\x00'},{'\xf8','\xd3'},{'\xc6','\x4a'},
+ {'\xf9','\x76'},{'\x00','\x00'},{'\xc6','\x6a'},{'\x9c','\xfe'},{'\xf9','\xb3'},
+ {'\xc6','\x6b'},{'\xf9','\xb4'},{'\xf9','\xb5'},{'\xf9','\xc3'},{'\xf9','\xc2'},
+ {'\xc6','\x7a'},{'\xf9','\xcd'},{'\x83','\xe9'},{'\x85','\xae'},{'\x86','\xa8'},
+ {'\x86','\xa9'},{'\x86','\xa7'},{'\x8c','\xbb'},{'\x00','\x00'},{'\x87','\x7a'},
+ {'\x8d','\xa1'},{'\x8e','\xde'},{'\x88','\xbb'},{'\x88','\xba'},{'\x88','\xbf'},
+ {'\x88','\xbe'},{'\x8f','\xf2'},{'\x88','\xb9'},{'\x88','\xb8'},{'\x88','\xbc'},
+ {'\x88','\xbd'},{'\x8d','\x49'},{'\x8e','\xdf'},{'\x8c','\xeb'},{'\x88','\x4c'},
+ {'\x00','\x00'},{'\x8c','\xea'},{'\x90','\x63'},{'\x89','\xbc'},{'\x89','\xba'},
+ {'\x89','\xbb'},{'\x00','\x00'},{'\x8d','\xaf'},{'\x8a','\xb3'},{'\x8d','\x4a'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x8a','\xb4'},{'\x8f','\xad'},{'\x8b','\x65'},
+ {'\x8f','\xae'},{'\x8f','\xaf'},{'\x00','\x00'},{'\x00','\x00'},{'\x90','\x4c'},
+ {'\x8b','\xe3'},{'\x8f','\xf5'},{'\x00','\x00'},{'\x8c','\x66'},{'\x8b','\xe2'},
+ {'\x90','\x4d'},{'\x8f','\xf3'},{'\x8c','\x64'},{'\x8f','\xf4'},{'\x8c','\xbc'},
+ {'\x8c','\xbe'},{'\x90','\x4b'},{'\x90','\x62'},{'\x8d','\x62'},{'\x8d','\xa2'},
+ {'\x00','\x00'},{'\x90','\xa9'},{'\xb0','\xa9'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xe0','\xe9'},{'\x00','\x00'},{'\xe0','\xe8'},{'\x00','\x00'},{'\xbb','\xea'},
+ {'\xbb','\xeb'},{'\xe4','\xda'},{'\x9d','\xb0'},{'\xe8','\xd2'},{'\xec','\x6c'},
+ {'\x00','\x00'},{'\x97','\xb9'},{'\xbe','\x75'},{'\xc0','\x65'},{'\xec','\x6a'},
+ {'\xfd','\xe6'},{'\xec','\x6d'},{'\xc0','\x66'},{'\xfd','\xe7'},{'\xef','\x64'},
+ {'\xec','\x6b'},{'\xf1','\xb9'},{'\xc3','\x4e'},{'\xf3','\xc1'},{'\x00','\x00'},
+ {'\x92','\xfb'},{'\x8c','\xbf'},{'\xf5','\x66'},{'\xf5','\x64'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xf5','\x65'},{'\x8d','\x79'},{'\x90','\x79'},{'\xf6','\xa2'},
+ {'\x00','\x00'},{'\xc5','\x5c'},{'\xf7','\xa4'},{'\xc5','\xea'},{'\xc5','\xbc'},
+ {'\xc5','\xe8'},{'\xc5','\xe9'},{'\xf8','\xd4'},{'\xc6','\x62'},{'\xfb','\xb6'},
+ {'\xb0','\xaa'},{'\x97','\xba'},{'\x00','\x00'},{'\x00','\x00'},{'\xf1','\xba'},
+ {'\x00','\x00'},{'\x97','\xbb'},{'\xd4','\x49'},{'\x9d','\xb1'},{'\xb9','\xa6'},
+ {'\xfd','\xec'},{'\xe4','\xdb'},{'\x00','\x00'},{'\x00','\x00'},{'\xbb','\xec'},
+ {'\xe4','\xdc'},{'\x00','\x00'},{'\x00','\x00'},{'\x93','\xba'},{'\xe8','\xd4'},
+ {'\xe8','\xd3'},{'\xc0','\x68'},{'\xbe','\x76'},{'\xbe','\x77'},{'\x00','\x00'},
+ {'\xe8','\xd7'},{'\xe8','\xd6'},{'\xe8','\xd5'},{'\xfe','\x57'},{'\x00','\x00'},
+ {'\xec','\x6e'},{'\xec','\x71'},{'\x00','\x00'},{'\xec','\x70'},{'\xec','\x6f'},
+ {'\xc0','\x67'},{'\xef','\x68'},{'\xef','\x66'},{'\xef','\x65'},{'\xfd','\xee'},
+ {'\x00','\x00'},{'\xef','\x67'},{'\xfd','\xed'},{'\xc3','\x4f'},{'\xf1','\xbc'},
+ {'\xf1','\xbd'},{'\xc3','\x50'},{'\x00','\x00'},{'\xf1','\xbb'},{'\xfd','\xf0'},
+ {'\xf3','\xc3'},{'\xf3','\xc2'},{'\xf3','\xc5'},{'\xc4','\x47'},{'\xf3','\xc4'},
+ {'\x97','\xbc'},{'\xf5','\x67'},{'\xf5','\x69'},{'\xf5','\x68'},{'\x8d','\x63'},
+ {'\x9d','\xb2'},{'\xf6','\xa3'},{'\xf6','\xa6'},{'\xf6','\xa4'},{'\xf6','\xa5'},
+ {'\xf7','\xa5'},{'\xc5','\xbd'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xf8','\x54'},{'\xf8','\x55'},{'\xf8','\x56'},{'\x00','\x00'},{'\xc6','\x4b'},
+ {'\xc6','\x63'},{'\xf9','\xb6'},{'\xb0','\xab'},{'\x00','\x00'},{'\xbe','\x78'},
+ {'\xc0','\x69'},{'\xf1','\xbe'},{'\xfd','\xe9'},{'\xf7','\xa6'},{'\x00','\x00'},
+ {'\xfd','\xeb'},{'\xf9','\xc4'},{'\xd4','\x4a'},{'\x00','\x00'},{'\xc6','\x7b'},
+ {'\xb0','\xac'},{'\xec','\x72'},{'\x9d','\xb3'},{'\xf1','\xbf'},{'\x00','\x00'},
+ {'\xf3','\xc6'},{'\x00','\x00'},{'\x9d','\xb4'},{'\xf6','\xa7'},{'\xf7','\xa7'},
+ {'\xb0','\xad'},{'\x00','\x00'},{'\xe4','\xdd'},{'\xe4','\xde'},{'\x9d','\xb5'},
+ {'\xbb','\xed'},{'\xbb','\xee'},{'\xe8','\xd9'},{'\xbe','\x7a'},{'\xbe','\x79'},
+ {'\xe8','\xd8'},{'\x8d','\x64'},{'\xef','\x69'},{'\x97','\xbd'},{'\xf1','\xc0'},
+ {'\xf1','\xc2'},{'\xf1','\xc1'},{'\xc3','\x53'},{'\xc3','\x52'},{'\xc3','\x51'},
+ {'\x9d','\xb6'},{'\xc5','\x5e'},{'\xf6','\xa8'},{'\x00','\x00'},{'\xc5','\x5d'},
+ {'\xf7','\xa9'},{'\xf7','\xa8'},{'\x00','\x00'},{'\xc6','\x4c'},{'\xf8','\xd5'},
+ {'\xb3','\xbd'},{'\xe0','\xea'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xe4','\xe1'},{'\xe4','\xdf'},{'\xe4','\xe0'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xe8','\xe2'},{'\x00','\x00'},{'\xe8','\xdd'},{'\xe8','\xda'},{'\xe8','\xe1'},
+ {'\xfe','\xaf'},{'\x00','\x00'},{'\x00','\x00'},{'\xe8','\xe3'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xbe','\x7c'},{'\xe8','\xe0'},{'\xe8','\xdc'},{'\x97','\xbe'},
+ {'\x00','\x00'},{'\xe8','\xdb'},{'\xe8','\xdf'},{'\xe8','\xde'},{'\xbe','\x7b'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xec','\x7d'},{'\xec','\x78'},{'\xec','\x76'},
+ {'\xec','\xa1'},{'\xec','\x77'},{'\x9d','\xb7'},{'\xec','\x73'},{'\x9d','\xee'},
+ {'\xec','\x79'},{'\x97','\xbf'},{'\x00','\x00'},{'\xec','\x74'},{'\xef','\x72'},
+ {'\xec','\x75'},{'\xec','\xa2'},{'\x00','\x00'},{'\x00','\x00'},{'\x9d','\xef'},
+ {'\x00','\x00'},{'\x9d','\xf0'},{'\x94','\xfe'},{'\xfd','\xf3'},{'\xec','\x7c'},
+ {'\xc0','\x6a'},{'\xec','\x7b'},{'\xec','\x7a'},{'\x00','\x00'},{'\xec','\x7e'},
+ {'\x94','\xe3'},{'\x94','\xe4'},{'\x00','\x00'},{'\x00','\x00'},{'\xef','\x6a'},
+ {'\xef','\x6d'},{'\x00','\x00'},{'\xfd','\xf4'},{'\xef','\x6c'},{'\x97','\xc0'},
+ {'\xef','\x74'},{'\xef','\x6f'},{'\xef','\x73'},{'\x00','\x00'},{'\xef','\x71'},
+ {'\xef','\x70'},{'\xef','\x6e'},{'\x00','\x00'},{'\xef','\x6b'},{'\x00','\x00'},
+ {'\xc2','\x43'},{'\xc2','\x42'},{'\x00','\x00'},{'\xc2','\x44'},{'\xc2','\x41'},
+ {'\xef','\x75'},{'\xfd','\xf5'},{'\x94','\xf5'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x94','\xe5'},{'\xf1','\xc8'},{'\xf1','\xcb'},{'\x00','\x00'},{'\xf1','\xc9'},
+ {'\xf1','\xcd'},{'\x00','\x00'},{'\x97','\xc1'},{'\x00','\x00'},{'\xf1','\xce'},
+ {'\x00','\x00'},{'\xf1','\xc6'},{'\xc3','\x58'},{'\xf1','\xc7'},{'\x00','\x00'},
+ {'\xf1','\xc5'},{'\xf1','\xcc'},{'\x00','\x00'},{'\xf1','\xc4'},{'\xf1','\xc3'},
+ {'\xc3','\x57'},{'\xc3','\x55'},{'\xc3','\x54'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x94','\xe6'},{'\x00','\x00'},{'\x94','\xe7'},
+ {'\x94','\xe8'},{'\xf1','\xca'},{'\xf3','\xcf'},{'\xf3','\xd5'},{'\xc4','\x4a'},
+ {'\xf3','\xd0'},{'\x00','\x00'},{'\xf3','\xd3'},{'\xf3','\xd7'},{'\xc4','\x4b'},
+ {'\xf3','\xd2'},{'\x9d','\xf1'},{'\xf3','\xca'},{'\x00','\x00'},{'\xf3','\xc9'},
+ {'\xf3','\xd6'},{'\xf3','\xcd'},{'\x97','\xc2'},{'\xf3','\xcb'},{'\xf3','\xd4'},
+ {'\xf3','\xcc'},{'\xc4','\x49'},{'\xc4','\x48'},{'\x9d','\xf2'},{'\xf3','\xc7'},
+ {'\xf3','\xc8'},{'\xf3','\xd1'},{'\x9d','\xf3'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xf3','\xce'},{'\x94','\xea'},{'\x94','\xe9'},{'\x00','\x00'},{'\x9d','\xf4'},
+ {'\x97','\xc3'},{'\x00','\x00'},{'\xf5','\x6c'},{'\xf5','\x6f'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xc3','\x56'},{'\x00','\x00'},
+ {'\xfd','\xf9'},{'\x97','\xc4'},{'\x00','\x00'},{'\xfe','\x50'},{'\x00','\x00'},
+ {'\x97','\xc5'},{'\xf5','\x6d'},{'\xf5','\x73'},{'\xf5','\x71'},{'\xf5','\x6b'},
+ {'\xf5','\x76'},{'\xfd','\xf8'},{'\xf5','\x6a'},{'\xfd','\xf6'},{'\xc4','\xcf'},
+ {'\xf5','\x72'},{'\x00','\x00'},{'\x95','\xfd'},{'\x00','\x00'},{'\xf5','\x6e'},
+ {'\xc4','\xce'},{'\xf5','\x75'},{'\xfd','\xf7'},{'\x00','\x00'},{'\xf5','\x74'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x97','\xc6'},{'\xf6','\xab'},
+ {'\xf6','\xaa'},{'\x00','\x00'},{'\x9d','\xf5'},{'\x9d','\xf6'},{'\xf6','\xb1'},
+ {'\x00','\x00'},{'\xf6','\xad'},{'\xf6','\xb0'},{'\xc5','\x60'},{'\x9d','\xf7'},
+ {'\x00','\x00'},{'\xf6','\xae'},{'\xf6','\xaf'},{'\x00','\x00'},{'\xf6','\xa9'},
+ {'\xf6','\xac'},{'\xc5','\x5f'},{'\xfd','\xfa'},{'\x94','\xf9'},{'\x94','\xeb'},
+ {'\xc5','\xbf'},{'\xf7','\xb4'},{'\xf7','\xaf'},{'\xf7','\xb3'},{'\xfd','\x53'},
+ {'\xf7','\xb6'},{'\xf7','\xb2'},{'\x00','\x00'},{'\xf7','\xae'},{'\xfc','\xcb'},
+ {'\xc5','\xc1'},{'\xf7','\xb1'},{'\xf7','\xb5'},{'\xc5','\xc0'},{'\xf7','\xac'},
+ {'\xf5','\x70'},{'\xf7','\xb0'},{'\x00','\x00'},{'\x00','\x00'},{'\xf7','\xad'},
+ {'\xfd','\x70'},{'\xf7','\xaa'},{'\x94','\xec'},{'\xf7','\xab'},{'\xc5','\xbe'},
+ {'\xf8','\x5a'},{'\xf8','\x5c'},{'\xf8','\x5f'},{'\xf8','\x5b'},{'\xf8','\x60'},
+ {'\x9f','\x50'},{'\xf8','\x59'},{'\x00','\x00'},{'\xf8','\x57'},{'\x9d','\xf8'},
+ {'\xc5','\xeb'},{'\xf8','\x5d'},{'\xc5','\xed'},{'\xc5','\xec'},{'\xf8','\x58'},
+ {'\xf8','\x5e'},{'\x94','\xed'},{'\x00','\x00'},{'\x00','\x00'},{'\x9d','\xf9'},
+ {'\xf8','\xda'},{'\xc6','\x4d'},{'\xf8','\xdb'},{'\x00','\x00'},{'\xf8','\xd9'},
+ {'\xf8','\xd6'},{'\x00','\x00'},{'\x00','\x00'},{'\xf8','\xd8'},{'\xf8','\xd7'},
+ {'\xf9','\x5a'},{'\x94','\xf6'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xf9','\x5c'},{'\xf9','\x5b'},{'\x00','\x00'},{'\x00','\x00'},{'\xf9','\x79'},
+ {'\xfb','\x78'},{'\xf9','\x78'},{'\xf9','\x77'},{'\xf9','\x7a'},{'\x98','\x40'},
+ {'\xc6','\x73'},{'\xc6','\x74'},{'\xf9','\xca'},{'\xf9','\xce'},{'\x9d','\xfa'},
+ {'\x84','\xbe'},{'\x00','\x00'},{'\x00','\x00'},{'\x88','\xc2'},{'\x00','\x00'},
+ {'\x88','\xc3'},{'\x8e','\xe0'},{'\x00','\x00'},{'\x00','\x00'},{'\x98','\x4b'},
+ {'\x98','\x4c'},{'\x98','\x4d'},{'\x8d','\xab'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x98','\x4e'},{'\x00','\x00'},{'\x89','\xbf'},{'\x8d','\x65'},{'\x00','\x00'},
+ {'\x98','\x4f'},{'\x8a','\xb8'},{'\x8f','\x6e'},{'\x00','\x00'},{'\x8a','\xb7'},
+ {'\x8f','\x6f'},{'\x00','\x00'},{'\x90','\xf2'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x90','\xa2'},{'\x8a','\xb6'},{'\x8a','\xb5'},{'\x00','\x00'},{'\x98','\x50'},
+ {'\x90','\x70'},{'\x8f','\xb2'},{'\x90','\xad'},{'\x8c','\xed'},{'\x90','\x65'},
+ {'\x8b','\x68'},{'\x90','\x4e'},{'\x90','\x66'},{'\x8b','\x6a'},{'\x8b','\x67'},
+ {'\x8f','\xb1'},{'\x00','\x00'},{'\x8b','\x69'},{'\x00','\x00'},{'\x8b','\xe6'},
+ {'\x98','\x51'},{'\x00','\x00'},{'\x98','\x52'},{'\x8f','\xd5'},{'\x98','\x53'},
+ {'\x8b','\xe5'},{'\x98','\x54'},{'\x8f','\xd2'},{'\x8f','\xd3'},{'\x8b','\xe7'},
+ {'\x8b','\xe4'},{'\x00','\x00'},{'\x98','\x55'},{'\x8f','\xd4'},{'\x98','\x56'},
+ {'\x98','\x57'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x8c','\x67'},{'\x8d','\xaa'},{'\x8c','\x68'},{'\x98','\x58'},
+ {'\x98','\x59'},{'\x00','\x00'},{'\x00','\x00'},{'\x98','\x5a'},{'\x98','\x5b'},
+ {'\x8d','\x6a'},{'\x8c','\xc0'},{'\x90','\x4f'},{'\x8c','\xc1'},{'\x90','\x50'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x98','\x5c'},{'\x8c','\xee'},{'\x90','\x64'},
+ {'\x8c','\xec'},{'\x8c','\xef'},{'\x98','\x5d'},{'\x98','\x5e'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x8d','\x4f'},{'\x8d','\x4d'},{'\x8d','\x4e'},{'\x90','\x6f'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x98','\x5f'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xb3','\xbe'},{'\xdc','\xaf'},{'\xe0','\xed'},{'\x00','\x00'},{'\xb9','\xa7'},
+ {'\xe0','\xeb'},{'\x98','\x60'},{'\x98','\x61'},{'\xe0','\xec'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x94','\xee'},{'\xe4','\xe2'},{'\xe4','\xe3'},{'\xbb','\xf1'},
+ {'\xbb','\xef'},{'\xe4','\xe4'},{'\xbb','\xf0'},{'\xe8','\xe8'},{'\x00','\x00'},
+ {'\xe8','\xeb'},{'\xe8','\xe5'},{'\xe8','\xec'},{'\xe8','\xe4'},{'\xe8','\xe6'},
+ {'\x00','\x00'},{'\xe8','\xe7'},{'\xe8','\xea'},{'\x00','\x00'},{'\xfd','\x61'},
+ {'\xbe','\xa1'},{'\xe8','\xef'},{'\xe8','\xee'},{'\xbe','\x7d'},{'\xe8','\xe9'},
+ {'\xe8','\xed'},{'\xbe','\x7e'},{'\x00','\x00'},{'\x00','\x00'},{'\x9d','\xfb'},
+ {'\x00','\x00'},{'\x82','\x48'},{'\x00','\x00'},{'\xec','\xac'},{'\x00','\x00'},
+ {'\xc0','\x6f'},{'\x00','\x00'},{'\xec','\xa7'},{'\xc0','\x6b'},{'\x9d','\xfc'},
+ {'\xec','\xa4'},{'\xec','\xaa'},{'\xec','\xad'},{'\x00','\x00'},{'\xc0','\x70'},
+ {'\x00','\x00'},{'\xec','\xa9'},{'\xec','\xa6'},{'\xec','\xae'},{'\xec','\xa5'},
+ {'\x9f','\x40'},{'\xec','\xab'},{'\xc0','\x6c'},{'\x00','\x00'},{'\xec','\xa3'},
+ {'\xc0','\x6d'},{'\x00','\x00'},{'\xc0','\x6e'},{'\xec','\xa8'},{'\x98','\x62'},
+ {'\x94','\x47'},{'\x82','\x47'},{'\xef','\xa9'},{'\xef','\x7a'},{'\xef','\x7b'},
+ {'\xef','\x7e'},{'\xef','\x7c'},{'\x00','\x00'},{'\xef','\x76'},{'\x9f','\x41'},
+ {'\x00','\x00'},{'\xef','\x79'},{'\xef','\xa5'},{'\xef','\x7d'},{'\x9f','\x42'},
+ {'\x00','\x00'},{'\xc2','\x45'},{'\x00','\x00'},{'\xef','\xa7'},{'\xef','\xa4'},
+ {'\xc2','\x46'},{'\xef','\xa6'},{'\xef','\x77'},{'\xef','\xa2'},{'\xef','\xa3'},
+ {'\xfd','\xaa'},{'\xef','\xa1'},{'\x94','\xef'},{'\x94','\xf7'},{'\x98','\x63'},
+ {'\x9f','\x43'},{'\xf1','\xd2'},{'\xf1','\xd4'},{'\xf1','\xd7'},{'\x00','\x00'},
+ {'\x9f','\x44'},{'\xf1','\xd1'},{'\x98','\x64'},{'\xc3','\x59'},{'\xf1','\xd9'},
+ {'\xf1','\xd0'},{'\xf1','\xda'},{'\x00','\x00'},{'\xf1','\xd6'},{'\xf1','\xd8'},
+ {'\xf1','\xdc'},{'\xf1','\xd5'},{'\xf1','\xdd'},{'\xf1','\xd3'},{'\xf1','\xcf'},
+ {'\xc3','\x5a'},{'\x95','\x72'},{'\xf1','\xdb'},{'\xc3','\x5b'},{'\xc4','\x4d'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x94','\xf0'},{'\x94','\xf8'},{'\x00','\x00'},
+ {'\xef','\x78'},{'\xf3','\xf1'},{'\xf3','\xe8'},{'\xc4','\x4f'},{'\xf3','\xe4'},
+ {'\xc4','\x50'},{'\x9f','\x45'},{'\x9f','\x47'},{'\xf3','\xed'},{'\xf3','\xe7'},
+ {'\xf3','\xdd'},{'\xc4','\x4e'},{'\xf3','\xea'},{'\xf3','\xe5'},{'\xf3','\xe6'},
+ {'\x00','\x00'},{'\xf3','\xd8'},{'\xf3','\xdf'},{'\xf3','\xee'},{'\x98','\x65'},
+ {'\xf3','\xeb'},{'\x9f','\x48'},{'\xf3','\xe3'},{'\xfc','\xc6'},{'\xf3','\xef'},
+ {'\xf3','\xde'},{'\xf3','\xd9'},{'\xf3','\xec'},{'\x9f','\x49'},{'\xf3','\xdb'},
+ {'\xf3','\xe9'},{'\xf3','\xe0'},{'\xf3','\xf0'},{'\xf3','\xdc'},{'\xc4','\x4c'},
+ {'\xf3','\xda'},{'\xf3','\xe1'},{'\xf3','\xe2'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x92','\xaf'},{'\xf5','\x7d'},{'\x00','\x00'},{'\xf5','\x7b'},{'\x9f','\x4a'},
+ {'\xf5','\xa2'},{'\x00','\x00'},{'\xf5','\xae'},{'\xf5','\xa5'},{'\xf5','\x7c'},
+ {'\xf5','\x78'},{'\xf5','\xa7'},{'\xf5','\x7e'},{'\xf5','\xa3'},{'\xf5','\x7a'},
+ {'\xf5','\xaa'},{'\xf5','\x77'},{'\xf5','\xa1'},{'\xf5','\xa6'},{'\xf5','\xa8'},
+ {'\xf5','\xab'},{'\xf5','\x79'},{'\x9f','\x4b'},{'\xf5','\xaf'},{'\xf5','\xb0'},
+ {'\xf5','\xa9'},{'\xf5','\xad'},{'\xf5','\xa4'},{'\x94','\xf1'},{'\xf6','\xc1'},
+ {'\xf6','\xc4'},{'\x00','\x00'},{'\xc5','\x61'},{'\x00','\x00'},{'\xf6','\xc3'},
+ {'\xf6','\xc8'},{'\xf6','\xc6'},{'\xc5','\x62'},{'\xf6','\xbd'},{'\xf6','\xb3'},
+ {'\xf6','\xb2'},{'\xc5','\x64'},{'\xf6','\xbf'},{'\xf6','\xc0'},{'\xf6','\xbc'},
+ {'\xf6','\xb4'},{'\x9f','\x4d'},{'\xf6','\xb9'},{'\xf5','\xac'},{'\x9f','\x52'},
+ {'\xf6','\xb5'},{'\xc5','\x63'},{'\xf6','\xbb'},{'\x95','\x75'},{'\xf6','\xba'},
+ {'\x98','\x66'},{'\xf6','\xb6'},{'\xf6','\xc2'},{'\x9f','\x5e'},{'\xf6','\xb7'},
+ {'\xf7','\xbb'},{'\xf6','\xc5'},{'\xf6','\xc7'},{'\xf6','\xbe'},{'\xf6','\xb8'},
+ {'\xf7','\xbc'},{'\xf7','\xbe'},{'\xf7','\xb8'},{'\xc5','\xc2'},{'\x9f','\x5f'},
+ {'\xf7','\xc5'},{'\xf7','\xc3'},{'\xc5','\xc3'},{'\xf7','\xc2'},{'\xf7','\xc1'},
+ {'\xf7','\xba'},{'\xf7','\xb7'},{'\xf7','\xbd'},{'\xf7','\xc6'},{'\xf7','\xb9'},
+ {'\xf7','\xbf'},{'\x00','\x00'},{'\xf8','\x69'},{'\xf8','\x6e'},{'\xf8','\x64'},
+ {'\xf8','\x67'},{'\xc5','\xee'},{'\xf8','\x6b'},{'\x00','\x00'},{'\xf8','\x72'},
+ {'\xf7','\xc0'},{'\x00','\x00'},{'\xf8','\x65'},{'\xf8','\x6f'},{'\xf8','\x73'},
+ {'\xf8','\x6a'},{'\xf8','\x63'},{'\xf8','\x6d'},{'\x00','\x00'},{'\xf8','\x6c'},
+ {'\xf8','\x71'},{'\xf8','\x70'},{'\xf7','\xc4'},{'\xf8','\x68'},{'\xf8','\x62'},
+ {'\xf8','\x66'},{'\xc6','\x4e'},{'\xc6','\x4f'},{'\xf8','\x61'},{'\x9f','\x60'},
+ {'\xf8','\xe6'},{'\xf8','\xdd'},{'\xf8','\xe5'},{'\xf8','\xe2'},{'\xf8','\xe3'},
+ {'\xf8','\xdc'},{'\xf8','\xdf'},{'\xf8','\xe7'},{'\xf8','\xe1'},{'\xf8','\xe0'},
+ {'\xf8','\xde'},{'\x00','\x00'},{'\xf8','\xe4'},{'\x9f','\x61'},{'\xf9','\x5d'},
+ {'\x9f','\x62'},{'\xf9','\x5e'},{'\x9f','\x63'},{'\xf9','\x60'},{'\xf9','\x5f'},
+ {'\xf9','\x62'},{'\xf9','\x61'},{'\xf9','\x7c'},{'\xf9','\x7b'},{'\xf9','\xb7'},
+ {'\x00','\x00'},{'\xf9','\xb8'},{'\x9f','\x64'},{'\xf9','\xc5'},{'\xc6','\x78'},
+ {'\xc6','\x7c'},{'\xfd','\x4a'},{'\xf9','\xcf'},{'\xc6','\x7d'},{'\x84','\xbf'},
+ {'\x86','\xaa'},{'\x8b','\x5c'},{'\x87','\x7e'},{'\x87','\x7d'},{'\x00','\x00'},
+ {'\x8c','\xf1'},{'\x88','\xc5'},{'\x00','\x00'},{'\x8e','\xe1'},{'\x88','\xc4'},
+ {'\x89','\xc1'},{'\x8f','\xd7'},{'\x90','\xaa'},{'\x89','\xc3'},{'\x00','\x00'},
+ {'\x89','\xc2'},{'\x00','\x00'},{'\x8f','\x4e'},{'\x8f','\x4d'},{'\x89','\xc4'},
+ {'\x00','\x00'},{'\x89','\xc0'},{'\x8d','\x50'},{'\x90','\x68'},{'\x8f','\x70'},
+ {'\x8f','\x71'},{'\x8f','\x72'},{'\x00','\x00'},{'\x00','\x00'},{'\x8a','\xba'},
+ {'\x8d','\xb1'},{'\x8a','\xb9'},{'\x00','\x00'},{'\x8f','\xb4'},{'\x90','\xae'},
+ {'\x8b','\x6b'},{'\x8b','\x6d'},{'\x8b','\x6c'},{'\x8f','\xb5'},{'\x90','\x75'},
+ {'\x8f','\xb3'},{'\x8b','\xe9'},{'\x8b','\xea'},{'\x98','\x67'},{'\x8b','\xeb'},
+ {'\x00','\x00'},{'\x8f','\xd6'},{'\x8b','\xec'},{'\x00','\x00'},{'\x8b','\xe8'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x98','\x68'},{'\x00','\x00'},
+ {'\x8f','\xf6'},{'\x90','\x52'},{'\x00','\x00'},{'\x8f','\xf7'},{'\x98','\x69'},
+ {'\x8f','\xf8'},{'\x00','\x00'},{'\x8c','\xc4'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x90','\x51'},{'\x8c','\xc3'},{'\x00','\x00'},
+ {'\x8d','\xae'},{'\x8c','\xf0'},{'\x90','\x67'},{'\x90','\x71'},{'\x90','\x73'},
+ {'\x90','\x74'},{'\x90','\x72'},{'\x8d','\x67'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x8d','\x66'},{'\x98','\x6a'},{'\x00','\x00'},{'\x8d','\xb0'},{'\x00','\x00'},
+ {'\xb3','\xbf'},{'\x00','\x00'},{'\x00','\x00'},{'\x82','\x5e'},{'\xc4','\xd0'},
+ {'\xf6','\xc9'},{'\x9f','\x65'},{'\xc6','\x50'},{'\xc6','\x51'},{'\x90','\x53'},
+ {'\xb3','\xc0'},{'\xe0','\xee'},{'\xfc','\xfd'},{'\xb9','\xa8'},{'\xe8','\xf0'},
+ {'\xfb','\x5e'},{'\x9f','\x66'},{'\xec','\xb0'},{'\xec','\xb1'},{'\xec','\xaf'},
+ {'\xef','\xab'},{'\xef','\xaa'},{'\xc2','\x47'},{'\xf1','\xdf'},{'\xef','\xac'},
+ {'\xf1','\xde'},{'\x00','\x00'},{'\x9f','\x51'},{'\xf3','\xf3'},{'\xc4','\x51'},
+ {'\xc4','\x53'},{'\xf3','\xf2'},{'\xfc','\xf4'},{'\xfb','\x7c'},{'\xc4','\x52'},
+ {'\xfb','\xb7'},{'\xf5','\xb1'},{'\xf5','\xb3'},{'\xf5','\xb2'},{'\xf6','\xca'},
+ {'\xc5','\x65'},{'\xfd','\x48'},{'\xc5','\xef'},{'\xf8','\xe8'},{'\xf9','\x63'},
+ {'\x9f','\x67'},{'\x00','\x00'},{'\xf9','\xd2'},{'\xb3','\xc1'},{'\x84','\xc1'},
+ {'\xe4','\xe5'},{'\xfd','\xb4'},{'\xbe','\xa2'},{'\x98','\x6b'},{'\xfb','\xa2'},
+ {'\x9f','\x68'},{'\xec','\xb3'},{'\xec','\xb2'},{'\x95','\x73'},{'\xef','\xad'},
+ {'\x9f','\x69'},{'\x00','\x00'},{'\x00','\x00'},{'\xc4','\x54'},{'\xc4','\xd1'},
+ {'\xf7','\xc7'},{'\xf9','\xcb'},{'\x88','\xc6'},{'\x82','\x60'},{'\x82','\x61'},
+ {'\xb3','\xc2'},{'\xbb','\xf2'},{'\x98','\x6c'},{'\xbe','\xa3'},{'\x94','\xfa'},
+ {'\xf3','\xf4'},{'\x9f','\x6a'},{'\xf8','\x74'},{'\xb6','\xc0'},{'\x98','\x6d'},
+ {'\x00','\x00'},{'\x9f','\x6b'},{'\x9f','\x6c'},{'\xef','\xae'},{'\x8d','\x7a'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc6','\x64'},{'\xb6','\xc1'},{'\xbe','\xa4'},
+ {'\xc2','\x48'},{'\xf8','\x75'},{'\xb6','\xc2'},{'\x92','\xc3'},{'\xe8','\xf1'},
+ {'\xc0','\x72'},{'\xec','\xb4'},{'\xec','\xb5'},{'\x00','\x00'},{'\xc0','\x71'},
+ {'\x93','\xd4'},{'\xef','\xaf'},{'\xc2','\x4c'},{'\xc2','\x4a'},{'\xc2','\x4b'},
+ {'\xc2','\x49'},{'\xf1','\xe0'},{'\xc3','\x5c'},{'\x00','\x00'},{'\x98','\x6e'},
+ {'\x00','\x00'},{'\xf5','\xb5'},{'\xf5','\xb4'},{'\xf5','\xb7'},{'\xf5','\xb6'},
+ {'\xc4','\xd2'},{'\x8d','\xac'},{'\x98','\x6f'},{'\xf6','\xcb'},{'\x00','\x00'},
+ {'\xf6','\xcd'},{'\xf6','\xcc'},{'\xc5','\x66'},{'\xf7','\xc8'},{'\x9f','\x6d'},
+ {'\xf8','\x76'},{'\xf8','\x77'},{'\xc5','\xf0'},{'\xf9','\x64'},{'\xf9','\x7d'},
+ {'\xc6','\x75'},{'\x9f','\x6e'},{'\xdc','\xb0'},{'\xec','\xb6'},{'\xef','\xb0'},
+ {'\xf3','\xf5'},{'\xe0','\xef'},{'\x8e','\x64'},{'\xef','\xb1'},{'\xf1','\xe2'},
+ {'\xf1','\xe1'},{'\xfd','\xe8'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xf8','\x78'},{'\xc6','\x52'},{'\x98','\x70'},{'\xf9','\x65'},{'\xf9','\x7e'},
+ {'\x98','\x71'},{'\x00','\x00'},{'\x98','\x72'},{'\xb9','\xa9'},{'\xe8','\xf2'},
+ {'\xe8','\xf3'},{'\x00','\x00'},{'\xec','\xb7'},{'\xb9','\xaa'},{'\x00','\x00'},
+ {'\xc3','\x5d'},{'\xf1','\xe3'},{'\xfc','\xdb'},{'\xf6','\xcf'},{'\xc5','\x67'},
+ {'\xf6','\xd0'},{'\xf6','\xce'},{'\xf8','\x79'},{'\x00','\x00'},{'\xf8','\xe9'},
+ {'\x00','\x00'},{'\xb9','\xab'},{'\x98','\x73'},{'\xef','\xb4'},{'\xef','\xb3'},
+ {'\xef','\xb2'},{'\xf1','\xe4'},{'\xfb','\xb8'},{'\x9f','\x6f'},{'\xf1','\xe8'},
+ {'\xf1','\xe7'},{'\xf1','\xe6'},{'\xf1','\xe5'},{'\xc3','\x5e'},{'\xf3','\xf6'},
+ {'\xf5','\xb9'},{'\xc4','\xd3'},{'\xf5','\xb8'},{'\xf6','\xd1'},{'\xf7','\xcb'},
+ {'\xf7','\xca'},{'\xc5','\xc4'},{'\xf7','\xc9'},{'\xf8','\x7c'},{'\xf8','\x7b'},
+ {'\xf8','\x7a'},{'\x8c','\xf2'},{'\x00','\x00'},{'\xbb','\xf3'},{'\x00','\x00'},
+ {'\xec','\xb8'},{'\xc2','\x4d'},{'\x00','\x00'},{'\xf3','\xf7'},{'\xf3','\xf8'},
+ {'\xf7','\xcc'},{'\xf8','\x7d'},{'\x98','\x74'},{'\xfd','\xe2'},{'\xf8','\xea'},
+ {'\xf9','\x66'},{'\xf9','\xb9'},{'\xf9','\xd4'},{'\xbb','\xf4'},{'\xc2','\x4e'},
+ {'\xf1','\xe9'},{'\xf3','\xf9'},{'\xf6','\xd2'},{'\xf8','\x7e'},{'\x87','\xa2'},
+ {'\x98','\x75'},{'\xbe','\xa6'},{'\xfd','\xe0'},{'\xef','\xb5'},{'\xf1','\xea'},
+ {'\xf3','\xfa'},{'\xf3','\xfb'},{'\xf3','\xfc'},{'\xf5','\xbe'},{'\xfd','\xda'},
+ {'\xf5','\xba'},{'\xc5','\x68'},{'\xf5','\xbd'},{'\xf5','\xbc'},{'\xc4','\xd4'},
+ {'\xf5','\xbb'},{'\xc4','\xd6'},{'\x93','\xee'},{'\xc4','\xd5'},{'\xf6','\xd4'},
+ {'\xf6','\xd3'},{'\xc5','\x69'},{'\xc5','\x6a'},{'\x00','\x00'},{'\xfd','\x62'},
+ {'\xc5','\xc6'},{'\xf7','\xcd'},{'\xc5','\xc5'},{'\x00','\x00'},{'\xf8','\xa3'},
+ {'\xf8','\xa4'},{'\xf8','\xa2'},{'\xf8','\xa1'},{'\xc6','\x54'},{'\x00','\x00'},
+ {'\xf8','\xeb'},{'\xf8','\xec'},{'\xf8','\xed'},{'\xc6','\x53'},{'\xf9','\x67'},
+ {'\xf9','\x6a'},{'\xf9','\x69'},{'\xf9','\x68'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xf9','\xd3'},{'\x88','\xc7'},{'\x8f','\x73'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x8c','\x6a'},{'\x8c','\x6b'},{'\x8f','\xfa'},{'\x8f','\xf9'},{'\x8c','\xc5'},
+ {'\x8c','\xc6'},{'\x8c','\xf3'},{'\x8c','\xf4'},{'\x8d','\x6c'},{'\x8d','\x6b'},
+ {'\xc0','\x73'},{'\xfb','\xd8'},{'\x00','\x00'},{'\xc3','\x65'},{'\xf5','\xbf'},
+ {'\xf6','\xd5'},{'\x00','\x00'},{'\xc5','\xc7'},{'\xf7','\xce'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xf9','\xd5'},{'\x89','\xc5'},{'\x8c','\xf5'},{'\x90','\x69'},
+ {'\xc0','\x74'},{'\x98','\x76'},{'\x00','\x00'},{'\x89','\xc6'},{'\xef','\xb6'},
+ {'\x00','\x00'},{'\xf7','\xcf'},{'\x00','\x00'},{'\xf9','\xa1'},{'\xfd','\xd4'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xc8','\xa1'},{'\xc8','\xa3'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xfa','\x40'},
+ {'\xfa','\x41'},{'\xfa','\x42'},{'\xfa','\x43'},{'\xfa','\x44'},{'\xfa','\x45'},
+ {'\xfa','\x46'},{'\xfa','\x47'},{'\xfa','\x48'},{'\xfa','\x49'},{'\xfa','\x4a'},
+ {'\xfa','\x4b'},{'\xfa','\x4c'},{'\xfa','\x4d'},{'\xfa','\x4e'},{'\xfa','\x4f'},
+ {'\xfa','\x50'},{'\xfa','\x51'},{'\xfa','\x52'},{'\xfa','\x53'},{'\xfa','\x54'},
+ {'\xfa','\x55'},{'\xfa','\x56'},{'\xfa','\x57'},{'\xfa','\x58'},{'\xfa','\x59'},
+ {'\xfa','\x5a'},{'\xfa','\x5b'},{'\xfa','\x5c'},{'\xfa','\x5d'},{'\xfa','\x5e'},
+ {'\xfa','\x5f'},{'\xfa','\x60'},{'\xfa','\x61'},{'\xfa','\x62'},{'\xfa','\x63'},
+ {'\xfa','\x64'},{'\xfa','\x65'},{'\xfa','\x66'},{'\xfa','\x67'},{'\xfa','\x68'},
+ {'\xfa','\x69'},{'\xfa','\x6a'},{'\xfa','\x6b'},{'\xfa','\x6c'},{'\xfa','\x6d'},
+ {'\xfa','\x6e'},{'\xfa','\x6f'},{'\xfa','\x70'},{'\xfa','\x71'},{'\xfa','\x72'},
+ {'\xfa','\x73'},{'\xfa','\x74'},{'\xfa','\x75'},{'\xfa','\x76'},{'\xfa','\x77'},
+ {'\xfa','\x78'},{'\xfa','\x79'},{'\xfa','\x7a'},{'\xfa','\x7b'},{'\xfa','\x7c'},
+ {'\xfa','\x7d'},{'\xfa','\x7e'},{'\xfa','\xa1'},{'\xfa','\xa2'},{'\xfa','\xa3'},
+ {'\xfa','\xa4'},{'\xfa','\xa5'},{'\xfa','\xa6'},{'\xfa','\xa7'},{'\xfa','\xa8'},
+ {'\xfa','\xa9'},{'\xfa','\xaa'},{'\xfa','\xab'},{'\xfa','\xac'},{'\xfa','\xad'},
+ {'\xfa','\xae'},{'\xfa','\xaf'},{'\xfa','\xb0'},{'\xfa','\xb1'},{'\xfa','\xb2'},
+ {'\xfa','\xb3'},{'\xfa','\xb4'},{'\xfa','\xb5'},{'\xfa','\xb6'},{'\xfa','\xb7'},
+ {'\xfa','\xb8'},{'\xfa','\xb9'},{'\xfa','\xba'},{'\xfa','\xbb'},{'\xfa','\xbc'},
+ {'\xfa','\xbd'},{'\xfa','\xbe'},{'\xfa','\xbf'},{'\xfa','\xc0'},{'\xfa','\xc1'},
+ {'\xfa','\xc2'},{'\xfa','\xc3'},{'\xfa','\xc4'},{'\xfa','\xc5'},{'\xfa','\xc6'},
+ {'\xfa','\xc7'},{'\xfa','\xc8'},{'\xfa','\xc9'},{'\xfa','\xca'},{'\xfa','\xcb'},
+ {'\xfa','\xcc'},{'\xfa','\xcd'},{'\xfa','\xce'},{'\xfa','\xcf'},{'\xfa','\xd0'},
+ {'\xfa','\xd1'},{'\xfa','\xd2'},{'\xfa','\xd3'},{'\xfa','\xd4'},{'\xfa','\xd5'},
+ {'\xfa','\xd6'},{'\xfa','\xd7'},{'\xfa','\xd8'},{'\xfa','\xd9'},{'\xfa','\xda'},
+ {'\xfa','\xdb'},{'\xfa','\xdc'},{'\xfa','\xdd'},{'\xfa','\xde'},{'\xfa','\xdf'},
+ {'\xfa','\xe0'},{'\xfa','\xe1'},{'\xfa','\xe2'},{'\xfa','\xe3'},{'\xfa','\xe4'},
+ {'\xfa','\xe5'},{'\xfa','\xe6'},{'\xfa','\xe7'},{'\xfa','\xe8'},{'\xfa','\xe9'},
+ {'\xfa','\xea'},{'\xfa','\xeb'},{'\xfa','\xec'},{'\xfa','\xed'},{'\xfa','\xee'},
+ {'\xfa','\xef'},{'\xfa','\xf0'},{'\xfa','\xf1'},{'\xfa','\xf2'},{'\xfa','\xf3'},
+ {'\xfa','\xf4'},{'\xfa','\xf5'},{'\xfa','\xf6'},{'\xfa','\xf7'},{'\xfa','\xf8'},
+ {'\xfa','\xf9'},{'\xfa','\xfa'},{'\xfa','\xfb'},{'\xfa','\xfc'},{'\xfa','\xfd'},
+ {'\xfa','\xfe'},{'\xfb','\x40'},{'\xfb','\x41'},{'\xfb','\x42'},{'\xfb','\x43'},
+ {'\xfb','\x44'},{'\xfb','\x45'},{'\xfb','\x46'},{'\xfb','\x47'},{'\xfb','\x48'},
+ {'\xfb','\x49'},{'\xfb','\x4a'},{'\xfb','\x4b'},{'\xfb','\x4c'},{'\xfb','\x4d'},
+ {'\xfb','\x4e'},{'\xfb','\x4f'},{'\xfb','\x50'},{'\xfb','\x51'},{'\xfb','\x52'},
+ {'\xfb','\x53'},{'\xfb','\x54'},{'\xfb','\x55'},{'\xfb','\x56'},{'\xfb','\x57'},
+ {'\xfb','\x58'},{'\xfb','\x59'},{'\xfb','\x5a'},{'\xfb','\x5b'},{'\xfb','\x5c'},
+ {'\xfb','\x5d'},{'\xfb','\x5e'},{'\xfb','\x5f'},{'\xfb','\x60'},{'\xfb','\x61'},
+ {'\xfb','\x62'},{'\xfb','\x63'},{'\xfb','\x64'},{'\xfb','\x65'},{'\xfb','\x66'},
+ {'\xfb','\x67'},{'\xfb','\x68'},{'\xfb','\x69'},{'\xfb','\x6a'},{'\xfb','\x6b'},
+ {'\xfb','\x6c'},{'\xfb','\x6d'},{'\xfb','\x6e'},{'\xfb','\x6f'},{'\xfb','\x70'},
+ {'\xfb','\x71'},{'\xfb','\x72'},{'\xfb','\x73'},{'\xfb','\x74'},{'\xfb','\x75'},
+ {'\xfb','\x76'},{'\xfb','\x77'},{'\xfb','\x78'},{'\xfb','\x79'},{'\xfb','\x7a'},
+ {'\xfb','\x7b'},{'\xfb','\x7c'},{'\xfb','\x7d'},{'\xfb','\x7e'},{'\xfb','\xa1'},
+ {'\xfb','\xa2'},{'\xfb','\xa3'},{'\xfb','\xa4'},{'\xfb','\xa5'},{'\xfb','\xa6'},
+ {'\xfb','\xa7'},{'\xfb','\xa8'},{'\xfb','\xa9'},{'\xfb','\xaa'},{'\xfb','\xab'},
+ {'\xfb','\xac'},{'\xfb','\xad'},{'\xfb','\xae'},{'\xfb','\xaf'},{'\xfb','\xb0'},
+ {'\xfb','\xb1'},{'\xfb','\xb2'},{'\xfb','\xb3'},{'\xfb','\xb4'},{'\xfb','\xb5'},
+ {'\xfb','\xb6'},{'\xfb','\xb7'},{'\xfb','\xb8'},{'\xfb','\xb9'},{'\xfb','\xba'},
+ {'\xfb','\xbb'},{'\xfb','\xbc'},{'\xfb','\xbd'},{'\xfb','\xbe'},{'\xfb','\xbf'},
+ {'\xfb','\xc0'},{'\xfb','\xc1'},{'\xfb','\xc2'},{'\xfb','\xc3'},{'\xfb','\xc4'},
+ {'\xfb','\xc5'},{'\xfb','\xc6'},{'\xfb','\xc7'},{'\xfb','\xc8'},{'\xfb','\xc9'},
+ {'\xfb','\xca'},{'\xfb','\xcb'},{'\xfb','\xcc'},{'\xfb','\xcd'},{'\xfb','\xce'},
+ {'\xfb','\xcf'},{'\xfb','\xd0'},{'\xfb','\xd1'},{'\xfb','\xd2'},{'\xfb','\xd3'},
+ {'\xfb','\xd4'},{'\xfb','\xd5'},{'\xfb','\xd6'},{'\xfb','\xd7'},{'\xfb','\xd8'},
+ {'\xfb','\xd9'},{'\xfb','\xda'},{'\xfb','\xdb'},{'\xfb','\xdc'},{'\xfb','\xdd'},
+ {'\xfb','\xde'},{'\xfb','\xdf'},{'\xfb','\xe0'},{'\xfb','\xe1'},{'\xfb','\xe2'},
+ {'\xfb','\xe3'},{'\xfb','\xe4'},{'\xfb','\xe5'},{'\xfb','\xe6'},{'\xfb','\xe7'},
+ {'\xfb','\xe8'},{'\xfb','\xe9'},{'\xfb','\xea'},{'\xfb','\xeb'},{'\xfb','\xec'},
+ {'\xfb','\xed'},{'\xfb','\xee'},{'\xfb','\xef'},{'\xfb','\xf0'},{'\xfb','\xf1'},
+ {'\xfb','\xf2'},{'\xfb','\xf3'},{'\xfb','\xf4'},{'\xfb','\xf5'},{'\xfb','\xf6'},
+ {'\xfb','\xf7'},{'\xfb','\xf8'},{'\xfb','\xf9'},{'\xfb','\xfa'},{'\xfb','\xfb'},
+ {'\xfb','\xfc'},{'\xfb','\xfd'},{'\xfb','\xfe'},{'\xfc','\x40'},{'\xfc','\x41'},
+ {'\xfc','\x42'},{'\xfc','\x43'},{'\xfc','\x44'},{'\xfc','\x45'},{'\xfc','\x46'},
+ {'\xfc','\x47'},{'\xfc','\x48'},{'\xfc','\x49'},{'\xfc','\x4a'},{'\xfc','\x4b'},
+ {'\xfc','\x4c'},{'\xfc','\x4d'},{'\xfc','\x4e'},{'\xfc','\x4f'},{'\xfc','\x50'},
+ {'\xfc','\x51'},{'\xfc','\x52'},{'\xfc','\x53'},{'\xfc','\x54'},{'\xfc','\x55'},
+ {'\xfc','\x56'},{'\xfc','\x57'},{'\xfc','\x58'},{'\xfc','\x59'},{'\xfc','\x5a'},
+ {'\xfc','\x5b'},{'\xfc','\x5c'},{'\xfc','\x5d'},{'\xfc','\x5e'},{'\xfc','\x5f'},
+ {'\xfc','\x60'},{'\xfc','\x61'},{'\xfc','\x62'},{'\xfc','\x63'},{'\xfc','\x64'},
+ {'\xfc','\x65'},{'\xfc','\x66'},{'\xfc','\x67'},{'\xfc','\x68'},{'\xfc','\x69'},
+ {'\xfc','\x6a'},{'\xfc','\x6b'},{'\xfc','\x6c'},{'\xfc','\x6d'},{'\xfc','\x6e'},
+ {'\xfc','\x6f'},{'\xfc','\x70'},{'\xfc','\x71'},{'\xfc','\x72'},{'\xfc','\x73'},
+ {'\xfc','\x74'},{'\xfc','\x75'},{'\xfc','\x76'},{'\xfc','\x77'},{'\xfc','\x78'},
+ {'\xfc','\x79'},{'\xfc','\x7a'},{'\xfc','\x7b'},{'\xfc','\x7c'},{'\xfc','\x7d'},
+ {'\xfc','\x7e'},{'\xfc','\xa1'},{'\xfc','\xa2'},{'\xfc','\xa3'},{'\xfc','\xa4'},
+ {'\xfc','\xa5'},{'\xfc','\xa6'},{'\xfc','\xa7'},{'\xfc','\xa8'},{'\xfc','\xa9'},
+ {'\xfc','\xaa'},{'\xfc','\xab'},{'\xfc','\xac'},{'\xfc','\xad'},{'\xfc','\xae'},
+ {'\xfc','\xaf'},{'\xfc','\xb0'},{'\xfc','\xb1'},{'\xfc','\xb2'},{'\xfc','\xb3'},
+ {'\xfc','\xb4'},{'\xfc','\xb5'},{'\xfc','\xb6'},{'\xfc','\xb7'},{'\xfc','\xb8'},
+ {'\xfc','\xb9'},{'\xfc','\xba'},{'\xfc','\xbb'},{'\xfc','\xbc'},{'\xfc','\xbd'},
+ {'\xfc','\xbe'},{'\xfc','\xbf'},{'\xfc','\xc0'},{'\xfc','\xc1'},{'\xfc','\xc2'},
+ {'\xfc','\xc3'},{'\xfc','\xc4'},{'\xfc','\xc5'},{'\xfc','\xc6'},{'\xfc','\xc7'},
+ {'\xfc','\xc8'},{'\xfc','\xc9'},{'\xfc','\xca'},{'\xfc','\xcb'},{'\xfc','\xcc'},
+ {'\xfc','\xcd'},{'\xfc','\xce'},{'\xfc','\xcf'},{'\xfc','\xd0'},{'\xfc','\xd1'},
+ {'\xfc','\xd2'},{'\xfc','\xd3'},{'\xfc','\xd4'},{'\xfc','\xd5'},{'\xfc','\xd6'},
+ {'\xfc','\xd7'},{'\xfc','\xd8'},{'\xfc','\xd9'},{'\xfc','\xda'},{'\xfc','\xdb'},
+ {'\xfc','\xdc'},{'\xfc','\xdd'},{'\xfc','\xde'},{'\xfc','\xdf'},{'\xfc','\xe0'},
+ {'\xfc','\xe1'},{'\xfc','\xe2'},{'\xfc','\xe3'},{'\xfc','\xe4'},{'\xfc','\xe5'},
+ {'\xfc','\xe6'},{'\xfc','\xe7'},{'\xfc','\xe8'},{'\xfc','\xe9'},{'\xfc','\xea'},
+ {'\xfc','\xeb'},{'\xfc','\xec'},{'\xfc','\xed'},{'\xfc','\xee'},{'\xfc','\xef'},
+ {'\xfc','\xf0'},{'\xfc','\xf1'},{'\xfc','\xf2'},{'\xfc','\xf3'},{'\xfc','\xf4'},
+ {'\xfc','\xf5'},{'\xfc','\xf6'},{'\xfc','\xf7'},{'\xfc','\xf8'},{'\xfc','\xf9'},
+ {'\xfc','\xfa'},{'\xfc','\xfb'},{'\xfc','\xfc'},{'\xfc','\xfd'},{'\xfc','\xfe'},
+ {'\xfd','\x40'},{'\xfd','\x41'},{'\xfd','\x42'},{'\xfd','\x43'},{'\xfd','\x44'},
+ {'\xfd','\x45'},{'\xfd','\x46'},{'\xfd','\x47'},{'\xfd','\x48'},{'\xfd','\x49'},
+ {'\xfd','\x4a'},{'\xfd','\x4b'},{'\xfd','\x4c'},{'\xfd','\x4d'},{'\xfd','\x4e'},
+ {'\xfd','\x4f'},{'\xfd','\x50'},{'\xfd','\x51'},{'\xfd','\x52'},{'\xfd','\x53'},
+ {'\xfd','\x54'},{'\xfd','\x55'},{'\xfd','\x56'},{'\xfd','\x57'},{'\xfd','\x58'},
+ {'\xfd','\x59'},{'\xfd','\x5a'},{'\xfd','\x5b'},{'\xfd','\x5c'},{'\xfd','\x5d'},
+ {'\xfd','\x5e'},{'\xfd','\x5f'},{'\xfd','\x60'},{'\xfd','\x61'},{'\xfd','\x62'},
+ {'\xfd','\x63'},{'\xfd','\x64'},{'\xfd','\x65'},{'\xfd','\x66'},{'\xfd','\x67'},
+ {'\xfd','\x68'},{'\xfd','\x69'},{'\xfd','\x6a'},{'\xfd','\x6b'},{'\xfd','\x6c'},
+ {'\xfd','\x6d'},{'\xfd','\x6e'},{'\xfd','\x6f'},{'\xfd','\x70'},{'\xfd','\x71'},
+ {'\xfd','\x72'},{'\xfd','\x73'},{'\xfd','\x74'},{'\xfd','\x75'},{'\xfd','\x76'},
+ {'\xfd','\x77'},{'\xfd','\x78'},{'\xfd','\x79'},{'\xfd','\x7a'},{'\xfd','\x7b'},
+ {'\xfd','\x7c'},{'\xfd','\x7d'},{'\xfd','\x7e'},{'\xfd','\xa1'},{'\xfd','\xa2'},
+ {'\xfd','\xa3'},{'\xfd','\xa4'},{'\xfd','\xa5'},{'\xfd','\xa6'},{'\xfd','\xa7'},
+ {'\xfd','\xa8'},{'\xfd','\xa9'},{'\xfd','\xaa'},{'\xfd','\xab'},{'\xfd','\xac'},
+ {'\xfd','\xad'},{'\xfd','\xae'},{'\xfd','\xaf'},{'\xfd','\xb0'},{'\xfd','\xb1'},
+ {'\xfd','\xb2'},{'\xfd','\xb3'},{'\xfd','\xb4'},{'\xfd','\xb5'},{'\xfd','\xb6'},
+ {'\xfd','\xb7'},{'\xfd','\xb8'},{'\xfd','\xb9'},{'\xfd','\xba'},{'\xfd','\xbb'},
+ {'\xfd','\xbc'},{'\xfd','\xbd'},{'\xfd','\xbe'},{'\xfd','\xbf'},{'\xfd','\xc0'},
+ {'\xfd','\xc1'},{'\xfd','\xc2'},{'\xfd','\xc3'},{'\xfd','\xc4'},{'\xfd','\xc5'},
+ {'\xfd','\xc6'},{'\xfd','\xc7'},{'\xfd','\xc8'},{'\xfd','\xc9'},{'\xfd','\xca'},
+ {'\xfd','\xcb'},{'\xfd','\xcc'},{'\xfd','\xcd'},{'\xfd','\xce'},{'\xfd','\xcf'},
+ {'\xfd','\xd0'},{'\xfd','\xd1'},{'\xfd','\xd2'},{'\xfd','\xd3'},{'\xfd','\xd4'},
+ {'\xfd','\xd5'},{'\xfd','\xd6'},{'\xfd','\xd7'},{'\xfd','\xd8'},{'\xfd','\xd9'},
+ {'\xfd','\xda'},{'\xfd','\xdb'},{'\xfd','\xdc'},{'\xfd','\xdd'},{'\xfd','\xde'},
+ {'\xfd','\xdf'},{'\xfd','\xe0'},{'\xfd','\xe1'},{'\xfd','\xe2'},{'\xfd','\xe3'},
+ {'\xfd','\xe4'},{'\xfd','\xe5'},{'\xfd','\xe6'},{'\xfd','\xe7'},{'\xfd','\xe8'},
+ {'\xfd','\xe9'},{'\xfd','\xea'},{'\xfd','\xeb'},{'\xfd','\xec'},{'\xfd','\xed'},
+ {'\xfd','\xee'},{'\xfd','\xef'},{'\xfd','\xf0'},{'\xfd','\xf1'},{'\xfd','\xf2'},
+ {'\xfd','\xf3'},{'\xfd','\xf4'},{'\xfd','\xf5'},{'\xfd','\xf6'},{'\xfd','\xf7'},
+ {'\xfd','\xf8'},{'\xfd','\xf9'},{'\xfd','\xfa'},{'\xfd','\xfb'},{'\xfd','\xfc'},
+ {'\xfd','\xfd'},{'\xfd','\xfe'},{'\xfe','\x40'},{'\xfe','\x41'},{'\xfe','\x42'},
+ {'\xfe','\x43'},{'\xfe','\x44'},{'\xfe','\x45'},{'\xfe','\x46'},{'\xfe','\x47'},
+ {'\xfe','\x48'},{'\xfe','\x49'},{'\xfe','\x4a'},{'\xfe','\x4b'},{'\xfe','\x4c'},
+ {'\xfe','\x4d'},{'\xfe','\x4e'},{'\xfe','\x4f'},{'\xfe','\x50'},{'\xfe','\x51'},
+ {'\xfe','\x52'},{'\xfe','\x53'},{'\xfe','\x54'},{'\xfe','\x55'},{'\xfe','\x56'},
+ {'\xfe','\x57'},{'\xfe','\x58'},{'\xfe','\x59'},{'\xfe','\x5a'},{'\xfe','\x5b'},
+ {'\xfe','\x5c'},{'\xfe','\x5d'},{'\xfe','\x5e'},{'\xfe','\x5f'},{'\xfe','\x60'},
+ {'\xfe','\x61'},{'\xfe','\x62'},{'\xfe','\x63'},{'\xfe','\x64'},{'\xfe','\x65'},
+ {'\xfe','\x66'},{'\xfe','\x67'},{'\xfe','\x68'},{'\xfe','\x69'},{'\xfe','\x6a'},
+ {'\xfe','\x6b'},{'\xfe','\x6c'},{'\xfe','\x6d'},{'\xfe','\x6e'},{'\xfe','\x6f'},
+ {'\xfe','\x70'},{'\xfe','\x71'},{'\xfe','\x72'},{'\xfe','\x73'},{'\xfe','\x74'},
+ {'\xfe','\x75'},{'\xfe','\x76'},{'\xfe','\x77'},{'\xfe','\x78'},{'\xfe','\x79'},
+ {'\xfe','\x7a'},{'\xfe','\x7b'},{'\xfe','\x7c'},{'\xfe','\x7d'},{'\xfe','\x7e'},
+ {'\xfe','\xa1'},{'\xfe','\xa2'},{'\xfe','\xa3'},{'\xfe','\xa4'},{'\xfe','\xa5'},
+ {'\xfe','\xa6'},{'\xfe','\xa7'},{'\xfe','\xa8'},{'\xfe','\xa9'},{'\xfe','\xaa'},
+ {'\xfe','\xab'},{'\xfe','\xac'},{'\xfe','\xad'},{'\xfe','\xae'},{'\xfe','\xaf'},
+ {'\xfe','\xb0'},{'\xfe','\xb1'},{'\xfe','\xb2'},{'\xfe','\xb3'},{'\xfe','\xb4'},
+ {'\xfe','\xb5'},{'\xfe','\xb6'},{'\xfe','\xb7'},{'\xfe','\xb8'},{'\xfe','\xb9'},
+ {'\xfe','\xba'},{'\xfe','\xbb'},{'\xfe','\xbc'},{'\xfe','\xbd'},{'\xfe','\xbe'},
+ {'\xfe','\xbf'},{'\xfe','\xc0'},{'\xfe','\xc1'},{'\xfe','\xc2'},{'\xfe','\xc3'},
+ {'\xfe','\xc4'},{'\xfe','\xc5'},{'\xfe','\xc6'},{'\xfe','\xc7'},{'\xfe','\xc8'},
+ {'\xfe','\xc9'},{'\xfe','\xca'},{'\xfe','\xcb'},{'\xfe','\xcc'},{'\xfe','\xcd'},
+ {'\xfe','\xce'},{'\xfe','\xcf'},{'\xfe','\xd0'},{'\xfe','\xd1'},{'\xfe','\xd2'},
+ {'\xfe','\xd3'},{'\xfe','\xd4'},{'\xfe','\xd5'},{'\xfe','\xd6'},{'\xfe','\xd7'},
+ {'\xfe','\xd8'},{'\xfe','\xd9'},{'\xfe','\xda'},{'\xfe','\xdb'},{'\xfe','\xdc'},
+ {'\xfe','\xdd'},{'\xfe','\xde'},{'\xfe','\xdf'},{'\xfe','\xe0'},{'\xfe','\xe1'},
+ {'\xfe','\xe2'},{'\xfe','\xe3'},{'\xfe','\xe4'},{'\xfe','\xe5'},{'\xfe','\xe6'},
+ {'\xfe','\xe7'},{'\xfe','\xe8'},{'\xfe','\xe9'},{'\xfe','\xea'},{'\xfe','\xeb'},
+ {'\xfe','\xec'},{'\xfe','\xed'},{'\xfe','\xee'},{'\xfe','\xef'},{'\xfe','\xf0'},
+ {'\xfe','\xf1'},{'\xfe','\xf2'},{'\xfe','\xf3'},{'\xfe','\xf4'},{'\xfe','\xf5'},
+ {'\xfe','\xf6'},{'\xfe','\xf7'},{'\xfe','\xf8'},{'\xfe','\xf9'},{'\xfe','\xfa'},
+ {'\xfe','\xfb'},{'\xfe','\xfc'},{'\xfe','\xfd'},{'\xfe','\xfe'},{'\x8e','\x40'},
+ {'\x8e','\x41'},{'\x8e','\x42'},{'\x8e','\x43'},{'\x8e','\x44'},{'\x8e','\x45'},
+ {'\x8e','\x46'},{'\x8e','\x47'},{'\x8e','\x48'},{'\x8e','\x49'},{'\x8e','\x4a'},
+ {'\x8e','\x4b'},{'\x8e','\x4c'},{'\x8e','\x4d'},{'\x8e','\x4e'},{'\x8e','\x4f'},
+ {'\x8e','\x50'},{'\x8e','\x51'},{'\x8e','\x52'},{'\x8e','\x53'},{'\x8e','\x54'},
+ {'\x8e','\x55'},{'\x8e','\x56'},{'\x8e','\x57'},{'\x8e','\x58'},{'\x8e','\x59'},
+ {'\x8e','\x5a'},{'\x8e','\x5b'},{'\x8e','\x5c'},{'\x8e','\x5d'},{'\x8e','\x5e'},
+ {'\x8e','\x5f'},{'\x8e','\x60'},{'\x8e','\x61'},{'\x8e','\x62'},{'\x8e','\x63'},
+ {'\x8e','\x64'},{'\x8e','\x65'},{'\x8e','\x66'},{'\x8e','\x67'},{'\x8e','\x68'},
+ {'\x8e','\x69'},{'\x8e','\x6a'},{'\x8e','\x6b'},{'\x8e','\x6c'},{'\x8e','\x6d'},
+ {'\x8e','\x6e'},{'\x8e','\x6f'},{'\x8e','\x70'},{'\x8e','\x71'},{'\x8e','\x72'},
+ {'\x8e','\x73'},{'\x8e','\x74'},{'\x8e','\x75'},{'\x8e','\x76'},{'\x8e','\x77'},
+ {'\x8e','\x78'},{'\x8e','\x79'},{'\x8e','\x7a'},{'\x8e','\x7b'},{'\x8e','\x7c'},
+ {'\x8e','\x7d'},{'\x8e','\x7e'},{'\x8e','\xa1'},{'\x8e','\xa2'},{'\x8e','\xa3'},
+ {'\x8e','\xa4'},{'\x8e','\xa5'},{'\x8e','\xa6'},{'\x8e','\xa7'},{'\x8e','\xa8'},
+ {'\x8e','\xa9'},{'\x8e','\xaa'},{'\x8e','\xab'},{'\x8e','\xac'},{'\x8e','\xad'},
+ {'\x8e','\xae'},{'\x8e','\xaf'},{'\x8e','\xb0'},{'\x8e','\xb1'},{'\x8e','\xb2'},
+ {'\x8e','\xb3'},{'\x8e','\xb4'},{'\x8e','\xb5'},{'\x8e','\xb6'},{'\x8e','\xb7'},
+ {'\x8e','\xb8'},{'\x8e','\xb9'},{'\x8e','\xba'},{'\x8e','\xbb'},{'\x8e','\xbc'},
+ {'\x8e','\xbd'},{'\x8e','\xbe'},{'\x8e','\xbf'},{'\x8e','\xc0'},{'\x8e','\xc1'},
+ {'\x8e','\xc2'},{'\x8e','\xc3'},{'\x8e','\xc4'},{'\x8e','\xc5'},{'\x8e','\xc6'},
+ {'\x8e','\xc7'},{'\x8e','\xc8'},{'\x8e','\xc9'},{'\x8e','\xca'},{'\x8e','\xcb'},
+ {'\x8e','\xcc'},{'\x8e','\xcd'},{'\x8e','\xce'},{'\x8e','\xcf'},{'\x8e','\xd0'},
+ {'\x8e','\xd1'},{'\x8e','\xd2'},{'\x8e','\xd3'},{'\x8e','\xd4'},{'\x8e','\xd5'},
+ {'\x8e','\xd6'},{'\x8e','\xd7'},{'\x8e','\xd8'},{'\x8e','\xd9'},{'\x8e','\xda'},
+ {'\x8e','\xdb'},{'\x8e','\xdc'},{'\x8e','\xdd'},{'\x8e','\xde'},{'\x8e','\xdf'},
+ {'\x8e','\xe0'},{'\x8e','\xe1'},{'\x8e','\xe2'},{'\x8e','\xe3'},{'\x8e','\xe4'},
+ {'\x8e','\xe5'},{'\x8e','\xe6'},{'\x8e','\xe7'},{'\x8e','\xe8'},{'\x8e','\xe9'},
+ {'\x8e','\xea'},{'\x8e','\xeb'},{'\x8e','\xec'},{'\x8e','\xed'},{'\x8e','\xee'},
+ {'\x8e','\xef'},{'\x8e','\xf0'},{'\x8e','\xf1'},{'\x8e','\xf2'},{'\x8e','\xf3'},
+ {'\x8e','\xf4'},{'\x8e','\xf5'},{'\x8e','\xf6'},{'\x8e','\xf7'},{'\x8e','\xf8'},
+ {'\x8e','\xf9'},{'\x8e','\xfa'},{'\x8e','\xfb'},{'\x8e','\xfc'},{'\x8e','\xfd'},
+ {'\x8e','\xfe'},{'\x8f','\x40'},{'\x8f','\x41'},{'\x8f','\x42'},{'\x8f','\x43'},
+ {'\x8f','\x44'},{'\x8f','\x45'},{'\x8f','\x46'},{'\x8f','\x47'},{'\x8f','\x48'},
+ {'\x8f','\x49'},{'\x8f','\x4a'},{'\x8f','\x4b'},{'\x8f','\x4c'},{'\x8f','\x4d'},
+ {'\x8f','\x4e'},{'\x8f','\x4f'},{'\x8f','\x50'},{'\x8f','\x51'},{'\x8f','\x52'},
+ {'\x8f','\x53'},{'\x8f','\x54'},{'\x8f','\x55'},{'\x8f','\x56'},{'\x8f','\x57'},
+ {'\x8f','\x58'},{'\x8f','\x59'},{'\x8f','\x5a'},{'\x8f','\x5b'},{'\x8f','\x5c'},
+ {'\x8f','\x5d'},{'\x8f','\x5e'},{'\x8f','\x5f'},{'\x8f','\x60'},{'\x8f','\x61'},
+ {'\x8f','\x62'},{'\x8f','\x63'},{'\x8f','\x64'},{'\x8f','\x65'},{'\x8f','\x66'},
+ {'\x8f','\x67'},{'\x8f','\x68'},{'\x8f','\x69'},{'\x8f','\x6a'},{'\x8f','\x6b'},
+ {'\x8f','\x6c'},{'\x8f','\x6d'},{'\x8f','\x6e'},{'\x8f','\x6f'},{'\x8f','\x70'},
+ {'\x8f','\x71'},{'\x8f','\x72'},{'\x8f','\x73'},{'\x8f','\x74'},{'\x8f','\x75'},
+ {'\x8f','\x76'},{'\x8f','\x77'},{'\x8f','\x78'},{'\x8f','\x79'},{'\x8f','\x7a'},
+ {'\x8f','\x7b'},{'\x8f','\x7c'},{'\x8f','\x7d'},{'\x8f','\x7e'},{'\x8f','\xa1'},
+ {'\x8f','\xa2'},{'\x8f','\xa3'},{'\x8f','\xa4'},{'\x8f','\xa5'},{'\x8f','\xa6'},
+ {'\x8f','\xa7'},{'\x8f','\xa8'},{'\x8f','\xa9'},{'\x8f','\xaa'},{'\x8f','\xab'},
+ {'\x8f','\xac'},{'\x8f','\xad'},{'\x8f','\xae'},{'\x8f','\xaf'},{'\x8f','\xb0'},
+ {'\x8f','\xb1'},{'\x8f','\xb2'},{'\x8f','\xb3'},{'\x8f','\xb4'},{'\x8f','\xb5'},
+ {'\x8f','\xb6'},{'\x8f','\xb7'},{'\x8f','\xb8'},{'\x8f','\xb9'},{'\x8f','\xba'},
+ {'\x8f','\xbb'},{'\x8f','\xbc'},{'\x8f','\xbd'},{'\x8f','\xbe'},{'\x8f','\xbf'},
+ {'\x8f','\xc0'},{'\x8f','\xc1'},{'\x8f','\xc2'},{'\x8f','\xc3'},{'\x8f','\xc4'},
+ {'\x8f','\xc5'},{'\x8f','\xc6'},{'\x8f','\xc7'},{'\x8f','\xc8'},{'\x8f','\xc9'},
+ {'\x8f','\xca'},{'\x8f','\xcb'},{'\x8f','\xcc'},{'\x8f','\xcd'},{'\x8f','\xce'},
+ {'\x8f','\xcf'},{'\x8f','\xd0'},{'\x8f','\xd1'},{'\x8f','\xd2'},{'\x8f','\xd3'},
+ {'\x8f','\xd4'},{'\x8f','\xd5'},{'\x8f','\xd6'},{'\x8f','\xd7'},{'\x8f','\xd8'},
+ {'\x8f','\xd9'},{'\x8f','\xda'},{'\x8f','\xdb'},{'\x8f','\xdc'},{'\x8f','\xdd'},
+ {'\x8f','\xde'},{'\x8f','\xdf'},{'\x8f','\xe0'},{'\x8f','\xe1'},{'\x8f','\xe2'},
+ {'\x8f','\xe3'},{'\x8f','\xe4'},{'\x8f','\xe5'},{'\x8f','\xe6'},{'\x8f','\xe7'},
+ {'\x8f','\xe8'},{'\x8f','\xe9'},{'\x8f','\xea'},{'\x8f','\xeb'},{'\x8f','\xec'},
+ {'\x8f','\xed'},{'\x8f','\xee'},{'\x8f','\xef'},{'\x8f','\xf0'},{'\x8f','\xf1'},
+ {'\x8f','\xf2'},{'\x8f','\xf3'},{'\x8f','\xf4'},{'\x8f','\xf5'},{'\x8f','\xf6'},
+ {'\x8f','\xf7'},{'\x8f','\xf8'},{'\x8f','\xf9'},{'\x8f','\xfa'},{'\x8f','\xfb'},
+ {'\x8f','\xfc'},{'\x8f','\xfd'},{'\x8f','\xfe'},{'\x90','\x40'},{'\x90','\x41'},
+ {'\x90','\x42'},{'\x90','\x43'},{'\x90','\x44'},{'\x90','\x45'},{'\x90','\x46'},
+ {'\x90','\x47'},{'\x90','\x48'},{'\x90','\x49'},{'\x90','\x4a'},{'\x90','\x4b'},
+ {'\x90','\x4c'},{'\x90','\x4d'},{'\x90','\x4e'},{'\x90','\x4f'},{'\x90','\x50'},
+ {'\x90','\x51'},{'\x90','\x52'},{'\x90','\x53'},{'\x90','\x54'},{'\x90','\x55'},
+ {'\x90','\x56'},{'\x90','\x57'},{'\x90','\x58'},{'\x90','\x59'},{'\x90','\x5a'},
+ {'\x90','\x5b'},{'\x90','\x5c'},{'\x90','\x5d'},{'\x90','\x5e'},{'\x90','\x5f'},
+ {'\x90','\x60'},{'\x90','\x61'},{'\x90','\x62'},{'\x90','\x63'},{'\x90','\x64'},
+ {'\x90','\x65'},{'\x90','\x66'},{'\x90','\x67'},{'\x90','\x68'},{'\x90','\x69'},
+ {'\x90','\x6a'},{'\x90','\x6b'},{'\x90','\x6c'},{'\x90','\x6d'},{'\x90','\x6e'},
+ {'\x90','\x6f'},{'\x90','\x70'},{'\x90','\x71'},{'\x90','\x72'},{'\x90','\x73'},
+ {'\x90','\x74'},{'\x90','\x75'},{'\x90','\x76'},{'\x90','\x77'},{'\x90','\x78'},
+ {'\x90','\x79'},{'\x90','\x7a'},{'\x90','\x7b'},{'\x90','\x7c'},{'\x90','\x7d'},
+ {'\x90','\x7e'},{'\x90','\xa1'},{'\x90','\xa2'},{'\x90','\xa3'},{'\x90','\xa4'},
+ {'\x90','\xa5'},{'\x90','\xa6'},{'\x90','\xa7'},{'\x90','\xa8'},{'\x90','\xa9'},
+ {'\x90','\xaa'},{'\x90','\xab'},{'\x90','\xac'},{'\x90','\xad'},{'\x90','\xae'},
+ {'\x90','\xaf'},{'\x90','\xb0'},{'\x90','\xb1'},{'\x90','\xb2'},{'\x90','\xb3'},
+ {'\x90','\xb4'},{'\x90','\xb5'},{'\x90','\xb6'},{'\x90','\xb7'},{'\x90','\xb8'},
+ {'\x90','\xb9'},{'\x90','\xba'},{'\x90','\xbb'},{'\x90','\xbc'},{'\x90','\xbd'},
+ {'\x90','\xbe'},{'\x90','\xbf'},{'\x90','\xc0'},{'\x90','\xc1'},{'\x90','\xc2'},
+ {'\x90','\xc3'},{'\x90','\xc4'},{'\x90','\xc5'},{'\x90','\xc6'},{'\x90','\xc7'},
+ {'\x90','\xc8'},{'\x90','\xc9'},{'\x90','\xca'},{'\x90','\xcb'},{'\x90','\xcc'},
+ {'\x90','\xcd'},{'\x90','\xce'},{'\x90','\xcf'},{'\x90','\xd0'},{'\x90','\xd1'},
+ {'\x90','\xd2'},{'\x90','\xd3'},{'\x90','\xd4'},{'\x90','\xd5'},{'\x90','\xd6'},
+ {'\x90','\xd7'},{'\x90','\xd8'},{'\x90','\xd9'},{'\x90','\xda'},{'\x90','\xdb'},
+ {'\x90','\xdc'},{'\x90','\xdd'},{'\x90','\xde'},{'\x90','\xdf'},{'\x90','\xe0'},
+ {'\x90','\xe1'},{'\x90','\xe2'},{'\x90','\xe3'},{'\x90','\xe4'},{'\x90','\xe5'},
+ {'\x90','\xe6'},{'\x90','\xe7'},{'\x90','\xe8'},{'\x90','\xe9'},{'\x90','\xea'},
+ {'\x90','\xeb'},{'\x90','\xec'},{'\x90','\xed'},{'\x90','\xee'},{'\x90','\xef'},
+ {'\x90','\xf0'},{'\x90','\xf1'},{'\x90','\xf2'},{'\x90','\xf3'},{'\x90','\xf4'},
+ {'\x90','\xf5'},{'\x90','\xf6'},{'\x90','\xf7'},{'\x90','\xf8'},{'\x90','\xf9'},
+ {'\x90','\xfa'},{'\x90','\xfb'},{'\x90','\xfc'},{'\x90','\xfd'},{'\x90','\xfe'},
+ {'\x91','\x40'},{'\x91','\x41'},{'\x91','\x42'},{'\x91','\x43'},{'\x91','\x44'},
+ {'\x91','\x45'},{'\x91','\x46'},{'\x91','\x47'},{'\x91','\x48'},{'\x91','\x49'},
+ {'\x91','\x4a'},{'\x91','\x4b'},{'\x91','\x4c'},{'\x91','\x4d'},{'\x91','\x4e'},
+ {'\x91','\x4f'},{'\x91','\x50'},{'\x91','\x51'},{'\x91','\x52'},{'\x91','\x53'},
+ {'\x91','\x54'},{'\x91','\x55'},{'\x91','\x56'},{'\x91','\x57'},{'\x91','\x58'},
+ {'\x91','\x59'},{'\x91','\x5a'},{'\x91','\x5b'},{'\x91','\x5c'},{'\x91','\x5d'},
+ {'\x91','\x5e'},{'\x91','\x5f'},{'\x91','\x60'},{'\x91','\x61'},{'\x91','\x62'},
+ {'\x91','\x63'},{'\x91','\x64'},{'\x91','\x65'},{'\x91','\x66'},{'\x91','\x67'},
+ {'\x91','\x68'},{'\x91','\x69'},{'\x91','\x6a'},{'\x91','\x6b'},{'\x91','\x6c'},
+ {'\x91','\x6d'},{'\x91','\x6e'},{'\x91','\x6f'},{'\x91','\x70'},{'\x91','\x71'},
+ {'\x91','\x72'},{'\x91','\x73'},{'\x91','\x74'},{'\x91','\x75'},{'\x91','\x76'},
+ {'\x91','\x77'},{'\x91','\x78'},{'\x91','\x79'},{'\x91','\x7a'},{'\x91','\x7b'},
+ {'\x91','\x7c'},{'\x91','\x7d'},{'\x91','\x7e'},{'\x91','\xa1'},{'\x91','\xa2'},
+ {'\x91','\xa3'},{'\x91','\xa4'},{'\x91','\xa5'},{'\x91','\xa6'},{'\x91','\xa7'},
+ {'\x91','\xa8'},{'\x91','\xa9'},{'\x91','\xaa'},{'\x91','\xab'},{'\x91','\xac'},
+ {'\x91','\xad'},{'\x91','\xae'},{'\x91','\xaf'},{'\x91','\xb0'},{'\x91','\xb1'},
+ {'\x91','\xb2'},{'\x91','\xb3'},{'\x91','\xb4'},{'\x91','\xb5'},{'\x91','\xb6'},
+ {'\x91','\xb7'},{'\x91','\xb8'},{'\x91','\xb9'},{'\x91','\xba'},{'\x91','\xbb'},
+ {'\x91','\xbc'},{'\x91','\xbd'},{'\x91','\xbe'},{'\x91','\xbf'},{'\x91','\xc0'},
+ {'\x91','\xc1'},{'\x91','\xc2'},{'\x91','\xc3'},{'\x91','\xc4'},{'\x91','\xc5'},
+ {'\x91','\xc6'},{'\x91','\xc7'},{'\x91','\xc8'},{'\x91','\xc9'},{'\x91','\xca'},
+ {'\x91','\xcb'},{'\x91','\xcc'},{'\x91','\xcd'},{'\x91','\xce'},{'\x91','\xcf'},
+ {'\x91','\xd0'},{'\x91','\xd1'},{'\x91','\xd2'},{'\x91','\xd3'},{'\x91','\xd4'},
+ {'\x91','\xd5'},{'\x91','\xd6'},{'\x91','\xd7'},{'\x91','\xd8'},{'\x91','\xd9'},
+ {'\x91','\xda'},{'\x91','\xdb'},{'\x91','\xdc'},{'\x91','\xdd'},{'\x91','\xde'},
+ {'\x91','\xdf'},{'\x91','\xe0'},{'\x91','\xe1'},{'\x91','\xe2'},{'\x91','\xe3'},
+ {'\x91','\xe4'},{'\x91','\xe5'},{'\x91','\xe6'},{'\x91','\xe7'},{'\x91','\xe8'},
+ {'\x91','\xe9'},{'\x91','\xea'},{'\x91','\xeb'},{'\x91','\xec'},{'\x91','\xed'},
+ {'\x91','\xee'},{'\x91','\xef'},{'\x91','\xf0'},{'\x91','\xf1'},{'\x91','\xf2'},
+ {'\x91','\xf3'},{'\x91','\xf4'},{'\x91','\xf5'},{'\x91','\xf6'},{'\x91','\xf7'},
+ {'\x91','\xf8'},{'\x91','\xf9'},{'\x91','\xfa'},{'\x91','\xfb'},{'\x91','\xfc'},
+ {'\x91','\xfd'},{'\x91','\xfe'},{'\x92','\x40'},{'\x92','\x41'},{'\x92','\x42'},
+ {'\x92','\x43'},{'\x92','\x44'},{'\x92','\x45'},{'\x92','\x46'},{'\x92','\x47'},
+ {'\x92','\x48'},{'\x92','\x49'},{'\x92','\x4a'},{'\x92','\x4b'},{'\x92','\x4c'},
+ {'\x92','\x4d'},{'\x92','\x4e'},{'\x92','\x4f'},{'\x92','\x50'},{'\x92','\x51'},
+ {'\x92','\x52'},{'\x92','\x53'},{'\x92','\x54'},{'\x92','\x55'},{'\x92','\x56'},
+ {'\x92','\x57'},{'\x92','\x58'},{'\x92','\x59'},{'\x92','\x5a'},{'\x92','\x5b'},
+ {'\x92','\x5c'},{'\x92','\x5d'},{'\x92','\x5e'},{'\x92','\x5f'},{'\x92','\x60'},
+ {'\x92','\x61'},{'\x92','\x62'},{'\x92','\x63'},{'\x92','\x64'},{'\x92','\x65'},
+ {'\x92','\x66'},{'\x92','\x67'},{'\x92','\x68'},{'\x92','\x69'},{'\x92','\x6a'},
+ {'\x92','\x6b'},{'\x92','\x6c'},{'\x92','\x6d'},{'\x92','\x6e'},{'\x92','\x6f'},
+ {'\x92','\x70'},{'\x92','\x71'},{'\x92','\x72'},{'\x92','\x73'},{'\x92','\x74'},
+ {'\x92','\x75'},{'\x92','\x76'},{'\x92','\x77'},{'\x92','\x78'},{'\x92','\x79'},
+ {'\x92','\x7a'},{'\x92','\x7b'},{'\x92','\x7c'},{'\x92','\x7d'},{'\x92','\x7e'},
+ {'\x92','\xa1'},{'\x92','\xa2'},{'\x92','\xa3'},{'\x92','\xa4'},{'\x92','\xa5'},
+ {'\x92','\xa6'},{'\x92','\xa7'},{'\x92','\xa8'},{'\x92','\xa9'},{'\x92','\xaa'},
+ {'\x92','\xab'},{'\x92','\xac'},{'\x92','\xad'},{'\x92','\xae'},{'\x92','\xaf'},
+ {'\x92','\xb0'},{'\x92','\xb1'},{'\x92','\xb2'},{'\x92','\xb3'},{'\x92','\xb4'},
+ {'\x92','\xb5'},{'\x92','\xb6'},{'\x92','\xb7'},{'\x92','\xb8'},{'\x92','\xb9'},
+ {'\x92','\xba'},{'\x92','\xbb'},{'\x92','\xbc'},{'\x92','\xbd'},{'\x92','\xbe'},
+ {'\x92','\xbf'},{'\x92','\xc0'},{'\x92','\xc1'},{'\x92','\xc2'},{'\x92','\xc3'},
+ {'\x92','\xc4'},{'\x92','\xc5'},{'\x92','\xc6'},{'\x92','\xc7'},{'\x92','\xc8'},
+ {'\x92','\xc9'},{'\x92','\xca'},{'\x92','\xcb'},{'\x92','\xcc'},{'\x92','\xcd'},
+ {'\x92','\xce'},{'\x92','\xcf'},{'\x92','\xd0'},{'\x92','\xd1'},{'\x92','\xd2'},
+ {'\x92','\xd3'},{'\x92','\xd4'},{'\x92','\xd5'},{'\x92','\xd6'},{'\x92','\xd7'},
+ {'\x92','\xd8'},{'\x92','\xd9'},{'\x92','\xda'},{'\x92','\xdb'},{'\x92','\xdc'},
+ {'\x92','\xdd'},{'\x92','\xde'},{'\x92','\xdf'},{'\x92','\xe0'},{'\x92','\xe1'},
+ {'\x92','\xe2'},{'\x92','\xe3'},{'\x92','\xe4'},{'\x92','\xe5'},{'\x92','\xe6'},
+ {'\x92','\xe7'},{'\x92','\xe8'},{'\x92','\xe9'},{'\x92','\xea'},{'\x92','\xeb'},
+ {'\x92','\xec'},{'\x92','\xed'},{'\x92','\xee'},{'\x92','\xef'},{'\x92','\xf0'},
+ {'\x92','\xf1'},{'\x92','\xf2'},{'\x92','\xf3'},{'\x92','\xf4'},{'\x92','\xf5'},
+ {'\x92','\xf6'},{'\x92','\xf7'},{'\x92','\xf8'},{'\x92','\xf9'},{'\x92','\xfa'},
+ {'\x92','\xfb'},{'\x92','\xfc'},{'\x92','\xfd'},{'\x92','\xfe'},{'\x93','\x40'},
+ {'\x93','\x41'},{'\x93','\x42'},{'\x93','\x43'},{'\x93','\x44'},{'\x93','\x45'},
+ {'\x93','\x46'},{'\x93','\x47'},{'\x93','\x48'},{'\x93','\x49'},{'\x93','\x4a'},
+ {'\x93','\x4b'},{'\x93','\x4c'},{'\x93','\x4d'},{'\x93','\x4e'},{'\x93','\x4f'},
+ {'\x93','\x50'},{'\x93','\x51'},{'\x93','\x52'},{'\x93','\x53'},{'\x93','\x54'},
+ {'\x93','\x55'},{'\x93','\x56'},{'\x93','\x57'},{'\x93','\x58'},{'\x93','\x59'},
+ {'\x93','\x5a'},{'\x93','\x5b'},{'\x93','\x5c'},{'\x93','\x5d'},{'\x93','\x5e'},
+ {'\x93','\x5f'},{'\x93','\x60'},{'\x93','\x61'},{'\x93','\x62'},{'\x93','\x63'},
+ {'\x93','\x64'},{'\x93','\x65'},{'\x93','\x66'},{'\x93','\x67'},{'\x93','\x68'},
+ {'\x93','\x69'},{'\x93','\x6a'},{'\x93','\x6b'},{'\x93','\x6c'},{'\x93','\x6d'},
+ {'\x93','\x6e'},{'\x93','\x6f'},{'\x93','\x70'},{'\x93','\x71'},{'\x93','\x72'},
+ {'\x93','\x73'},{'\x93','\x74'},{'\x93','\x75'},{'\x93','\x76'},{'\x93','\x77'},
+ {'\x93','\x78'},{'\x93','\x79'},{'\x93','\x7a'},{'\x93','\x7b'},{'\x93','\x7c'},
+ {'\x93','\x7d'},{'\x93','\x7e'},{'\x93','\xa1'},{'\x93','\xa2'},{'\x93','\xa3'},
+ {'\x93','\xa4'},{'\x93','\xa5'},{'\x93','\xa6'},{'\x93','\xa7'},{'\x93','\xa8'},
+ {'\x93','\xa9'},{'\x93','\xaa'},{'\x93','\xab'},{'\x93','\xac'},{'\x93','\xad'},
+ {'\x93','\xae'},{'\x93','\xaf'},{'\x93','\xb0'},{'\x93','\xb1'},{'\x93','\xb2'},
+ {'\x93','\xb3'},{'\x93','\xb4'},{'\x93','\xb5'},{'\x93','\xb6'},{'\x93','\xb7'},
+ {'\x93','\xb8'},{'\x93','\xb9'},{'\x93','\xba'},{'\x93','\xbb'},{'\x93','\xbc'},
+ {'\x93','\xbd'},{'\x93','\xbe'},{'\x93','\xbf'},{'\x93','\xc0'},{'\x93','\xc1'},
+ {'\x93','\xc2'},{'\x93','\xc3'},{'\x93','\xc4'},{'\x93','\xc5'},{'\x93','\xc6'},
+ {'\x93','\xc7'},{'\x93','\xc8'},{'\x93','\xc9'},{'\x93','\xca'},{'\x93','\xcb'},
+ {'\x93','\xcc'},{'\x93','\xcd'},{'\x93','\xce'},{'\x93','\xcf'},{'\x93','\xd0'},
+ {'\x93','\xd1'},{'\x93','\xd2'},{'\x93','\xd3'},{'\x93','\xd4'},{'\x93','\xd5'},
+ {'\x93','\xd6'},{'\x93','\xd7'},{'\x93','\xd8'},{'\x93','\xd9'},{'\x93','\xda'},
+ {'\x93','\xdb'},{'\x93','\xdc'},{'\x93','\xdd'},{'\x93','\xde'},{'\x93','\xdf'},
+ {'\x93','\xe0'},{'\x93','\xe1'},{'\x93','\xe2'},{'\x93','\xe3'},{'\x93','\xe4'},
+ {'\x93','\xe5'},{'\x93','\xe6'},{'\x93','\xe7'},{'\x93','\xe8'},{'\x93','\xe9'},
+ {'\x93','\xea'},{'\x93','\xeb'},{'\x93','\xec'},{'\x93','\xed'},{'\x93','\xee'},
+ {'\x93','\xef'},{'\x93','\xf0'},{'\x93','\xf1'},{'\x93','\xf2'},{'\x93','\xf3'},
+ {'\x93','\xf4'},{'\x93','\xf5'},{'\x93','\xf6'},{'\x93','\xf7'},{'\x93','\xf8'},
+ {'\x93','\xf9'},{'\x93','\xfa'},{'\x93','\xfb'},{'\x93','\xfc'},{'\x93','\xfd'},
+ {'\x93','\xfe'},{'\x94','\x40'},{'\x94','\x41'},{'\x94','\x42'},{'\x94','\x43'},
+ {'\x94','\x44'},{'\x94','\x45'},{'\x94','\x46'},{'\x94','\x47'},{'\x94','\x48'},
+ {'\x94','\x49'},{'\x94','\x4a'},{'\x94','\x4b'},{'\x94','\x4c'},{'\x94','\x4d'},
+ {'\x94','\x4e'},{'\x94','\x4f'},{'\x94','\x50'},{'\x94','\x51'},{'\x94','\x52'},
+ {'\x94','\x53'},{'\x94','\x54'},{'\x94','\x55'},{'\x94','\x56'},{'\x94','\x57'},
+ {'\x94','\x58'},{'\x94','\x59'},{'\x94','\x5a'},{'\x94','\x5b'},{'\x94','\x5c'},
+ {'\x94','\x5d'},{'\x94','\x5e'},{'\x94','\x5f'},{'\x94','\x60'},{'\x94','\x61'},
+ {'\x94','\x62'},{'\x94','\x63'},{'\x94','\x64'},{'\x94','\x65'},{'\x94','\x66'},
+ {'\x94','\x67'},{'\x94','\x68'},{'\x94','\x69'},{'\x94','\x6a'},{'\x94','\x6b'},
+ {'\x94','\x6c'},{'\x94','\x6d'},{'\x94','\x6e'},{'\x94','\x6f'},{'\x94','\x70'},
+ {'\x94','\x71'},{'\x94','\x72'},{'\x94','\x73'},{'\x94','\x74'},{'\x94','\x75'},
+ {'\x94','\x76'},{'\x94','\x77'},{'\x94','\x78'},{'\x94','\x79'},{'\x94','\x7a'},
+ {'\x94','\x7b'},{'\x94','\x7c'},{'\x94','\x7d'},{'\x94','\x7e'},{'\x94','\xa1'},
+ {'\x94','\xa2'},{'\x94','\xa3'},{'\x94','\xa4'},{'\x94','\xa5'},{'\x94','\xa6'},
+ {'\x94','\xa7'},{'\x94','\xa8'},{'\x94','\xa9'},{'\x94','\xaa'},{'\x94','\xab'},
+ {'\x94','\xac'},{'\x94','\xad'},{'\x94','\xae'},{'\x94','\xaf'},{'\x94','\xb0'},
+ {'\x94','\xb1'},{'\x94','\xb2'},{'\x94','\xb3'},{'\x94','\xb4'},{'\x94','\xb5'},
+ {'\x94','\xb6'},{'\x94','\xb7'},{'\x94','\xb8'},{'\x94','\xb9'},{'\x94','\xba'},
+ {'\x94','\xbb'},{'\x94','\xbc'},{'\x94','\xbd'},{'\x94','\xbe'},{'\x94','\xbf'},
+ {'\x94','\xc0'},{'\x94','\xc1'},{'\x94','\xc2'},{'\x94','\xc3'},{'\x94','\xc4'},
+ {'\x94','\xc5'},{'\x94','\xc6'},{'\x94','\xc7'},{'\x94','\xc8'},{'\x94','\xc9'},
+ {'\x94','\xca'},{'\x94','\xcb'},{'\x94','\xcc'},{'\x94','\xcd'},{'\x94','\xce'},
+ {'\x94','\xcf'},{'\x94','\xd0'},{'\x94','\xd1'},{'\x94','\xd2'},{'\x94','\xd3'},
+ {'\x94','\xd4'},{'\x94','\xd5'},{'\x94','\xd6'},{'\x94','\xd7'},{'\x94','\xd8'},
+ {'\x94','\xd9'},{'\x94','\xda'},{'\x94','\xdb'},{'\x94','\xdc'},{'\x94','\xdd'},
+ {'\x94','\xde'},{'\x94','\xdf'},{'\x94','\xe0'},{'\x94','\xe1'},{'\x94','\xe2'},
+ {'\x94','\xe3'},{'\x94','\xe4'},{'\x94','\xe5'},{'\x94','\xe6'},{'\x94','\xe7'},
+ {'\x94','\xe8'},{'\x94','\xe9'},{'\x94','\xea'},{'\x94','\xeb'},{'\x94','\xec'},
+ {'\x94','\xed'},{'\x94','\xee'},{'\x94','\xef'},{'\x94','\xf0'},{'\x94','\xf1'},
+ {'\x94','\xf2'},{'\x94','\xf3'},{'\x94','\xf4'},{'\x94','\xf5'},{'\x94','\xf6'},
+ {'\x94','\xf7'},{'\x94','\xf8'},{'\x94','\xf9'},{'\x94','\xfa'},{'\x94','\xfb'},
+ {'\x94','\xfc'},{'\x94','\xfd'},{'\x94','\xfe'},{'\x95','\x40'},{'\x95','\x41'},
+ {'\x95','\x42'},{'\x95','\x43'},{'\x95','\x44'},{'\x95','\x45'},{'\x95','\x46'},
+ {'\x95','\x47'},{'\x95','\x48'},{'\x95','\x49'},{'\x95','\x4a'},{'\x95','\x4b'},
+ {'\x95','\x4c'},{'\x95','\x4d'},{'\x95','\x4e'},{'\x95','\x4f'},{'\x95','\x50'},
+ {'\x95','\x51'},{'\x95','\x52'},{'\x95','\x53'},{'\x95','\x54'},{'\x95','\x55'},
+ {'\x95','\x56'},{'\x95','\x57'},{'\x95','\x58'},{'\x95','\x59'},{'\x95','\x5a'},
+ {'\x95','\x5b'},{'\x95','\x5c'},{'\x95','\x5d'},{'\x95','\x5e'},{'\x95','\x5f'},
+ {'\x95','\x60'},{'\x95','\x61'},{'\x95','\x62'},{'\x95','\x63'},{'\x95','\x64'},
+ {'\x95','\x65'},{'\x95','\x66'},{'\x95','\x67'},{'\x95','\x68'},{'\x95','\x69'},
+ {'\x95','\x6a'},{'\x95','\x6b'},{'\x95','\x6c'},{'\x95','\x6d'},{'\x95','\x6e'},
+ {'\x95','\x6f'},{'\x95','\x70'},{'\x95','\x71'},{'\x95','\x72'},{'\x95','\x73'},
+ {'\x95','\x74'},{'\x95','\x75'},{'\x95','\x76'},{'\x95','\x77'},{'\x95','\x78'},
+ {'\x95','\x79'},{'\x95','\x7a'},{'\x95','\x7b'},{'\x95','\x7c'},{'\x95','\x7d'},
+ {'\x95','\x7e'},{'\x95','\xa1'},{'\x95','\xa2'},{'\x95','\xa3'},{'\x95','\xa4'},
+ {'\x95','\xa5'},{'\x95','\xa6'},{'\x95','\xa7'},{'\x95','\xa8'},{'\x95','\xa9'},
+ {'\x95','\xaa'},{'\x95','\xab'},{'\x95','\xac'},{'\x95','\xad'},{'\x95','\xae'},
+ {'\x95','\xaf'},{'\x95','\xb0'},{'\x95','\xb1'},{'\x95','\xb2'},{'\x95','\xb3'},
+ {'\x95','\xb4'},{'\x95','\xb5'},{'\x95','\xb6'},{'\x95','\xb7'},{'\x95','\xb8'},
+ {'\x95','\xb9'},{'\x95','\xba'},{'\x95','\xbb'},{'\x95','\xbc'},{'\x95','\xbd'},
+ {'\x95','\xbe'},{'\x95','\xbf'},{'\x95','\xc0'},{'\x95','\xc1'},{'\x95','\xc2'},
+ {'\x95','\xc3'},{'\x95','\xc4'},{'\x95','\xc5'},{'\x95','\xc6'},{'\x95','\xc7'},
+ {'\x95','\xc8'},{'\x95','\xc9'},{'\x95','\xca'},{'\x95','\xcb'},{'\x95','\xcc'},
+ {'\x95','\xcd'},{'\x95','\xce'},{'\x95','\xcf'},{'\x95','\xd0'},{'\x95','\xd1'},
+ {'\x95','\xd2'},{'\x95','\xd3'},{'\x95','\xd4'},{'\x95','\xd5'},{'\x95','\xd6'},
+ {'\x95','\xd7'},{'\x95','\xd8'},{'\x95','\xd9'},{'\x95','\xda'},{'\x95','\xdb'},
+ {'\x95','\xdc'},{'\x95','\xdd'},{'\x95','\xde'},{'\x95','\xdf'},{'\x95','\xe0'},
+ {'\x95','\xe1'},{'\x95','\xe2'},{'\x95','\xe3'},{'\x95','\xe4'},{'\x95','\xe5'},
+ {'\x95','\xe6'},{'\x95','\xe7'},{'\x95','\xe8'},{'\x95','\xe9'},{'\x95','\xea'},
+ {'\x95','\xeb'},{'\x95','\xec'},{'\x95','\xed'},{'\x95','\xee'},{'\x95','\xef'},
+ {'\x95','\xf0'},{'\x95','\xf1'},{'\x95','\xf2'},{'\x95','\xf3'},{'\x95','\xf4'},
+ {'\x95','\xf5'},{'\x95','\xf6'},{'\x95','\xf7'},{'\x95','\xf8'},{'\x95','\xf9'},
+ {'\x95','\xfa'},{'\x95','\xfb'},{'\x95','\xfc'},{'\x95','\xfd'},{'\x95','\xfe'},
+ {'\x96','\x40'},{'\x96','\x41'},{'\x96','\x42'},{'\x96','\x43'},{'\x96','\x44'},
+ {'\x96','\x45'},{'\x96','\x46'},{'\x96','\x47'},{'\x96','\x48'},{'\x96','\x49'},
+ {'\x96','\x4a'},{'\x96','\x4b'},{'\x96','\x4c'},{'\x96','\x4d'},{'\x96','\x4e'},
+ {'\x96','\x4f'},{'\x96','\x50'},{'\x96','\x51'},{'\x96','\x52'},{'\x96','\x53'},
+ {'\x96','\x54'},{'\x96','\x55'},{'\x96','\x56'},{'\x96','\x57'},{'\x96','\x58'},
+ {'\x96','\x59'},{'\x96','\x5a'},{'\x96','\x5b'},{'\x96','\x5c'},{'\x96','\x5d'},
+ {'\x96','\x5e'},{'\x96','\x5f'},{'\x96','\x60'},{'\x96','\x61'},{'\x96','\x62'},
+ {'\x96','\x63'},{'\x96','\x64'},{'\x96','\x65'},{'\x96','\x66'},{'\x96','\x67'},
+ {'\x96','\x68'},{'\x96','\x69'},{'\x96','\x6a'},{'\x96','\x6b'},{'\x96','\x6c'},
+ {'\x96','\x6d'},{'\x96','\x6e'},{'\x96','\x6f'},{'\x96','\x70'},{'\x96','\x71'},
+ {'\x96','\x72'},{'\x96','\x73'},{'\x96','\x74'},{'\x96','\x75'},{'\x96','\x76'},
+ {'\x96','\x77'},{'\x96','\x78'},{'\x96','\x79'},{'\x96','\x7a'},{'\x96','\x7b'},
+ {'\x96','\x7c'},{'\x96','\x7d'},{'\x96','\x7e'},{'\x96','\xa1'},{'\x96','\xa2'},
+ {'\x96','\xa3'},{'\x96','\xa4'},{'\x96','\xa5'},{'\x96','\xa6'},{'\x96','\xa7'},
+ {'\x96','\xa8'},{'\x96','\xa9'},{'\x96','\xaa'},{'\x96','\xab'},{'\x96','\xac'},
+ {'\x96','\xad'},{'\x96','\xae'},{'\x96','\xaf'},{'\x96','\xb0'},{'\x96','\xb1'},
+ {'\x96','\xb2'},{'\x96','\xb3'},{'\x96','\xb4'},{'\x96','\xb5'},{'\x96','\xb6'},
+ {'\x96','\xb7'},{'\x96','\xb8'},{'\x96','\xb9'},{'\x96','\xba'},{'\x96','\xbb'},
+ {'\x96','\xbc'},{'\x96','\xbd'},{'\x96','\xbe'},{'\x96','\xbf'},{'\x96','\xc0'},
+ {'\x96','\xc1'},{'\x96','\xc2'},{'\x96','\xc3'},{'\x96','\xc4'},{'\x96','\xc5'},
+ {'\x96','\xc6'},{'\x96','\xc7'},{'\x96','\xc8'},{'\x96','\xc9'},{'\x96','\xca'},
+ {'\x96','\xcb'},{'\x96','\xcc'},{'\x96','\xcd'},{'\x96','\xce'},{'\x96','\xcf'},
+ {'\x96','\xd0'},{'\x96','\xd1'},{'\x96','\xd2'},{'\x96','\xd3'},{'\x96','\xd4'},
+ {'\x96','\xd5'},{'\x96','\xd6'},{'\x96','\xd7'},{'\x96','\xd8'},{'\x96','\xd9'},
+ {'\x96','\xda'},{'\x96','\xdb'},{'\x96','\xdc'},{'\x96','\xdd'},{'\x96','\xde'},
+ {'\x96','\xdf'},{'\x96','\xe0'},{'\x96','\xe1'},{'\x96','\xe2'},{'\x96','\xe3'},
+ {'\x96','\xe4'},{'\x96','\xe5'},{'\x96','\xe6'},{'\x96','\xe7'},{'\x96','\xe8'},
+ {'\x96','\xe9'},{'\x96','\xea'},{'\x96','\xeb'},{'\x96','\xec'},{'\x96','\xed'},
+ {'\x96','\xee'},{'\x96','\xef'},{'\x96','\xf0'},{'\x96','\xf1'},{'\x96','\xf2'},
+ {'\x96','\xf3'},{'\x96','\xf4'},{'\x96','\xf5'},{'\x96','\xf6'},{'\x96','\xf7'},
+ {'\x96','\xf8'},{'\x96','\xf9'},{'\x96','\xfa'},{'\x96','\xfb'},{'\x96','\xfc'},
+ {'\x96','\xfd'},{'\x96','\xfe'},{'\x97','\x40'},{'\x97','\x41'},{'\x97','\x42'},
+ {'\x97','\x43'},{'\x97','\x44'},{'\x97','\x45'},{'\x97','\x46'},{'\x97','\x47'},
+ {'\x97','\x48'},{'\x97','\x49'},{'\x97','\x4a'},{'\x97','\x4b'},{'\x97','\x4c'},
+ {'\x97','\x4d'},{'\x97','\x4e'},{'\x97','\x4f'},{'\x97','\x50'},{'\x97','\x51'},
+ {'\x97','\x52'},{'\x97','\x53'},{'\x97','\x54'},{'\x97','\x55'},{'\x97','\x56'},
+ {'\x97','\x57'},{'\x97','\x58'},{'\x97','\x59'},{'\x97','\x5a'},{'\x97','\x5b'},
+ {'\x97','\x5c'},{'\x97','\x5d'},{'\x97','\x5e'},{'\x97','\x5f'},{'\x97','\x60'},
+ {'\x97','\x61'},{'\x97','\x62'},{'\x97','\x63'},{'\x97','\x64'},{'\x97','\x65'},
+ {'\x97','\x66'},{'\x97','\x67'},{'\x97','\x68'},{'\x97','\x69'},{'\x97','\x6a'},
+ {'\x97','\x6b'},{'\x97','\x6c'},{'\x97','\x6d'},{'\x97','\x6e'},{'\x97','\x6f'},
+ {'\x97','\x70'},{'\x97','\x71'},{'\x97','\x72'},{'\x97','\x73'},{'\x97','\x74'},
+ {'\x97','\x75'},{'\x97','\x76'},{'\x97','\x77'},{'\x97','\x78'},{'\x97','\x79'},
+ {'\x97','\x7a'},{'\x97','\x7b'},{'\x97','\x7c'},{'\x97','\x7d'},{'\x97','\x7e'},
+ {'\x97','\xa1'},{'\x97','\xa2'},{'\x97','\xa3'},{'\x97','\xa4'},{'\x97','\xa5'},
+ {'\x97','\xa6'},{'\x97','\xa7'},{'\x97','\xa8'},{'\x97','\xa9'},{'\x97','\xaa'},
+ {'\x97','\xab'},{'\x97','\xac'},{'\x97','\xad'},{'\x97','\xae'},{'\x97','\xaf'},
+ {'\x97','\xb0'},{'\x97','\xb1'},{'\x97','\xb2'},{'\x97','\xb3'},{'\x97','\xb4'},
+ {'\x97','\xb5'},{'\x97','\xb6'},{'\x97','\xb7'},{'\x97','\xb8'},{'\x97','\xb9'},
+ {'\x97','\xba'},{'\x97','\xbb'},{'\x97','\xbc'},{'\x97','\xbd'},{'\x97','\xbe'},
+ {'\x97','\xbf'},{'\x97','\xc0'},{'\x97','\xc1'},{'\x97','\xc2'},{'\x97','\xc3'},
+ {'\x97','\xc4'},{'\x97','\xc5'},{'\x97','\xc6'},{'\x97','\xc7'},{'\x97','\xc8'},
+ {'\x97','\xc9'},{'\x97','\xca'},{'\x97','\xcb'},{'\x97','\xcc'},{'\x97','\xcd'},
+ {'\x97','\xce'},{'\x97','\xcf'},{'\x97','\xd0'},{'\x97','\xd1'},{'\x97','\xd2'},
+ {'\x97','\xd3'},{'\x97','\xd4'},{'\x97','\xd5'},{'\x97','\xd6'},{'\x97','\xd7'},
+ {'\x97','\xd8'},{'\x97','\xd9'},{'\x97','\xda'},{'\x97','\xdb'},{'\x97','\xdc'},
+ {'\x97','\xdd'},{'\x97','\xde'},{'\x97','\xdf'},{'\x97','\xe0'},{'\x97','\xe1'},
+ {'\x97','\xe2'},{'\x97','\xe3'},{'\x97','\xe4'},{'\x97','\xe5'},{'\x97','\xe6'},
+ {'\x97','\xe7'},{'\x97','\xe8'},{'\x97','\xe9'},{'\x97','\xea'},{'\x97','\xeb'},
+ {'\x97','\xec'},{'\x97','\xed'},{'\x97','\xee'},{'\x97','\xef'},{'\x97','\xf0'},
+ {'\x97','\xf1'},{'\x97','\xf2'},{'\x97','\xf3'},{'\x97','\xf4'},{'\x97','\xf5'},
+ {'\x97','\xf6'},{'\x97','\xf7'},{'\x97','\xf8'},{'\x97','\xf9'},{'\x97','\xfa'},
+ {'\x97','\xfb'},{'\x97','\xfc'},{'\x97','\xfd'},{'\x97','\xfe'},{'\x98','\x40'},
+ {'\x98','\x41'},{'\x98','\x42'},{'\x98','\x43'},{'\x98','\x44'},{'\x98','\x45'},
+ {'\x98','\x46'},{'\x98','\x47'},{'\x98','\x48'},{'\x98','\x49'},{'\x98','\x4a'},
+ {'\x98','\x4b'},{'\x98','\x4c'},{'\x98','\x4d'},{'\x98','\x4e'},{'\x98','\x4f'},
+ {'\x98','\x50'},{'\x98','\x51'},{'\x98','\x52'},{'\x98','\x53'},{'\x98','\x54'},
+ {'\x98','\x55'},{'\x98','\x56'},{'\x98','\x57'},{'\x98','\x58'},{'\x98','\x59'},
+ {'\x98','\x5a'},{'\x98','\x5b'},{'\x98','\x5c'},{'\x98','\x5d'},{'\x98','\x5e'},
+ {'\x98','\x5f'},{'\x98','\x60'},{'\x98','\x61'},{'\x98','\x62'},{'\x98','\x63'},
+ {'\x98','\x64'},{'\x98','\x65'},{'\x98','\x66'},{'\x98','\x67'},{'\x98','\x68'},
+ {'\x98','\x69'},{'\x98','\x6a'},{'\x98','\x6b'},{'\x98','\x6c'},{'\x98','\x6d'},
+ {'\x98','\x6e'},{'\x98','\x6f'},{'\x98','\x70'},{'\x98','\x71'},{'\x98','\x72'},
+ {'\x98','\x73'},{'\x98','\x74'},{'\x98','\x75'},{'\x98','\x76'},{'\x98','\x77'},
+ {'\x98','\x78'},{'\x98','\x79'},{'\x98','\x7a'},{'\x98','\x7b'},{'\x98','\x7c'},
+ {'\x98','\x7d'},{'\x98','\x7e'},{'\x98','\xa1'},{'\x98','\xa2'},{'\x98','\xa3'},
+ {'\x98','\xa4'},{'\x98','\xa5'},{'\x98','\xa6'},{'\x98','\xa7'},{'\x98','\xa8'},
+ {'\x98','\xa9'},{'\x98','\xaa'},{'\x98','\xab'},{'\x98','\xac'},{'\x98','\xad'},
+ {'\x98','\xae'},{'\x98','\xaf'},{'\x98','\xb0'},{'\x98','\xb1'},{'\x98','\xb2'},
+ {'\x98','\xb3'},{'\x98','\xb4'},{'\x98','\xb5'},{'\x98','\xb6'},{'\x98','\xb7'},
+ {'\x98','\xb8'},{'\x98','\xb9'},{'\x98','\xba'},{'\x98','\xbb'},{'\x98','\xbc'},
+ {'\x98','\xbd'},{'\x98','\xbe'},{'\x98','\xbf'},{'\x98','\xc0'},{'\x98','\xc1'},
+ {'\x98','\xc2'},{'\x98','\xc3'},{'\x98','\xc4'},{'\x98','\xc5'},{'\x98','\xc6'},
+ {'\x98','\xc7'},{'\x98','\xc8'},{'\x98','\xc9'},{'\x98','\xca'},{'\x98','\xcb'},
+ {'\x98','\xcc'},{'\x98','\xcd'},{'\x98','\xce'},{'\x98','\xcf'},{'\x98','\xd0'},
+ {'\x98','\xd1'},{'\x98','\xd2'},{'\x98','\xd3'},{'\x98','\xd4'},{'\x98','\xd5'},
+ {'\x98','\xd6'},{'\x98','\xd7'},{'\x98','\xd8'},{'\x98','\xd9'},{'\x98','\xda'},
+ {'\x98','\xdb'},{'\x98','\xdc'},{'\x98','\xdd'},{'\x98','\xde'},{'\x98','\xdf'},
+ {'\x98','\xe0'},{'\x98','\xe1'},{'\x98','\xe2'},{'\x98','\xe3'},{'\x98','\xe4'},
+ {'\x98','\xe5'},{'\x98','\xe6'},{'\x98','\xe7'},{'\x98','\xe8'},{'\x98','\xe9'},
+ {'\x98','\xea'},{'\x98','\xeb'},{'\x98','\xec'},{'\x98','\xed'},{'\x98','\xee'},
+ {'\x98','\xef'},{'\x98','\xf0'},{'\x98','\xf1'},{'\x98','\xf2'},{'\x98','\xf3'},
+ {'\x98','\xf4'},{'\x98','\xf5'},{'\x98','\xf6'},{'\x98','\xf7'},{'\x98','\xf8'},
+ {'\x98','\xf9'},{'\x98','\xfa'},{'\x98','\xfb'},{'\x98','\xfc'},{'\x98','\xfd'},
+ {'\x98','\xfe'},{'\x99','\x40'},{'\x99','\x41'},{'\x99','\x42'},{'\x99','\x43'},
+ {'\x99','\x44'},{'\x99','\x45'},{'\x99','\x46'},{'\x99','\x47'},{'\x99','\x48'},
+ {'\x99','\x49'},{'\x99','\x4a'},{'\x99','\x4b'},{'\x99','\x4c'},{'\x99','\x4d'},
+ {'\x99','\x4e'},{'\x99','\x4f'},{'\x99','\x50'},{'\x99','\x51'},{'\x99','\x52'},
+ {'\x99','\x53'},{'\x99','\x54'},{'\x99','\x55'},{'\x99','\x56'},{'\x99','\x57'},
+ {'\x99','\x58'},{'\x99','\x59'},{'\x99','\x5a'},{'\x99','\x5b'},{'\x99','\x5c'},
+ {'\x99','\x5d'},{'\x99','\x5e'},{'\x99','\x5f'},{'\x99','\x60'},{'\x99','\x61'},
+ {'\x99','\x62'},{'\x99','\x63'},{'\x99','\x64'},{'\x99','\x65'},{'\x99','\x66'},
+ {'\x99','\x67'},{'\x99','\x68'},{'\x99','\x69'},{'\x99','\x6a'},{'\x99','\x6b'},
+ {'\x99','\x6c'},{'\x99','\x6d'},{'\x99','\x6e'},{'\x99','\x6f'},{'\x99','\x70'},
+ {'\x99','\x71'},{'\x99','\x72'},{'\x99','\x73'},{'\x99','\x74'},{'\x99','\x75'},
+ {'\x99','\x76'},{'\x99','\x77'},{'\x99','\x78'},{'\x99','\x79'},{'\x99','\x7a'},
+ {'\x99','\x7b'},{'\x99','\x7c'},{'\x99','\x7d'},{'\x99','\x7e'},{'\x99','\xa1'},
+ {'\x99','\xa2'},{'\x99','\xa3'},{'\x99','\xa4'},{'\x99','\xa5'},{'\x99','\xa6'},
+ {'\x99','\xa7'},{'\x99','\xa8'},{'\x99','\xa9'},{'\x99','\xaa'},{'\x99','\xab'},
+ {'\x99','\xac'},{'\x99','\xad'},{'\x99','\xae'},{'\x99','\xaf'},{'\x99','\xb0'},
+ {'\x99','\xb1'},{'\x99','\xb2'},{'\x99','\xb3'},{'\x99','\xb4'},{'\x99','\xb5'},
+ {'\x99','\xb6'},{'\x99','\xb7'},{'\x99','\xb8'},{'\x99','\xb9'},{'\x99','\xba'},
+ {'\x99','\xbb'},{'\x99','\xbc'},{'\x99','\xbd'},{'\x99','\xbe'},{'\x99','\xbf'},
+ {'\x99','\xc0'},{'\x99','\xc1'},{'\x99','\xc2'},{'\x99','\xc3'},{'\x99','\xc4'},
+ {'\x99','\xc5'},{'\x99','\xc6'},{'\x99','\xc7'},{'\x99','\xc8'},{'\x99','\xc9'},
+ {'\x99','\xca'},{'\x99','\xcb'},{'\x99','\xcc'},{'\x99','\xcd'},{'\x99','\xce'},
+ {'\x99','\xcf'},{'\x99','\xd0'},{'\x99','\xd1'},{'\x99','\xd2'},{'\x99','\xd3'},
+ {'\x99','\xd4'},{'\x99','\xd5'},{'\x99','\xd6'},{'\x99','\xd7'},{'\x99','\xd8'},
+ {'\x99','\xd9'},{'\x99','\xda'},{'\x99','\xdb'},{'\x99','\xdc'},{'\x99','\xdd'},
+ {'\x99','\xde'},{'\x99','\xdf'},{'\x99','\xe0'},{'\x99','\xe1'},{'\x99','\xe2'},
+ {'\x99','\xe3'},{'\x99','\xe4'},{'\x99','\xe5'},{'\x99','\xe6'},{'\x99','\xe7'},
+ {'\x99','\xe8'},{'\x99','\xe9'},{'\x99','\xea'},{'\x99','\xeb'},{'\x99','\xec'},
+ {'\x99','\xed'},{'\x99','\xee'},{'\x99','\xef'},{'\x99','\xf0'},{'\x99','\xf1'},
+ {'\x99','\xf2'},{'\x99','\xf3'},{'\x99','\xf4'},{'\x99','\xf5'},{'\x99','\xf6'},
+ {'\x99','\xf7'},{'\x99','\xf8'},{'\x99','\xf9'},{'\x99','\xfa'},{'\x99','\xfb'},
+ {'\x99','\xfc'},{'\x99','\xfd'},{'\x99','\xfe'},{'\x9a','\x40'},{'\x9a','\x41'},
+ {'\x9a','\x42'},{'\x9a','\x43'},{'\x9a','\x44'},{'\x9a','\x45'},{'\x9a','\x46'},
+ {'\x9a','\x47'},{'\x9a','\x48'},{'\x9a','\x49'},{'\x9a','\x4a'},{'\x9a','\x4b'},
+ {'\x9a','\x4c'},{'\x9a','\x4d'},{'\x9a','\x4e'},{'\x9a','\x4f'},{'\x9a','\x50'},
+ {'\x9a','\x51'},{'\x9a','\x52'},{'\x9a','\x53'},{'\x9a','\x54'},{'\x9a','\x55'},
+ {'\x9a','\x56'},{'\x9a','\x57'},{'\x9a','\x58'},{'\x9a','\x59'},{'\x9a','\x5a'},
+ {'\x9a','\x5b'},{'\x9a','\x5c'},{'\x9a','\x5d'},{'\x9a','\x5e'},{'\x9a','\x5f'},
+ {'\x9a','\x60'},{'\x9a','\x61'},{'\x9a','\x62'},{'\x9a','\x63'},{'\x9a','\x64'},
+ {'\x9a','\x65'},{'\x9a','\x66'},{'\x9a','\x67'},{'\x9a','\x68'},{'\x9a','\x69'},
+ {'\x9a','\x6a'},{'\x9a','\x6b'},{'\x9a','\x6c'},{'\x9a','\x6d'},{'\x9a','\x6e'},
+ {'\x9a','\x6f'},{'\x9a','\x70'},{'\x9a','\x71'},{'\x9a','\x72'},{'\x9a','\x73'},
+ {'\x9a','\x74'},{'\x9a','\x75'},{'\x9a','\x76'},{'\x9a','\x77'},{'\x9a','\x78'},
+ {'\x9a','\x79'},{'\x9a','\x7a'},{'\x9a','\x7b'},{'\x9a','\x7c'},{'\x9a','\x7d'},
+ {'\x9a','\x7e'},{'\x9a','\xa1'},{'\x9a','\xa2'},{'\x9a','\xa3'},{'\x9a','\xa4'},
+ {'\x9a','\xa5'},{'\x9a','\xa6'},{'\x9a','\xa7'},{'\x9a','\xa8'},{'\x9a','\xa9'},
+ {'\x9a','\xaa'},{'\x9a','\xab'},{'\x9a','\xac'},{'\x9a','\xad'},{'\x9a','\xae'},
+ {'\x9a','\xaf'},{'\x9a','\xb0'},{'\x9a','\xb1'},{'\x9a','\xb2'},{'\x9a','\xb3'},
+ {'\x9a','\xb4'},{'\x9a','\xb5'},{'\x9a','\xb6'},{'\x9a','\xb7'},{'\x9a','\xb8'},
+ {'\x9a','\xb9'},{'\x9a','\xba'},{'\x9a','\xbb'},{'\x9a','\xbc'},{'\x9a','\xbd'},
+ {'\x9a','\xbe'},{'\x9a','\xbf'},{'\x9a','\xc0'},{'\x9a','\xc1'},{'\x9a','\xc2'},
+ {'\x9a','\xc3'},{'\x9a','\xc4'},{'\x9a','\xc5'},{'\x9a','\xc6'},{'\x9a','\xc7'},
+ {'\x9a','\xc8'},{'\x9a','\xc9'},{'\x9a','\xca'},{'\x9a','\xcb'},{'\x9a','\xcc'},
+ {'\x9a','\xcd'},{'\x9a','\xce'},{'\x9a','\xcf'},{'\x9a','\xd0'},{'\x9a','\xd1'},
+ {'\x9a','\xd2'},{'\x9a','\xd3'},{'\x9a','\xd4'},{'\x9a','\xd5'},{'\x9a','\xd6'},
+ {'\x9a','\xd7'},{'\x9a','\xd8'},{'\x9a','\xd9'},{'\x9a','\xda'},{'\x9a','\xdb'},
+ {'\x9a','\xdc'},{'\x9a','\xdd'},{'\x9a','\xde'},{'\x9a','\xdf'},{'\x9a','\xe0'},
+ {'\x9a','\xe1'},{'\x9a','\xe2'},{'\x9a','\xe3'},{'\x9a','\xe4'},{'\x9a','\xe5'},
+ {'\x9a','\xe6'},{'\x9a','\xe7'},{'\x9a','\xe8'},{'\x9a','\xe9'},{'\x9a','\xea'},
+ {'\x9a','\xeb'},{'\x9a','\xec'},{'\x9a','\xed'},{'\x9a','\xee'},{'\x9a','\xef'},
+ {'\x9a','\xf0'},{'\x9a','\xf1'},{'\x9a','\xf2'},{'\x9a','\xf3'},{'\x9a','\xf4'},
+ {'\x9a','\xf5'},{'\x9a','\xf6'},{'\x9a','\xf7'},{'\x9a','\xf8'},{'\x9a','\xf9'},
+ {'\x9a','\xfa'},{'\x9a','\xfb'},{'\x9a','\xfc'},{'\x9a','\xfd'},{'\x9a','\xfe'},
+ {'\x9b','\x40'},{'\x9b','\x41'},{'\x9b','\x42'},{'\x9b','\x43'},{'\x9b','\x44'},
+ {'\x9b','\x45'},{'\x9b','\x46'},{'\x9b','\x47'},{'\x9b','\x48'},{'\x9b','\x49'},
+ {'\x9b','\x4a'},{'\x9b','\x4b'},{'\x9b','\x4c'},{'\x9b','\x4d'},{'\x9b','\x4e'},
+ {'\x9b','\x4f'},{'\x9b','\x50'},{'\x9b','\x51'},{'\x9b','\x52'},{'\x9b','\x53'},
+ {'\x9b','\x54'},{'\x9b','\x55'},{'\x9b','\x56'},{'\x9b','\x57'},{'\x9b','\x58'},
+ {'\x9b','\x59'},{'\x9b','\x5a'},{'\x9b','\x5b'},{'\x9b','\x5c'},{'\x9b','\x5d'},
+ {'\x9b','\x5e'},{'\x9b','\x5f'},{'\x9b','\x60'},{'\x9b','\x61'},{'\x9b','\x62'},
+ {'\x9b','\x63'},{'\x9b','\x64'},{'\x9b','\x65'},{'\x9b','\x66'},{'\x9b','\x67'},
+ {'\x9b','\x68'},{'\x9b','\x69'},{'\x9b','\x6a'},{'\x9b','\x6b'},{'\x9b','\x6c'},
+ {'\x9b','\x6d'},{'\x9b','\x6e'},{'\x9b','\x6f'},{'\x9b','\x70'},{'\x9b','\x71'},
+ {'\x9b','\x72'},{'\x9b','\x73'},{'\x9b','\x74'},{'\x9b','\x75'},{'\x9b','\x76'},
+ {'\x9b','\x77'},{'\x9b','\x78'},{'\x9b','\x79'},{'\x9b','\x7a'},{'\x9b','\x7b'},
+ {'\x9b','\x7c'},{'\x9b','\x7d'},{'\x9b','\x7e'},{'\x9b','\xa1'},{'\x9b','\xa2'},
+ {'\x9b','\xa3'},{'\x9b','\xa4'},{'\x9b','\xa5'},{'\x9b','\xa6'},{'\x9b','\xa7'},
+ {'\x9b','\xa8'},{'\x9b','\xa9'},{'\x9b','\xaa'},{'\x9b','\xab'},{'\x9b','\xac'},
+ {'\x9b','\xad'},{'\x9b','\xae'},{'\x9b','\xaf'},{'\x9b','\xb0'},{'\x9b','\xb1'},
+ {'\x9b','\xb2'},{'\x9b','\xb3'},{'\x9b','\xb4'},{'\x9b','\xb5'},{'\x9b','\xb6'},
+ {'\x9b','\xb7'},{'\x9b','\xb8'},{'\x9b','\xb9'},{'\x9b','\xba'},{'\x9b','\xbb'},
+ {'\x9b','\xbc'},{'\x9b','\xbd'},{'\x9b','\xbe'},{'\x9b','\xbf'},{'\x9b','\xc0'},
+ {'\x9b','\xc1'},{'\x9b','\xc2'},{'\x9b','\xc3'},{'\x9b','\xc4'},{'\x9b','\xc5'},
+ {'\x9b','\xc6'},{'\x9b','\xc7'},{'\x9b','\xc8'},{'\x9b','\xc9'},{'\x9b','\xca'},
+ {'\x9b','\xcb'},{'\x9b','\xcc'},{'\x9b','\xcd'},{'\x9b','\xce'},{'\x9b','\xcf'},
+ {'\x9b','\xd0'},{'\x9b','\xd1'},{'\x9b','\xd2'},{'\x9b','\xd3'},{'\x9b','\xd4'},
+ {'\x9b','\xd5'},{'\x9b','\xd6'},{'\x9b','\xd7'},{'\x9b','\xd8'},{'\x9b','\xd9'},
+ {'\x9b','\xda'},{'\x9b','\xdb'},{'\x9b','\xdc'},{'\x9b','\xdd'},{'\x9b','\xde'},
+ {'\x9b','\xdf'},{'\x9b','\xe0'},{'\x9b','\xe1'},{'\x9b','\xe2'},{'\x9b','\xe3'},
+ {'\x9b','\xe4'},{'\x9b','\xe5'},{'\x9b','\xe6'},{'\x9b','\xe7'},{'\x9b','\xe8'},
+ {'\x9b','\xe9'},{'\x9b','\xea'},{'\x9b','\xeb'},{'\x9b','\xec'},{'\x9b','\xed'},
+ {'\x9b','\xee'},{'\x9b','\xef'},{'\x9b','\xf0'},{'\x9b','\xf1'},{'\x9b','\xf2'},
+ {'\x9b','\xf3'},{'\x9b','\xf4'},{'\x9b','\xf5'},{'\x9b','\xf6'},{'\x9b','\xf7'},
+ {'\x9b','\xf8'},{'\x9b','\xf9'},{'\x9b','\xfa'},{'\x9b','\xfb'},{'\x9b','\xfc'},
+ {'\x9b','\xfd'},{'\x9b','\xfe'},{'\x9c','\x40'},{'\x9c','\x41'},{'\x9c','\x42'},
+ {'\x9c','\x43'},{'\x9c','\x44'},{'\x9c','\x45'},{'\x9c','\x46'},{'\x9c','\x47'},
+ {'\x9c','\x48'},{'\x9c','\x49'},{'\x9c','\x4a'},{'\x9c','\x4b'},{'\x9c','\x4c'},
+ {'\x9c','\x4d'},{'\x9c','\x4e'},{'\x9c','\x4f'},{'\x9c','\x50'},{'\x9c','\x51'},
+ {'\x9c','\x52'},{'\x9c','\x53'},{'\x9c','\x54'},{'\x9c','\x55'},{'\x9c','\x56'},
+ {'\x9c','\x57'},{'\x9c','\x58'},{'\x9c','\x59'},{'\x9c','\x5a'},{'\x9c','\x5b'},
+ {'\x9c','\x5c'},{'\x9c','\x5d'},{'\x9c','\x5e'},{'\x9c','\x5f'},{'\x9c','\x60'},
+ {'\x9c','\x61'},{'\x9c','\x62'},{'\x9c','\x63'},{'\x9c','\x64'},{'\x9c','\x65'},
+ {'\x9c','\x66'},{'\x9c','\x67'},{'\x9c','\x68'},{'\x9c','\x69'},{'\x9c','\x6a'},
+ {'\x9c','\x6b'},{'\x9c','\x6c'},{'\x9c','\x6d'},{'\x9c','\x6e'},{'\x9c','\x6f'},
+ {'\x9c','\x70'},{'\x9c','\x71'},{'\x9c','\x72'},{'\x9c','\x73'},{'\x9c','\x74'},
+ {'\x9c','\x75'},{'\x9c','\x76'},{'\x9c','\x77'},{'\x9c','\x78'},{'\x9c','\x79'},
+ {'\x9c','\x7a'},{'\x9c','\x7b'},{'\x9c','\x7c'},{'\x9c','\x7d'},{'\x9c','\x7e'},
+ {'\x9c','\xa1'},{'\x9c','\xa2'},{'\x9c','\xa3'},{'\x9c','\xa4'},{'\x9c','\xa5'},
+ {'\x9c','\xa6'},{'\x9c','\xa7'},{'\x9c','\xa8'},{'\x9c','\xa9'},{'\x9c','\xaa'},
+ {'\x9c','\xab'},{'\x9c','\xac'},{'\x9c','\xad'},{'\x9c','\xae'},{'\x9c','\xaf'},
+ {'\x9c','\xb0'},{'\x9c','\xb1'},{'\x9c','\xb2'},{'\x9c','\xb3'},{'\x9c','\xb4'},
+ {'\x9c','\xb5'},{'\x9c','\xb6'},{'\x9c','\xb7'},{'\x9c','\xb8'},{'\x9c','\xb9'},
+ {'\x9c','\xba'},{'\x9c','\xbb'},{'\x9c','\xbc'},{'\x9c','\xbd'},{'\x9c','\xbe'},
+ {'\x9c','\xbf'},{'\x9c','\xc0'},{'\x9c','\xc1'},{'\x9c','\xc2'},{'\x9c','\xc3'},
+ {'\x9c','\xc4'},{'\x9c','\xc5'},{'\x9c','\xc6'},{'\x9c','\xc7'},{'\x9c','\xc8'},
+ {'\x9c','\xc9'},{'\x9c','\xca'},{'\x9c','\xcb'},{'\x9c','\xcc'},{'\x9c','\xcd'},
+ {'\x9c','\xce'},{'\x9c','\xcf'},{'\x9c','\xd0'},{'\x9c','\xd1'},{'\x9c','\xd2'},
+ {'\x9c','\xd3'},{'\x9c','\xd4'},{'\x9c','\xd5'},{'\x9c','\xd6'},{'\x9c','\xd7'},
+ {'\x9c','\xd8'},{'\x9c','\xd9'},{'\x9c','\xda'},{'\x9c','\xdb'},{'\x9c','\xdc'},
+ {'\x9c','\xdd'},{'\x9c','\xde'},{'\x9c','\xdf'},{'\x9c','\xe0'},{'\x9c','\xe1'},
+ {'\x9c','\xe2'},{'\x9c','\xe3'},{'\x9c','\xe4'},{'\x9c','\xe5'},{'\x9c','\xe6'},
+ {'\x9c','\xe7'},{'\x9c','\xe8'},{'\x9c','\xe9'},{'\x9c','\xea'},{'\x9c','\xeb'},
+ {'\x9c','\xec'},{'\x9c','\xed'},{'\x9c','\xee'},{'\x9c','\xef'},{'\x9c','\xf0'},
+ {'\x9c','\xf1'},{'\x9c','\xf2'},{'\x9c','\xf3'},{'\x9c','\xf4'},{'\x9c','\xf5'},
+ {'\x9c','\xf6'},{'\x9c','\xf7'},{'\x9c','\xf8'},{'\x9c','\xf9'},{'\x9c','\xfa'},
+ {'\x9c','\xfb'},{'\x9c','\xfc'},{'\x9c','\xfd'},{'\x9c','\xfe'},{'\x9d','\x40'},
+ {'\x9d','\x41'},{'\x9d','\x42'},{'\x9d','\x43'},{'\x9d','\x44'},{'\x9d','\x45'},
+ {'\x9d','\x46'},{'\x9d','\x47'},{'\x9d','\x48'},{'\x9d','\x49'},{'\x9d','\x4a'},
+ {'\x9d','\x4b'},{'\x9d','\x4c'},{'\x9d','\x4d'},{'\x9d','\x4e'},{'\x9d','\x4f'},
+ {'\x9d','\x50'},{'\x9d','\x51'},{'\x9d','\x52'},{'\x9d','\x53'},{'\x9d','\x54'},
+ {'\x9d','\x55'},{'\x9d','\x56'},{'\x9d','\x57'},{'\x9d','\x58'},{'\x9d','\x59'},
+ {'\x9d','\x5a'},{'\x9d','\x5b'},{'\x9d','\x5c'},{'\x9d','\x5d'},{'\x9d','\x5e'},
+ {'\x9d','\x5f'},{'\x9d','\x60'},{'\x9d','\x61'},{'\x9d','\x62'},{'\x9d','\x63'},
+ {'\x9d','\x64'},{'\x9d','\x65'},{'\x9d','\x66'},{'\x9d','\x67'},{'\x9d','\x68'},
+ {'\x9d','\x69'},{'\x9d','\x6a'},{'\x9d','\x6b'},{'\x9d','\x6c'},{'\x9d','\x6d'},
+ {'\x9d','\x6e'},{'\x9d','\x6f'},{'\x9d','\x70'},{'\x9d','\x71'},{'\x9d','\x72'},
+ {'\x9d','\x73'},{'\x9d','\x74'},{'\x9d','\x75'},{'\x9d','\x76'},{'\x9d','\x77'},
+ {'\x9d','\x78'},{'\x9d','\x79'},{'\x9d','\x7a'},{'\x9d','\x7b'},{'\x9d','\x7c'},
+ {'\x9d','\x7d'},{'\x9d','\x7e'},{'\x9d','\xa1'},{'\x9d','\xa2'},{'\x9d','\xa3'},
+ {'\x9d','\xa4'},{'\x9d','\xa5'},{'\x9d','\xa6'},{'\x9d','\xa7'},{'\x9d','\xa8'},
+ {'\x9d','\xa9'},{'\x9d','\xaa'},{'\x9d','\xab'},{'\x9d','\xac'},{'\x9d','\xad'},
+ {'\x9d','\xae'},{'\x9d','\xaf'},{'\x9d','\xb0'},{'\x9d','\xb1'},{'\x9d','\xb2'},
+ {'\x9d','\xb3'},{'\x9d','\xb4'},{'\x9d','\xb5'},{'\x9d','\xb6'},{'\x9d','\xb7'},
+ {'\x9d','\xb8'},{'\x9d','\xb9'},{'\x9d','\xba'},{'\x9d','\xbb'},{'\x9d','\xbc'},
+ {'\x9d','\xbd'},{'\x9d','\xbe'},{'\x9d','\xbf'},{'\x9d','\xc0'},{'\x9d','\xc1'},
+ {'\x9d','\xc2'},{'\x9d','\xc3'},{'\x9d','\xc4'},{'\x9d','\xc5'},{'\x9d','\xc6'},
+ {'\x9d','\xc7'},{'\x9d','\xc8'},{'\x9d','\xc9'},{'\x9d','\xca'},{'\x9d','\xcb'},
+ {'\x9d','\xcc'},{'\x9d','\xcd'},{'\x9d','\xce'},{'\x9d','\xcf'},{'\x9d','\xd0'},
+ {'\x9d','\xd1'},{'\x9d','\xd2'},{'\x9d','\xd3'},{'\x9d','\xd4'},{'\x9d','\xd5'},
+ {'\x9d','\xd6'},{'\x9d','\xd7'},{'\x9d','\xd8'},{'\x9d','\xd9'},{'\x9d','\xda'},
+ {'\x9d','\xdb'},{'\x9d','\xdc'},{'\x9d','\xdd'},{'\x9d','\xde'},{'\x9d','\xdf'},
+ {'\x9d','\xe0'},{'\x9d','\xe1'},{'\x9d','\xe2'},{'\x9d','\xe3'},{'\x9d','\xe4'},
+ {'\x9d','\xe5'},{'\x9d','\xe6'},{'\x9d','\xe7'},{'\x9d','\xe8'},{'\x9d','\xe9'},
+ {'\x9d','\xea'},{'\x9d','\xeb'},{'\x9d','\xec'},{'\x9d','\xed'},{'\x9d','\xee'},
+ {'\x9d','\xef'},{'\x9d','\xf0'},{'\x9d','\xf1'},{'\x9d','\xf2'},{'\x9d','\xf3'},
+ {'\x9d','\xf4'},{'\x9d','\xf5'},{'\x9d','\xf6'},{'\x9d','\xf7'},{'\x9d','\xf8'},
+ {'\x9d','\xf9'},{'\x9d','\xfa'},{'\x9d','\xfb'},{'\x9d','\xfc'},{'\x9d','\xfd'},
+ {'\x9d','\xfe'},{'\x9e','\x40'},{'\x9e','\x41'},{'\x9e','\x42'},{'\x9e','\x43'},
+ {'\x9e','\x44'},{'\x9e','\x45'},{'\x9e','\x46'},{'\x9e','\x47'},{'\x9e','\x48'},
+ {'\x9e','\x49'},{'\x9e','\x4a'},{'\x9e','\x4b'},{'\x9e','\x4c'},{'\x9e','\x4d'},
+ {'\x9e','\x4e'},{'\x9e','\x4f'},{'\x9e','\x50'},{'\x9e','\x51'},{'\x9e','\x52'},
+ {'\x9e','\x53'},{'\x9e','\x54'},{'\x9e','\x55'},{'\x9e','\x56'},{'\x9e','\x57'},
+ {'\x9e','\x58'},{'\x9e','\x59'},{'\x9e','\x5a'},{'\x9e','\x5b'},{'\x9e','\x5c'},
+ {'\x9e','\x5d'},{'\x9e','\x5e'},{'\x9e','\x5f'},{'\x9e','\x60'},{'\x9e','\x61'},
+ {'\x9e','\x62'},{'\x9e','\x63'},{'\x9e','\x64'},{'\x9e','\x65'},{'\x9e','\x66'},
+ {'\x9e','\x67'},{'\x9e','\x68'},{'\x9e','\x69'},{'\x9e','\x6a'},{'\x9e','\x6b'},
+ {'\x9e','\x6c'},{'\x9e','\x6d'},{'\x9e','\x6e'},{'\x9e','\x6f'},{'\x9e','\x70'},
+ {'\x9e','\x71'},{'\x9e','\x72'},{'\x9e','\x73'},{'\x9e','\x74'},{'\x9e','\x75'},
+ {'\x9e','\x76'},{'\x9e','\x77'},{'\x9e','\x78'},{'\x9e','\x79'},{'\x9e','\x7a'},
+ {'\x9e','\x7b'},{'\x9e','\x7c'},{'\x9e','\x7d'},{'\x9e','\x7e'},{'\x9e','\xa1'},
+ {'\x9e','\xa2'},{'\x9e','\xa3'},{'\x9e','\xa4'},{'\x9e','\xa5'},{'\x9e','\xa6'},
+ {'\x9e','\xa7'},{'\x9e','\xa8'},{'\x9e','\xa9'},{'\x9e','\xaa'},{'\x9e','\xab'},
+ {'\x9e','\xac'},{'\x9e','\xad'},{'\x9e','\xae'},{'\x9e','\xaf'},{'\x9e','\xb0'},
+ {'\x9e','\xb1'},{'\x9e','\xb2'},{'\x9e','\xb3'},{'\x9e','\xb4'},{'\x9e','\xb5'},
+ {'\x9e','\xb6'},{'\x9e','\xb7'},{'\x9e','\xb8'},{'\x9e','\xb9'},{'\x9e','\xba'},
+ {'\x9e','\xbb'},{'\x9e','\xbc'},{'\x9e','\xbd'},{'\x9e','\xbe'},{'\x9e','\xbf'},
+ {'\x9e','\xc0'},{'\x9e','\xc1'},{'\x9e','\xc2'},{'\x9e','\xc3'},{'\x9e','\xc4'},
+ {'\x9e','\xc5'},{'\x9e','\xc6'},{'\x9e','\xc7'},{'\x9e','\xc8'},{'\x9e','\xc9'},
+ {'\x9e','\xca'},{'\x9e','\xcb'},{'\x9e','\xcc'},{'\x9e','\xcd'},{'\x9e','\xce'},
+ {'\x9e','\xcf'},{'\x9e','\xd0'},{'\x9e','\xd1'},{'\x9e','\xd2'},{'\x9e','\xd3'},
+ {'\x9e','\xd4'},{'\x9e','\xd5'},{'\x9e','\xd6'},{'\x9e','\xd7'},{'\x9e','\xd8'},
+ {'\x9e','\xd9'},{'\x9e','\xda'},{'\x9e','\xdb'},{'\x9e','\xdc'},{'\x9e','\xdd'},
+ {'\x9e','\xde'},{'\x9e','\xdf'},{'\x9e','\xe0'},{'\x9e','\xe1'},{'\x9e','\xe2'},
+ {'\x9e','\xe3'},{'\x9e','\xe4'},{'\x9e','\xe5'},{'\x9e','\xe6'},{'\x9e','\xe7'},
+ {'\x9e','\xe8'},{'\x9e','\xe9'},{'\x9e','\xea'},{'\x9e','\xeb'},{'\x9e','\xec'},
+ {'\x9e','\xed'},{'\x9e','\xee'},{'\x9e','\xef'},{'\x9e','\xf0'},{'\x9e','\xf1'},
+ {'\x9e','\xf2'},{'\x9e','\xf3'},{'\x9e','\xf4'},{'\x9e','\xf5'},{'\x9e','\xf6'},
+ {'\x9e','\xf7'},{'\x9e','\xf8'},{'\x9e','\xf9'},{'\x9e','\xfa'},{'\x9e','\xfb'},
+ {'\x9e','\xfc'},{'\x9e','\xfd'},{'\x9e','\xfe'},{'\x9f','\x40'},{'\x9f','\x41'},
+ {'\x9f','\x42'},{'\x9f','\x43'},{'\x9f','\x44'},{'\x9f','\x45'},{'\x9f','\x46'},
+ {'\x9f','\x47'},{'\x9f','\x48'},{'\x9f','\x49'},{'\x9f','\x4a'},{'\x9f','\x4b'},
+ {'\x9f','\x4c'},{'\x9f','\x4d'},{'\x9f','\x4e'},{'\x9f','\x4f'},{'\x9f','\x50'},
+ {'\x9f','\x51'},{'\x9f','\x52'},{'\x9f','\x53'},{'\x9f','\x54'},{'\x9f','\x55'},
+ {'\x9f','\x56'},{'\x9f','\x57'},{'\x9f','\x58'},{'\x9f','\x59'},{'\x9f','\x5a'},
+ {'\x9f','\x5b'},{'\x9f','\x5c'},{'\x9f','\x5d'},{'\x9f','\x5e'},{'\x9f','\x5f'},
+ {'\x9f','\x60'},{'\x9f','\x61'},{'\x9f','\x62'},{'\x9f','\x63'},{'\x9f','\x64'},
+ {'\x9f','\x65'},{'\x9f','\x66'},{'\x9f','\x67'},{'\x9f','\x68'},{'\x9f','\x69'},
+ {'\x9f','\x6a'},{'\x9f','\x6b'},{'\x9f','\x6c'},{'\x9f','\x6d'},{'\x9f','\x6e'},
+ {'\x9f','\x6f'},{'\x9f','\x70'},{'\x9f','\x71'},{'\x9f','\x72'},{'\x9f','\x73'},
+ {'\x9f','\x74'},{'\x9f','\x75'},{'\x9f','\x76'},{'\x9f','\x77'},{'\x9f','\x78'},
+ {'\x9f','\x79'},{'\x9f','\x7a'},{'\x9f','\x7b'},{'\x9f','\x7c'},{'\x9f','\x7d'},
+ {'\x9f','\x7e'},{'\x9f','\xa1'},{'\x9f','\xa2'},{'\x9f','\xa3'},{'\x9f','\xa4'},
+ {'\x9f','\xa5'},{'\x9f','\xa6'},{'\x9f','\xa7'},{'\x9f','\xa8'},{'\x9f','\xa9'},
+ {'\x9f','\xaa'},{'\x9f','\xab'},{'\x9f','\xac'},{'\x9f','\xad'},{'\x9f','\xae'},
+ {'\x9f','\xaf'},{'\x9f','\xb0'},{'\x9f','\xb1'},{'\x9f','\xb2'},{'\x9f','\xb3'},
+ {'\x9f','\xb4'},{'\x9f','\xb5'},{'\x9f','\xb6'},{'\x9f','\xb7'},{'\x9f','\xb8'},
+ {'\x9f','\xb9'},{'\x9f','\xba'},{'\x9f','\xbb'},{'\x9f','\xbc'},{'\x9f','\xbd'},
+ {'\x9f','\xbe'},{'\x9f','\xbf'},{'\x9f','\xc0'},{'\x9f','\xc1'},{'\x9f','\xc2'},
+ {'\x9f','\xc3'},{'\x9f','\xc4'},{'\x9f','\xc5'},{'\x9f','\xc6'},{'\x9f','\xc7'},
+ {'\x9f','\xc8'},{'\x9f','\xc9'},{'\x9f','\xca'},{'\x9f','\xcb'},{'\x9f','\xcc'},
+ {'\x9f','\xcd'},{'\x9f','\xce'},{'\x9f','\xcf'},{'\x9f','\xd0'},{'\x9f','\xd1'},
+ {'\x9f','\xd2'},{'\x9f','\xd3'},{'\x9f','\xd4'},{'\x9f','\xd5'},{'\x9f','\xd6'},
+ {'\x9f','\xd7'},{'\x9f','\xd8'},{'\x9f','\xd9'},{'\x9f','\xda'},{'\x9f','\xdb'},
+ {'\x9f','\xdc'},{'\x9f','\xdd'},{'\x9f','\xde'},{'\x9f','\xdf'},{'\x9f','\xe0'},
+ {'\x9f','\xe1'},{'\x9f','\xe2'},{'\x9f','\xe3'},{'\x9f','\xe4'},{'\x9f','\xe5'},
+ {'\x9f','\xe6'},{'\x9f','\xe7'},{'\x9f','\xe8'},{'\x9f','\xe9'},{'\x9f','\xea'},
+ {'\x9f','\xeb'},{'\x9f','\xec'},{'\x9f','\xed'},{'\x9f','\xee'},{'\x9f','\xef'},
+ {'\x9f','\xf0'},{'\x9f','\xf1'},{'\x9f','\xf2'},{'\x9f','\xf3'},{'\x9f','\xf4'},
+ {'\x9f','\xf5'},{'\x9f','\xf6'},{'\x9f','\xf7'},{'\x9f','\xf8'},{'\x9f','\xf9'},
+ {'\x9f','\xfa'},{'\x9f','\xfb'},{'\x9f','\xfc'},{'\x9f','\xfd'},{'\x9f','\xfe'},
+ {'\xa0','\x40'},{'\xa0','\x41'},{'\xa0','\x42'},{'\xa0','\x43'},{'\xa0','\x44'},
+ {'\xa0','\x45'},{'\xa0','\x46'},{'\xa0','\x47'},{'\xa0','\x48'},{'\xa0','\x49'},
+ {'\xa0','\x4a'},{'\xa0','\x4b'},{'\xa0','\x4c'},{'\xa0','\x4d'},{'\xa0','\x4e'},
+ {'\xa0','\x4f'},{'\xa0','\x50'},{'\xa0','\x51'},{'\xa0','\x52'},{'\xa0','\x53'},
+ {'\xa0','\x54'},{'\xa0','\x55'},{'\xa0','\x56'},{'\xa0','\x57'},{'\xa0','\x58'},
+ {'\xa0','\x59'},{'\xa0','\x5a'},{'\xa0','\x5b'},{'\xa0','\x5c'},{'\xa0','\x5d'},
+ {'\xa0','\x5e'},{'\xa0','\x5f'},{'\xa0','\x60'},{'\xa0','\x61'},{'\xa0','\x62'},
+ {'\xa0','\x63'},{'\xa0','\x64'},{'\xa0','\x65'},{'\xa0','\x66'},{'\xa0','\x67'},
+ {'\xa0','\x68'},{'\xa0','\x69'},{'\xa0','\x6a'},{'\xa0','\x6b'},{'\xa0','\x6c'},
+ {'\xa0','\x6d'},{'\xa0','\x6e'},{'\xa0','\x6f'},{'\xa0','\x70'},{'\xa0','\x71'},
+ {'\xa0','\x72'},{'\xa0','\x73'},{'\xa0','\x74'},{'\xa0','\x75'},{'\xa0','\x76'},
+ {'\xa0','\x77'},{'\xa0','\x78'},{'\xa0','\x79'},{'\xa0','\x7a'},{'\xa0','\x7b'},
+ {'\xa0','\x7c'},{'\xa0','\x7d'},{'\xa0','\x7e'},{'\xa0','\xa1'},{'\xa0','\xa2'},
+ {'\xa0','\xa3'},{'\xa0','\xa4'},{'\xa0','\xa5'},{'\xa0','\xa6'},{'\xa0','\xa7'},
+ {'\xa0','\xa8'},{'\xa0','\xa9'},{'\xa0','\xaa'},{'\xa0','\xab'},{'\xa0','\xac'},
+ {'\xa0','\xad'},{'\xa0','\xae'},{'\xa0','\xaf'},{'\xa0','\xb0'},{'\xa0','\xb1'},
+ {'\xa0','\xb2'},{'\xa0','\xb3'},{'\xa0','\xb4'},{'\xa0','\xb5'},{'\xa0','\xb6'},
+ {'\xa0','\xb7'},{'\xa0','\xb8'},{'\xa0','\xb9'},{'\xa0','\xba'},{'\xa0','\xbb'},
+ {'\xa0','\xbc'},{'\xa0','\xbd'},{'\xa0','\xbe'},{'\xa0','\xbf'},{'\xa0','\xc0'},
+ {'\xa0','\xc1'},{'\xa0','\xc2'},{'\xa0','\xc3'},{'\xa0','\xc4'},{'\xa0','\xc5'},
+ {'\xa0','\xc6'},{'\xa0','\xc7'},{'\xa0','\xc8'},{'\xa0','\xc9'},{'\xa0','\xca'},
+ {'\xa0','\xcb'},{'\xa0','\xcc'},{'\xa0','\xcd'},{'\xa0','\xce'},{'\xa0','\xcf'},
+ {'\xa0','\xd0'},{'\xa0','\xd1'},{'\xa0','\xd2'},{'\xa0','\xd3'},{'\xa0','\xd4'},
+ {'\xa0','\xd5'},{'\xa0','\xd6'},{'\xa0','\xd7'},{'\xa0','\xd8'},{'\xa0','\xd9'},
+ {'\xa0','\xda'},{'\xa0','\xdb'},{'\xa0','\xdc'},{'\xa0','\xdd'},{'\xa0','\xde'},
+ {'\xa0','\xdf'},{'\xa0','\xe0'},{'\xa0','\xe1'},{'\xa0','\xe2'},{'\xa0','\xe3'},
+ {'\xa0','\xe4'},{'\xa0','\xe5'},{'\xa0','\xe6'},{'\xa0','\xe7'},{'\xa0','\xe8'},
+ {'\xa0','\xe9'},{'\xa0','\xea'},{'\xa0','\xeb'},{'\xa0','\xec'},{'\xa0','\xed'},
+ {'\xa0','\xee'},{'\xa0','\xef'},{'\xa0','\xf0'},{'\xa0','\xf1'},{'\xa0','\xf2'},
+ {'\xa0','\xf3'},{'\xa0','\xf4'},{'\xa0','\xf5'},{'\xa0','\xf6'},{'\xa0','\xf7'},
+ {'\xa0','\xf8'},{'\xa0','\xf9'},{'\xa0','\xfa'},{'\xa0','\xfb'},{'\xa0','\xfc'},
+ {'\xa0','\xfd'},{'\xa0','\xfe'},{'\x81','\x40'},{'\x81','\x41'},{'\x81','\x42'},
+ {'\x81','\x43'},{'\x81','\x44'},{'\x81','\x45'},{'\x81','\x46'},{'\x81','\x47'},
+ {'\x81','\x48'},{'\x81','\x49'},{'\x81','\x4a'},{'\x81','\x4b'},{'\x81','\x4c'},
+ {'\x81','\x4d'},{'\x81','\x4e'},{'\x81','\x4f'},{'\x81','\x50'},{'\x81','\x51'},
+ {'\x81','\x52'},{'\x81','\x53'},{'\x81','\x54'},{'\x81','\x55'},{'\x81','\x56'},
+ {'\x81','\x57'},{'\x81','\x58'},{'\x81','\x59'},{'\x81','\x5a'},{'\x81','\x5b'},
+ {'\x81','\x5c'},{'\x81','\x5d'},{'\x81','\x5e'},{'\x81','\x5f'},{'\x81','\x60'},
+ {'\x81','\x61'},{'\x81','\x62'},{'\x81','\x63'},{'\x81','\x64'},{'\x81','\x65'},
+ {'\x81','\x66'},{'\x81','\x67'},{'\x81','\x68'},{'\x81','\x69'},{'\x81','\x6a'},
+ {'\x81','\x6b'},{'\x81','\x6c'},{'\x81','\x6d'},{'\x81','\x6e'},{'\x81','\x6f'},
+ {'\x81','\x70'},{'\x81','\x71'},{'\x81','\x72'},{'\x81','\x73'},{'\x81','\x74'},
+ {'\x81','\x75'},{'\x81','\x76'},{'\x81','\x77'},{'\x81','\x78'},{'\x81','\x79'},
+ {'\x81','\x7a'},{'\x81','\x7b'},{'\x81','\x7c'},{'\x81','\x7d'},{'\x81','\x7e'},
+ {'\x81','\xa1'},{'\x81','\xa2'},{'\x81','\xa3'},{'\x81','\xa4'},{'\x81','\xa5'},
+ {'\x81','\xa6'},{'\x81','\xa7'},{'\x81','\xa8'},{'\x81','\xa9'},{'\x81','\xaa'},
+ {'\x81','\xab'},{'\x81','\xac'},{'\x81','\xad'},{'\x81','\xae'},{'\x81','\xaf'},
+ {'\x81','\xb0'},{'\x81','\xb1'},{'\x81','\xb2'},{'\x81','\xb3'},{'\x81','\xb4'},
+ {'\x81','\xb5'},{'\x81','\xb6'},{'\x81','\xb7'},{'\x81','\xb8'},{'\x81','\xb9'},
+ {'\x81','\xba'},{'\x81','\xbb'},{'\x81','\xbc'},{'\x81','\xbd'},{'\x81','\xbe'},
+ {'\x81','\xbf'},{'\x81','\xc0'},{'\x81','\xc1'},{'\x81','\xc2'},{'\x81','\xc3'},
+ {'\x81','\xc4'},{'\x81','\xc5'},{'\x81','\xc6'},{'\x81','\xc7'},{'\x81','\xc8'},
+ {'\x81','\xc9'},{'\x81','\xca'},{'\x81','\xcb'},{'\x81','\xcc'},{'\x81','\xcd'},
+ {'\x81','\xce'},{'\x81','\xcf'},{'\x81','\xd0'},{'\x81','\xd1'},{'\x81','\xd2'},
+ {'\x81','\xd3'},{'\x81','\xd4'},{'\x81','\xd5'},{'\x81','\xd6'},{'\x81','\xd7'},
+ {'\x81','\xd8'},{'\x81','\xd9'},{'\x81','\xda'},{'\x81','\xdb'},{'\x81','\xdc'},
+ {'\x81','\xdd'},{'\x81','\xde'},{'\x81','\xdf'},{'\x81','\xe0'},{'\x81','\xe1'},
+ {'\x81','\xe2'},{'\x81','\xe3'},{'\x81','\xe4'},{'\x81','\xe5'},{'\x81','\xe6'},
+ {'\x81','\xe7'},{'\x81','\xe8'},{'\x81','\xe9'},{'\x81','\xea'},{'\x81','\xeb'},
+ {'\x81','\xec'},{'\x81','\xed'},{'\x81','\xee'},{'\x81','\xef'},{'\x81','\xf0'},
+ {'\x81','\xf1'},{'\x81','\xf2'},{'\x81','\xf3'},{'\x81','\xf4'},{'\x81','\xf5'},
+ {'\x81','\xf6'},{'\x81','\xf7'},{'\x81','\xf8'},{'\x81','\xf9'},{'\x81','\xfa'},
+ {'\x81','\xfb'},{'\x81','\xfc'},{'\x81','\xfd'},{'\x81','\xfe'},{'\x82','\x40'},
+ {'\x82','\x41'},{'\x82','\x42'},{'\x82','\x43'},{'\x82','\x44'},{'\x82','\x45'},
+ {'\x82','\x46'},{'\x82','\x47'},{'\x82','\x48'},{'\x82','\x49'},{'\x82','\x4a'},
+ {'\x82','\x4b'},{'\x82','\x4c'},{'\x82','\x4d'},{'\x82','\x4e'},{'\x82','\x4f'},
+ {'\x82','\x50'},{'\x82','\x51'},{'\x82','\x52'},{'\x82','\x53'},{'\x82','\x54'},
+ {'\x82','\x55'},{'\x82','\x56'},{'\x82','\x57'},{'\x82','\x58'},{'\x82','\x59'},
+ {'\x82','\x5a'},{'\x82','\x5b'},{'\x82','\x5c'},{'\x82','\x5d'},{'\x82','\x5e'},
+ {'\x82','\x5f'},{'\x82','\x60'},{'\x82','\x61'},{'\x82','\x62'},{'\x82','\x63'},
+ {'\x82','\x64'},{'\x82','\x65'},{'\x82','\x66'},{'\x82','\x67'},{'\x82','\x68'},
+ {'\x82','\x69'},{'\x82','\x6a'},{'\x82','\x6b'},{'\x82','\x6c'},{'\x82','\x6d'},
+ {'\x82','\x6e'},{'\x82','\x6f'},{'\x82','\x70'},{'\x82','\x71'},{'\x82','\x72'},
+ {'\x82','\x73'},{'\x82','\x74'},{'\x82','\x75'},{'\x82','\x76'},{'\x82','\x77'},
+ {'\x82','\x78'},{'\x82','\x79'},{'\x82','\x7a'},{'\x82','\x7b'},{'\x82','\x7c'},
+ {'\x82','\x7d'},{'\x82','\x7e'},{'\x82','\xa1'},{'\x82','\xa2'},{'\x82','\xa3'},
+ {'\x82','\xa4'},{'\x82','\xa5'},{'\x82','\xa6'},{'\x82','\xa7'},{'\x82','\xa8'},
+ {'\x82','\xa9'},{'\x82','\xaa'},{'\x82','\xab'},{'\x82','\xac'},{'\x82','\xad'},
+ {'\x82','\xae'},{'\x82','\xaf'},{'\x82','\xb0'},{'\x82','\xb1'},{'\x82','\xb2'},
+ {'\x82','\xb3'},{'\x82','\xb4'},{'\x82','\xb5'},{'\x82','\xb6'},{'\x82','\xb7'},
+ {'\x82','\xb8'},{'\x82','\xb9'},{'\x82','\xba'},{'\x82','\xbb'},{'\x82','\xbc'},
+ {'\x82','\xbd'},{'\x82','\xbe'},{'\x82','\xbf'},{'\x82','\xc0'},{'\x82','\xc1'},
+ {'\x82','\xc2'},{'\x82','\xc3'},{'\x82','\xc4'},{'\x82','\xc5'},{'\x82','\xc6'},
+ {'\x82','\xc7'},{'\x82','\xc8'},{'\x82','\xc9'},{'\x82','\xca'},{'\x82','\xcb'},
+ {'\x82','\xcc'},{'\x82','\xcd'},{'\x82','\xce'},{'\x82','\xcf'},{'\x82','\xd0'},
+ {'\x82','\xd1'},{'\x82','\xd2'},{'\x82','\xd3'},{'\x82','\xd4'},{'\x82','\xd5'},
+ {'\x82','\xd6'},{'\x82','\xd7'},{'\x82','\xd8'},{'\x82','\xd9'},{'\x82','\xda'},
+ {'\x82','\xdb'},{'\x82','\xdc'},{'\x82','\xdd'},{'\x82','\xde'},{'\x82','\xdf'},
+ {'\x82','\xe0'},{'\x82','\xe1'},{'\x82','\xe2'},{'\x82','\xe3'},{'\x82','\xe4'},
+ {'\x82','\xe5'},{'\x82','\xe6'},{'\x82','\xe7'},{'\x82','\xe8'},{'\x82','\xe9'},
+ {'\x82','\xea'},{'\x82','\xeb'},{'\x82','\xec'},{'\x82','\xed'},{'\x82','\xee'},
+ {'\x82','\xef'},{'\x82','\xf0'},{'\x82','\xf1'},{'\x82','\xf2'},{'\x82','\xf3'},
+ {'\x82','\xf4'},{'\x82','\xf5'},{'\x82','\xf6'},{'\x82','\xf7'},{'\x82','\xf8'},
+ {'\x82','\xf9'},{'\x82','\xfa'},{'\x82','\xfb'},{'\x82','\xfc'},{'\x82','\xfd'},
+ {'\x82','\xfe'},{'\x83','\x40'},{'\x83','\x41'},{'\x83','\x42'},{'\x83','\x43'},
+ {'\x83','\x44'},{'\x83','\x45'},{'\x83','\x46'},{'\x83','\x47'},{'\x83','\x48'},
+ {'\x83','\x49'},{'\x83','\x4a'},{'\x83','\x4b'},{'\x83','\x4c'},{'\x83','\x4d'},
+ {'\x83','\x4e'},{'\x83','\x4f'},{'\x83','\x50'},{'\x83','\x51'},{'\x83','\x52'},
+ {'\x83','\x53'},{'\x83','\x54'},{'\x83','\x55'},{'\x83','\x56'},{'\x83','\x57'},
+ {'\x83','\x58'},{'\x83','\x59'},{'\x83','\x5a'},{'\x83','\x5b'},{'\x83','\x5c'},
+ {'\x83','\x5d'},{'\x83','\x5e'},{'\x83','\x5f'},{'\x83','\x60'},{'\x83','\x61'},
+ {'\x83','\x62'},{'\x83','\x63'},{'\x83','\x64'},{'\x83','\x65'},{'\x83','\x66'},
+ {'\x83','\x67'},{'\x83','\x68'},{'\x83','\x69'},{'\x83','\x6a'},{'\x83','\x6b'},
+ {'\x83','\x6c'},{'\x83','\x6d'},{'\x83','\x6e'},{'\x83','\x6f'},{'\x83','\x70'},
+ {'\x83','\x71'},{'\x83','\x72'},{'\x83','\x73'},{'\x83','\x74'},{'\x83','\x75'},
+ {'\x83','\x76'},{'\x83','\x77'},{'\x83','\x78'},{'\x83','\x79'},{'\x83','\x7a'},
+ {'\x83','\x7b'},{'\x83','\x7c'},{'\x83','\x7d'},{'\x83','\x7e'},{'\x83','\xa1'},
+ {'\x83','\xa2'},{'\x83','\xa3'},{'\x83','\xa4'},{'\x83','\xa5'},{'\x83','\xa6'},
+ {'\x83','\xa7'},{'\x83','\xa8'},{'\x83','\xa9'},{'\x83','\xaa'},{'\x83','\xab'},
+ {'\x83','\xac'},{'\x83','\xad'},{'\x83','\xae'},{'\x83','\xaf'},{'\x83','\xb0'},
+ {'\x83','\xb1'},{'\x83','\xb2'},{'\x83','\xb3'},{'\x83','\xb4'},{'\x83','\xb5'},
+ {'\x83','\xb6'},{'\x83','\xb7'},{'\x83','\xb8'},{'\x83','\xb9'},{'\x83','\xba'},
+ {'\x83','\xbb'},{'\x83','\xbc'},{'\x83','\xbd'},{'\x83','\xbe'},{'\x83','\xbf'},
+ {'\x83','\xc0'},{'\x83','\xc1'},{'\x83','\xc2'},{'\x83','\xc3'},{'\x83','\xc4'},
+ {'\x83','\xc5'},{'\x83','\xc6'},{'\x83','\xc7'},{'\x83','\xc8'},{'\x83','\xc9'},
+ {'\x83','\xca'},{'\x83','\xcb'},{'\x83','\xcc'},{'\x83','\xcd'},{'\x83','\xce'},
+ {'\x83','\xcf'},{'\x83','\xd0'},{'\x83','\xd1'},{'\x83','\xd2'},{'\x83','\xd3'},
+ {'\x83','\xd4'},{'\x83','\xd5'},{'\x83','\xd6'},{'\x83','\xd7'},{'\x83','\xd8'},
+ {'\x83','\xd9'},{'\x83','\xda'},{'\x83','\xdb'},{'\x83','\xdc'},{'\x83','\xdd'},
+ {'\x83','\xde'},{'\x83','\xdf'},{'\x83','\xe0'},{'\x83','\xe1'},{'\x83','\xe2'},
+ {'\x83','\xe3'},{'\x83','\xe4'},{'\x83','\xe5'},{'\x83','\xe6'},{'\x83','\xe7'},
+ {'\x83','\xe8'},{'\x83','\xe9'},{'\x83','\xea'},{'\x83','\xeb'},{'\x83','\xec'},
+ {'\x83','\xed'},{'\x83','\xee'},{'\x83','\xef'},{'\x83','\xf0'},{'\x83','\xf1'},
+ {'\x83','\xf2'},{'\x83','\xf3'},{'\x83','\xf4'},{'\x83','\xf5'},{'\x83','\xf6'},
+ {'\x83','\xf7'},{'\x83','\xf8'},{'\x83','\xf9'},{'\x83','\xfa'},{'\x83','\xfb'},
+ {'\x83','\xfc'},{'\x83','\xfd'},{'\x83','\xfe'},{'\x84','\x40'},{'\x84','\x41'},
+ {'\x84','\x42'},{'\x84','\x43'},{'\x84','\x44'},{'\x84','\x45'},{'\x84','\x46'},
+ {'\x84','\x47'},{'\x84','\x48'},{'\x84','\x49'},{'\x84','\x4a'},{'\x84','\x4b'},
+ {'\x84','\x4c'},{'\x84','\x4d'},{'\x84','\x4e'},{'\x84','\x4f'},{'\x84','\x50'},
+ {'\x84','\x51'},{'\x84','\x52'},{'\x84','\x53'},{'\x84','\x54'},{'\x84','\x55'},
+ {'\x84','\x56'},{'\x84','\x57'},{'\x84','\x58'},{'\x84','\x59'},{'\x84','\x5a'},
+ {'\x84','\x5b'},{'\x84','\x5c'},{'\x84','\x5d'},{'\x84','\x5e'},{'\x84','\x5f'},
+ {'\x84','\x60'},{'\x84','\x61'},{'\x84','\x62'},{'\x84','\x63'},{'\x84','\x64'},
+ {'\x84','\x65'},{'\x84','\x66'},{'\x84','\x67'},{'\x84','\x68'},{'\x84','\x69'},
+ {'\x84','\x6a'},{'\x84','\x6b'},{'\x84','\x6c'},{'\x84','\x6d'},{'\x84','\x6e'},
+ {'\x84','\x6f'},{'\x84','\x70'},{'\x84','\x71'},{'\x84','\x72'},{'\x84','\x73'},
+ {'\x84','\x74'},{'\x84','\x75'},{'\x84','\x76'},{'\x84','\x77'},{'\x84','\x78'},
+ {'\x84','\x79'},{'\x84','\x7a'},{'\x84','\x7b'},{'\x84','\x7c'},{'\x84','\x7d'},
+ {'\x84','\x7e'},{'\x84','\xa1'},{'\x84','\xa2'},{'\x84','\xa3'},{'\x84','\xa4'},
+ {'\x84','\xa5'},{'\x84','\xa6'},{'\x84','\xa7'},{'\x84','\xa8'},{'\x84','\xa9'},
+ {'\x84','\xaa'},{'\x84','\xab'},{'\x84','\xac'},{'\x84','\xad'},{'\x84','\xae'},
+ {'\x84','\xaf'},{'\x84','\xb0'},{'\x84','\xb1'},{'\x84','\xb2'},{'\x84','\xb3'},
+ {'\x84','\xb4'},{'\x84','\xb5'},{'\x84','\xb6'},{'\x84','\xb7'},{'\x84','\xb8'},
+ {'\x84','\xb9'},{'\x84','\xba'},{'\x84','\xbb'},{'\x84','\xbc'},{'\x84','\xbd'},
+ {'\x84','\xbe'},{'\x84','\xbf'},{'\x84','\xc0'},{'\x84','\xc1'},{'\x84','\xc2'},
+ {'\x84','\xc3'},{'\x84','\xc4'},{'\x84','\xc5'},{'\x84','\xc6'},{'\x84','\xc7'},
+ {'\x84','\xc8'},{'\x84','\xc9'},{'\x84','\xca'},{'\x84','\xcb'},{'\x84','\xcc'},
+ {'\x84','\xcd'},{'\x84','\xce'},{'\x84','\xcf'},{'\x84','\xd0'},{'\x84','\xd1'},
+ {'\x84','\xd2'},{'\x84','\xd3'},{'\x84','\xd4'},{'\x84','\xd5'},{'\x84','\xd6'},
+ {'\x84','\xd7'},{'\x84','\xd8'},{'\x84','\xd9'},{'\x84','\xda'},{'\x84','\xdb'},
+ {'\x84','\xdc'},{'\x84','\xdd'},{'\x84','\xde'},{'\x84','\xdf'},{'\x84','\xe0'},
+ {'\x84','\xe1'},{'\x84','\xe2'},{'\x84','\xe3'},{'\x84','\xe4'},{'\x84','\xe5'},
+ {'\x84','\xe6'},{'\x84','\xe7'},{'\x84','\xe8'},{'\x84','\xe9'},{'\x84','\xea'},
+ {'\x84','\xeb'},{'\x84','\xec'},{'\x84','\xed'},{'\x84','\xee'},{'\x84','\xef'},
+ {'\x84','\xf0'},{'\x84','\xf1'},{'\x84','\xf2'},{'\x84','\xf3'},{'\x84','\xf4'},
+ {'\x84','\xf5'},{'\x84','\xf6'},{'\x84','\xf7'},{'\x84','\xf8'},{'\x84','\xf9'},
+ {'\x84','\xfa'},{'\x84','\xfb'},{'\x84','\xfc'},{'\x84','\xfd'},{'\x84','\xfe'},
+ {'\x85','\x40'},{'\x85','\x41'},{'\x85','\x42'},{'\x85','\x43'},{'\x85','\x44'},
+ {'\x85','\x45'},{'\x85','\x46'},{'\x85','\x47'},{'\x85','\x48'},{'\x85','\x49'},
+ {'\x85','\x4a'},{'\x85','\x4b'},{'\x85','\x4c'},{'\x85','\x4d'},{'\x85','\x4e'},
+ {'\x85','\x4f'},{'\x85','\x50'},{'\x85','\x51'},{'\x85','\x52'},{'\x85','\x53'},
+ {'\x85','\x54'},{'\x85','\x55'},{'\x85','\x56'},{'\x85','\x57'},{'\x85','\x58'},
+ {'\x85','\x59'},{'\x85','\x5a'},{'\x85','\x5b'},{'\x85','\x5c'},{'\x85','\x5d'},
+ {'\x85','\x5e'},{'\x85','\x5f'},{'\x85','\x60'},{'\x85','\x61'},{'\x85','\x62'},
+ {'\x85','\x63'},{'\x85','\x64'},{'\x85','\x65'},{'\x85','\x66'},{'\x85','\x67'},
+ {'\x85','\x68'},{'\x85','\x69'},{'\x85','\x6a'},{'\x85','\x6b'},{'\x85','\x6c'},
+ {'\x85','\x6d'},{'\x85','\x6e'},{'\x85','\x6f'},{'\x85','\x70'},{'\x85','\x71'},
+ {'\x85','\x72'},{'\x85','\x73'},{'\x85','\x74'},{'\x85','\x75'},{'\x85','\x76'},
+ {'\x85','\x77'},{'\x85','\x78'},{'\x85','\x79'},{'\x85','\x7a'},{'\x85','\x7b'},
+ {'\x85','\x7c'},{'\x85','\x7d'},{'\x85','\x7e'},{'\x85','\xa1'},{'\x85','\xa2'},
+ {'\x85','\xa3'},{'\x85','\xa4'},{'\x85','\xa5'},{'\x85','\xa6'},{'\x85','\xa7'},
+ {'\x85','\xa8'},{'\x85','\xa9'},{'\x85','\xaa'},{'\x85','\xab'},{'\x85','\xac'},
+ {'\x85','\xad'},{'\x85','\xae'},{'\x85','\xaf'},{'\x85','\xb0'},{'\x85','\xb1'},
+ {'\x85','\xb2'},{'\x85','\xb3'},{'\x85','\xb4'},{'\x85','\xb5'},{'\x85','\xb6'},
+ {'\x85','\xb7'},{'\x85','\xb8'},{'\x85','\xb9'},{'\x85','\xba'},{'\x85','\xbb'},
+ {'\x85','\xbc'},{'\x85','\xbd'},{'\x85','\xbe'},{'\x85','\xbf'},{'\x85','\xc0'},
+ {'\x85','\xc1'},{'\x85','\xc2'},{'\x85','\xc3'},{'\x85','\xc4'},{'\x85','\xc5'},
+ {'\x85','\xc6'},{'\x85','\xc7'},{'\x85','\xc8'},{'\x85','\xc9'},{'\x85','\xca'},
+ {'\x85','\xcb'},{'\x85','\xcc'},{'\x85','\xcd'},{'\x85','\xce'},{'\x85','\xcf'},
+ {'\x85','\xd0'},{'\x85','\xd1'},{'\x85','\xd2'},{'\x85','\xd3'},{'\x85','\xd4'},
+ {'\x85','\xd5'},{'\x85','\xd6'},{'\x85','\xd7'},{'\x85','\xd8'},{'\x85','\xd9'},
+ {'\x85','\xda'},{'\x85','\xdb'},{'\x85','\xdc'},{'\x85','\xdd'},{'\x85','\xde'},
+ {'\x85','\xdf'},{'\x85','\xe0'},{'\x85','\xe1'},{'\x85','\xe2'},{'\x85','\xe3'},
+ {'\x85','\xe4'},{'\x85','\xe5'},{'\x85','\xe6'},{'\x85','\xe7'},{'\x85','\xe8'},
+ {'\x85','\xe9'},{'\x85','\xea'},{'\x85','\xeb'},{'\x85','\xec'},{'\x85','\xed'},
+ {'\x85','\xee'},{'\x85','\xef'},{'\x85','\xf0'},{'\x85','\xf1'},{'\x85','\xf2'},
+ {'\x85','\xf3'},{'\x85','\xf4'},{'\x85','\xf5'},{'\x85','\xf6'},{'\x85','\xf7'},
+ {'\x85','\xf8'},{'\x85','\xf9'},{'\x85','\xfa'},{'\x85','\xfb'},{'\x85','\xfc'},
+ {'\x85','\xfd'},{'\x85','\xfe'},{'\x86','\x40'},{'\x86','\x41'},{'\x86','\x42'},
+ {'\x86','\x43'},{'\x86','\x44'},{'\x86','\x45'},{'\x86','\x46'},{'\x86','\x47'},
+ {'\x86','\x48'},{'\x86','\x49'},{'\x86','\x4a'},{'\x86','\x4b'},{'\x86','\x4c'},
+ {'\x86','\x4d'},{'\x86','\x4e'},{'\x86','\x4f'},{'\x86','\x50'},{'\x86','\x51'},
+ {'\x86','\x52'},{'\x86','\x53'},{'\x86','\x54'},{'\x86','\x55'},{'\x86','\x56'},
+ {'\x86','\x57'},{'\x86','\x58'},{'\x86','\x59'},{'\x86','\x5a'},{'\x86','\x5b'},
+ {'\x86','\x5c'},{'\x86','\x5d'},{'\x86','\x5e'},{'\x86','\x5f'},{'\x86','\x60'},
+ {'\x86','\x61'},{'\x86','\x62'},{'\x86','\x63'},{'\x86','\x64'},{'\x86','\x65'},
+ {'\x86','\x66'},{'\x86','\x67'},{'\x86','\x68'},{'\x86','\x69'},{'\x86','\x6a'},
+ {'\x86','\x6b'},{'\x86','\x6c'},{'\x86','\x6d'},{'\x86','\x6e'},{'\x86','\x6f'},
+ {'\x86','\x70'},{'\x86','\x71'},{'\x86','\x72'},{'\x86','\x73'},{'\x86','\x74'},
+ {'\x86','\x75'},{'\x86','\x76'},{'\x86','\x77'},{'\x86','\x78'},{'\x86','\x79'},
+ {'\x86','\x7a'},{'\x86','\x7b'},{'\x86','\x7c'},{'\x86','\x7d'},{'\x86','\x7e'},
+ {'\x86','\xa1'},{'\x86','\xa2'},{'\x86','\xa3'},{'\x86','\xa4'},{'\x86','\xa5'},
+ {'\x86','\xa6'},{'\x86','\xa7'},{'\x86','\xa8'},{'\x86','\xa9'},{'\x86','\xaa'},
+ {'\x86','\xab'},{'\x86','\xac'},{'\x86','\xad'},{'\x86','\xae'},{'\x86','\xaf'},
+ {'\x86','\xb0'},{'\x86','\xb1'},{'\x86','\xb2'},{'\x86','\xb3'},{'\x86','\xb4'},
+ {'\x86','\xb5'},{'\x86','\xb6'},{'\x86','\xb7'},{'\x86','\xb8'},{'\x86','\xb9'},
+ {'\x86','\xba'},{'\x86','\xbb'},{'\x86','\xbc'},{'\x86','\xbd'},{'\x86','\xbe'},
+ {'\x86','\xbf'},{'\x86','\xc0'},{'\x86','\xc1'},{'\x86','\xc2'},{'\x86','\xc3'},
+ {'\x86','\xc4'},{'\x86','\xc5'},{'\x86','\xc6'},{'\x86','\xc7'},{'\x86','\xc8'},
+ {'\x86','\xc9'},{'\x86','\xca'},{'\x86','\xcb'},{'\x86','\xcc'},{'\x86','\xcd'},
+ {'\x86','\xce'},{'\x86','\xcf'},{'\x86','\xd0'},{'\x86','\xd1'},{'\x86','\xd2'},
+ {'\x86','\xd3'},{'\x86','\xd4'},{'\x86','\xd5'},{'\x86','\xd6'},{'\x86','\xd7'},
+ {'\x86','\xd8'},{'\x86','\xd9'},{'\x86','\xda'},{'\x86','\xdb'},{'\x86','\xdc'},
+ {'\x86','\xdd'},{'\x86','\xde'},{'\x86','\xdf'},{'\x86','\xe0'},{'\x86','\xe1'},
+ {'\x86','\xe2'},{'\x86','\xe3'},{'\x86','\xe4'},{'\x86','\xe5'},{'\x86','\xe6'},
+ {'\x86','\xe7'},{'\x86','\xe8'},{'\x86','\xe9'},{'\x86','\xea'},{'\x86','\xeb'},
+ {'\x86','\xec'},{'\x86','\xed'},{'\x86','\xee'},{'\x86','\xef'},{'\x86','\xf0'},
+ {'\x86','\xf1'},{'\x86','\xf2'},{'\x86','\xf3'},{'\x86','\xf4'},{'\x86','\xf5'},
+ {'\x86','\xf6'},{'\x86','\xf7'},{'\x86','\xf8'},{'\x86','\xf9'},{'\x86','\xfa'},
+ {'\x86','\xfb'},{'\x86','\xfc'},{'\x86','\xfd'},{'\x86','\xfe'},{'\x87','\x40'},
+ {'\x87','\x41'},{'\x87','\x42'},{'\x87','\x43'},{'\x87','\x44'},{'\x87','\x45'},
+ {'\x87','\x46'},{'\x87','\x47'},{'\x87','\x48'},{'\x87','\x49'},{'\x87','\x4a'},
+ {'\x87','\x4b'},{'\x87','\x4c'},{'\x87','\x4d'},{'\x87','\x4e'},{'\x87','\x4f'},
+ {'\x87','\x50'},{'\x87','\x51'},{'\x87','\x52'},{'\x87','\x53'},{'\x87','\x54'},
+ {'\x87','\x55'},{'\x87','\x56'},{'\x87','\x57'},{'\x87','\x58'},{'\x87','\x59'},
+ {'\x87','\x5a'},{'\x87','\x5b'},{'\x87','\x5c'},{'\x87','\x5d'},{'\x87','\x5e'},
+ {'\x87','\x5f'},{'\x87','\x60'},{'\x87','\x61'},{'\x87','\x62'},{'\x87','\x63'},
+ {'\x87','\x64'},{'\x87','\x65'},{'\x87','\x66'},{'\x87','\x67'},{'\x87','\x68'},
+ {'\x87','\x69'},{'\x87','\x6a'},{'\x87','\x6b'},{'\x87','\x6c'},{'\x87','\x6d'},
+ {'\x87','\x6e'},{'\x87','\x6f'},{'\x87','\x70'},{'\x87','\x71'},{'\x87','\x72'},
+ {'\x87','\x73'},{'\x87','\x74'},{'\x87','\x75'},{'\x87','\x76'},{'\x87','\x77'},
+ {'\x87','\x78'},{'\x87','\x79'},{'\x87','\x7a'},{'\x87','\x7b'},{'\x87','\x7c'},
+ {'\x87','\x7d'},{'\x87','\x7e'},{'\x87','\xa1'},{'\x87','\xa2'},{'\x87','\xa3'},
+ {'\x87','\xa4'},{'\x87','\xa5'},{'\x87','\xa6'},{'\x87','\xa7'},{'\x87','\xa8'},
+ {'\x87','\xa9'},{'\x87','\xaa'},{'\x87','\xab'},{'\x87','\xac'},{'\x87','\xad'},
+ {'\x87','\xae'},{'\x87','\xaf'},{'\x87','\xb0'},{'\x87','\xb1'},{'\x87','\xb2'},
+ {'\x87','\xb3'},{'\x87','\xb4'},{'\x87','\xb5'},{'\x87','\xb6'},{'\x87','\xb7'},
+ {'\x87','\xb8'},{'\x87','\xb9'},{'\x87','\xba'},{'\x87','\xbb'},{'\x87','\xbc'},
+ {'\x87','\xbd'},{'\x87','\xbe'},{'\x87','\xbf'},{'\x87','\xc0'},{'\x87','\xc1'},
+ {'\x87','\xc2'},{'\x87','\xc3'},{'\x87','\xc4'},{'\x87','\xc5'},{'\x87','\xc6'},
+ {'\x87','\xc7'},{'\x87','\xc8'},{'\x87','\xc9'},{'\x87','\xca'},{'\x87','\xcb'},
+ {'\x87','\xcc'},{'\x87','\xcd'},{'\x87','\xce'},{'\x87','\xcf'},{'\x87','\xd0'},
+ {'\x87','\xd1'},{'\x87','\xd2'},{'\x87','\xd3'},{'\x87','\xd4'},{'\x87','\xd5'},
+ {'\x87','\xd6'},{'\x87','\xd7'},{'\x87','\xd8'},{'\x87','\xd9'},{'\x87','\xda'},
+ {'\x87','\xdb'},{'\x87','\xdc'},{'\x87','\xdd'},{'\x87','\xde'},{'\x87','\xdf'},
+ {'\x87','\xe0'},{'\x87','\xe1'},{'\x87','\xe2'},{'\x87','\xe3'},{'\x87','\xe4'},
+ {'\x87','\xe5'},{'\x87','\xe6'},{'\x87','\xe7'},{'\x87','\xe8'},{'\x87','\xe9'},
+ {'\x87','\xea'},{'\x87','\xeb'},{'\x87','\xec'},{'\x87','\xed'},{'\x87','\xee'},
+ {'\x87','\xef'},{'\x87','\xf0'},{'\x87','\xf1'},{'\x87','\xf2'},{'\x87','\xf3'},
+ {'\x87','\xf4'},{'\x87','\xf5'},{'\x87','\xf6'},{'\x87','\xf7'},{'\x87','\xf8'},
+ {'\x87','\xf9'},{'\x87','\xfa'},{'\x87','\xfb'},{'\x87','\xfc'},{'\x87','\xfd'},
+ {'\x87','\xfe'},{'\x88','\x40'},{'\x88','\x41'},{'\x88','\x42'},{'\x88','\x43'},
+ {'\x88','\x44'},{'\x88','\x45'},{'\x88','\x46'},{'\x88','\x47'},{'\x88','\x48'},
+ {'\x88','\x49'},{'\x88','\x4a'},{'\x88','\x4b'},{'\x88','\x4c'},{'\x88','\x4d'},
+ {'\x88','\x4e'},{'\x88','\x4f'},{'\x88','\x50'},{'\x88','\x51'},{'\x88','\x52'},
+ {'\x88','\x53'},{'\x88','\x54'},{'\x88','\x55'},{'\x88','\x56'},{'\x88','\x57'},
+ {'\x88','\x58'},{'\x88','\x59'},{'\x88','\x5a'},{'\x88','\x5b'},{'\x88','\x5c'},
+ {'\x88','\x5d'},{'\x88','\x5e'},{'\x88','\x5f'},{'\x88','\x60'},{'\x88','\x61'},
+ {'\x88','\x62'},{'\x88','\x63'},{'\x88','\x64'},{'\x88','\x65'},{'\x88','\x66'},
+ {'\x88','\x67'},{'\x88','\x68'},{'\x88','\x69'},{'\x88','\x6a'},{'\x88','\x6b'},
+ {'\x88','\x6c'},{'\x88','\x6d'},{'\x88','\x6e'},{'\x88','\x6f'},{'\x88','\x70'},
+ {'\x88','\x71'},{'\x88','\x72'},{'\x88','\x73'},{'\x88','\x74'},{'\x88','\x75'},
+ {'\x88','\x76'},{'\x88','\x77'},{'\x88','\x78'},{'\x88','\x79'},{'\x88','\x7a'},
+ {'\x88','\x7b'},{'\x88','\x7c'},{'\x88','\x7d'},{'\x88','\x7e'},{'\x88','\xa1'},
+ {'\x88','\xa2'},{'\x88','\xa3'},{'\x88','\xa4'},{'\x88','\xa5'},{'\x88','\xa6'},
+ {'\x88','\xa7'},{'\x88','\xa8'},{'\x88','\xa9'},{'\x88','\xaa'},{'\x88','\xab'},
+ {'\x88','\xac'},{'\x88','\xad'},{'\x88','\xae'},{'\x88','\xaf'},{'\x88','\xb0'},
+ {'\x88','\xb1'},{'\x88','\xb2'},{'\x88','\xb3'},{'\x88','\xb4'},{'\x88','\xb5'},
+ {'\x88','\xb6'},{'\x88','\xb7'},{'\x88','\xb8'},{'\x88','\xb9'},{'\x88','\xba'},
+ {'\x88','\xbb'},{'\x88','\xbc'},{'\x88','\xbd'},{'\x88','\xbe'},{'\x88','\xbf'},
+ {'\x88','\xc0'},{'\x88','\xc1'},{'\x88','\xc2'},{'\x88','\xc3'},{'\x88','\xc4'},
+ {'\x88','\xc5'},{'\x88','\xc6'},{'\x88','\xc7'},{'\x88','\xc8'},{'\x88','\xc9'},
+ {'\x88','\xca'},{'\x88','\xcb'},{'\x88','\xcc'},{'\x88','\xcd'},{'\x88','\xce'},
+ {'\x88','\xcf'},{'\x88','\xd0'},{'\x88','\xd1'},{'\x88','\xd2'},{'\x88','\xd3'},
+ {'\x88','\xd4'},{'\x88','\xd5'},{'\x88','\xd6'},{'\x88','\xd7'},{'\x88','\xd8'},
+ {'\x88','\xd9'},{'\x88','\xda'},{'\x88','\xdb'},{'\x88','\xdc'},{'\x88','\xdd'},
+ {'\x88','\xde'},{'\x88','\xdf'},{'\x88','\xe0'},{'\x88','\xe1'},{'\x88','\xe2'},
+ {'\x88','\xe3'},{'\x88','\xe4'},{'\x88','\xe5'},{'\x88','\xe6'},{'\x88','\xe7'},
+ {'\x88','\xe8'},{'\x88','\xe9'},{'\x88','\xea'},{'\x88','\xeb'},{'\x88','\xec'},
+ {'\x88','\xed'},{'\x88','\xee'},{'\x88','\xef'},{'\x88','\xf0'},{'\x88','\xf1'},
+ {'\x88','\xf2'},{'\x88','\xf3'},{'\x88','\xf4'},{'\x88','\xf5'},{'\x88','\xf6'},
+ {'\x88','\xf7'},{'\x88','\xf8'},{'\x88','\xf9'},{'\x88','\xfa'},{'\x88','\xfb'},
+ {'\x88','\xfc'},{'\x88','\xfd'},{'\x88','\xfe'},{'\x89','\x40'},{'\x89','\x41'},
+ {'\x89','\x42'},{'\x89','\x43'},{'\x89','\x44'},{'\x89','\x45'},{'\x89','\x46'},
+ {'\x89','\x47'},{'\x89','\x48'},{'\x89','\x49'},{'\x89','\x4a'},{'\x89','\x4b'},
+ {'\x89','\x4c'},{'\x89','\x4d'},{'\x89','\x4e'},{'\x89','\x4f'},{'\x89','\x50'},
+ {'\x89','\x51'},{'\x89','\x52'},{'\x89','\x53'},{'\x89','\x54'},{'\x89','\x55'},
+ {'\x89','\x56'},{'\x89','\x57'},{'\x89','\x58'},{'\x89','\x59'},{'\x89','\x5a'},
+ {'\x89','\x5b'},{'\x89','\x5c'},{'\x89','\x5d'},{'\x89','\x5e'},{'\x89','\x5f'},
+ {'\x89','\x60'},{'\x89','\x61'},{'\x89','\x62'},{'\x89','\x63'},{'\x89','\x64'},
+ {'\x89','\x65'},{'\x89','\x66'},{'\x89','\x67'},{'\x89','\x68'},{'\x89','\x69'},
+ {'\x89','\x6a'},{'\x89','\x6b'},{'\x89','\x6c'},{'\x89','\x6d'},{'\x89','\x6e'},
+ {'\x89','\x6f'},{'\x89','\x70'},{'\x89','\x71'},{'\x89','\x72'},{'\x89','\x73'},
+ {'\x89','\x74'},{'\x89','\x75'},{'\x89','\x76'},{'\x89','\x77'},{'\x89','\x78'},
+ {'\x89','\x79'},{'\x89','\x7a'},{'\x89','\x7b'},{'\x89','\x7c'},{'\x89','\x7d'},
+ {'\x89','\x7e'},{'\x89','\xa1'},{'\x89','\xa2'},{'\x89','\xa3'},{'\x89','\xa4'},
+ {'\x89','\xa5'},{'\x89','\xa6'},{'\x89','\xa7'},{'\x89','\xa8'},{'\x89','\xa9'},
+ {'\x89','\xaa'},{'\x89','\xab'},{'\x89','\xac'},{'\x89','\xad'},{'\x89','\xae'},
+ {'\x89','\xaf'},{'\x89','\xb0'},{'\x89','\xb1'},{'\x89','\xb2'},{'\x89','\xb3'},
+ {'\x89','\xb4'},{'\x89','\xb5'},{'\x89','\xb6'},{'\x89','\xb7'},{'\x89','\xb8'},
+ {'\x89','\xb9'},{'\x89','\xba'},{'\x89','\xbb'},{'\x89','\xbc'},{'\x89','\xbd'},
+ {'\x89','\xbe'},{'\x89','\xbf'},{'\x89','\xc0'},{'\x89','\xc1'},{'\x89','\xc2'},
+ {'\x89','\xc3'},{'\x89','\xc4'},{'\x89','\xc5'},{'\x89','\xc6'},{'\x89','\xc7'},
+ {'\x89','\xc8'},{'\x89','\xc9'},{'\x89','\xca'},{'\x89','\xcb'},{'\x89','\xcc'},
+ {'\x89','\xcd'},{'\x89','\xce'},{'\x89','\xcf'},{'\x89','\xd0'},{'\x89','\xd1'},
+ {'\x89','\xd2'},{'\x89','\xd3'},{'\x89','\xd4'},{'\x89','\xd5'},{'\x89','\xd6'},
+ {'\x89','\xd7'},{'\x89','\xd8'},{'\x89','\xd9'},{'\x89','\xda'},{'\x89','\xdb'},
+ {'\x89','\xdc'},{'\x89','\xdd'},{'\x89','\xde'},{'\x89','\xdf'},{'\x89','\xe0'},
+ {'\x89','\xe1'},{'\x89','\xe2'},{'\x89','\xe3'},{'\x89','\xe4'},{'\x89','\xe5'},
+ {'\x89','\xe6'},{'\x89','\xe7'},{'\x89','\xe8'},{'\x89','\xe9'},{'\x89','\xea'},
+ {'\x89','\xeb'},{'\x89','\xec'},{'\x89','\xed'},{'\x89','\xee'},{'\x89','\xef'},
+ {'\x89','\xf0'},{'\x89','\xf1'},{'\x89','\xf2'},{'\x89','\xf3'},{'\x89','\xf4'},
+ {'\x89','\xf5'},{'\x89','\xf6'},{'\x89','\xf7'},{'\x89','\xf8'},{'\x89','\xf9'},
+ {'\x89','\xfa'},{'\x89','\xfb'},{'\x89','\xfc'},{'\x89','\xfd'},{'\x89','\xfe'},
+ {'\x8a','\x40'},{'\x8a','\x41'},{'\x8a','\x42'},{'\x8a','\x43'},{'\x8a','\x44'},
+ {'\x8a','\x45'},{'\x8a','\x46'},{'\x8a','\x47'},{'\x8a','\x48'},{'\x8a','\x49'},
+ {'\x8a','\x4a'},{'\x8a','\x4b'},{'\x8a','\x4c'},{'\x8a','\x4d'},{'\x8a','\x4e'},
+ {'\x8a','\x4f'},{'\x8a','\x50'},{'\x8a','\x51'},{'\x8a','\x52'},{'\x8a','\x53'},
+ {'\x8a','\x54'},{'\x8a','\x55'},{'\x8a','\x56'},{'\x8a','\x57'},{'\x8a','\x58'},
+ {'\x8a','\x59'},{'\x8a','\x5a'},{'\x8a','\x5b'},{'\x8a','\x5c'},{'\x8a','\x5d'},
+ {'\x8a','\x5e'},{'\x8a','\x5f'},{'\x8a','\x60'},{'\x8a','\x61'},{'\x8a','\x62'},
+ {'\x8a','\x63'},{'\x8a','\x64'},{'\x8a','\x65'},{'\x8a','\x66'},{'\x8a','\x67'},
+ {'\x8a','\x68'},{'\x8a','\x69'},{'\x8a','\x6a'},{'\x8a','\x6b'},{'\x8a','\x6c'},
+ {'\x8a','\x6d'},{'\x8a','\x6e'},{'\x8a','\x6f'},{'\x8a','\x70'},{'\x8a','\x71'},
+ {'\x8a','\x72'},{'\x8a','\x73'},{'\x8a','\x74'},{'\x8a','\x75'},{'\x8a','\x76'},
+ {'\x8a','\x77'},{'\x8a','\x78'},{'\x8a','\x79'},{'\x8a','\x7a'},{'\x8a','\x7b'},
+ {'\x8a','\x7c'},{'\x8a','\x7d'},{'\x8a','\x7e'},{'\x8a','\xa1'},{'\x8a','\xa2'},
+ {'\x8a','\xa3'},{'\x8a','\xa4'},{'\x8a','\xa5'},{'\x8a','\xa6'},{'\x8a','\xa7'},
+ {'\x8a','\xa8'},{'\x8a','\xa9'},{'\x8a','\xaa'},{'\x8a','\xab'},{'\x8a','\xac'},
+ {'\x8a','\xad'},{'\x8a','\xae'},{'\x8a','\xaf'},{'\x8a','\xb0'},{'\x8a','\xb1'},
+ {'\x8a','\xb2'},{'\x8a','\xb3'},{'\x8a','\xb4'},{'\x8a','\xb5'},{'\x8a','\xb6'},
+ {'\x8a','\xb7'},{'\x8a','\xb8'},{'\x8a','\xb9'},{'\x8a','\xba'},{'\x8a','\xbb'},
+ {'\x8a','\xbc'},{'\x8a','\xbd'},{'\x8a','\xbe'},{'\x8a','\xbf'},{'\x8a','\xc0'},
+ {'\x8a','\xc1'},{'\x8a','\xc2'},{'\x8a','\xc3'},{'\x8a','\xc4'},{'\x8a','\xc5'},
+ {'\x8a','\xc6'},{'\x8a','\xc7'},{'\x8a','\xc8'},{'\x8a','\xc9'},{'\x8a','\xca'},
+ {'\x8a','\xcb'},{'\x8a','\xcc'},{'\x8a','\xcd'},{'\x8a','\xce'},{'\x8a','\xcf'},
+ {'\x8a','\xd0'},{'\x8a','\xd1'},{'\x8a','\xd2'},{'\x8a','\xd3'},{'\x8a','\xd4'},
+ {'\x8a','\xd5'},{'\x8a','\xd6'},{'\x8a','\xd7'},{'\x8a','\xd8'},{'\x8a','\xd9'},
+ {'\x8a','\xda'},{'\x8a','\xdb'},{'\x8a','\xdc'},{'\x8a','\xdd'},{'\x8a','\xde'},
+ {'\x8a','\xdf'},{'\x8a','\xe0'},{'\x8a','\xe1'},{'\x8a','\xe2'},{'\x8a','\xe3'},
+ {'\x8a','\xe4'},{'\x8a','\xe5'},{'\x8a','\xe6'},{'\x8a','\xe7'},{'\x8a','\xe8'},
+ {'\x8a','\xe9'},{'\x8a','\xea'},{'\x8a','\xeb'},{'\x8a','\xec'},{'\x8a','\xed'},
+ {'\x8a','\xee'},{'\x8a','\xef'},{'\x8a','\xf0'},{'\x8a','\xf1'},{'\x8a','\xf2'},
+ {'\x8a','\xf3'},{'\x8a','\xf4'},{'\x8a','\xf5'},{'\x8a','\xf6'},{'\x8a','\xf7'},
+ {'\x8a','\xf8'},{'\x8a','\xf9'},{'\x8a','\xfa'},{'\x8a','\xfb'},{'\x8a','\xfc'},
+ {'\x8a','\xfd'},{'\x8a','\xfe'},{'\x8b','\x40'},{'\x8b','\x41'},{'\x8b','\x42'},
+ {'\x8b','\x43'},{'\x8b','\x44'},{'\x8b','\x45'},{'\x8b','\x46'},{'\x8b','\x47'},
+ {'\x8b','\x48'},{'\x8b','\x49'},{'\x8b','\x4a'},{'\x8b','\x4b'},{'\x8b','\x4c'},
+ {'\x8b','\x4d'},{'\x8b','\x4e'},{'\x8b','\x4f'},{'\x8b','\x50'},{'\x8b','\x51'},
+ {'\x8b','\x52'},{'\x8b','\x53'},{'\x8b','\x54'},{'\x8b','\x55'},{'\x8b','\x56'},
+ {'\x8b','\x57'},{'\x8b','\x58'},{'\x8b','\x59'},{'\x8b','\x5a'},{'\x8b','\x5b'},
+ {'\x8b','\x5c'},{'\x8b','\x5d'},{'\x8b','\x5e'},{'\x8b','\x5f'},{'\x8b','\x60'},
+ {'\x8b','\x61'},{'\x8b','\x62'},{'\x8b','\x63'},{'\x8b','\x64'},{'\x8b','\x65'},
+ {'\x8b','\x66'},{'\x8b','\x67'},{'\x8b','\x68'},{'\x8b','\x69'},{'\x8b','\x6a'},
+ {'\x8b','\x6b'},{'\x8b','\x6c'},{'\x8b','\x6d'},{'\x8b','\x6e'},{'\x8b','\x6f'},
+ {'\x8b','\x70'},{'\x8b','\x71'},{'\x8b','\x72'},{'\x8b','\x73'},{'\x8b','\x74'},
+ {'\x8b','\x75'},{'\x8b','\x76'},{'\x8b','\x77'},{'\x8b','\x78'},{'\x8b','\x79'},
+ {'\x8b','\x7a'},{'\x8b','\x7b'},{'\x8b','\x7c'},{'\x8b','\x7d'},{'\x8b','\x7e'},
+ {'\x8b','\xa1'},{'\x8b','\xa2'},{'\x8b','\xa3'},{'\x8b','\xa4'},{'\x8b','\xa5'},
+ {'\x8b','\xa6'},{'\x8b','\xa7'},{'\x8b','\xa8'},{'\x8b','\xa9'},{'\x8b','\xaa'},
+ {'\x8b','\xab'},{'\x8b','\xac'},{'\x8b','\xad'},{'\x8b','\xae'},{'\x8b','\xaf'},
+ {'\x8b','\xb0'},{'\x8b','\xb1'},{'\x8b','\xb2'},{'\x8b','\xb3'},{'\x8b','\xb4'},
+ {'\x8b','\xb5'},{'\x8b','\xb6'},{'\x8b','\xb7'},{'\x8b','\xb8'},{'\x8b','\xb9'},
+ {'\x8b','\xba'},{'\x8b','\xbb'},{'\x8b','\xbc'},{'\x8b','\xbd'},{'\x8b','\xbe'},
+ {'\x8b','\xbf'},{'\x8b','\xc0'},{'\x8b','\xc1'},{'\x8b','\xc2'},{'\x8b','\xc3'},
+ {'\x8b','\xc4'},{'\x8b','\xc5'},{'\x8b','\xc6'},{'\x8b','\xc7'},{'\x8b','\xc8'},
+ {'\x8b','\xc9'},{'\x8b','\xca'},{'\x8b','\xcb'},{'\x8b','\xcc'},{'\x8b','\xcd'},
+ {'\x8b','\xce'},{'\x8b','\xcf'},{'\x8b','\xd0'},{'\x8b','\xd1'},{'\x8b','\xd2'},
+ {'\x8b','\xd3'},{'\x8b','\xd4'},{'\x8b','\xd5'},{'\x8b','\xd6'},{'\x8b','\xd7'},
+ {'\x8b','\xd8'},{'\x8b','\xd9'},{'\x8b','\xda'},{'\x8b','\xdb'},{'\x8b','\xdc'},
+ {'\x8b','\xdd'},{'\x8b','\xde'},{'\x8b','\xdf'},{'\x8b','\xe0'},{'\x8b','\xe1'},
+ {'\x8b','\xe2'},{'\x8b','\xe3'},{'\x8b','\xe4'},{'\x8b','\xe5'},{'\x8b','\xe6'},
+ {'\x8b','\xe7'},{'\x8b','\xe8'},{'\x8b','\xe9'},{'\x8b','\xea'},{'\x8b','\xeb'},
+ {'\x8b','\xec'},{'\x8b','\xed'},{'\x8b','\xee'},{'\x8b','\xef'},{'\x8b','\xf0'},
+ {'\x8b','\xf1'},{'\x8b','\xf2'},{'\x8b','\xf3'},{'\x8b','\xf4'},{'\x8b','\xf5'},
+ {'\x8b','\xf6'},{'\x8b','\xf7'},{'\x8b','\xf8'},{'\x8b','\xf9'},{'\x8b','\xfa'},
+ {'\x8b','\xfb'},{'\x8b','\xfc'},{'\x8b','\xfd'},{'\x8b','\xfe'},{'\x8c','\x40'},
+ {'\x8c','\x41'},{'\x8c','\x42'},{'\x8c','\x43'},{'\x8c','\x44'},{'\x8c','\x45'},
+ {'\x8c','\x46'},{'\x8c','\x47'},{'\x8c','\x48'},{'\x8c','\x49'},{'\x8c','\x4a'},
+ {'\x8c','\x4b'},{'\x8c','\x4c'},{'\x8c','\x4d'},{'\x8c','\x4e'},{'\x8c','\x4f'},
+ {'\x8c','\x50'},{'\x8c','\x51'},{'\x8c','\x52'},{'\x8c','\x53'},{'\x8c','\x54'},
+ {'\x8c','\x55'},{'\x8c','\x56'},{'\x8c','\x57'},{'\x8c','\x58'},{'\x8c','\x59'},
+ {'\x8c','\x5a'},{'\x8c','\x5b'},{'\x8c','\x5c'},{'\x8c','\x5d'},{'\x8c','\x5e'},
+ {'\x8c','\x5f'},{'\x8c','\x60'},{'\x8c','\x61'},{'\x8c','\x62'},{'\x8c','\x63'},
+ {'\x8c','\x64'},{'\x8c','\x65'},{'\x8c','\x66'},{'\x8c','\x67'},{'\x8c','\x68'},
+ {'\x8c','\x69'},{'\x8c','\x6a'},{'\x8c','\x6b'},{'\x8c','\x6c'},{'\x8c','\x6d'},
+ {'\x8c','\x6e'},{'\x8c','\x6f'},{'\x8c','\x70'},{'\x8c','\x71'},{'\x8c','\x72'},
+ {'\x8c','\x73'},{'\x8c','\x74'},{'\x8c','\x75'},{'\x8c','\x76'},{'\x8c','\x77'},
+ {'\x8c','\x78'},{'\x8c','\x79'},{'\x8c','\x7a'},{'\x8c','\x7b'},{'\x8c','\x7c'},
+ {'\x8c','\x7d'},{'\x8c','\x7e'},{'\x8c','\xa1'},{'\x8c','\xa2'},{'\x8c','\xa3'},
+ {'\x8c','\xa4'},{'\x8c','\xa5'},{'\x8c','\xa6'},{'\x8c','\xa7'},{'\x8c','\xa8'},
+ {'\x8c','\xa9'},{'\x8c','\xaa'},{'\x8c','\xab'},{'\x8c','\xac'},{'\x8c','\xad'},
+ {'\x8c','\xae'},{'\x8c','\xaf'},{'\x8c','\xb0'},{'\x8c','\xb1'},{'\x8c','\xb2'},
+ {'\x8c','\xb3'},{'\x8c','\xb4'},{'\x8c','\xb5'},{'\x8c','\xb6'},{'\x8c','\xb7'},
+ {'\x8c','\xb8'},{'\x8c','\xb9'},{'\x8c','\xba'},{'\x8c','\xbb'},{'\x8c','\xbc'},
+ {'\x8c','\xbd'},{'\x8c','\xbe'},{'\x8c','\xbf'},{'\x8c','\xc0'},{'\x8c','\xc1'},
+ {'\x8c','\xc2'},{'\x8c','\xc3'},{'\x8c','\xc4'},{'\x8c','\xc5'},{'\x8c','\xc6'},
+ {'\x8c','\xc7'},{'\x8c','\xc8'},{'\x8c','\xc9'},{'\x8c','\xca'},{'\x8c','\xcb'},
+ {'\x8c','\xcc'},{'\x8c','\xcd'},{'\x8c','\xce'},{'\x8c','\xcf'},{'\x8c','\xd0'},
+ {'\x8c','\xd1'},{'\x8c','\xd2'},{'\x8c','\xd3'},{'\x8c','\xd4'},{'\x8c','\xd5'},
+ {'\x8c','\xd6'},{'\x8c','\xd7'},{'\x8c','\xd8'},{'\x8c','\xd9'},{'\x8c','\xda'},
+ {'\x8c','\xdb'},{'\x8c','\xdc'},{'\x8c','\xdd'},{'\x8c','\xde'},{'\x8c','\xdf'},
+ {'\x8c','\xe0'},{'\x8c','\xe1'},{'\x8c','\xe2'},{'\x8c','\xe3'},{'\x8c','\xe4'},
+ {'\x8c','\xe5'},{'\x8c','\xe6'},{'\x8c','\xe7'},{'\x8c','\xe8'},{'\x8c','\xe9'},
+ {'\x8c','\xea'},{'\x8c','\xeb'},{'\x8c','\xec'},{'\x8c','\xed'},{'\x8c','\xee'},
+ {'\x8c','\xef'},{'\x8c','\xf0'},{'\x8c','\xf1'},{'\x8c','\xf2'},{'\x8c','\xf3'},
+ {'\x8c','\xf4'},{'\x8c','\xf5'},{'\x8c','\xf6'},{'\x8c','\xf7'},{'\x8c','\xf8'},
+ {'\x8c','\xf9'},{'\x8c','\xfa'},{'\x8c','\xfb'},{'\x8c','\xfc'},{'\x8c','\xfd'},
+ {'\x8c','\xfe'},{'\x8d','\x40'},{'\x8d','\x41'},{'\x8d','\x42'},{'\x8d','\x43'},
+ {'\x8d','\x44'},{'\x8d','\x45'},{'\x8d','\x46'},{'\x8d','\x47'},{'\x8d','\x48'},
+ {'\x8d','\x49'},{'\x8d','\x4a'},{'\x8d','\x4b'},{'\x8d','\x4c'},{'\x8d','\x4d'},
+ {'\x8d','\x4e'},{'\x8d','\x4f'},{'\x8d','\x50'},{'\x8d','\x51'},{'\x8d','\x52'},
+ {'\x8d','\x53'},{'\x8d','\x54'},{'\x8d','\x55'},{'\x8d','\x56'},{'\x8d','\x57'},
+ {'\x8d','\x58'},{'\x8d','\x59'},{'\x8d','\x5a'},{'\x8d','\x5b'},{'\x8d','\x5c'},
+ {'\x8d','\x5d'},{'\x8d','\x5e'},{'\x8d','\x5f'},{'\x8d','\x60'},{'\x8d','\x61'},
+ {'\x8d','\x62'},{'\x8d','\x63'},{'\x8d','\x64'},{'\x8d','\x65'},{'\x8d','\x66'},
+ {'\x8d','\x67'},{'\x8d','\x68'},{'\x8d','\x69'},{'\x8d','\x6a'},{'\x8d','\x6b'},
+ {'\x8d','\x6c'},{'\x8d','\x6d'},{'\x8d','\x6e'},{'\x8d','\x6f'},{'\x8d','\x70'},
+ {'\x8d','\x71'},{'\x8d','\x72'},{'\x8d','\x73'},{'\x8d','\x74'},{'\x8d','\x75'},
+ {'\x8d','\x76'},{'\x8d','\x77'},{'\x8d','\x78'},{'\x8d','\x79'},{'\x8d','\x7a'},
+ {'\x8d','\x7b'},{'\x8d','\x7c'},{'\x8d','\x7d'},{'\x8d','\x7e'},{'\x8d','\xa1'},
+ {'\x8d','\xa2'},{'\x8d','\xa3'},{'\x8d','\xa4'},{'\x8d','\xa5'},{'\x8d','\xa6'},
+ {'\x8d','\xa7'},{'\x8d','\xa8'},{'\x8d','\xa9'},{'\x8d','\xaa'},{'\x8d','\xab'},
+ {'\x8d','\xac'},{'\x8d','\xad'},{'\x8d','\xae'},{'\x8d','\xaf'},{'\x8d','\xb0'},
+ {'\x8d','\xb1'},{'\x8d','\xb2'},{'\x8d','\xb3'},{'\x8d','\xb4'},{'\x8d','\xb5'},
+ {'\x8d','\xb6'},{'\x8d','\xb7'},{'\x8d','\xb8'},{'\x8d','\xb9'},{'\x8d','\xba'},
+ {'\x8d','\xbb'},{'\x8d','\xbc'},{'\x8d','\xbd'},{'\x8d','\xbe'},{'\x8d','\xbf'},
+ {'\x8d','\xc0'},{'\x8d','\xc1'},{'\x8d','\xc2'},{'\x8d','\xc3'},{'\x8d','\xc4'},
+ {'\x8d','\xc5'},{'\x8d','\xc6'},{'\x8d','\xc7'},{'\x8d','\xc8'},{'\x8d','\xc9'},
+ {'\x8d','\xca'},{'\x8d','\xcb'},{'\x8d','\xcc'},{'\x8d','\xcd'},{'\x8d','\xce'},
+ {'\x8d','\xcf'},{'\x8d','\xd0'},{'\x8d','\xd1'},{'\x8d','\xd2'},{'\x8d','\xd3'},
+ {'\x8d','\xd4'},{'\x8d','\xd5'},{'\x8d','\xd6'},{'\x8d','\xd7'},{'\x8d','\xd8'},
+ {'\x8d','\xd9'},{'\x8d','\xda'},{'\x8d','\xdb'},{'\x8d','\xdc'},{'\x8d','\xdd'},
+ {'\x8d','\xde'},{'\x8d','\xdf'},{'\x8d','\xe0'},{'\x8d','\xe1'},{'\x8d','\xe2'},
+ {'\x8d','\xe3'},{'\x8d','\xe4'},{'\x8d','\xe5'},{'\x8d','\xe6'},{'\x8d','\xe7'},
+ {'\x8d','\xe8'},{'\x8d','\xe9'},{'\x8d','\xea'},{'\x8d','\xeb'},{'\x8d','\xec'},
+ {'\x8d','\xed'},{'\x8d','\xee'},{'\x8d','\xef'},{'\x8d','\xf0'},{'\x8d','\xf1'},
+ {'\x8d','\xf2'},{'\x8d','\xf3'},{'\x8d','\xf4'},{'\x8d','\xf5'},{'\x8d','\xf6'},
+ {'\x8d','\xf7'},{'\x8d','\xf8'},{'\x8d','\xf9'},{'\x8d','\xfa'},{'\x8d','\xfb'},
+ {'\x8d','\xfc'},{'\x8d','\xfd'},{'\x8d','\xfe'},{'\xc6','\xa1'},{'\xc6','\xa2'},
+ {'\xc6','\xa3'},{'\xc6','\xa4'},{'\xc6','\xa5'},{'\xc6','\xa6'},{'\xc6','\xa7'},
+ {'\xc6','\xa8'},{'\xc6','\xa9'},{'\xc6','\xaa'},{'\xc6','\xab'},{'\xc6','\xac'},
+ {'\xc6','\xad'},{'\xc6','\xae'},{'\xc6','\xaf'},{'\xc6','\xb0'},{'\xc6','\xb1'},
+ {'\xc6','\xb2'},{'\xc6','\xb3'},{'\xc6','\xb4'},{'\xc6','\xb5'},{'\xc6','\xb6'},
+ {'\xc6','\xb7'},{'\xc6','\xb8'},{'\xc6','\xb9'},{'\xc6','\xba'},{'\xc6','\xbb'},
+ {'\xc6','\xbc'},{'\xc6','\xbd'},{'\xc6','\xbe'},{'\xc6','\xbf'},{'\xc6','\xc0'},
+ {'\xc6','\xc1'},{'\xc6','\xc2'},{'\xc6','\xc3'},{'\xc6','\xc4'},{'\xc6','\xc5'},
+ {'\xc6','\xc6'},{'\xc6','\xc7'},{'\xc6','\xc8'},{'\xc6','\xc9'},{'\xc6','\xca'},
+ {'\xc6','\xcb'},{'\xc6','\xcc'},{'\xc6','\xcd'},{'\xc6','\xce'},{'\xc6','\xcf'},
+ {'\xc6','\xd0'},{'\xc6','\xd1'},{'\xc6','\xd2'},{'\xc6','\xd3'},{'\xc6','\xd4'},
+ {'\xc6','\xd5'},{'\xc6','\xd6'},{'\xc6','\xd7'},{'\xc6','\xd8'},{'\xc6','\xd9'},
+ {'\xc6','\xda'},{'\xc6','\xdb'},{'\xc6','\xdc'},{'\xc6','\xdd'},{'\xc6','\xde'},
+ {'\xc6','\xdf'},{'\xc6','\xe0'},{'\xc6','\xe1'},{'\xc6','\xe2'},{'\xc6','\xe3'},
+ {'\xc6','\xe4'},{'\xc6','\xe5'},{'\xc6','\xe6'},{'\xc6','\xe7'},{'\xc6','\xe8'},
+ {'\xc6','\xe9'},{'\xc6','\xea'},{'\xc6','\xeb'},{'\xc6','\xec'},{'\xc6','\xed'},
+ {'\xc6','\xee'},{'\xc6','\xef'},{'\xc6','\xf0'},{'\xc6','\xf1'},{'\xc6','\xf2'},
+ {'\xc6','\xf3'},{'\xc6','\xf4'},{'\xc6','\xf5'},{'\xc6','\xf6'},{'\xc6','\xf7'},
+ {'\xc6','\xf8'},{'\xc6','\xf9'},{'\xc6','\xfa'},{'\xc6','\xfb'},{'\xc6','\xfc'},
+ {'\xc6','\xfd'},{'\xc6','\xfe'},{'\xc7','\x40'},{'\xc7','\x41'},{'\xc7','\x42'},
+ {'\xc7','\x43'},{'\xc7','\x44'},{'\xc7','\x45'},{'\xc7','\x46'},{'\xc7','\x47'},
+ {'\xc7','\x48'},{'\xc7','\x49'},{'\xc7','\x4a'},{'\xc7','\x4b'},{'\xc7','\x4c'},
+ {'\xc7','\x4d'},{'\xc7','\x4e'},{'\xc7','\x4f'},{'\xc7','\x50'},{'\xc7','\x51'},
+ {'\xc7','\x52'},{'\xc7','\x53'},{'\xc7','\x54'},{'\xc7','\x55'},{'\xc7','\x56'},
+ {'\xc7','\x57'},{'\xc7','\x58'},{'\xc7','\x59'},{'\xc7','\x5a'},{'\xc7','\x5b'},
+ {'\xc7','\x5c'},{'\xc7','\x5d'},{'\xc7','\x5e'},{'\xc7','\x5f'},{'\xc7','\x60'},
+ {'\xc7','\x61'},{'\xc7','\x62'},{'\xc7','\x63'},{'\xc7','\x64'},{'\xc7','\x65'},
+ {'\xc7','\x66'},{'\xc7','\x67'},{'\xc7','\x68'},{'\xc7','\x69'},{'\xc7','\x6a'},
+ {'\xc7','\x6b'},{'\xc7','\x6c'},{'\xc7','\x6d'},{'\xc7','\x6e'},{'\xc7','\x6f'},
+ {'\xc7','\x70'},{'\xc7','\x71'},{'\xc7','\x72'},{'\xc7','\x73'},{'\xc7','\x74'},
+ {'\xc7','\x75'},{'\xc7','\x76'},{'\xc7','\x77'},{'\xc7','\x78'},{'\xc7','\x79'},
+ {'\xc7','\x7a'},{'\xc7','\x7b'},{'\xc7','\x7c'},{'\xc7','\x7d'},{'\xc7','\x7e'},
+ {'\xc7','\xa1'},{'\xc7','\xa2'},{'\xc7','\xa3'},{'\xc7','\xa4'},{'\xc7','\xa5'},
+ {'\xc7','\xa6'},{'\xc7','\xa7'},{'\xc7','\xa8'},{'\xc7','\xa9'},{'\xc7','\xaa'},
+ {'\xc7','\xab'},{'\xc7','\xac'},{'\xc7','\xad'},{'\xc7','\xae'},{'\xc7','\xaf'},
+ {'\xc7','\xb0'},{'\xc7','\xb1'},{'\xc7','\xb2'},{'\xc7','\xb3'},{'\xc7','\xb4'},
+ {'\xc7','\xb5'},{'\xc7','\xb6'},{'\xc7','\xb7'},{'\xc7','\xb8'},{'\xc7','\xb9'},
+ {'\xc7','\xba'},{'\xc7','\xbb'},{'\xc7','\xbc'},{'\xc7','\xbd'},{'\xc7','\xbe'},
+ {'\xc7','\xbf'},{'\xc7','\xc0'},{'\xc7','\xc1'},{'\xc7','\xc2'},{'\xc7','\xc3'},
+ {'\xc7','\xc4'},{'\xc7','\xc5'},{'\xc7','\xc6'},{'\xc7','\xc7'},{'\xc7','\xc8'},
+ {'\xc7','\xc9'},{'\xc7','\xca'},{'\xc7','\xcb'},{'\xc7','\xcc'},{'\xc7','\xcd'},
+ {'\xc7','\xce'},{'\xc7','\xcf'},{'\xc7','\xd0'},{'\xc7','\xd1'},{'\xc7','\xd2'},
+ {'\xc7','\xd3'},{'\xc7','\xd4'},{'\xc7','\xd5'},{'\xc7','\xd6'},{'\xc7','\xd7'},
+ {'\xc7','\xd8'},{'\xc7','\xd9'},{'\xc7','\xda'},{'\xc7','\xdb'},{'\xc7','\xdc'},
+ {'\xc7','\xdd'},{'\xc7','\xde'},{'\xc7','\xdf'},{'\xc7','\xe0'},{'\xc7','\xe1'},
+ {'\xc7','\xe2'},{'\xc7','\xe3'},{'\xc7','\xe4'},{'\xc7','\xe5'},{'\xc7','\xe6'},
+ {'\xc7','\xe7'},{'\xc7','\xe8'},{'\xc7','\xe9'},{'\xc7','\xea'},{'\xc7','\xeb'},
+ {'\xc7','\xec'},{'\xc7','\xed'},{'\xc7','\xee'},{'\xc7','\xef'},{'\xc7','\xf0'},
+ {'\xc7','\xf1'},{'\xc7','\xf2'},{'\xc7','\xf3'},{'\xc7','\xf4'},{'\xc7','\xf5'},
+ {'\xc7','\xf6'},{'\xc7','\xf7'},{'\xc7','\xf8'},{'\xc7','\xf9'},{'\xc7','\xfa'},
+ {'\xc7','\xfb'},{'\xc7','\xfc'},{'\xc7','\xfd'},{'\xc7','\xfe'},{'\xc8','\x40'},
+ {'\xc8','\x41'},{'\xc8','\x42'},{'\xc8','\x43'},{'\xc8','\x44'},{'\xc8','\x45'},
+ {'\xc8','\x46'},{'\xc8','\x47'},{'\xc8','\x48'},{'\xc8','\x49'},{'\xc8','\x4a'},
+ {'\xc8','\x4b'},{'\xc8','\x4c'},{'\xc8','\x4d'},{'\xc8','\x4e'},{'\xc8','\x4f'},
+ {'\xc8','\x50'},{'\xc8','\x51'},{'\xc8','\x52'},{'\xc8','\x53'},{'\xc8','\x54'},
+ {'\xc8','\x55'},{'\xc8','\x56'},{'\xc8','\x57'},{'\xc8','\x58'},{'\xc8','\x59'},
+ {'\xc8','\x5a'},{'\xc8','\x5b'},{'\xc8','\x5c'},{'\xc8','\x5d'},{'\xc8','\x5e'},
+ {'\xc8','\x5f'},{'\xc8','\x60'},{'\xc8','\x61'},{'\xc8','\x62'},{'\xc8','\x63'},
+ {'\xc8','\x64'},{'\xc8','\x65'},{'\xc8','\x66'},{'\xc8','\x67'},{'\xc8','\x68'},
+ {'\xc8','\x69'},{'\xc8','\x6a'},{'\xc8','\x6b'},{'\xc8','\x6c'},{'\xc8','\x6d'},
+ {'\xc8','\x6e'},{'\xc8','\x6f'},{'\xc8','\x70'},{'\xc8','\x71'},{'\xc8','\x72'},
+ {'\xc8','\x73'},{'\xc8','\x74'},{'\xc8','\x75'},{'\xc8','\x76'},{'\xc8','\x77'},
+ {'\xc8','\x78'},{'\xc8','\x79'},{'\xc8','\x7a'},{'\xc8','\x7b'},{'\xc8','\x7c'},
+ {'\xc8','\x7d'},{'\xc8','\x7e'},{'\xc8','\xa1'},{'\xc8','\xa2'},{'\xc8','\xa3'},
+ {'\xc8','\xa4'},{'\xc8','\xa5'},{'\xc8','\xa6'},{'\xc8','\xa7'},{'\xc8','\xa8'},
+ {'\xc8','\xa9'},{'\xc8','\xaa'},{'\xc8','\xab'},{'\xc8','\xac'},{'\xc8','\xad'},
+ {'\xc8','\xae'},{'\xc8','\xaf'},{'\xc8','\xb0'},{'\xc8','\xb1'},{'\xc8','\xb2'},
+ {'\xc8','\xb3'},{'\xc8','\xb4'},{'\xc8','\xb5'},{'\xc8','\xb6'},{'\xc8','\xb7'},
+ {'\xc8','\xb8'},{'\xc8','\xb9'},{'\xc8','\xba'},{'\xc8','\xbb'},{'\xc8','\xbc'},
+ {'\xc8','\xbd'},{'\xc8','\xbe'},{'\xc8','\xbf'},{'\xc8','\xc0'},{'\xc8','\xc1'},
+ {'\xc8','\xc2'},{'\xc8','\xc3'},{'\xc8','\xc4'},{'\xc8','\xc5'},{'\xc8','\xc6'},
+ {'\xc8','\xc7'},{'\xc8','\xc8'},{'\xc8','\xc9'},{'\xc8','\xca'},{'\xc8','\xcb'},
+ {'\xc8','\xcc'},{'\xc8','\xcd'},{'\xc8','\xce'},{'\xc8','\xcf'},{'\xc8','\xd0'},
+ {'\xc8','\xd1'},{'\xc8','\xd2'},{'\xc8','\xd3'},{'\xc8','\xd4'},{'\xc8','\xd5'},
+ {'\xc8','\xd6'},{'\xc8','\xd7'},{'\xc8','\xd8'},{'\xc8','\xd9'},{'\xc8','\xda'},
+ {'\xc8','\xdb'},{'\xc8','\xdc'},{'\xc8','\xdd'},{'\xc8','\xde'},{'\xc8','\xdf'},
+ {'\xc8','\xe0'},{'\xc8','\xe1'},{'\xc8','\xe2'},{'\xc8','\xe3'},{'\xc8','\xe4'},
+ {'\xc8','\xe5'},{'\xc8','\xe6'},{'\xc8','\xe7'},{'\xc8','\xe8'},{'\xc8','\xe9'},
+ {'\xc8','\xea'},{'\xc8','\xeb'},{'\xc8','\xec'},{'\xc8','\xed'},{'\xc8','\xee'},
+ {'\xc8','\xef'},{'\xc8','\xf0'},{'\xc8','\xf1'},{'\xc8','\xf2'},{'\xc8','\xf3'},
+ {'\xc8','\xf4'},{'\xc8','\xf5'},{'\xc8','\xf6'},{'\xc8','\xf7'},{'\xc8','\xf8'},
+ {'\xc8','\xf9'},{'\xc8','\xfa'},{'\xc8','\xfb'},{'\xc8','\xfc'},{'\xc8','\xfd'},
+ {'\xc8','\xfe'},{'\xa3','\xe2'},{'\xa3','\xe3'},{'\xa3','\xe4'},{'\xa3','\xe5'},
+ {'\xa3','\xe6'},{'\xa3','\xe7'},{'\xa3','\xe8'},{'\xa3','\xe9'},{'\xa3','\xea'},
+ {'\xa3','\xeb'},{'\xa3','\xec'},{'\xa3','\xed'},{'\xa3','\xee'},{'\xa3','\xef'},
+ {'\xa3','\xf0'},{'\xa3','\xf1'},{'\xa3','\xf2'},{'\xa3','\xf3'},{'\xa3','\xf4'},
+ {'\xa3','\xf5'},{'\xa3','\xf6'},{'\xa3','\xf7'},{'\xa3','\xf8'},{'\xa3','\xf9'},
+ {'\xa3','\xfa'},{'\xa3','\xfb'},{'\xa3','\xfc'},{'\xa3','\xfd'},{'\xa3','\xfe'},
+ {'\xc6','\xde'},{'\xc6','\xdf'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\xff'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xb0','\x5a'},
+ {'\xa7','\xf3'},{'\xa8','\xae'},{'\xb8','\xeb'},{'\xb7','\xc6'},{'\xa6','\xea'},
+ {'\xa5','\x79'},{'\xc0','\x74'},{'\xc0','\x74'},{'\xab','\xb4'},{'\xaa','\xf7'},
+ {'\xb3','\xe2'},{'\xa9','\x60'},{'\xc3','\x69'},{'\xc4','\xee'},{'\xc3','\xb9'},
+ {'\xc5','\xda'},{'\xc1','\xb3'},{'\xbb','\x72'},{'\xc5','\xde'},{'\xbc','\xd6'},
+ {'\xac','\xa5'},{'\xaf','\x4f'},{'\xaf','\x5f'},{'\xb8','\xa8'},{'\xb9','\x54'},
+ {'\xc0','\x64'},{'\xb6','\xc3'},{'\xa7','\x5a'},{'\xc4','\xe6'},{'\xc4','\xea'},
+ {'\xc4','\xf5'},{'\xc6','\x7d'},{'\xb4','\x50'},{'\xc0','\xdd'},{'\xc2','\xc5'},
+ {'\xc4','\xb0'},{'\xa9','\xd4'},{'\xc3','\xbe'},{'\xc4','\xfa'},{'\xb4','\x59'},
+ {'\xae','\xd4'},{'\xae','\xf6'},{'\xaf','\x54'},{'\xad','\xa6'},{'\xa8','\xd3'},
+ {'\xa7','\x4e'},{'\xb3','\xd2'},{'\xbe','\xdb'},{'\xc3','\x72'},{'\xc4','\x6c'},
+ {'\xbf','\x63'},{'\xa6','\xd1'},{'\xc4','\xaa'},{'\xb8','\xb8'},{'\xb8','\xf4'},
+ {'\xc5','\x53'},{'\xbe','\x7c'},{'\xc6','\x4f'},{'\xb8','\x4c'},{'\xb8','\x53'},
+ {'\xba','\xf1'},{'\xdb','\x77'},{'\xbf','\xfd'},{'\xb3','\xc0'},{'\xbd','\xd7'},
+ {'\xc3','\x62'},{'\xa7','\xcb'},{'\xc5','\xa2'},{'\xc5','\xa4'},{'\xa8','\x63'},
+ {'\xbd','\x55'},{'\xb8','\xef'},{'\xb9','\x70'},{'\xc2','\x53'},{'\xb9','\xf0'},
+ {'\xbc','\xd3'},{'\xb2','\x5c'},{'\xba','\x7c'},{'\xb2','\xd6'},{'\xc1','\x5c'},
+ {'\xad','\xae'},{'\xb0','\xc7'},{'\xa6','\xd8'},{'\xbb','\xfe'},{'\xad','\xe2'},
+ {'\xb8','\x57'},{'\xba','\xf0'},{'\xb5','\xd9'},{'\xb3','\xae'},{'\xc5','\xaa'},
+ {'\xce','\xd4'},{'\xbc','\xd6'},{'\xbf','\xd5'},{'\xa4','\xa6'},{'\xb9','\xe7'},
+ {'\xab','\xe3'},{'\xb2','\x76'},{'\xb2','\xa7'},{'\xa5','\x5f'},{'\xed','\xa8'},
+ {'\xab','\x4b'},{'\xb4','\x5f'},{'\xa4','\xa3'},{'\xaa','\x63'},{'\xbc','\xc6'},
+ {'\xaf','\xc1'},{'\xb0','\xd1'},{'\xb6','\xeb'},{'\xac','\xd9'},{'\xb8','\xad'},
+ {'\xbb','\xa1'},{'\xb1','\xfe'},{'\xa8','\xb0'},{'\xa8','\x48'},{'\xac','\x42'},
+ {'\xad','\x59'},{'\xb1','\xb0'},{'\xb2','\xa4'},{'\xab','\x47'},{'\xa8','\xe2'},
+ {'\x84','\x5b'},{'\xb1','\xe7'},{'\xc2','\xb3'},{'\xa8','\x7d'},{'\xbd','\xcc'},
+ {'\xb6','\x71'},{'\xc0','\x79'},{'\xa7','\x66'},{'\xa4','\x6b'},{'\xc3','\x66'},
+ {'\xae','\xc8'},{'\xc2','\x6f'},{'\xc4','\x72'},{'\xbe','\x5b'},{'\xc6','\x7a'},
+ {'\xc4','\x52'},{'\xbe','\xa4'},{'\xa4','\x4f'},{'\xbe','\xe4'},{'\xbe','\xfa'},
+ {'\xf7','\x65'},{'\xa6','\x7e'},{'\xbc','\xa6'},{'\xc5','\xca'},{'\xbc','\xbf'},
+ {'\xba','\xa7'},{'\xb7','\xd2'},{'\xe6','\xa3'},{'\x9d','\xce'},{'\xbd','\x6d'},
+ {'\xc1','\x70'},{'\xbd','\xfb'},{'\xbd','\xac'},{'\xb3','\x73'},{'\xc1','\xe5'},
+ {'\xa6','\x43'},{'\xa6','\x48'},{'\xab','\x7c'},{'\xaf','\x50'},{'\xb5','\xf5'},
+ {'\xbb','\xa1'},{'\xb7','\x47'},{'\xa9','\xc0'},{'\xb1','\xc9'},{'\xc0','\xd4'},
+ {'\xc3','\xae'},{'\xc2','\x79'},{'\xa5','\x4f'},{'\xcb','\xf1'},{'\xb9','\xe7'},
+ {'\xc0','\xad'},{'\xcc','\xb0'},{'\xac','\xc2'},{'\xbc','\xfc'},{'\xb2','\xdc'},
+ {'\xb2','\xe2'},{'\xb9','\x61'},{'\xb9','\x73'},{'\xc6','\x46'},{'\xbb','\xe2'},
+ {'\xa8','\xd2'},{'\xc2','\xa7'},{'\xc4','\xbf'},{'\xc1','\xf5'},{'\xb4','\x63'},
+ {'\xa4','\x46'},{'\xb9','\xb1'},{'\xbc','\x64'},{'\xa7','\xbf'},{'\xae','\xc6'},
+ {'\xbc','\xd6'},{'\xbf','\x52'},{'\xc0','\xf8'},{'\xe7','\x64'},{'\xbf','\xf1'},
+ {'\xc0','\x73'},{'\xb7','\x77'},{'\xa8','\xbf'},{'\xbc','\x42'},{'\xcc','\xd8'},
+ {'\xac','\x68'},{'\xac','\x79'},{'\xb7','\xc8'},{'\xaf','\x5b'},{'\xaf','\x64'},
+ {'\xb2','\xb8'},{'\xaf','\xc3'},{'\xc3','\xfe'},{'\xa4','\xbb'},{'\xbc','\xae'},
+ {'\xb3','\xb0'},{'\xad','\xdb'},{'\xb1','\x5b'},{'\xb2','\x5f'},{'\xbd','\xfc'},
+ {'\xab','\xdf'},{'\xb7','\x58'},{'\xae','\xdf'},{'\xb2','\x76'},{'\xb6','\xa9'},
+ {'\xa7','\x51'},{'\xa6','\x4f'},{'\xbc','\x69'},{'\xa9','\xf6'},{'\xa7','\xf5'},
+ {'\xb1','\xf9'},{'\xaa','\x64'},{'\xb2','\x7a'},{'\xb5','\x67'},{'\xbf','\xa9'},
+ {'\xf9','\xd8'},{'\xb8','\xcc'},{'\xa8','\xbd'},{'\xc2','\xf7'},{'\xb0','\xce'},
+ {'\xb7','\xc4'},{'\xa7','\x5b'},{'\xbf','\x4d'},{'\xbf','\x5a'},{'\xc4','\xa9'},
+ {'\x95','\xf9'},{'\xc5','\xec'},{'\xc5','\xef'},{'\xaa','\x4c'},{'\xb2','\x4f'},
+ {'\xc1','\x7b'},{'\xa5','\xdf'},{'\xb2','\xc1'},{'\xb2','\xc9'},{'\xaa','\xac'},
+ {'\xaa','\xa5'},{'\xc3','\xd1'},{'\xa4','\xb0'},{'\xaf','\xf9'},{'\xa8','\xeb'},
+ {'\xa4','\xc1'},{'\xab','\xd7'},{'\xa9','\xdd'},{'\xbf','\x7d'},{'\xa6','\x76'},
+ {'\xac','\x7d'},{'\xbc','\xc9'},{'\xbf','\xe7'},{'\xa6','\xe6'},{'\xad','\xb0'},
+ {'\xa8','\xa3'},{'\xb9','\xf8'},{'\xc9','\x4a'},{'\xdd','\xfc'},{'\x98','\x77'},
+ {'\x98','\x78'},{'\xb6','\xef'},{'\x98','\x79'},{'\xb4','\xb8'},{'\x98','\x7a'},
+ {'\x98','\x7b'},{'\xe8','\xf9'},{'\x95','\xbd'},{'\xaf','\x71'},{'\x98','\x7c'},
+ {'\xaf','\xab'},{'\xb2','\xbb'},{'\xba','\xd6'},{'\xb9','\x74'},{'\xba','\xeb'},
+ {'\xa6','\xd0'},{'\x98','\x7d'},{'\x98','\x7e'},{'\x98','\xa1'},{'\xbd','\xd1'},
+ {'\x98','\xa2'},{'\x98','\xa3'},{'\xb6','\x68'},{'\xb3','\xa3'},{'\x98','\xa4'},
+ {'\x98','\xa5'},{'\x98','\xa6'},{'\xb6','\xba'},{'\xb9','\x7d'},{'\xc0','\x5d'},
+ {'\xc5','\x62'},{'\x00','\x00'},{'\x00','\x00'},{'\xab','\x56'},{'\xb9','\xac'},
+ {'\xa7','\x4b'},{'\xab','\x6a'},{'\xb6','\xd4'},{'\xa8','\xf5'},{'\xb3','\xdc'},
+ {'\xb9','\xc4'},{'\xbe','\xb9'},{'\x94','\x59'},{'\xbe','\xa5'},{'\xbc','\x68'},
+ {'\xc9','\x4b'},{'\xae','\xac'},{'\xb4','\x6e'},{'\xbc','\xa8'},{'\xc3','\x67'},
+ {'\xb1','\xd3'},{'\xac','\x4a'},{'\xb4','\xbb'},{'\xb1','\xf6'},{'\xae','\xfc'},
+ {'\xb2','\x5a'},{'\xba','\x7e'},{'\xb5','\x4e'},{'\x9c','\x70'},{'\xb5','\x5a'},
+ {'\xb8','\x4f'},{'\xaa','\xc0'},{'\xac','\xe7'},{'\xac','\xe8'},{'\xaf','\xa7'},
+ {'\xaf','\xaa'},{'\xaf','\xac'},{'\xba','\xd7'},{'\xba','\xd5'},{'\xbd','\x5c'},
+ {'\xac','\xf0'},{'\xb8','\x60'},{'\xbd','\x6d'},{'\xbf','\xa7'},{'\xc1','\x63'},
+ {'\xb8','\x70'},{'\xaa','\xcc'},{'\xaf','\xe4'},{'\x9c','\xd2'},{'\x9c','\xd2'},
+ {'\xb5','\xdb'},{'\xbd','\xc5'},{'\xb5','\xf8'},{'\xbf','\xd6'},{'\xc2','\xd4'},
+ {'\xbb','\xab'},{'\xc3','\xd8'},{'\x9c','\xe0'},{'\xb6','\x68'},{'\xc3','\xf8'},
+ {'\xc5','\x54'},{'\xc0','\x57'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa1','\x4a'},{'\xa1','\x57'},{'\x00','\x00'},
+ {'\xa1','\x59'},{'\xa1','\x5b'},{'\xa1','\x5f'},{'\xa1','\x60'},{'\xa1','\x63'},
+ {'\xa1','\x64'},{'\xa1','\x67'},{'\xa1','\x68'},{'\xa1','\x6b'},{'\xa1','\x6c'},
+ {'\xa1','\x6f'},{'\xa1','\x70'},{'\xa1','\x73'},{'\xa1','\x74'},{'\xa1','\x77'},
+ {'\xa1','\x78'},{'\xa1','\x7b'},{'\xa1','\x7c'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa1','\xc6'},{'\xa1','\xc7'},{'\xa1','\xca'},
+ {'\xa1','\xcb'},{'\xa1','\xc8'},{'\xa1','\xc9'},{'\xa1','\x5c'},{'\xa1','\x4d'},
+ {'\xa1','\x4e'},{'\xa1','\x4f'},{'\x00','\x00'},{'\xa1','\x51'},{'\xa1','\x52'},
+ {'\xa1','\x53'},{'\xa1','\x54'},{'\x00','\x00'},{'\xa1','\x7d'},{'\xa1','\x7e'},
+ {'\xa1','\xa1'},{'\xa1','\xa2'},{'\xa1','\xa3'},{'\xa1','\xa4'},{'\xa1','\xcc'},
+ {'\xa1','\xcd'},{'\xa1','\xce'},{'\xa1','\xde'},{'\xa1','\xdf'},{'\xa1','\xe0'},
+ {'\xa1','\xe1'},{'\xa1','\xe2'},{'\x00','\x00'},{'\xa2','\x42'},{'\xa2','\x4c'},
+ {'\xa2','\x4d'},{'\xa2','\x4e'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa1','\x49'},{'\xc8','\xd0'},{'\xa1','\xad'},{'\xa2','\x43'},
+ {'\xa2','\x48'},{'\xa1','\xae'},{'\x91','\xc2'},{'\xa1','\x5d'},{'\xa1','\x5e'},
+ {'\xa1','\xaf'},{'\xa1','\xcf'},{'\xa1','\x41'},{'\xa1','\xd0'},{'\xa1','\x44'},
+ {'\xa1','\xfe'},{'\xa2','\xaf'},{'\xa2','\xb0'},{'\xa2','\xb1'},{'\xa2','\xb2'},
+ {'\xa2','\xb3'},{'\xa2','\xb4'},{'\xa2','\xb5'},{'\xa2','\xb6'},{'\xa2','\xb7'},
+ {'\xa2','\xb8'},{'\xa1','\x47'},{'\xa1','\x46'},{'\xa1','\xd5'},{'\xa1','\xd7'},
+ {'\xa1','\xd6'},{'\xa1','\x48'},{'\xa2','\x49'},{'\xa2','\xcf'},{'\xa2','\xd0'},
+ {'\xa2','\xd1'},{'\xa2','\xd2'},{'\xa2','\xd3'},{'\xa2','\xd4'},{'\xa2','\xd5'},
+ {'\xa2','\xd6'},{'\xa2','\xd7'},{'\xa2','\xd8'},{'\xa2','\xd9'},{'\xa2','\xda'},
+ {'\xa2','\xdb'},{'\xa2','\xdc'},{'\xa2','\xdd'},{'\xa2','\xde'},{'\xa2','\xdf'},
+ {'\xa2','\xe0'},{'\xa2','\xe1'},{'\xa2','\xe2'},{'\xa2','\xe3'},{'\xa2','\xe4'},
+ {'\xa2','\xe5'},{'\xa2','\xe6'},{'\xa2','\xe7'},{'\xa2','\xe8'},{'\xc6','\xe4'},
+ {'\xa2','\x40'},{'\xc6','\xe5'},{'\x5e','\x20'},{'\xa1','\xc4'},{'\xa1','\xab'},
+ {'\xa2','\xe9'},{'\xa2','\xea'},{'\xa2','\xeb'},{'\xa2','\xec'},{'\xa2','\xed'},
+ {'\xa2','\xee'},{'\xa2','\xef'},{'\xa2','\xf0'},{'\xa2','\xf1'},{'\xa2','\xf2'},
+ {'\xa2','\xf3'},{'\xa2','\xf4'},{'\xa2','\xf5'},{'\xa2','\xf6'},{'\xa2','\xf7'},
+ {'\xa2','\xf8'},{'\xa2','\xf9'},{'\xa2','\xfa'},{'\xa2','\xfb'},{'\xa2','\xfc'},
+ {'\xa2','\xfd'},{'\xa2','\xfe'},{'\xa3','\x40'},{'\xa3','\x41'},{'\xa3','\x42'},
+ {'\xa3','\x43'},{'\xa1','\x61'},{'\xa1','\x55'},{'\xa1','\x62'},{'\xa1','\xe3'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc8','\xb9'},{'\xc8','\xba'},{'\xc8','\xbb'},
+ {'\xc8','\xbc'},{'\xc8','\xbd'},{'\xc8','\xbe'},{'\xc8','\xbf'},{'\xc8','\xc0'},
+ {'\xc8','\xc1'},{'\xc8','\xc2'},{'\xc8','\xc3'},{'\xc8','\xc4'},{'\xc8','\xc5'},
+ {'\xc8','\xc6'},{'\xc8','\xc7'},{'\xc8','\xc8'},{'\xc8','\xc9'},{'\xc8','\xca'},
+ {'\xc8','\xcb'},{'\xc8','\xcc'},{'\xc8','\xd4'},{'\xc8','\xd5'},{'\xc8','\xd6'},
+ {'\xc8','\xd7'},{'\xc8','\xd8'},{'\xc8','\xd9'},{'\xc8','\xda'},{'\xc8','\xdb'},
+ {'\xc8','\xdc'},{'\xc8','\xdd'},{'\xc8','\xde'},{'\xc8','\xdf'},{'\xc8','\xe0'},
+ {'\xc8','\xe1'},{'\xc8','\xe2'},{'\xc8','\xe3'},{'\xc8','\xe4'},{'\xc8','\xe5'},
+ {'\xc8','\xe6'},{'\xc8','\xe7'},{'\xc8','\xe8'},{'\xc8','\xe9'},{'\xc8','\xea'},
+ {'\xc8','\xeb'},{'\xc8','\xec'},{'\xc8','\xed'},{'\xc8','\xee'},{'\xc8','\xef'},
+ {'\xc8','\xf0'},{'\xc8','\xf1'},{'\xc8','\xf2'},{'\xc8','\xf3'},{'\xc8','\xf4'},
+ {'\xc8','\xf5'},{'\xc8','\xf6'},{'\xc8','\xf7'},{'\xc8','\xf8'},{'\xc8','\xf9'},
+ {'\xc8','\xfa'},{'\xc8','\xfb'},{'\xc8','\xfc'},{'\xc8','\xfd'},{'\xc8','\xfe'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa2','\x46'},
+ {'\xa2','\x47'},{'\xc8','\xcd'},{'\xa1','\xc3'},{'\xc8','\xce'},{'\xa2','\x44'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa2','\x78'},{'\xa1','\xf6'},{'\xa1','\xf4'},
+ {'\xa1','\xf7'},{'\xa1','\xf5'},{'\xa1','\xbd'},{'\xa1','\xb3'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'}
+};
+
+static int qt_Big5ToUnicode(const uchar *s, uint *pwc)
+{
+ uchar c1 = s[0];
+ int idx;
+ ushort wc = 0xfffd;
+
+ if ((c1 >= 0x81 && c1 <= 0xfe)) {
+ uchar c2 = s[1];
+
+ if (c2 < 0x40 || c2 > 0xfe
+ || (idx = ((c1 - 0x81) * 191) + (c2 - 0x40),
+ (wc = big5_to_ucs[idx]) == 0))
+ return 0;
+ else {
+ *pwc = (uint) wc;
+ return 2;
+ }
+
+ } else if (c1 < 0x80) {
+ *pwc = (uint) c1;
+ return 1;
+ }
+ return 0;
+}
+
+static int qt_UnicodeToBig5(uint wc, uchar *r)
+{
+ const Summary16 *summary = NULL;
+ const uchar * c;
+ if (wc < 0x80) {
+ r[0] = (uchar) wc;
+ return 1;
+ }
+ else {
+ if (wc >= 0 && wc <= 65535){
+ c = ucs_to_big5[wc];
+ if (c [0] == '\0')
+ return 0;
+ if (c [1] != 0) {
+ r[0] = c[0];
+ r[1] = c[1];
+ return 2;
+ } else { // (c [1] == 0)
+ r[0] = c[0];
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+QString UAOCodec::convertToUnicode(const char* chars, int len, ConverterState *state) const
+{
+ QChar replacement = QChar::ReplacementCharacter;
+ uchar buf[2] = {0};
+ int nbuf = 0;
+ if (state) {
+ if (state->flags & ConvertInvalidToNull)
+ replacement = QChar::Null;
+ nbuf = state->remainingChars;
+ buf[0] = state->state_data[0];
+ buf[1] = state->state_data[1];
+ }
+ int invalid = 0;
+
+ //qDebug("UAOCodec::toUnicode(const char* chars = \"%s\", int len = %d)", chars, len);
+ QString result;
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ switch (nbuf) {
+ case 0:
+ if (IsLatin(ch)) {
+ // ASCII
+ result += QLatin1Char(ch);
+ } else if (IsFirstByte(ch)) {
+ // Big5-ETen
+ buf[0] = ch;
+ nbuf = 1;
+ } else {
+ // Invalid
+ result += replacement;
+ ++invalid;
+ }
+ break;
+ case 1:
+ if (IsSecondByte(ch)) {
+ // Big5-ETen
+ uint u;
+ buf[1] = ch;
+ if (qt_Big5ToUnicode(buf, &u) == 2)
+ result += QValidChar(u);
+ else {
+ // Error
+ result += replacement;
+ ++invalid;
+ }
+ } else {
+ // Error
+ result += replacement;
+ ++invalid;
+ }
+ nbuf = 0;
+ break;
+ }
+ }
+ if (state) {
+ state->remainingChars = nbuf;
+ state->state_data[0] = buf[0];
+ state->state_data[1] = buf[1];
+ state->invalidChars += invalid;
+ }
+ return result;
+}
+
+QByteArray UAOCodec::convertFromUnicode(const QChar *uc, int len, ConverterState *state) const
+{
+ char replacement = '?';
+ if (state) {
+ if (state->flags & ConvertInvalidToNull)
+ replacement = 0;
+ }
+
+ int invalid = 0;
+
+ int rlen = 2*len + 1;
+ QByteArray rstr;
+ rstr.resize(rlen);
+
+ uchar* cursor = (uchar*)rstr.data();
+ for (int i=0; i<len; i++) {
+ ushort ch = uc[i].unicode();
+ uchar c[2];
+ if (ch < 0x80) {
+ // ASCII
+ *cursor++ = ch;
+ } else if (qt_UnicodeToBig5(ch, c) == 2 && c[0] >= 0xa1 && c[0] <= 0xf9) {
+ *cursor++ = c[0];
+ *cursor++ = c[1];
+ } else {
+ *cursor++ = replacement;
+ ++invalid;
+ }
+ }
+ rstr.resize(cursor - (uchar*)rstr.constData());
+
+ if (state) {
+ state->invalidChars += invalid;
+ }
+ return rstr;
+}
+
+QList<QByteArray> UAOCodec::_aliases()
+{
+ QList<QByteArray> aliases;
+ aliases += "Unicode-at-on";
+ return aliases;
+}
+
+/* ====================================================================== */
+#endif // QT_NO_TEXTCODEC
+
+QT_END_NAMESPACE
diff --git a/src/fqterm/3rdparty/uaocodec.h b/src/fqterm/3rdparty/uaocodec.h
new file mode 100644
index 0000000..9984250
--- /dev/null
+++ b/src/fqterm/3rdparty/uaocodec.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Most of the code here was originally written by UAO project (http://uao.cpatch.org/)
+// Ported to Qt by hooey <hephooey@gmail.com> (from uao-051123-src.tar.gz)
+
+#ifndef UAOCODEC_H
+#define UAOCODEC_H
+
+#include <QtCore/qtextcodec.h>
+#include <QtCore/qlist.h>
+
+QT_BEGIN_NAMESPACE
+
+class UAOCodec : public QTextCodec {
+public:
+ static QByteArray _name();
+ static QList<QByteArray> _aliases();
+ static int _mibEnum();
+
+ QByteArray name() const { return _name(); }
+ QList<QByteArray> aliases() const { return _aliases(); }
+ int mibEnum() const { return _mibEnum(); }
+
+ QString convertToUnicode(const char *, int, ConverterState *) const;
+ QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const;
+};
+
+QT_END_NAMESPACE
+
+#endif // UAOCODEC_H
diff --git a/src/fqterm/CMakeLists.txt b/src/fqterm/CMakeLists.txt
new file mode 100644
index 0000000..a93cdaf
--- /dev/null
+++ b/src/fqterm/CMakeLists.txt
@@ -0,0 +1,83 @@
+set(fqterm_SRCS
+ fqterm_app.h
+ fqterm_autoupdate.h
+ fqterm_frame.h
+ fqterm_screen.h
+ fqterm_window.h
+ fqterm_wndmgr.h
+ fqterm_autoupdate.cpp
+ fqterm_app.cpp
+ fqterm_frame.cpp
+ fqterm_screen.cpp
+ fqterm_window.cpp
+ fqterm_wndmgr.cpp
+ fqterm_python.h
+ fqterm_python.cpp
+ fqterm_scriptengine.h
+ fqterm_scriptengine.cpp
+)
+
+
+IF(WIN32)
+ set(global_shortcut_impl_SRCS 3rdparty/qxtglobalshortcut_win.cpp)
+ELSE(WIN32)
+ IF(APPLE)
+ set(global_shortcut_impl_SRCS 3rdparty/qxtglobalshortcut_mac.cpp)
+ ELSE(APPLE)
+ set(global_shortcut_impl_SRCS 3rdparty/qxtglobalshortcut_x11.cpp)
+ ENDIF(APPLE)
+ENDIF(WIN32)
+
+
+
+set(3rdparty_SRCS
+ 3rdparty/dotnetstyle.cpp
+ 3rdparty/dotnetstyle.h
+ 3rdparty/qxtglobalshortcut.cpp
+ 3rdparty/qxtglobalshortcut.h
+ 3rdparty/qxtglobalshortcut_p.h
+ 3rdparty/qxtglobal.h
+ 3rdparty/uaocodec.h
+ 3rdparty/uaocodec.cpp
+ ${global_shortcut_impl_SRCS}
+)
+
+qt4_automoc(${fqterm_SRCS}
+ ${3rdparty_SRCS}
+)
+
+qt4_create_translation(fqterm_qm_file
+ ${fqterm_SRCS}
+ ${CMAKE_SOURCE_DIR}/res/dict/fqterm_zh_CN.ts
+)
+
+include_directories(
+ ${QT_INCLUDE_DIR}
+ ${QT_QTCORE_INCLUDE_DIR}
+ ${QT_QTGUI_INCLUDE_DIR}
+ ${QT_QTNETWORK_INCLUDE_DIR}
+ ${QT_QTSCRIPT_INCLUDE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../common
+ ${CMAKE_CURRENT_SOURCE_DIR}/../protocol
+ ${CMAKE_CURRENT_SOURCE_DIR}/../terminal
+ ${CMAKE_CURRENT_SOURCE_DIR}/../utilities
+ ${CMAKE_CURRENT_SOURCE_DIR}/../unite
+ ${CMAKE_CURRENT_SOURCE_DIR}/../ui
+ ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty
+ ${CMAKE_CURRENT_BINARY_DIR}/../ui
+ ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+add_library(fqterm_main
+ ${fqterm_SRCS}
+ ${3rdparty_SRCS}
+)
+
+add_dependencies(fqterm_main
+ fqterm_common
+ fqterm_terminal
+ fqterm_protocol
+ fqterm_ui
+ fqterm_utilities
+ fqterm_unite
+)
diff --git a/src/fqterm/fqterm.rc b/src/fqterm/fqterm.rc
new file mode 100644
index 0000000..88394ab
--- /dev/null
+++ b/src/fqterm/fqterm.rc
Binary files differ
diff --git a/src/fqterm/fqterm_app.cpp b/src/fqterm/fqterm_app.cpp
new file mode 100644
index 0000000..393355a
--- /dev/null
+++ b/src/fqterm/fqterm_app.cpp
@@ -0,0 +1,38 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_app.h"
+
+namespace FQTerm {
+
+FQTermApplication::FQTermApplication( int & argc, char ** argv ) : QApplication(argc, argv)
+{
+
+}
+
+void FQTermApplication::commitData( QSessionManager & manager )
+{
+ emit saveData();
+}
+
+
+} //namespace FQTerm
+
+#include "fqterm_app.moc" \ No newline at end of file
diff --git a/src/fqterm/fqterm_app.h b/src/fqterm/fqterm_app.h
new file mode 100644
index 0000000..ee0778a
--- /dev/null
+++ b/src/fqterm/fqterm_app.h
@@ -0,0 +1,41 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_APP
+#define FQTERM_APP
+#include <QApplication>
+#include <QObject>
+namespace FQTerm {
+
+class FQTermApplication : public QApplication {
+ Q_OBJECT;
+public:
+ FQTermApplication(int & argc, char ** argv);
+protected:
+ virtual void commitData(QSessionManager & manager);
+signals:
+ void saveData();
+protected slots:
+ void mainWindowDestroyed(QObject* obj) {quit();}
+};
+
+} //namespace FQTerm
+
+#endif \ No newline at end of file
diff --git a/src/fqterm/fqterm_autoupdate.cpp b/src/fqterm/fqterm_autoupdate.cpp
new file mode 100644
index 0000000..0f49c38
--- /dev/null
+++ b/src/fqterm/fqterm_autoupdate.cpp
@@ -0,0 +1,178 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_autoupdate.h"
+#include "fqterm_config.h"
+#include "fqterm_trace.h"
+#include "fqterm_param.h"
+
+#include <QDesktopServices>
+#include <QFile>
+#include <QHttp>
+#include <QMessageBox>
+#include <QString>
+#include <QUrl>
+
+namespace FQTerm {
+
+////////////////////////////////////////////////
+static int versionCompare(QString lhs, QString rhs) {
+ //0 -- lhs == rhs, -1 -- lhs > rhs, 1 -- lhs < rhs
+
+ int versionEnd = lhs.indexOf('-');
+ if (versionEnd != -1) {
+ lhs = lhs.mid(0, versionEnd);
+ }
+ versionEnd = rhs.indexOf('-');
+ if (versionEnd != -1) {
+ rhs = rhs.mid(0, versionEnd);
+ }
+ QStringList lhsList = lhs.split(".");
+ QStringList rhsList = rhs.split(".");
+ if (lhsList.size() != 3 || rhsList.size() != 3) {
+ return 0; //something is wrong
+ }
+ for (int i = 0; i < 3; ++i) {
+ if (lhsList[i].toInt() < rhsList[i].toInt()) {
+ return 1;
+ }
+ else if (lhsList[i].toInt() > rhsList[i].toInt()) {
+ return -1;
+ }
+ }
+ return 0;
+}
+///////////////////////////////////////////////
+
+void FQTermAutoUpdater::checkUpdate() {
+ QString fileName = FQTermPref::getInstance()->poolDir_ + "VersionInfo";
+ if (QFile::exists(fileName)) {
+ QFile::remove(fileName);
+ }
+ versionInfoFile_ = new QFile(fileName, this);
+ if (!versionInfoFile_->open(QIODevice::WriteOnly)) {
+ delete versionInfoFile_;
+ return;
+ }
+ FQ_VERIFY(connect(updateChecker_, SIGNAL(requestFinished(int, bool)),
+ this, SLOT(checkRequestFinished(int, bool))));
+ FQ_VERIFY(connect(updateChecker_, SIGNAL(done(bool)),
+ this, SLOT(httpDone(bool))));
+
+ const QString versionInfoURL = "http://fqterm.googlecode.com/svn/trunk/VersionInfo";
+ QUrl url(versionInfoURL);
+ QHttp::ConnectionMode mode = url.scheme().toLower() == "https" ? QHttp::ConnectionModeHttps : QHttp::ConnectionModeHttp;
+ updateChecker_->setHost(url.host(), mode, url.port() == -1 ? 0 : url.port());
+ if (!url.userName().isEmpty())
+ updateChecker_->setUser(url.userName(), url.password());
+ checkRequestId_ = updateChecker_->get(url.path(), versionInfoFile_);
+}
+
+QString FQTermAutoUpdater::getNewestVersion() {
+#if defined(WIN32)
+ const QString platform = "FQWin";
+#elif defined(__unix__) && !defined(__APPLE__)
+ const QString platform = "FQLinux";
+#else
+ const QString platform = "FQMac";
+#endif
+ FQTermConfig versionInfo(FQTermPref::getInstance()->poolDir_ + "VersionInfo");
+ QString ver = versionInfo.getItemValue(platform, "version");
+ if (ver.isEmpty()) {
+ return FQTERM_VERSION_STRING;
+ }
+ return ver;
+}
+
+void FQTermAutoUpdater::promptUpdate() {
+ const QString updateURL = "http://code.google.com/p/fqterm/downloads/list";
+ QMessageBox msgBox(QMessageBox::Information, tr("FQTerm Update Notifier"),
+ tr("FQTerm update available.\nPress OK to visit our download list,\nDiscard for a future prompt,\nIgnore for no more notification."),
+ QMessageBox::Ok | QMessageBox::Discard | QMessageBox::Ignore);
+ switch (msgBox.exec()) {
+ case QMessageBox::Ok:
+ QDesktopServices::openUrl(updateURL);
+ break;
+ case QMessageBox::Discard:
+ break;
+ case QMessageBox::Ignore:
+ config_->setItemValue("global", "newestversion", getNewestVersion());
+ config_->setItemValue("global", "updateprompt", "0");
+ break;
+ }
+}
+
+void FQTermAutoUpdater::checkRequestFinished(int requestId, bool error){
+
+ if (checkDone_ || requestId != checkRequestId_) {
+ return;
+ }
+ if (!error) {
+ checkDone_ = true;
+ }
+}
+
+void FQTermAutoUpdater::httpDone(bool err) {
+ if (!err) {
+ versionInfoFile_->flush();
+ if (checkDone_) {
+ QString newestVersionRecorded = config_->getItemValue("global", "newestversion");
+ if (newestVersionRecorded.isEmpty()) {
+ newestVersionRecorded = FQTERM_VERSION_STRING;
+ config_->setItemValue("global", "newestversion", newestVersionRecorded);
+ }
+ QString newestVersionReleased = getNewestVersion();
+
+ QString updatePrompt = config_->getItemValue("global", "updateprompt");
+ if (updatePrompt == "0") {
+ //if newest version > recorded version, still prompt.
+ if (versionCompare(newestVersionRecorded, newestVersionReleased) > 0) {
+ config_->setItemValue("global", "updateprompt", "1");
+ promptUpdate();
+ }
+ }
+ else {
+ config_->setItemValue("global", "updateprompt", "1");
+ //if newest version > version in use, prompt.
+ if (versionCompare(FQTERM_VERSION_STRING, newestVersionReleased) > 0) {
+ promptUpdate();
+ }
+ }
+ }
+ }
+ deleteLater();
+}
+
+FQTermAutoUpdater::FQTermAutoUpdater(QObject* parent, FQTermConfig* config)
+: QObject(parent),
+ config_(config),
+ versionInfoFile_(0),
+ checkDone_(false) {
+ updateChecker_ = new QHttp(this);
+}
+
+FQTermAutoUpdater::~FQTermAutoUpdater()
+{
+
+}
+
+} //FQTerm namespace
+
+#include "fqterm_autoupdate.moc"
diff --git a/src/fqterm/fqterm_autoupdate.h b/src/fqterm/fqterm_autoupdate.h
new file mode 100644
index 0000000..0ad8aaf
--- /dev/null
+++ b/src/fqterm/fqterm_autoupdate.h
@@ -0,0 +1,61 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_AUTO_UPDATE_H
+#define FQTERM_AUTO_UPDATE_H
+
+#include <QObject>
+
+class QHttp;
+class QFile;
+class QString;
+
+namespace FQTerm {
+
+class FQTermConfig;
+
+class FQTermAutoUpdater : public QObject{
+
+ Q_OBJECT;
+
+public:
+ FQTermAutoUpdater(QObject* parent, FQTermConfig* config);
+ ~FQTermAutoUpdater();
+
+ void checkUpdate();
+
+protected slots:
+ void checkRequestFinished(int requestId, bool error);
+ void httpDone(bool err);
+
+private:
+ QString getNewestVersion();
+ void promptUpdate();
+
+ FQTermConfig* config_;
+ QHttp * updateChecker_;
+ QFile * versionInfoFile_;
+ int checkRequestId_;
+ bool checkDone_;
+};
+
+} //namespace FQTerm
+
+#endif
diff --git a/src/fqterm/fqterm_frame.cpp b/src/fqterm/fqterm_frame.cpp
new file mode 100644
index 0000000..b50eff9
--- /dev/null
+++ b/src/fqterm/fqterm_frame.cpp
@@ -0,0 +1,2162 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#if !defined(WIN32)
+#include <unistd.h>
+#endif
+
+#if defined(__linux__) || defined(__GLIBC__)
+#include <QLocale>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <QDesktopServices>
+#include <QDir>
+#include <QFontComboBox>
+#include <QFontDialog>
+#include <QInputDialog>
+#include <QKeySequence>
+#include <QList>
+#include <QMdiArea>
+#include <QMdiSubWindow>
+#include <QMenuBar>
+#include <QMessageBox>
+#include <QSignalMapper>
+#include <QStatusBar>
+#include <QStyleFactory>
+#include <QTime>
+#include <QDate>
+#include <QSizePolicy>
+#include <QTimer>
+#include <QToolBar>
+#include <QTranslator>
+#include <QWindowStateChangeEvent>
+
+#include "aboutdialog.h"
+#include "addrdialog.h"
+#include "common.h"
+#include "keydialog.h"
+#include "prefdialog.h"
+#include "fqterm.h"
+
+#include "fqterm_path.h"
+#include "fqterm_autoupdate.h"
+#include "fqterm_config.h"
+#include "fqterm_frame.h"
+#include "fqterm_param.h"
+#include "fqterm_session.h"
+#include "fqterm_screen.h"
+#include "fqterm_time_label.h"
+#include "fqterm_tool_button.h"
+#include "fqterm_window.h"
+#include "fqterm_wndmgr.h"
+#include "imageviewer.h"
+#include "quickdialog.h"
+#include "statusBar.h"
+#include "sitemanager.h"
+#include "fqterm_shortcuthelper.h"
+#include "fqterm_mini_server.h"
+#include "shortcutdialog.h"
+#include "schemadialog.h"
+#include "fqterm_ip_location.h"
+#include "iplookup.h"
+#include "defineescape.h"
+#include "uaocodec.h"
+
+#ifdef USE_DOTNET_STYLE
+#include "dotnetstyle.h"
+#endif //USE_DOTNET_STYLE
+
+#ifdef USE_GLOBAL_HOTKEY
+#include "qxtglobalshortcut.h"
+#endif //USE_GLOBAL_HOTKEY
+
+#ifdef HAVE_PYTHON
+#include <Python.h>
+#include "fqterm_python.h"
+#endif //HAVE_PYTHON
+
+namespace FQTerm {
+
+
+const QString FQTermFrame::qmPrefix[FQTermFrame::translatedModule] =
+{"fqterm_", "ui_", "protocol_", "common_"};
+const QString FQTermFrame::qmPostfix = ".qm";
+
+//constructor
+FQTermFrame::FQTermFrame()
+ : QMainWindow(0),
+ tray_(0),
+ trayMenu_(0),
+#ifdef HAVE_PYTHON
+ pythonHelper_(0),
+#endif
+#ifdef USE_GLOBAL_HOTKEY
+ globalHotkey_(0),
+#endif //USE_GLOBAL_HOTKEY
+ shortcutHelper_(0)
+{
+ setAttribute(Qt::WA_DeleteOnClose);
+
+/*#ifndef __APPLE__
+ setWindowFlags(Qt::CustomizeWindowHint);
+#endif*/
+ uaoCodec_ = new UAOCodec;
+
+ config_ = new FQTermConfig(getPath(USER_CONFIG) + "fqterm.cfg");
+
+ initTranslator();
+ shortcutHelper_ = new FQTermShortcutHelper(config_, this);
+
+#ifdef IMAGE_USE_PICFLOW
+ imageViewer_ = new FQTermImageFlow(config_, NULL, Qt::Window);
+#else
+ imageViewer_ = new FQTermImageOrigin(config_, NULL, Qt::Window);
+#endif
+
+
+ //create the window manager to deal with the window-tab-icon pairs
+ windowManager_ = new FQTermWndMgr(this);
+ setCentralWidget(windowManager_);
+
+ //set menubar
+ addMainMenu();
+ FQ_VERIFY(connect(this, SIGNAL(changeLanguage()),
+ this, SLOT(recreateMenu())));
+
+ //initialize all settings
+ //This should be done before add main tool, since some status of tool will depend on setting
+ iniSetting();
+ FQTermConfig* conf = new FQTermConfig(getPath(USER_CONFIG) + "address.cfg");
+ checkHelpExists(conf);
+ delete conf;
+ //setup toolbar
+ addMainTool();
+
+ // add the custom defined key
+ // and load toolbar position
+ updateKeyToolBar();
+ loadToolBarPosition();
+ enableMenuToolBar(false);
+
+ // FIXME: !!!create a horizonal layout to hold the tabbar,the reason
+ //of why not put the tabbar directly on the status bar is when no
+ //tab in the tabbar,the statusbar display a horizonal line,ugly.
+ //perhaps there is some function in statusbar to solve this.
+ QWidget *hb = new QWidget(statusBar());
+ hb->setObjectName("taskbar");
+ QHBoxLayout *hbLayout = new QHBoxLayout(hb);
+ hbLayout->setMargin(0);
+ hbLayout->setObjectName("tasklayout");
+ statusBar()->addWidget(hb);
+ //create a tabbar in the hbox
+ hbLayout->addWidget(windowManager_->tabBar());
+
+ windowMapper_ = new QSignalMapper(this);
+ FQ_VERIFY(connect(windowMapper_, SIGNAL(mapped(int)),
+ windowManager_, SLOT(activateTheWindow(int))));
+ initAdditionalActions();
+
+ //create a progress bar to notify the download process
+ statusBar_ = new FQTerm::StatusBar(statusBar(), "mainStatusBar");
+ statusBar()->addWidget(statusBar_, 0);
+
+ installEventFilter(this);
+
+ QDate lastCheckDate = QDate::fromString(config_->getItemValue("global", "lastcheckupdate"));
+ QDate currentDate = QDate::currentDate();
+ if (!lastCheckDate.isValid() || lastCheckDate.daysTo(currentDate) >= 31) {
+ FQTermAutoUpdater* autoUpdater =
+ new FQTermAutoUpdater(this, config_);
+ autoUpdater->checkUpdate();
+ config_->setItemValue("global", "lastcheckupdate", currentDate.toString());
+ }
+
+ serverThread_ = new FQTermMiniServerThread();
+ if (FQTermPref::getInstance()->runServer_)
+ serverThread_->start();
+#ifdef HAVE_PYTHON
+ pythonHelper_ = new FQTermPythonHelper;
+#endif
+#ifdef USE_GLOBAL_HOTKEY
+ globalHotkey_ = new QxtGlobalShortcut(shortcutHelper_->getAction(FQTermShortcutHelper::GLOBAL_SHOW_FQTERM)->shortcut(), this);
+ FQ_VERIFY(connect(shortcutHelper_->getAction(FQTermShortcutHelper::GLOBAL_SHOW_FQTERM), SIGNAL(changed()),
+ this, SLOT(globalHotkeyChanged())));
+ FQ_VERIFY(connect(globalHotkey_, SIGNAL(activated()),
+ this, SLOT(globalHotkeyTriggered())));
+#endif //USE_GLOBAL_HOTKEY
+}
+
+//destructor
+FQTermFrame::~FQTermFrame() {
+#ifdef USE_GLOBAL_HOTKEY
+ delete globalHotkey_;
+#endif //USE_GLOBAL_HOTKEY
+#ifdef HAVE_PYTHON
+ delete pythonHelper_;
+#endif //HAVE_PYTHON
+ clearTranslator();
+ delete imageViewer_;
+ delete shortcutHelper_;
+ delete config_;
+ delete uaoCodec_;
+ delete windowManager_;
+ FQTermIPLocation::Destroy();
+ serverThread_->quit();
+ serverThread_->wait(1000);
+ delete serverThread_;
+
+}
+
+//initialize setting from fqterm.cfg
+void FQTermFrame::iniSetting() {
+ QString strTmp;
+
+ strTmp = config_->getItemValue("global", "fullscreen");
+ if (strTmp == "1") {
+ getAction(FQTermShortcutHelper::FULLSCREEN)->setChecked(true);
+ showFullScreen();
+ } else {
+ //window size
+ strTmp = config_->getItemValue("global", "max");
+ if (strTmp == "1") {
+ showMaximized();
+ } else {
+ QString size = config_->getItemValue("global", "size");
+ if (size != "") {
+ int x, y, cx, cy;
+ sscanf(size.toLatin1(), "%d %d %d %d", &x, &y, &cx, &cy);
+ resize(QSize(cx, cy));
+ move(QPoint(x, y));
+ }
+ }
+ }
+
+ theme_ = config_->getItemValue("global", "theme");
+ QStyle *style;
+#ifdef USE_DOTNET_STYLE
+ //javaboy@newsmth.org
+ if (theme_ == "Office")
+ style = new DotNetStyle(DotNetStyle::Office);
+ else
+#endif //USE_DOTNET_STYLE
+ style = QStyleFactory::create(theme_);
+ if (style) {
+ qApp->setStyle(style);
+ }
+
+ //language
+ updateLanguageMenu();
+
+ //TODO:
+ getAction(FQTermShortcutHelper::COLORCTL_NO)->setChecked(true);
+ FQTermPref::getInstance()->escapeString_ = config_->getItemValue("global", "escstr");
+ if (FQTermPref::getInstance()->escapeString_ == "") {
+ getAction(FQTermShortcutHelper::COLORCTL_NO)->setChecked(true);
+ getAction(FQTermShortcutHelper::COLORCTL_OLD_CUSTOM)->setVisible(false);
+ } else if (FQTermPref::getInstance()->escapeString_ == "^[^[[") {
+ getAction(FQTermShortcutHelper::COLORCTL_SMTH)->setChecked(true);
+ getAction(FQTermShortcutHelper::COLORCTL_OLD_CUSTOM)->setVisible(false);
+ } else if (FQTermPref::getInstance()->escapeString_ == "^u[") {
+ getAction(FQTermShortcutHelper::COLORCTL_PTT)->setChecked(true);
+ getAction(FQTermShortcutHelper::COLORCTL_OLD_CUSTOM)->setVisible(false);
+ } else {
+ QAction *pAction = getAction(FQTermShortcutHelper::COLORCTL_OLD_CUSTOM);
+ QString transStrEsc;
+ transEscapeStr(transStrEsc, FQTermPref::getInstance()->escapeString_);
+ pAction->setText(transStrEsc);
+ pAction->setVisible(true);
+ pAction->setChecked(true);
+ }
+
+ strTmp = config_->getItemValue("global", "vscrollpos");
+ if (strTmp == "0") {
+ FQTermPref::getInstance()->termScrollBarPosition_ = 0;
+ getAction(FQTermShortcutHelper::SCROLLBAR_HIDDEN)->setChecked(true);
+ } else if (strTmp == "1") {
+ FQTermPref::getInstance()->termScrollBarPosition_ = 1;
+ getAction(FQTermShortcutHelper::SCROLLBAR_LEFT)->setChecked(true);
+ } else {
+ FQTermPref::getInstance()->termScrollBarPosition_ = 2;
+ getAction(FQTermShortcutHelper::SCROLLBAR_RIGHT)->setChecked(true);
+ }
+ strTmp = config_->getItemValue("global", "switchbar");
+ isTabBarShown_ = (strTmp != "0");
+ getAction(FQTermShortcutHelper::SWITCHBAR)->setChecked(isTabBarShown_);
+ if (isTabBarShown_) {
+ statusBar()->show();
+ } else {
+ statusBar()->hide();
+ }
+
+ //read sub-window setting.
+ strTmp = config_->getItemValue("global", "subwindowmax");
+ windowManager_->setSubWindowMax((strTmp != "0"));
+
+
+ strTmp = config_->getItemValue("global", "subwindowsize");
+ if (strTmp != "") {
+ //FIXME: In case of sub window size not saved properly.
+ int w, h;
+ sscanf(strTmp.toLatin1(), "%d %d", &w, &h);
+ windowManager_->setSubWindowSize(QSize(w, h));
+ } else {
+ //Magic Number. Initialize Window Size to Avoid Errors.
+ windowManager_->setSubWindowSize(QSize(640, 480));
+ }
+
+ FQTermPref::getInstance()->isBossColor_ = false;
+
+ loadPref();
+
+ setUseDock(FQTermPref::getInstance()->openMinimizeToTray_);
+
+ if (FQTermPref::getInstance()->useStyleSheet_) {
+ loadStyleSheetFromFile(FQTermPref::getInstance()->styleSheetFile_);
+ }
+
+ strTmp = config_->getItemValue("global", "runserver");
+ FQTermPref::getInstance()->runServer_ = (strTmp != "0");
+}
+
+void FQTermFrame::loadPref() {
+ QString strTmp;
+
+ strTmp = config_->getItemValue("preference", "displayoffset");
+ FQTermPref::getInstance()->displayOffset_ = strTmp.toInt();
+ strTmp = config_->getItemValue("preference", "vsetting");
+ FQTermPref::getInstance()->vsetting_ = strTmp.toInt();
+ strTmp = config_->getItemValue("preference", "xim");
+ FQTermPref::getInstance()->imeEncodingID_ = strTmp.toInt();
+ strTmp = config_->getItemValue("preference", "wordwrap");
+ FQTermPref::getInstance()->widthToWrapWord_ = strTmp.toInt();
+ // strTmp = conf->getItemValue("preference", "smartww");
+ // m_pref.bSmartWW = (strTmp != "0");
+ strTmp = config_->getItemValue("preference", "wheel");
+ FQTermPref::getInstance()->isWheelSupported_ = (strTmp != "0");
+ strTmp = config_->getItemValue("preference", "url");
+ FQTermPref::getInstance()->openUrlCheck_ = (strTmp != "0");
+ // strTmp = conf->getItemValue("preference", "logmsg");
+ // m_pref.bLogMsg = (strTmp != "0");
+ strTmp = config_->getItemValue("preference", "blinktab");
+ FQTermPref::getInstance()->openTabBlinking_ = (strTmp != "0");
+ strTmp = config_->getItemValue("preference", "warn");
+ FQTermPref::getInstance()->openWarnOnClose_ = (strTmp != "0");
+ strTmp = config_->getItemValue("preference", "beep");
+ FQTermPref::getInstance()->openBeep_ = strTmp.toInt();
+ FQTermPref::getInstance()->beepSoundFileName_ = config_->getItemValue("preference", "wavefile");
+ strTmp = config_->getItemValue("preference", "http");
+ FQTermPref::getInstance()->httpBrowser_ = strTmp;
+ // m_pref.strHttp = strTmp;
+ strTmp = config_->getItemValue("preference", "antialias");
+ FQTermPref::getInstance()->openAntiAlias_ = (strTmp != "0");
+ strTmp = config_->getItemValue("preference", "enq");
+ FQTermPref::getInstance()->replyENQ_ = (strTmp != "0");
+ strTmp = config_->getItemValue("preference", "tray");
+ if (strTmp.isEmpty()) {
+#if defined(__APPLE__) || defined(__linux__) || defined(__GLIBC__)
+ FQTermPref::getInstance()->openMinimizeToTray_ = false;
+#else
+ FQTermPref::getInstance()->openMinimizeToTray_ = true;
+#endif
+ } else {
+ FQTermPref::getInstance()->openMinimizeToTray_ = (strTmp != "0");
+ }
+ strTmp = config_->getItemValue("preference", "playmethod");
+ FQTermPref::getInstance()->beepMethodID_ = strTmp.toInt();
+ strTmp = config_->getItemValue("preference", "externalplayer");
+ FQTermPref::getInstance()->beepPlayerName_ = strTmp;
+
+ strTmp = config_->getItemValue("preference", "clearpool");
+ FQTermPref::getInstance()->needClearZmodemPoolOnClose_ = (strTmp == "1");
+ strTmp = config_->getItemValue("preference", "pool");
+ FQTermPref::getInstance()->poolDir_ = strTmp.isEmpty() ?
+ getPath(USER_CONFIG) + "pool/": strTmp;
+ if (FQTermPref::getInstance()->poolDir_.right(1) != "/") {
+ FQTermPref::getInstance()->poolDir_.append('/');
+ }
+ strTmp = config_->getItemValue("preference", "zmodem");
+ FQTermPref::getInstance()->zmodemDir_ = strTmp.isEmpty() ?
+ getPath(USER_CONFIG) + "zmodem/": strTmp;
+ if (FQTermPref::getInstance()->zmodemDir_.right(1) != "/") {
+ FQTermPref::getInstance()->zmodemDir_.append('/');
+ }
+ strTmp = config_->getItemValue("preference", "image");
+ FQTermPref::getInstance()->imageViewerName_ = strTmp;
+ strTmp = config_->getItemValue("preference", "qssfile");
+ FQTermPref::getInstance()->styleSheetFile_ = strTmp;
+ FQTermPref::getInstance()->useStyleSheet_ = !strTmp.isEmpty();
+
+ strTmp = config_->getItemValue("preference", "editor");
+ FQTermPref::getInstance()->externalEditor_ = strTmp;
+
+ //FIXME: duplicated strings.
+ strTmp = config_->getItemValue("preference", "searchengine");
+ if (strTmp == "google") {
+ getAction(FQTermShortcutHelper::SEARCH_GOOGLE)->setChecked(true);
+ } else if (strTmp == "baidu") {
+ getAction(FQTermShortcutHelper::SEARCH_BAIDU)->setChecked(true);
+ } else if (strTmp == "bing") {
+ getAction(FQTermShortcutHelper::SEARCH_BING)->setChecked(true);
+ } else if (strTmp == "yahoo") {
+ getAction(FQTermShortcutHelper::SEARCH_YAHOO)->setChecked(true);
+ } else if (strTmp == "custom") {
+ getAction(FQTermShortcutHelper::SEARCH_CUSTOM)->setChecked(true);
+ } else {
+ getAction(FQTermShortcutHelper::SEARCH_GOOGLE)->setChecked(true);
+ strTmp = "google";
+ }
+ FQTermPref::getInstance()->searchEngine_ = strTmp;
+
+ strTmp = config_->getItemValue("preference", "editorarg");
+ FQTermPref::getInstance()->externalEditorArg_ = strTmp;
+
+ strTmp = config_->getItemValue("preference", "asciienhance");
+ FQTermPref::getInstance()->isAnsciiEnhance_ = (strTmp == "1");
+}
+
+//save current setting to fqterm.cfg
+void FQTermFrame::saveSetting() {
+ QString strTmp;
+ //save font
+ config_->setItemValue("global", "font", qApp->font().family());
+ strTmp.setNum(QFontInfo(qApp->font()).pointSize());
+ config_->setItemValue("global", "pointsize", strTmp);
+ strTmp.setNum(QFontInfo(qApp->font()).pixelSize());
+ config_->setItemValue("global", "pixelsize", strTmp);
+
+ //save window position and size
+ if (isMaximized()) {
+ config_->setItemValue("global", "max", "1");
+ } else {
+ strTmp = QString("%1 %2 %3 %4").arg(x()).arg(y()).arg(width()).arg(height());
+ // cstrTmp.sprintf("%d %d %d %d",x(),y(),width(),height());
+ config_->setItemValue("global", "size", strTmp);
+ config_->setItemValue("global", "max", "0");
+ }
+
+ if (windowState() & Qt::WindowFullScreen) {
+ config_->setItemValue("global", "fullscreen", "1");
+ } else {
+ config_->setItemValue("global", "fullscreen", "0");
+ }
+
+ // cstrTmp.setNum(theme);
+ config_->setItemValue("global", "theme", theme_);
+
+ config_->setItemValue("global", "escstr", FQTermPref::getInstance()->escapeString_);
+
+ strTmp.setNum(FQTermPref::getInstance()->termScrollBarPosition_);
+ config_->setItemValue("global", "vscrollpos", strTmp);
+
+ config_->setItemValue("global", "switchbar", isTabBarShown_ ? "1" : "0");
+
+ //save subwindow setting
+ config_->setItemValue("global", "subwindowmax", windowManager_->getSubWindowMax() ? "1" : "0");
+ int w = windowManager_->getSubWindowSize().width();
+ int h = windowManager_->getSubWindowSize().height();
+
+ strTmp = QString("%1 %2").arg(w).arg(h);
+ config_->setItemValue("global", "subwindowsize", strTmp);
+
+ //Save toolbarstate.
+ QByteArray state = saveState().toHex();
+ strTmp = QString(state);
+ config_->setItemValue("global", "toolbarstate", strTmp);
+
+ config_->setItemValue("global", "runserver", FQTermPref::getInstance()->runServer_ ? "1" : "0");
+
+ config_->save(getPath(USER_CONFIG) + "fqterm.cfg");
+}
+
+void FQTermFrame::initAdditionalActions()
+{
+
+#if defined(__APPLE__)
+ QString opt(tr("Ctrl"));
+#else
+ QString opt(tr("Alt"));
+#endif
+
+ for (int i = 1; i <= 10; ++i) {
+ QAction *idAction = new QAction(this);
+ QString shortcut(opt);
+ shortcut += "+" + QString("").setNum(i % 10);
+ idAction->setShortcut(shortcut);
+ connect(idAction, SIGNAL(triggered()), windowMapper_, SLOT(map()));
+ windowMapper_->setMapping(idAction, i - 1);
+ addAction(idAction);
+ }
+
+ FQTERM_ADDACTION(windowManager_, NEXTWINDOW, windowManager_, activateNextWindow);
+ FQTERM_ADDACTION(windowManager_, PREVWINDOW, windowManager_, activatePrevWindow);
+
+}
+
+//addressbook
+void FQTermFrame::addressBook() {
+ siteDialog siteManager(this, false);
+ if (siteManager.exec() == 1) {
+ newWindow(siteManager.currentParameter(), siteManager.currentSiteIndex());
+ }
+}
+
+//quicklogin
+void FQTermFrame::quickLogin() {
+ quickDialog quick(config_, this);
+ FQTermConfig *pConf = new FQTermConfig(getPath(USER_CONFIG) + "address.cfg");
+
+ loadAddress(pConf, -1, quick.param_);
+ delete pConf;
+
+ if (quick.exec() == 1) {
+ newWindow(quick.param_);
+ }
+}
+
+void FQTermFrame::exitFQTerm() {
+ if (!clearUp()) return;
+ deleteLater();
+}
+
+void FQTermFrame::newWindow(const FQTermParam &param, int index) {
+ QIcon *icon = new QIcon(QPixmap(getPath(RESOURCE) + "pic/tabpad.png"));
+ FQTermWindow* window = windowManager_->newWindow(param, config_, icon, index);
+
+ updateFontCombo();
+ FQ_VERIFY(connect(window->getScreen(), SIGNAL(termFontChange(bool,QFont)), this, SLOT(termFontChange(bool,QFont))));
+
+ window->connectHost();
+}
+
+
+void FQTermFrame::aboutFQTerm() {
+ aboutDialog about(this);
+ about.exec();
+}
+
+//slot Help->Homepage
+void FQTermFrame::homepage() {
+ const QString &httpBrowser = FQTermPref::getInstance()->httpBrowser_;
+ const QString homeUrl = "http://code.google.com/p/fqterm";
+
+ if (httpBrowser.isNull() || httpBrowser.isEmpty()) {
+ QDesktopServices::openUrl(homeUrl);
+ } else {
+ runProgram(httpBrowser, homeUrl);
+ }
+}
+
+//slot Windows menu aboutToShow
+void FQTermFrame::windowsMenuAboutToShow() {
+ menuWindows_->clear();
+ FQTERM_ADDACTION(menuWindows_, CASCADEWINDOWS, windowManager_, cascade);
+ FQTERM_ADDACTION(menuWindows_, TILEWINDOWS, windowManager_, tile);
+ if (windowManager_->count() == 0) {
+ getAction(FQTermShortcutHelper::CASCADEWINDOWS)->setEnabled(false);
+ getAction(FQTermShortcutHelper::TILEWINDOWS)->setEnabled(false);
+ }
+ menuWindows_->addSeparator();
+
+#ifdef Q_OS_MACX
+ // used to dock the program
+ if (isHidden()) {
+ menuWindows_->addAction(tr("Main Window"), this, SLOT(trayShow()));
+ }
+#endif
+
+ for (int i = 0; i < int(windowManager_->count()); ++i) {
+ QAction *idAction = menuWindows_->addAction(windowManager_->subWindowList().at(i)->windowTitle());
+ idAction->setCheckable(true);
+ idAction->setChecked(windowManager_->activeWindow() == windowManager_->nthWindow(i));
+ connect(idAction, SIGNAL(triggered()), windowMapper_, SLOT(map()));
+ windowMapper_->setMapping(idAction, i);
+ }
+}
+
+void FQTermFrame::reloadConfig() {
+ config_->load(getPath(USER_CONFIG) + "fqterm.cfg");
+}
+
+void FQTermFrame::popupConnectMenu() {
+ menuConnect_->clear();
+ menuConnect_->addAction(tr("Quick Login"), this, SLOT(quickLogin()));
+ menuConnect_->addSeparator();
+
+ FQTermConfig conf(getPath(USER_CONFIG) + "address.cfg");
+
+ QStringList listName;
+ loadNameList(&conf, listName);
+
+ for (int i = 0; i < listName.count(); i++) {
+ QAction *idAction = menuConnect_->addAction(listName[i], this, SLOT
+ (connectMenuActivated()));
+ idAction->setData(i);
+ if (i < 10) {
+#ifdef __APPLE__
+ QString shortCut(tr("Ctrl+Meta"));
+#else
+ QString shortCut(tr("Ctrl+Alt"));
+#endif
+ shortCut += "+" + QString("").setNum((i + 1)% 10);
+ idAction->setShortcut(shortCut);
+ }
+ }
+
+ int lastIndex = config_->getItemValue("global", "lastaddrindex").toInt();
+ if (lastIndex < 0 || lastIndex >= listName.count())
+ lastIndex = 0;
+ if (listName.count() > 0)
+ {
+ menuConnect_->addSeparator();
+ QAction *idAction = menuConnect_->addAction(listName[lastIndex], this, SLOT
+ (connectMenuActivated()));
+ idAction->setData(LAST_ADDRESS_INDEX);
+#ifdef __APPLE__
+ QString shortCut(tr("Ctrl+Meta"));
+#else
+ QString shortCut(tr("Ctrl+Alt"));
+#endif
+ shortCut += "+" + QString("-");
+ idAction->setShortcut(shortCut);
+
+ }
+}
+
+void FQTermFrame::connectMenuActivated() {
+ FQTermConfig *pConf = new FQTermConfig(getPath(USER_CONFIG) + "address.cfg");
+ int id = static_cast < QAction * > (sender())->data().toInt();
+ if (id == LAST_ADDRESS_INDEX)
+ {
+ id = config_->getItemValue("global", "lastaddrindex").toInt();
+ }
+
+ FQTermParam param;
+
+ // FIXME: don't know the relation with id and param setted by setItemParameter
+ if (loadAddress(pConf, id, param)) {
+ newWindow(param, id);
+ }
+ delete pConf;
+}
+
+
+bool FQTermFrame::eventFilter(QObject *o, QEvent *e) {
+ return false;
+}
+
+void FQTermFrame::closeEvent(QCloseEvent *clse) {
+ if (FQTermPref::getInstance()->openMinimizeToTray_ &&
+ windowManager_->count() > 0) {
+ trayHide();
+ clse->ignore();
+ return ;
+ }
+ if (!clearUp())
+ {
+ clse->ignore();
+ return;
+ }
+
+ clse->accept();
+
+ deleteLater();
+}
+
+void FQTermFrame::langEnglish() {
+ installTranslator("en_US");
+}
+
+void FQTermFrame::connectIt() {
+ if (windowManager_->activeWindow() == NULL) {
+ FQTermParam param;
+ FQTermConfig *pConf = new FQTermConfig(getPath(USER_CONFIG) + "address.cfg");
+
+ loadAddress(pConf, -1, param);
+ delete pConf;
+ newWindow(param);
+ } else if (!windowManager_->activeWindow()->isConnected()) {
+ windowManager_->activeWindow()->getSession()->reconnect();
+ }
+}
+
+void FQTermFrame::disconnect() {
+ FQTermWindow* aw = windowManager_->activeWindow();
+ if (aw) {
+ aw->disconnect();
+ }
+}
+
+void FQTermFrame::copy() {
+ windowManager_->activeWindow()->copy();
+}
+
+void FQTermFrame::paste() {
+ windowManager_->activeWindow()->paste();
+}
+
+void FQTermFrame::searchIt()
+{
+ windowManager_->activeWindow()->searchIt();
+}
+
+void FQTermFrame::shareIt()
+{
+ windowManager_->activeWindow()->shareIt();
+}
+
+void FQTermFrame::externalEditor() {
+ windowManager_->activeWindow()->externalEditor();
+}
+
+void FQTermFrame::fastPost() {
+ windowManager_->activeWindow()->fastPost();
+}
+
+void FQTermFrame::copyRect() {
+ windowManager_->activeWindow()->getSession()->param().isRectSelect_
+ = !windowManager_->activeWindow()->getSession()->param().isRectSelect_;
+
+ getAction(FQTermShortcutHelper::RECTANGLESELECTION)->setChecked(
+ windowManager_->activeWindow()->getSession()->param().isRectSelect_);
+}
+
+void FQTermFrame::copyColor() {
+ windowManager_->activeWindow()->getSession()->param().isColorCopy_
+ = !windowManager_->activeWindow()->getSession()->param().isColorCopy_;
+
+ getAction(FQTermShortcutHelper::COPYWITHCOLOR)->setChecked(
+ windowManager_->activeWindow()->getSession()->param().isColorCopy_);
+}
+
+void FQTermFrame::copyArticle() {
+ windowManager_->activeWindow()->copyArticle();
+}
+
+void FQTermFrame::autoCopy() {
+ windowManager_->activeWindow()->getSession()->param().isAutoCopy_
+ = !windowManager_->activeWindow()->getSession()->param().isAutoCopy_;
+
+ getAction(FQTermShortcutHelper::AUTOCOPYSELECTION)->setChecked(
+ windowManager_->activeWindow()->getSession()->param().isAutoCopy_);
+}
+
+void FQTermFrame::wordWrap() {
+ windowManager_->activeWindow()->getSession()->param().isAutoWrap_
+ = !windowManager_->activeWindow()->getSession()->param().isAutoWrap_;
+
+ getAction(FQTermShortcutHelper::PASTEWORDWRAP)->setChecked(
+ windowManager_->activeWindow()->getSession()->param().isAutoWrap_);
+}
+
+void FQTermFrame::noEsc() {
+ FQTermPref::getInstance()->escapeString_ = "";
+ getAction(FQTermShortcutHelper::COLORCTL_NO)->setChecked(true);
+ getAction(FQTermShortcutHelper::COLORCTL_OLD_CUSTOM)->setVisible(false);
+}
+
+void FQTermFrame::escEsc() {
+ FQTermPref::getInstance()->escapeString_ = "^[^[[";
+ getAction(FQTermShortcutHelper::COLORCTL_SMTH)->setChecked(true);
+ getAction(FQTermShortcutHelper::COLORCTL_OLD_CUSTOM)->setVisible(false);
+}
+
+void FQTermFrame::uEsc() {
+ FQTermPref::getInstance()->escapeString_ = "^u[";
+ getAction(FQTermShortcutHelper::COLORCTL_PTT)->setChecked(true);
+ getAction(FQTermShortcutHelper::COLORCTL_OLD_CUSTOM)->setVisible(false);
+}
+
+void FQTermFrame::oldCustomEsc() {
+}
+
+void FQTermFrame::customEsc() {
+ QString strEsc(FQTermPref::getInstance()->escapeString_);
+ DefineEscapeDialog defineEscapeDialog_(strEsc, this);
+ if (defineEscapeDialog_.exec() == 1)
+ {
+ FQTermPref::getInstance()->escapeString_ = strEsc;
+ QAction *pAction = getAction(FQTermShortcutHelper::COLORCTL_OLD_CUSTOM);
+ if (strEsc != QString("") && strEsc != QString("^[^[[") && strEsc != QString("^u["))
+ {
+ QString transStrEsc;
+ transEscapeStr(transStrEsc, strEsc);
+ pAction->setText(transStrEsc);
+ pAction->setVisible(true);
+ pAction->setChecked(true);
+ }
+ else
+ {
+ pAction->setVisible(false);
+ }
+ }
+}
+
+bool FQTermFrame::isDelimiterExistedBefore(const QString& str,
+ const std::vector<QString>& existingDelimiters) {
+ for (std::vector<QString>::const_iterator cit = existingDelimiters.begin();
+ cit != existingDelimiters.end();
+ ++cit)
+ {
+ if (str.right(cit->length()) == *cit)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+int FQTermFrame::isDelimiterExistedAfter(const QString& str,
+ const std::vector<QString>& existingDelimiters) {
+ for (std::vector<QString>::const_iterator cit = existingDelimiters.begin();
+ cit != existingDelimiters.end();
+ ++cit)
+ {
+ if (str.left(cit->length()) == *cit)
+ {
+ return cit->length();
+ }
+ }
+ return 0;
+}
+
+bool FQTermFrame::uppercaseCharFollowingCtrl(QString& str,
+ int& i,
+ const QString& after) {
+ if (after == QString("Ctrl") &&
+ str[i] > 'a' - 1 &&
+ str[i] < 'z' - 1)
+ {
+ str[i] = str[i].toUpper();
+ ++i;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void FQTermFrame::replaceEscapeString(QString& str,
+ const QString& before,
+ const QString& after,
+ const QString& delimiter,
+ const std::vector<QString> *existingDelimiters /* = NULL */) {
+ bool preMatched = false;
+ int i = 0;
+ while (i < str.length())
+ {
+ bool matched = true;
+ for (int j = 0; j < before.length(); ++j)
+ {
+ if (str[i + j] != before[j])
+ {
+ matched = false;
+ break;
+ }
+ }// end of for
+ if (matched)
+ {
+ if (i == 0)
+ {
+ // the matched string is the head of the string
+ str = after + delimiter + str.right(str.length() - before.length());
+ i = after.length() + delimiter.length();
+ bool changed = uppercaseCharFollowingCtrl(str, i, after);
+ preMatched = !changed;
+ }
+ else if (i == str.length() - before.length())
+ {
+ // the matched string is the tail of the string
+ if (existingDelimiters != NULL &&
+ isDelimiterExistedBefore(str.left(i), *existingDelimiters))
+ {
+ preMatched = true;
+ }
+
+ if (preMatched)
+ {
+ str = str.left(i) + after;
+ }
+ else
+ {
+ str = str.left(i) + delimiter + after;
+ }
+ break;
+ }
+ else
+ {
+ // the matched string is at the middle of the string
+ if (existingDelimiters != NULL &&
+ isDelimiterExistedBefore(str.left(i), *existingDelimiters))
+ {
+ preMatched = true;
+ }
+
+ if (preMatched)
+ {
+ str = str.left(i) + after + delimiter + str.right(str.length() - i - before.length());
+ i += after.length() + delimiter.length();
+ }
+ else
+ {
+ str = str.left(i) + delimiter + after + delimiter + str.right(str.length() - i - before.length());
+ i += after.length() + 2 * delimiter.length();
+ }
+ bool changed = uppercaseCharFollowingCtrl(str, i, after);
+ preMatched = !changed;
+ }
+ if (preMatched)
+ {
+ int len;
+ if (existingDelimiters != NULL &&
+ (len = isDelimiterExistedAfter(str.right(str.length() - i), *existingDelimiters)) != 0)
+ {
+ str = str.left(i) + str.right(str.length() - i - len);
+ }
+ }
+ }
+ else
+ {
+ preMatched = false;
+ ++i;
+ }
+ }// end of while
+}
+
+void FQTermFrame::transEscapeStr(QString& target, const QString& source) {
+ const QChar cSpecial(17);
+ target = source;
+ replaceEscapeString(target, QString("^["), QString("ESC"), QString(cSpecial));
+ std::vector<QString> existingDelimiters;
+ existingDelimiters.push_back(QString(cSpecial));
+ replaceEscapeString(target, QString("^"), QString("Ctrl"), QString("+"), &existingDelimiters);
+ target.replace(cSpecial, QChar(' '));
+}
+
+void FQTermFrame::setColor() {
+ windowManager_->activeWindow()->setColor();
+}
+
+void FQTermFrame::refreshScreen() {
+ windowManager_->activeWindow()->forcedRepaintScreen();
+}
+
+void FQTermFrame::uiFont() {
+ bool ok;
+ QFont font = QFontDialog::getFont(&ok, qApp->font());
+
+ if (FQTermPref::getInstance()->openAntiAlias_) {
+ font.setStyleStrategy(QFont::PreferAntialias);
+ }
+
+ if (ok == true) {
+ qApp->setFont(font);
+ //refresh style sheet
+ if (FQTermPref::getInstance()->useStyleSheet_) {
+ refreshStyleSheet();
+ }
+ imageViewer_->adjustItemSize();
+ }
+}
+
+void FQTermFrame::fullscreen() {
+
+
+ if (!(windowState() & Qt::WindowFullScreen)) {
+ menuBar()->hide();
+ toolBarMdiTools_->hide();
+ toolBarMdiConnectTools_->hide();
+ toolBarSetupKeys_->hide();
+ toolBarFonts_->hide();
+ hideScroll();
+ showSwitchBar();
+ showFullScreen();
+ } else {
+ menuBar()->show();
+ toolBarMdiTools_->show();
+ toolBarMdiConnectTools_->show();
+ toolBarSetupKeys_->show();
+ toolBarFonts_->show();
+ emit updateScroll();
+ showSwitchBar();
+ showNormal();
+ }
+
+}
+
+void FQTermFrame::bosscolor() {
+ FQTermPref::getInstance()->isBossColor_ = !FQTermPref::getInstance()->isBossColor_;
+ emit bossColor();
+ getAction(FQTermShortcutHelper::BOSSCOLOR)->setChecked(FQTermPref::getInstance()->isBossColor_);
+}
+
+
+void FQTermFrame::toggleServer(bool on) {
+ FQTermPref::getInstance()->runServer_ = on;
+ if (on) {
+ serverThread_->start();
+ } else {
+ serverThread_->quit();
+ serverThread_->wait(1000);
+ }
+}
+
+void FQTermFrame::themesMenuAboutToShow() {
+ QVector<QChar> vectorShortcutKeys;
+ menuThemes_->clear();
+ QStringList styles = QStyleFactory::keys();
+ for (QStringList::ConstIterator it = styles.begin();
+ it != styles.end(); it++) {
+ QString strTheme = *it;
+ for (int i = 0; i < strTheme.length(); ++i)
+ {
+ if (vectorShortcutKeys.indexOf(strTheme.at(i)) == -1)
+ {
+ vectorShortcutKeys.append(strTheme.at(i));
+ strTheme.insert(i, QChar('&'));
+ break;
+ }
+ }
+ insertThemeItem(strTheme);
+ }
+#ifdef USE_DOTNET_STYLE
+ insertThemeItem("Office"); //javaboy@newsmth.org
+#endif //USE_DOTNET_STYLE
+}
+
+void FQTermFrame::themesMenuActivated() {
+ theme_ = ((QAction*)QObject::sender())->text().remove(QChar('&'));
+ QStyle *style;
+#ifdef USE_DOTNET_STYLE
+ //javaboy@newsmth.org
+ if (theme_ == "Office")
+ style = new DotNetStyle(DotNetStyle::Office);
+ else
+#endif //USE_DOTNET_STYLE
+ style = QStyleFactory::create(theme_);
+ if (style) {
+ qApp->setStyle(style);
+ }
+}
+
+
+
+void FQTermFrame::hideScroll() {
+ FQTermPref::getInstance()->termScrollBarPosition_ = 0;
+ emit updateScroll();
+}
+
+void FQTermFrame::leftScroll() {
+ FQTermPref::getInstance()->termScrollBarPosition_ = 1;
+ emit updateScroll();
+}
+
+void FQTermFrame::rightScroll() {
+ FQTermPref::getInstance()->termScrollBarPosition_ = 2;
+ emit updateScroll();
+}
+
+void FQTermFrame::setSE(const QString& se) {
+ FQTermPref::getInstance()->searchEngine_ = se;
+ config_->setItemValue("preference", "searchengine", se);
+}
+
+void FQTermFrame::setSEGoogle() {
+ setSE("google");
+}
+void FQTermFrame::setSEBaidu(){
+ setSE("baidu");
+}
+void FQTermFrame::setSEYahoo() {
+ setSE("yahoo");
+}
+void FQTermFrame::setSEBing() {
+ setSE("bing");
+}
+void FQTermFrame::setSECustom(){
+ setSE("custom");
+}
+
+void FQTermFrame::showSwitchBar() {
+ isTabBarShown_ = !isTabBarShown_;
+ getAction(FQTermShortcutHelper::SWITCHBAR)->setChecked(isTabBarShown_);
+
+ if (isTabBarShown_) {
+ statusBar()->show();
+ } else {
+ statusBar()->hide();
+ }
+}
+
+void FQTermFrame::setting() {
+ windowManager_->activeWindow()->setting();
+ updateMenuToolBar();
+}
+
+void FQTermFrame::saveSessionSetting() {
+ windowManager_->activeWindow()->saveSetting(false);
+}
+
+void FQTermFrame::defaultSetting() {
+ FQTermConfig *pConf = new FQTermConfig(getPath(USER_CONFIG) + "address.cfg");
+ FQTermParam tmpParam;
+
+ if (pConf->hasSection("default")) {
+ loadAddress(pConf, -1, tmpParam);
+ }
+
+ addrDialog set(this, tmpParam, addrDialog::SAVE);
+
+ if (set.exec() == 2) {
+ saveAddress(pConf, -1, set.param());
+ pConf->save(getPath(USER_CONFIG) + "address.cfg");
+ }
+
+ delete pConf;
+}
+
+void FQTermFrame::preference() {
+ prefDialog pref(config_, this);
+ bool styleSheetUsed = FQTermPref::getInstance()->useStyleSheet_;
+
+ if (pref.exec() == 1) {
+ //TODO: refactor
+ loadPref();
+ setUseDock(FQTermPref::getInstance()->openMinimizeToTray_);
+ if (FQTermPref::getInstance()->useStyleSheet_) {
+ loadStyleSheetFromFile(FQTermPref::getInstance()->styleSheetFile_);
+ }
+ else if (styleSheetUsed) {
+ clearStyleSheet();
+ }
+ }
+ emit fontAntiAliasing(FQTermPref::getInstance()->openAntiAlias_);
+}
+
+void FQTermFrame::shortcutSetting() {
+ int act = windowManager_->activeWindowIndex();
+ FQTermShortcutDialog fsd(shortcutHelper_, this);
+ fsd.exec();
+ windowManager_->activateTheWindow(act);
+}
+
+void FQTermFrame::keySetup() {
+ keyDialog keyDlg(config_, this);
+ if (keyDlg.exec() == 1) {
+ updateKeyToolBar();
+ }
+}
+
+
+void FQTermFrame::ipLookup() {
+ IPLookupDialog ipLookupDialog_(this);
+ ipLookupDialog_.exec();
+}
+
+void FQTermFrame::antiIdle() {
+ windowManager_->activeWindow()->toggleAntiIdle();
+ getAction(FQTermShortcutHelper::ANTIIDLE)->setChecked(
+ windowManager_->activeWindow()->getSession()->isAntiIdle());
+}
+
+void FQTermFrame::autoReply() {
+ windowManager_->activeWindow()->toggleAutoReply();
+ getAction(FQTermShortcutHelper::AUTOREPLY)->setChecked(
+ windowManager_->activeWindow()->getSession()->isAutoReply());
+}
+
+void FQTermFrame::viewMessages() {
+ windowManager_->activeWindow()->viewMessages();
+}
+
+void FQTermFrame::enableMouse() {
+ windowManager_->activeWindow()->getSession()->param().isSupportMouse_
+ = !windowManager_->activeWindow()->getSession()->param().isSupportMouse_;
+ getAction(FQTermShortcutHelper::MOUSESUPPORT)->setChecked(
+ windowManager_->activeWindow()->getSession()->param().isSupportMouse_);
+}
+
+void FQTermFrame::viewImages(QString filename, bool raiseViewer) {
+ if (filename.isEmpty()) {
+ filename = FQTermPref::getInstance()->poolDir_;
+ }
+
+ if (raiseViewer) {
+ imageViewer_->scrollTo(filename);
+ if (imageViewer_->isHidden()) {
+ imageViewer_->resize(size() * 3 / 4 + QSize(1,1));
+ imageViewer_->show();
+ }
+ clearFocus();
+ imageViewer_->raise();
+ imageViewer_->activateWindow();
+ } else {
+ imageViewer_->updateImage(filename);
+ }
+}
+
+void FQTermFrame::viewImages() {
+ viewImages(FQTermPref::getInstance()->poolDir_, true);
+}
+
+void FQTermFrame::beep() {
+ windowManager_->activeWindow()->getSession()->param().isBeep_ =
+ !windowManager_->activeWindow()->getSession()->param().isBeep_;
+ getAction(FQTermShortcutHelper::BEEP)->setChecked(windowManager_->activeWindow()->getSession()->param().isBeep_);
+}
+
+void FQTermFrame::reconnect() {
+ FQTermWindow * qtw = windowManager_->activeWindow();
+ if (qtw){
+ qtw->toggleAutoReconnect();
+ }
+}
+
+
+void FQTermFrame::delayedRunScript() {
+ windowManager_->activeWindow()->runScript();
+}
+
+
+void FQTermFrame::runScript() {
+ QTimer::singleShot(1, this, SLOT(delayedRunScript()));
+}
+
+void FQTermFrame::stopScript() {
+ windowManager_->activeWindow()->stopScript();
+}
+
+
+void FQTermFrame::runPyScript() {
+#ifdef HAVE_PYTHON
+ windowManager_->activeWindow()->runPythonScript();
+#endif //HAVE_PYTHON
+}
+
+bool FQTermFrame::event(QEvent *e) {
+
+ static bool shown = false;
+ if (e->type() == QEvent::WindowStateChange) {
+ if ((((QWindowStateChangeEvent*)(e))->oldState() & Qt::WindowMinimized)
+ && !(windowState() & Qt::WindowMinimized)) {
+ shown = true;
+ }
+ if (!(windowState() & Qt::WindowMinimized))
+ {
+ config_->setItemValue("global", "max", (windowState() & Qt::WindowMaximized) ? "1" : "0");
+ config_->setItemValue("global", "fullscreen", (windowState() & Qt::WindowFullScreen) ? "1" : "0");
+ }
+ }
+ if (e->type() == QEvent::Paint && shown) {
+ shown = false;
+ qApp->setActiveWindow(NULL);
+ qApp->setActiveWindow(this);
+ }
+
+ bool res = this->QMainWindow::event(e);
+
+ if (e->type() == QEvent::HoverMove
+ || e->type() == QEvent::MouseMove
+ || e->type() == QEvent::Move) {
+ if (res) {
+ FQ_TRACE("frameEvent", 10) << "Accept event: " << e->type()
+ << " " << getEventName(e->type()) << ".";
+ } else {
+ FQ_TRACE("frameEvent", 10) << "Ignore event: " << e->type()
+ << " " << getEventName(e->type()) << ".";
+ }
+ } else {
+ if (res) {
+ FQ_TRACE("frameEvent", 9) << "Accept event: " << e->type()
+ << " " << getEventName(e->type()) << ".";
+ } else {
+ FQ_TRACE("frameEvent", 9) << "Ignore event: " << e->type()
+ << " " << getEventName(e->type()) << ".";
+ }
+ }
+
+ return res;
+}
+
+void FQTermFrame::keyClicked(int id) {
+ if (windowManager_->activeWindow() == NULL) {
+ return ;
+ }
+
+ QString strItem = QString("key%1").arg(id);
+ QString strTmp = config_->getItemValue("key", strItem);
+
+ if (strTmp[0] == '0') { // key
+ windowManager_->activeWindow()->externInput(strTmp.mid(1));
+ } else if (strTmp[0] == '1') { // script
+ QString scriptFile = strTmp.mid(1).trimmed();
+#ifdef HAVE_PYTHON
+ if (scriptFile.endsWith(".py", Qt::CaseInsensitive))
+ windowManager_->activeWindow()->runPythonScriptFile(scriptFile);
+ else
+#endif
+ windowManager_->activeWindow()->runScript(scriptFile.toAscii());
+ } else if (strTmp[0] == '2') { // program
+ runProgram(strTmp.mid(1));
+ }
+}
+
+void FQTermFrame::addMainTool() {
+ // the main toolbar
+ toolBarMdiTools_ = addToolBar("Main ToolBar");
+ toolBarMdiTools_->setObjectName("Main ToolBar");
+
+ connectButton_ = new QToolButton(toolBarMdiTools_);
+ connectButton_->setIcon(QPixmap(getPath(RESOURCE) + "pic/connect.png"));
+
+ toolBarMdiTools_->addWidget(connectButton_);
+ menuConnect_ = new QMenu(this);
+ //FIXME: autoupdate menu
+ FQ_VERIFY(connect(menuConnect_, SIGNAL(aboutToShow()),
+ this, SLOT(popupConnectMenu())));
+ connectButton_->setMenu(menuConnect_);
+ connectButton_->setPopupMode(QToolButton::InstantPopup);
+
+ toolBarMdiTools_->addAction(getAction(FQTermShortcutHelper::QUICKLOGIN));
+
+ serverButton_ = new QToolButton(toolBarMdiTools_);
+ serverButton_->setCheckable(true);
+ serverButton_->setIcon(QPixmap(getPath(RESOURCE) + "pic/fqterm_32x32.png"));
+ serverButton_->setChecked(FQTermPref::getInstance()->runServer_);
+ FQ_VERIFY(connect(serverButton_, SIGNAL(toggled(bool)), this, SLOT(toggleServer(bool))));
+ toolBarMdiTools_->addWidget(serverButton_);
+ // custom define
+ toolBarSetupKeys_ = addToolBar("Custom Key");
+ toolBarSetupKeys_->setObjectName("Custom Key");
+
+ // the toolbar
+ toolBarMdiConnectTools_ = addToolBar("BBS operations");
+ toolBarMdiConnectTools_->setObjectName("BBS operations");
+ FQTERM_ADDACTION(toolBarMdiConnectTools_, DISCONNECT, this, disconnect);
+ getAction(FQTermShortcutHelper::DISCONNECT)->setEnabled(false);
+ toolBarMdiConnectTools_->addSeparator();
+
+ //Font Tool Bar
+ toolBarFonts_ = addToolBar("Font ToolBar");
+ toolBarFonts_->setObjectName("Font ToolBar");
+
+
+
+ // Edit (5)
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::COPY));
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::PASTE));
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::COPYWITHCOLOR));
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::RECTANGLESELECTION));
+ toolBarMdiConnectTools_->addSeparator();
+
+ //Font
+ fontButton_ = new QToolButton(toolBarFonts_);
+ QAction* dummyAction = new QAction(QPixmap(getPath(RESOURCE) + "pic/change_fonts.png"),
+ tr("Set Terminal Fonts"), fontButton_);
+ fontButton_->setDefaultAction(dummyAction);
+ toolBarFonts_->addWidget(fontButton_);
+ fontButton_->setMenu(menuFont_);
+ fontButton_->setPopupMode(QToolButton::InstantPopup);
+
+ toolBarFonts_->addSeparator();
+ englishFontCombo_ = new QFontComboBox(toolBarFonts_);
+ otherFontCombo_ = new QFontComboBox(toolBarFonts_);
+ QLabel *englishFontLabel = new QLabel(toolBarFonts_);
+ englishFontLabel->setPixmap(QPixmap(getPath(RESOURCE) + "pic/english_font.png"));
+ toolBarFonts_->addWidget(englishFontLabel);
+ toolBarFonts_->addWidget(englishFontCombo_);
+ toolBarFonts_->addSeparator();
+ QLabel *otherFontLabel = new QLabel(toolBarFonts_);
+ otherFontLabel->setPixmap(QPixmap(getPath(RESOURCE) + "pic/other_font.png"));
+ toolBarFonts_->addWidget(otherFontLabel);
+ toolBarFonts_->addWidget(otherFontCombo_);
+ FQ_VERIFY(connect(englishFontCombo_, SIGNAL(currentFontChanged(const QFont&)),
+ this, SLOT(comboFontChanged(const QFont&))));
+ FQ_VERIFY(connect(otherFontCombo_, SIGNAL(currentFontChanged(const QFont&)),
+ this, SLOT(comboFontChanged(const QFont&))));
+
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::COLORSETTING));
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::ANSICOLOR));
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::REFRESHSCREEN));
+ toolBarMdiConnectTools_->addSeparator();
+
+ // Option
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::CURRENTSETTING));
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::SAVESETTING));
+ toolBarMdiConnectTools_->addSeparator();
+
+ // Spec (5)
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::COPYARTICLE));
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::ANTIIDLE));
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::AUTOREPLY));
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::VIEWMESSAGE));
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::IMAGEVIEWER));
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::MOUSESUPPORT));
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::BEEP));
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::AUTORECONNECT));
+
+ //call popupConnectMenu() to enable the shortcuts
+ popupConnectMenu();
+
+
+}
+
+
+QAction* FQTermFrame::getAction(int shortcut) {
+ if (!shortcutHelper_)
+ return NULL;
+ return shortcutHelper_->getAction(shortcut);
+}
+
+
+
+void FQTermFrame::addMainMenu() {
+ menuMain_ = menuBar();
+
+ //File Menu
+ menuFile_ = menuMain_->addMenu(tr("&File"));
+
+ FQTERM_ADDACTION(menuFile_, CONNECT, this, connectIt);
+ FQTERM_ADDACTION(menuFile_, DISCONNECT, this, disconnect);
+ menuFile_->addSeparator();
+ FQTERM_ADDACTION(menuFile_, ADDRESSBOOK, this, addressBook);
+ FQTERM_ADDACTION(menuFile_, QUICKLOGIN, this, quickLogin);
+ menuFile_->addSeparator();
+ FQTERM_ADDACTION(menuFile_, EXIT, this, exitFQTerm);
+ getAction(FQTermShortcutHelper::EXIT)->setMenuRole(QAction::QuitRole);
+
+ //Edit Menu
+ QMenu *edit = menuMain_->addMenu(tr("&Edit"));
+
+ FQTERM_ADDACTION(edit, COPY, this, copy);
+ FQTERM_ADDACTION(edit, PASTE, this, paste);
+ edit->addSeparator();
+ FQTERM_ADDACTION(edit, COPYWITHCOLOR, this, copyColor);
+ FQTERM_ADDACTION(edit, RECTANGLESELECTION, this, copyRect);
+ FQTERM_ADDACTION(edit, AUTOCOPYSELECTION, this, autoCopy);
+ FQTERM_ADDACTION(edit, PASTEWORDWRAP, this, wordWrap);
+ edit->addSeparator();
+ FQTERM_ADDACTION(edit, SEARCHIT, this, searchIt);
+ FQTERM_ADDACTION(edit, WEIBOSHARE, this, shareIt);
+ edit->addSeparator();
+ FQTERM_ADDACTION(edit, EXTERNALEDITOR, this, externalEditor);
+ edit->addSeparator();
+ FQTERM_ADDACTION(edit, FASTPOST, this, fastPost);
+ edit->addSeparator();
+
+ QMenu *escapeMenu = edit->addMenu(tr("Control sequence in clipboar&d"));
+ escapeGroup = new QActionGroup(this);
+ FQTERM_ADDACTION(escapeMenu, COLORCTL_NO,this, noEsc);
+ escapeGroup->addAction(getAction(FQTermShortcutHelper::COLORCTL_NO));
+ FQTERM_ADDACTION(escapeMenu, COLORCTL_SMTH,this, escEsc);
+ escapeGroup->addAction(getAction(FQTermShortcutHelper::COLORCTL_SMTH));
+ FQTERM_ADDACTION(escapeMenu, COLORCTL_PTT,this, uEsc);
+ escapeGroup->addAction(getAction(FQTermShortcutHelper::COLORCTL_PTT));
+ FQTERM_ADDACTION(escapeMenu, COLORCTL_OLD_CUSTOM,this, oldCustomEsc);
+ escapeGroup->addAction(getAction(FQTermShortcutHelper::COLORCTL_OLD_CUSTOM));
+ FQTERM_ADDACTION(escapeMenu, COLORCTL_CUSTOM,this, customEsc);
+ escapeGroup->addAction(getAction(FQTermShortcutHelper::COLORCTL_CUSTOM));
+
+ //View menu
+ QMenu *view = menuMain_->addMenu(tr("&View"));
+
+ menuFont_ = view->addMenu(tr("&Font"));
+ menuFont_->setIcon(QPixmap(getPath(RESOURCE) + "pic/change_fonts.png"));
+ view->addMenu(menuFont_);
+ FQTERM_ADDACTION(menuFont_, OTHERFONT, this, setFont);
+ getAction(FQTermShortcutHelper::OTHERFONT)->setData(0);
+ FQTERM_ADDACTION(menuFont_, ENGLISHFONT, this, setFont);
+ getAction(FQTermShortcutHelper::ENGLISHFONT)->setData(1);
+ FQTERM_ADDACTION(view, COLORSETTING, this, setColor);
+ FQTERM_ADDACTION(view, ANSICOLOR, this, toggleAnsiColor);
+ FQTERM_ADDACTION(view, REFRESHSCREEN, this, refreshScreen);
+ view->addSeparator();
+
+ //language menu
+ languageGroup = new QActionGroup(view);
+ languageGroup->setExclusive(true);
+ if (installerList_.isEmpty()) {
+ FQ_TRACE("frame", 0)
+ << "No language menu because of lack of translation files";
+ } else {
+ menuLanguage_ = view->addMenu(tr("&Language"));
+ FQTERM_ADDACTION(menuLanguage_, LANGUAGE_ENGLISH, this, langEnglish);
+ languageGroup->addAction(getAction(FQTermShortcutHelper::LANGUAGE_ENGLISH));
+
+ foreach(TranslatorInstaller* installer, installerList_) {
+ QAction* action = menuLanguage_->addAction(
+ installer->languageName(), installer, SLOT(installTranslator()));
+ action->setCheckable(true);
+ languageGroup->addAction(action);
+ }
+
+ }
+
+ FQTERM_ADDACTION(view, UIFONT, this, uiFont);
+
+ menuThemes_ = view->addMenu(tr("&Themes"));
+ FQ_VERIFY(connect(menuThemes_, SIGNAL(aboutToShow()), this, SLOT(themesMenuAboutToShow())));
+
+ FQTERM_ADDACTION(view, FULLSCREEN, this, fullscreen);
+ FQTERM_ADDACTION(view, BOSSCOLOR, this, bosscolor);
+
+ view->addSeparator();
+
+ QMenu *scrollMenu = view->addMenu(tr("&ScrollBar"));
+ scrollGroup = new QActionGroup(this);
+ FQTERM_ADDACTION(scrollMenu, SCROLLBAR_HIDDEN,this, hideScroll);
+ scrollGroup->addAction(getAction(FQTermShortcutHelper::SCROLLBAR_HIDDEN));
+ FQTERM_ADDACTION(scrollMenu, SCROLLBAR_RIGHT,this, rightScroll);
+ scrollGroup->addAction(getAction(FQTermShortcutHelper::SCROLLBAR_RIGHT));
+ FQTERM_ADDACTION(scrollMenu, SCROLLBAR_LEFT,this, leftScroll);
+ scrollGroup->addAction(getAction(FQTermShortcutHelper::SCROLLBAR_LEFT));
+
+ FQTERM_ADDACTION(view, SWITCHBAR, this, showSwitchBar);
+ // Option Menu
+ QMenu *option = menuMain_->addMenu(tr("&Option"));
+
+ FQTERM_ADDACTION(option, CURRENTSETTING, this, setting);
+ FQTERM_ADDACTION(option, SAVESETTING, this, saveSessionSetting);
+ option->addSeparator();
+ FQTERM_ADDACTION(option, DEFAULTSETTING, this, defaultSetting);
+#ifdef Q_OS_MAC
+ FQTERM_ADDACTION(menuFile_, PREFERENCE, this, preference);
+#else
+ FQTERM_ADDACTION(option, PREFERENCE, this, preference);
+#endif
+ getAction(FQTermShortcutHelper::PREFERENCE)->setMenuRole(QAction::PreferencesRole);
+ FQTERM_ADDACTION(option, SHORTCUTSETTING, this, shortcutSetting);
+ option->addSeparator();
+ FQTERM_ADDACTION(option, EDITSCHEMA, this, editSchema);
+ option->addSeparator();
+
+ QMenu *searchEngineMenu = option->addMenu(tr("Searc&h Engine"));
+ searchEngineGroup = new QActionGroup(this);
+ FQTERM_ADDACTION(searchEngineMenu, SEARCH_GOOGLE,this, setSEGoogle);
+ searchEngineGroup->addAction(getAction(FQTermShortcutHelper::SEARCH_GOOGLE));
+ FQTERM_ADDACTION(searchEngineMenu, SEARCH_BAIDU,this, setSEBaidu);
+ searchEngineGroup->addAction(getAction(FQTermShortcutHelper::SEARCH_BAIDU));
+ FQTERM_ADDACTION(searchEngineMenu, SEARCH_BING,this, setSEBing);
+ searchEngineGroup->addAction(getAction(FQTermShortcutHelper::SEARCH_BING));
+ FQTERM_ADDACTION(searchEngineMenu, SEARCH_YAHOO,this, setSEYahoo);
+ searchEngineGroup->addAction(getAction(FQTermShortcutHelper::SEARCH_YAHOO));
+ FQTERM_ADDACTION(searchEngineMenu, SEARCH_CUSTOM,this, setSECustom);
+ searchEngineGroup->addAction(getAction(FQTermShortcutHelper::SEARCH_CUSTOM));
+
+ // Special
+ QMenu *spec = menuMain_->addMenu(tr("&Special"));
+ FQTERM_ADDACTION(spec, COPYARTICLE, this, copyArticle);
+ FQTERM_ADDACTION(spec, ANTIIDLE, this, antiIdle);
+ FQTERM_ADDACTION(spec, AUTOREPLY, this, autoReply);
+ FQTERM_ADDACTION(spec, VIEWMESSAGE, this, viewMessages);
+ FQTERM_ADDACTION(spec, BEEP, this, beep);
+ FQTERM_ADDACTION(spec, MOUSESUPPORT, this, enableMouse);
+ FQTERM_ADDACTION(spec, IMAGEVIEWER, this, viewImages);
+ FQTERM_ADDACTION(spec, IPLOOKUP, this, ipLookup);
+
+ //Script
+ QMenu *script = menuMain_->addMenu(tr("Scrip&t"));
+ FQTERM_ADDACTION(script, RUNSCRIPT, this, runScript);
+ FQTERM_ADDACTION(script, STOPSCRIPT, this, stopScript);
+#ifdef HAVE_PYTHON
+ script->addSeparator();
+ FQTERM_ADDACTION(script, RUNPYTHONSCRIPT, this, runPyScript);
+#endif //HAVE_PYTHON
+
+ //Window menu
+ menuWindows_ = menuMain_->addMenu(tr("&Windows"));
+ FQ_VERIFY(connect(menuWindows_, SIGNAL(aboutToShow()),this, SLOT(windowsMenuAboutToShow())));
+ menuMain_->addSeparator();
+
+ //Help menu
+ QMenu *help = menuMain_->addMenu(tr("&Help"));
+ FQTERM_ADDACTION(help, ABOUT, this, aboutFQTerm);
+ getAction(FQTermShortcutHelper::ABOUT)->setMenuRole(QAction::AboutRole);
+ FQTERM_ADDACTION(help, HOMEPAGE, this, homepage);
+}
+
+void FQTermFrame::updateMenuToolBar() {
+ FQTermWindow *window = windowManager_->activeWindow();
+
+ if (window == NULL) {
+ return ;
+ }
+
+ // update menu
+ getAction(FQTermShortcutHelper::DISCONNECT)->setEnabled(window->isConnected());
+ getAction(FQTermShortcutHelper::COPYWITHCOLOR)->setChecked(window->getSession()->param().isColorCopy_);
+ getAction(FQTermShortcutHelper::RECTANGLESELECTION)->setChecked(window->getSession()->param().isRectSelect_);
+ getAction(FQTermShortcutHelper::AUTOCOPYSELECTION)->setChecked(window->getSession()->param().isAutoCopy_);
+ getAction(FQTermShortcutHelper::PASTEWORDWRAP)->setChecked(window->getSession()->param().isAutoWrap_);
+ getAction(FQTermShortcutHelper::FULLSCREEN)->setChecked(windowState() & Qt::WindowFullScreen);
+ getAction(FQTermShortcutHelper::ANSICOLOR)->setChecked(window->getSession()->param().isAnsiColor_);
+ getAction(FQTermShortcutHelper::ANTIIDLE)->setChecked(window->getSession()->isAntiIdle());
+ getAction(FQTermShortcutHelper::AUTOREPLY)->setChecked(window->getSession()->isAutoReply());
+ getAction(FQTermShortcutHelper::BEEP)->setChecked(window->getSession()->param().isBeep_);
+ getAction(FQTermShortcutHelper::MOUSESUPPORT)->setChecked(window->getSession()->param().isSupportMouse_);
+ getAction(FQTermShortcutHelper::AUTORECONNECT)->setChecked(window->getSession()->param().isAutoReconnect_);
+
+ updateFontCombo();
+}
+
+void FQTermFrame::updateFontCombo() {
+ FQTermWindow *window = windowManager_->activeWindow();
+
+ if (window == NULL) {
+ return ;
+ }
+ englishFontCombo_->blockSignals(true);
+ otherFontCombo_->blockSignals(true);
+ englishFontCombo_->setCurrentFont(window->getScreen()->termFont(true));
+ otherFontCombo_->setCurrentFont(window->getScreen()->termFont(false));
+ englishFontCombo_->blockSignals(false);
+ otherFontCombo_->blockSignals(false);
+}
+
+void FQTermFrame::termFontChange(bool isEnglish, QFont font) {
+ updateFontCombo();
+}
+
+void FQTermFrame::comboFontChanged(const QFont & font) {
+
+ FQTermWindow *window = windowManager_->activeWindow();
+
+ if (window == NULL) {
+ return ;
+ }
+
+ window->getScreen()->blockSignals(true);
+
+ bool isEnglish = (sender() == (QObject*)englishFontCombo_);
+
+ QString& fontName = isEnglish?
+ window->getSession()->param().englishFontName_:window->getSession()->param().otherFontName_;
+ int& fontSize = isEnglish?
+ window->getSession()->param().englishFontSize_:window->getSession()->param().otherFontSize_;
+ QFontComboBox* combo = isEnglish ? englishFontCombo_ : otherFontCombo_;
+
+ QFont f(combo->currentFont().family(), window->getScreen()->termFont(true).pointSize());
+
+ window->getScreen()->setTermFont(isEnglish, f);
+
+ fontName = f.family();
+ fontSize = f.pointSize();
+
+ window->getScreen()->blockSignals(false);
+
+ window->forcedRepaintScreen();
+}
+
+void FQTermFrame::enableMenuToolBar(bool enable) {
+ getAction(FQTermShortcutHelper::DISCONNECT)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::COPY)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::PASTE)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::COPYWITHCOLOR)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::RECTANGLESELECTION)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::AUTOCOPYSELECTION)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::PASTEWORDWRAP)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::ANSICOLOR)->setEnabled(enable);
+
+ fontButton_->setEnabled(enable);
+ englishFontCombo_->setEnabled(enable);
+ otherFontCombo_->setEnabled(enable);
+ menuFont_->setEnabled(enable);
+
+ getAction(FQTermShortcutHelper::COLORSETTING)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::REFRESHSCREEN)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::CURRENTSETTING)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::SAVESETTING)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::COPYARTICLE)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::ANTIIDLE)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::AUTOREPLY)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::VIEWMESSAGE)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::BEEP)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::MOUSESUPPORT)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::RUNSCRIPT)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::STOPSCRIPT)->setEnabled(enable);
+#ifdef HAVE_PYTHON
+ getAction(FQTermShortcutHelper::RUNPYTHONSCRIPT)->setEnabled(enable);
+#endif
+ getAction(FQTermShortcutHelper::SEARCHIT)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::WEIBOSHARE)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::EXTERNALEDITOR)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::FASTPOST)->setEnabled(enable);
+}
+
+void FQTermFrame::updateKeyToolBar() {
+ toolBarSetupKeys_->clear();
+ toolBarSetupKeys_->addAction(QPixmap(getPath(RESOURCE) + "pic/setup_shortcuts.png"),
+ tr("Key Setup"), this, SLOT(keySetup()));
+
+ QString strItem, strTmp;
+ strTmp = config_->getItemValue("key", "num");
+ int num = strTmp.toInt();
+
+ for (int i = 0; i < num; i++) {
+ strItem = QString("name%1").arg(i);
+ strTmp = config_->getItemValue("key", strItem);
+ FQTermToolButton *button =
+ new FQTermToolButton(toolBarSetupKeys_, i, strTmp);
+ button->setText(strTmp);
+ strItem = QString("key%1").arg(i);
+ strTmp = (config_->getItemValue("key", strItem));
+ //TODO: add tool tip here
+ // QToolTip::add( button, strTmp.mid(1) );
+ // button->addToolTip(strTmp.mid(1));
+
+ strTmp = config_->getItemValue("key", QString("shortcut%1").arg(i));
+ if (!strTmp.isEmpty()) {
+ QAction *act = new QAction(button);
+ act->setShortcut(strTmp);
+ button->addAction(act);
+ FQ_VERIFY(connect(act, SIGNAL(triggered()), button, SLOT(slotClicked())));
+ }
+
+ FQ_VERIFY(connect(button, SIGNAL(buttonClicked(int)),
+ this, SLOT(keyClicked(int))));
+ toolBarSetupKeys_->addWidget(button);
+ }
+
+
+
+}
+
+
+void FQTermFrame::popupFocusIn(FQTermWindow*) {
+ // bring to font
+ if (isHidden()) {
+ show();
+ }
+ if (isMinimized()) {
+ if (isMaximized()) {
+ showMaximized();
+ } else {
+ showNormal();
+ }
+ }
+ raise();
+ activateWindow();
+}
+
+void FQTermFrame::insertThemeItem(const QString& themeitem) {
+ QAction *idAction;
+
+ idAction = menuThemes_->addAction(themeitem,
+ this, SLOT(themesMenuActivated()));
+ idAction->setCheckable(true);
+ idAction->setChecked(themeitem == theme_);
+}
+
+void FQTermFrame::setUseDock(bool use) {
+ if (use == false) {
+ if (tray_) {
+ tray_->hide();
+ delete tray_;
+ tray_ = 0;
+ //delete menuTray_;
+ //menuTray_ = 0;
+ }
+ return ;
+ }
+
+ if (tray_ || !QSystemTrayIcon::isSystemTrayAvailable()) {
+ return ;
+ }
+
+ trayMenu_ = new QMenu;
+ FQ_VERIFY(connect(trayMenu_, SIGNAL(aboutToShow()), SLOT(buildTrayMenu())));
+
+ tray_ = new QSystemTrayIcon(this);
+ tray_->setIcon(QPixmap(getPath(RESOURCE) + "pic/fqterm_tray.png"));
+ tray_->setContextMenu(trayMenu_);
+ FQ_VERIFY(connect(tray_, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
+ SLOT(trayActived(QSystemTrayIcon::ActivationReason))));
+ tray_->show();
+}
+
+void FQTermFrame::buildTrayMenu() {
+ if (!trayMenu_) {
+ return ;
+ }
+ trayMenu_->clear();
+
+ if (isHidden()) {
+ trayMenu_->addAction(tr("Show"), this, SLOT(trayShow()));
+ } else {
+ trayMenu_->addAction(tr("Hide"), this, SLOT(trayHide()));
+ }
+ trayMenu_->addSeparator();
+ trayMenu_->addAction(tr("About"), this, SLOT(aboutFQTerm()));
+ trayMenu_->addAction(tr("Exit"), this, SLOT(exitFQTerm()));
+}
+
+void FQTermFrame::trayActived(QSystemTrayIcon::ActivationReason reason) {
+ if (reason == QSystemTrayIcon::Context) {
+ return ;
+ }
+ if (!isVisible()) {
+ trayShow();
+ } else {
+ trayHide();
+ }
+}
+
+void FQTermFrame::trayShow() {
+ show();
+ // bring to font
+ if (isHidden()) {
+ show();
+ }
+ if (isMinimized()) {
+ if (isMaximized()) {
+ showMaximized();
+ } else {
+#ifdef Q_OS_MACX
+ showMaximized();
+#else
+ showNormal();
+#endif
+ }
+ }
+ raise();
+ activateWindow();
+ FQTermWindow* window = windowManager_->activeWindow();
+ if (window) {
+ window->forcedRepaintScreen();
+ if (!window->isMaximized()) {
+ windowManager_->refreshAllExcept(window);
+ }
+ }
+}
+
+void FQTermFrame::trayHide() {
+ static bool showTip = true;
+ QString str = config_->getItemValue("global", "traytipshown");
+ if (str == "1") {
+ showTip = false;
+ }
+ hide();
+ if (showTip && tray_) {
+ tray_->showMessage(tr("FQTerm"),
+ tr("FQTerm will keep running in the system tray.\n"
+ "To terminate the program, "
+ "choose exit in the tray menu."));
+ showTip = false;
+ config_->setItemValue("global", "traytipshown", "1");
+ }
+}
+
+void FQTermFrame::buzz(FQTermWindow* window) {
+ if (windowManager_->activeWindow() == window)
+ return;
+ int xp = x();
+ int yp = y();
+ QTime t;
+
+ t.start();
+ for (int i = 32; i > 0;) {
+ if (t.elapsed() >= 1) {
+ int delta = i >> 2;
+ int dir = i &3;
+ int dx = ((dir == 1) || (dir == 2)) ? delta : -delta;
+ int dy = (dir < 2) ? delta : -delta;
+ move(xp + dx, yp + dy);
+ t.restart();
+ i--;
+ }
+ }
+ move(xp, yp);
+}
+
+
+//--------------------------
+//recreate the main menu
+//--------------------------
+void
+FQTermFrame::recreateMenu() {
+
+ if (shortcutHelper_) {
+ shortcutHelper_->retranslateActions();
+ }
+ menuBar()->clear();
+ delete escapeGroup;
+ delete languageGroup;
+ addMainMenu();
+ updateLanguageMenu();
+
+ QString strTmp = QString(saveState().toHex());
+ config_->setItemValue("global", "toolbarstate", strTmp);
+ config_->save(getPath(USER_CONFIG) + "fqterm.cfg");
+
+ delete toolBarMdiTools_;
+ delete toolBarSetupKeys_;
+ delete toolBarMdiConnectTools_;
+ delete toolBarFonts_;
+ delete menuConnect_;
+ addMainTool();
+ updateKeyToolBar();
+ loadToolBarPosition();
+ if (!windowManager_->activeWindow()) {
+ enableMenuToolBar(false);
+ } else {
+ enableMenuToolBar(true);
+ updateMenuToolBar();
+ }
+ if (FQTermPref::getInstance()->useStyleSheet_) {
+ refreshStyleSheet();
+ }
+}
+
+void FQTermFrame::installTranslator(const QString& lang) {
+ config_->setItemValue("global", "language", lang);
+ config_->save(getPath(USER_CONFIG) + "fqterm.cfg");
+
+ for (int i = 0; i < translatedModule; ++i) {
+ if (translator[i] != 0) {
+ qApp->removeTranslator(translator[i]);
+ delete translator[i];
+ translator[i] = 0;
+ }
+ }
+
+ if (lang != "en_US" && !lang.isEmpty()) {
+ for (int i = 0; i < translatedModule; ++i) {
+ QString dict =
+ getPath(RESOURCE) + "dict/" + qmPrefix[i] + lang + qmPostfix;
+ translator[i] = new QTranslator(0);
+ translator[i]->load(dict);
+ qApp->installTranslator(translator[i]);
+ }
+ }
+
+ emit changeLanguage();
+}
+
+void FQTermFrame::initTranslator() {
+ QString dict_path = getPath(RESOURCE) + "dict/";
+ QDir dictDir(dict_path);
+ QStringList langList;
+
+ for (int i = 0; i < translatedModule; ++i) {
+ translator[i] = 0;
+ QStringList filter;
+ filter << qmPrefix[i] + "*" + qmPostfix;
+ dictDir.setNameFilters(filter);
+ QFileInfoList list = dictDir.entryInfoList();
+
+ FQ_TRACE("translator", 3) << "Found " << list.size()
+ << " " << qmPostfix
+ << " file(s) under path "
+ << dict_path;
+
+ foreach(QFileInfo info, list){
+ QString language = info.fileName();
+ language = language.mid(
+ qmPrefix[i].length(),
+ language.length() - qmPrefix[i].length() - qmPostfix.length());
+
+ FQ_TRACE("translator", 3) << "Check file " << info.fileName();
+
+ if (!langList.contains(language)) {
+ langList << language;
+ installerList_.append(new TranslatorInstaller(language, this));
+ FQ_TRACE("translator", 3) << "Found translations for " << language;
+ } else {
+ FQ_TRACE("translator", 3) << "Language " << language
+ << " is already registered.";
+ }
+ }
+ }
+
+ if (installerList_.empty()) {
+ FQ_TRACE("translator", 0) << "No translations found.";
+ }
+
+ QString lang = config_->getItemValue("global", "language");
+ if (!langList.contains(lang)) {
+ lang = QLocale::system().name();
+ }
+#if defined(__linux__) || defined(__GLIBC__)
+ if (QLocale::system().language() == QLocale::English)
+ lang = QLocale::system().name();
+#endif
+ installTranslator(lang);
+}
+
+
+void FQTermFrame::clearTranslator() {
+ foreach(TranslatorInstaller* installer, installerList_){
+ delete installer;
+ }
+}
+
+void FQTermFrame::updateLanguageMenu() {
+ QString strTmp = config_->getItemValue("global", "language");
+ int i = 0;
+ foreach(TranslatorInstaller* installer, installerList_){
+ if (installer->languageFormalName() == strTmp) {
+ languageGroup->actions().at(i + 1)->setChecked(true);
+ break;
+ }
+ ++i;
+ }
+ if (!installerList_.isEmpty() &&
+ (strTmp == "en_US" || i == installerList_.size())) {
+ languageGroup->actions().at(0)->setChecked(true);
+ }
+}
+
+void FQTermFrame::setFont() {
+ bool isEnglish = (QAction*)(sender()) == getAction(FQTermShortcutHelper::ENGLISHFONT);
+ windowManager_->activeWindow()->setFont(isEnglish);
+}
+
+void FQTermFrame::refreshStyleSheet()
+{
+ qApp->setStyleSheet(qApp->styleSheet());
+}
+void FQTermFrame::loadStyleSheetFromFile( const QString qssFile )
+{
+ QFile file(qssFile);
+ file.open(QIODevice::ReadOnly);
+ QString qss = file.readAll();
+ qApp->setStyleSheet(qss);
+ file.close();
+}
+
+void FQTermFrame::clearStyleSheet() {
+ qApp->setStyleSheet("");
+}
+
+void FQTermFrame::loadToolBarPosition()
+{
+ //load toolbar setting
+ QString strTmp = config_->getItemValue("global", "toolbarstate");
+ if (!strTmp.isEmpty())
+ {
+ restoreState(QByteArray::fromHex(strTmp.toAscii()));
+ } else {
+ addToolBar(Qt::TopToolBarArea, toolBarMdiConnectTools_);
+ insertToolBar(toolBarMdiConnectTools_,toolBarSetupKeys_);
+ insertToolBar(toolBarSetupKeys_, toolBarMdiTools_);
+ insertToolBar(toolBarMdiTools_, toolBarFonts_);
+ }
+}
+
+void FQTermFrame::toggleAnsiColor() {
+ windowManager_->activeWindow()->getSession()->param().isAnsiColor_
+ = !windowManager_->activeWindow()->getSession()->param().isAnsiColor_;
+ getAction(FQTermShortcutHelper::ANSICOLOR)->setChecked(
+ windowManager_->activeWindow()->getSession()->param().isAnsiColor_);
+ refreshScreen();
+}
+
+bool FQTermFrame::clearUp() {
+ if (!windowManager_->closeAllWindow())
+ return false;
+
+ saveSetting();
+ // clear zmodem and pool if needed
+ if (FQTermPref::getInstance()->needClearZmodemPoolOnClose_) {
+ clearDir(FQTermPref::getInstance()->zmodemDir_);
+ clearDir(FQTermPref::getInstance()->poolDir_);
+ clearDir(FQTermPref::getInstance()->poolDir_ + "shadow-cache/");
+ }
+
+ setUseDock(false);
+
+ return true;
+}
+
+void FQTermFrame::editSchema() {
+
+ schemaDialog schema(this);
+ FQ_VERIFY(connect(&schema, SIGNAL(schemaEdited()),
+ this, SLOT(schemaUpdated())));
+ schema.exec();
+}
+
+void FQTermFrame::schemaUpdated() {
+ for (int i = 0; i < windowManager_->count(); ++i) {
+ windowManager_->nthWindow(i)->getScreen()->setSchema();
+ windowManager_->nthWindow(i)->forcedRepaintScreen();
+ }
+}
+
+
+void FQTermFrame::globalHotkeyTriggered() {
+ if (isActiveWindow() && !isMinimized() && isVisible())
+ {
+ showMinimized();
+ return;
+ }
+ show();
+ if (config_->getItemValue("global", "fullscreen") == "1")
+ showFullScreen();
+ else if (config_->getItemValue("global", "max") == "1")
+ showMaximized();
+ else
+ showNormal();
+ raise();
+ activateWindow();
+}
+
+void FQTermFrame::globalHotkeyChanged()
+{
+#ifdef USE_GLOBAL_HOTKEY
+ globalHotkey_->setShortcut(shortcutHelper_->getAction(FQTermShortcutHelper::GLOBAL_SHOW_FQTERM)->shortcut());
+#endif //USE_GLOBAL_HOTKEY
+}
+
+
+
+TranslatorInstaller::TranslatorInstaller(const QString& language,
+ FQTermFrame* frame)
+ : language_(language),
+ frame_(frame) {
+ FQTermConfig conf(getPath(USER_CONFIG) + "language.cfg");
+
+ languageName_ = conf.getItemValue("Name", language_);
+ if (languageName_.isEmpty()){
+ languageName_ = QLocale::languageToString(QLocale(language_).language());
+ if (languageName_ == "C") {
+ languageName_ = "Unknown Language";
+ }
+ }
+}
+
+QString TranslatorInstaller::languageName() {
+ return languageName_;
+}
+
+void TranslatorInstaller::installTranslator() {
+ frame_->installTranslator(language_);
+}
+
+QString TranslatorInstaller::languageFormalName() {
+ return language_;
+}
+
+} // namespace FQTerm
+
+#include "fqterm_frame.moc"
diff --git a/src/fqterm/fqterm_frame.h b/src/fqterm/fqterm_frame.h
new file mode 100644
index 0000000..8adaf49
--- /dev/null
+++ b/src/fqterm/fqterm_frame.h
@@ -0,0 +1,326 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_FRAME_H
+#define FQTERM_FRAME_H
+
+#include <QMainWindow>
+#include <QSystemTrayIcon>
+#include <QMenuBar>
+
+#include <vector>
+
+class QWidget;
+class QLineEdit;
+class QToolButton;
+class QMdiArea;
+class QSignalMapper;
+class QTabBar;
+class QFontDialog;
+class QActionGroup;
+class QString;
+class QFontComboBox;
+class UAOCodec;
+
+#ifdef USE_GLOBAL_HOTKEY
+class QxtGlobalShortcut;
+#endif //USE_GLOBAL_HOTKEY
+
+namespace FQTerm {
+
+class IPLookupDialog;
+class DefineEscapeDialog;
+class FQTermImage;
+class FQTermParam;
+class FQTermConfig;
+class FQTermWndMgr;
+class FQTermWindow;
+class StatusBar;
+class FQTermTimeLabel;
+class TranslatorInstaller;
+class FQTermMiniServerThread;
+class FQTermShortcutHelper;
+
+#ifdef HAVE_PYTHON
+class FQTermPythonHelper;
+#endif //HAVE_PYTHON
+
+class FQTermFrame: public QMainWindow {
+ Q_OBJECT;
+ public:
+ FQTermFrame();
+ ~FQTermFrame();
+
+ void updateMenuToolBar();
+ void enableMenuToolBar(bool);
+
+ void popupFocusIn(FQTermWindow*);
+
+ void viewImages(QString filename, bool raiseViewer);
+ void buzz(FQTermWindow* window = NULL);
+ void installTranslator(const QString& lang);
+ FQTermConfig * config() const { return config_; }
+
+ static const int translatedModule = 4;
+ static const QString qmPrefix[translatedModule];
+ static const QString qmPostfix;
+
+ signals:
+ void bossColor();
+ void updateScroll();
+ void changeLanguage();
+ void fontAntiAliasing(bool);
+
+ protected slots:
+
+ bool event(QEvent *event);
+
+ void viewImages();
+ bool clearUp();
+
+ // Menu
+ void recreateMenu();
+ void addressBook();
+ void quickLogin();
+ void exitFQTerm();
+
+ void aboutFQTerm();
+ void langEnglish();
+ void defaultSetting();
+ void preference();
+ void shortcutSetting();
+ void runScript();
+ void delayedRunScript(); // to avoid activate recursion guard
+ void stopScript();
+ void runPyScript();
+ void homepage();
+
+ void toggleAnsiColor();
+
+ // Toolbar
+ void keyClicked(int);
+
+ void connectIt();
+ void disconnect();
+ void copy();
+ void paste();
+ void searchIt();
+ void shareIt();
+ void externalEditor();
+ void fastPost();
+ void copyRect();
+ void copyColor();
+ void copyArticle();
+ void autoCopy();
+ void wordWrap();
+ void noEsc();
+ void escEsc();
+ void uEsc();
+ void oldCustomEsc();
+ void customEsc();
+ void hideScroll();
+ void leftScroll();
+ void rightScroll();
+ void setSEGoogle();
+ void setSEBaidu();
+ void setSEYahoo();
+ void setSEBing();
+ void setSECustom();
+ void showSwitchBar();
+ void setFont();
+ void setColor();
+ void refreshScreen();
+ void fullscreen();
+ void bosscolor();
+ void toggleServer(bool on);
+ void uiFont();
+ void antiIdle();
+ void autoReply();
+ void setting();
+ void saveSessionSetting();
+ void viewMessages();
+ void enableMouse();
+ void beep();
+ void reconnect();
+ void keySetup();
+ void ipLookup();
+ void termFontChange(bool isEnglish, QFont font);
+ void comboFontChanged(const QFont & font);
+
+ void themesMenuAboutToShow();
+ void themesMenuActivated();
+ void windowsMenuAboutToShow();
+ void connectMenuActivated();
+ void popupConnectMenu();
+ void trayActived(QSystemTrayIcon::ActivationReason);
+
+ //void trayClicked(const QPoint &, int);
+ //void trayDoubleClicked();
+ void trayHide();
+ void trayShow();
+ void buildTrayMenu();
+
+ void reloadConfig();
+
+ void saveSetting();
+ void schemaUpdated();
+ void editSchema();
+ private:
+
+ FQTermWndMgr *windowManager_;
+ // image viewer
+ FQTermImage *imageViewer_;
+
+ FQTermTimeLabel *labelTime_;
+
+ QString theme_;
+
+ QActionGroup *escapeGroup;
+ QActionGroup *languageGroup;
+ QActionGroup *scrollGroup;
+ QActionGroup *searchEngineGroup;
+ QMenu *menuWindows_;
+ QMenu *menuThemes_;
+ QMenu *menuFont_;
+ QMenu *menuFile_;
+ QMenu *menuLanguage_;
+ QMenu *menuConnect_;
+ QSignalMapper* windowMapper_;
+
+ FQTerm::StatusBar *statusBar_;
+
+ QToolButton *serverButton_;
+ QToolButton *connectButton_;
+ QToolButton *fontButton_;
+ QFontComboBox *englishFontCombo_;
+ QFontComboBox *otherFontCombo_;
+
+ QMenuBar *menuMain_;
+ QToolBar *toolBarMdiConnectTools_;
+ QToolBar *toolBarMdiTools_;
+ QToolBar *toolBarSetupKeys_;
+ QToolBar *toolBarFonts_;
+
+ bool isTabBarShown_;
+
+ QSystemTrayIcon *tray_;
+
+ QMenu *trayMenu_;
+
+ QTranslator * translator[translatedModule];
+ QList<TranslatorInstaller*> installerList_;
+
+ FQTermConfig * config_;
+ FQTermShortcutHelper * shortcutHelper_;
+ QAction* getAction(int shortcut);
+ FQTermMiniServerThread* serverThread_;
+
+ UAOCodec* uaoCodec_;
+
+private:
+ void newWindow(const FQTermParam &param, int index = -1);
+
+ void closeEvent(QCloseEvent*);
+ void selectStyleMenu(int, int);
+ void iniSetting();
+ void loadPref();
+
+ void addMainMenu();
+ void addMainTool();
+
+ void setSE(const QString& se);
+
+ void updateKeyToolBar();
+ void updateFontCombo();
+
+ void loadToolBarPosition();
+
+ bool eventFilter(QObject *, QEvent*);
+
+ void insertThemeItem(const QString&);
+ void setUseDock(bool);
+
+ void initAdditionalActions();
+
+ void initTranslator();
+ void clearTranslator();
+ void connector();
+ void updateLanguageMenu();
+
+ void loadStyleSheetFromFile(const QString qssFile);
+ void refreshStyleSheet();
+ void clearStyleSheet();
+
+ bool isDelimiterExistedBefore(const QString& str,
+ const std::vector<QString>& existingDelimiters);
+ int isDelimiterExistedAfter(const QString& str,
+ const std::vector<QString>& existingDelimiters);
+ bool uppercaseCharFollowingCtrl(QString& str,
+ int& i,
+ const QString& after);
+ void replaceEscapeString(QString& str,
+ const QString& before,
+ const QString& after,
+ const QString& delimiter,
+ const std::vector<QString> *existingDelimiters = NULL);
+ void transEscapeStr(QString& target, const QString& source);
+
+#ifdef HAVE_PYTHON
+public:
+ FQTermPythonHelper* getPythonHelper() {
+ return pythonHelper_;
+ }
+
+ //protected slots:
+private:
+ FQTermPythonHelper* pythonHelper_;
+#endif //HAVE_PYTHON
+
+#ifdef USE_GLOBAL_HOTKEY
+ QxtGlobalShortcut* globalHotkey_;
+#endif //USE_GLOBAL_HOTKEY
+private slots:
+ void globalHotkeyTriggered();
+ void globalHotkeyChanged();
+};
+
+class TranslatorInstaller : public QObject
+{
+ Q_OBJECT;
+
+public:
+ TranslatorInstaller(const QString& language, FQTermFrame* frame);
+
+ QString languageName();
+ QString languageFormalName();
+public slots:
+ void installTranslator();
+
+protected:
+ QString language_;
+ FQTermFrame* frame_;
+
+ QString languageName_;
+};
+
+
+} // namespace FQTerm
+
+#endif // FQTERM_FRAME_H
diff --git a/src/fqterm/fqterm_python.cpp b/src/fqterm/fqterm_python.cpp
new file mode 100644
index 0000000..68b9385
--- /dev/null
+++ b/src/fqterm/fqterm_python.cpp
@@ -0,0 +1,826 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+
+
+#include <QCustomEvent>
+#include <QTextStream>
+#include <QApplication>
+#include <QDir>
+#include <QFile>
+#include <QByteArray>
+#include <QMutex>
+#include <QThread>
+#include "fqterm.h"
+#ifdef HAVE_PYTHON
+#include <Python.h>
+#endif
+class SleeperThread : public QThread
+{
+public:
+ static void msleep(unsigned long msecs)
+ {
+ QThread::msleep(msecs);
+ }
+};
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_PYTHON
+
+#include "fqterm_window.h"
+#include "fqterm_buffer.h"
+#include "fqterm_text_line.h"
+#include "fqterm_param.h"
+#include "fqterm_session.h"
+#include "fqterm_python.h"
+#include "fqterm_path.h"
+#include "common.h"
+namespace FQTerm {
+
+/* **************************************************************************
+ *
+ * Pythons Embedding
+ *
+ * ***************************************************************************/
+
+QString getException() {
+ PyObject *pType = NULL, *pValue = NULL, *pTb = NULL, *pName, *pTraceback;
+
+ PyErr_Fetch(&pType, &pValue, &pTb);
+
+ pName = PyString_FromString("traceback");
+ pTraceback = PyImport_Import(pName);
+ Py_DECREF(pName);
+
+ if (pTraceback == NULL) {
+ return "General Error in Python Callback";
+ }
+
+ pName = PyString_FromString("format_exception");
+ PyObject *pRes = PyObject_CallMethodObjArgs(pTraceback, pName, pType, pValue,
+ pTb, NULL);
+ Py_DECREF(pName);
+
+ Py_DECREF(pTraceback);
+
+ Py_XDECREF(pType);
+ Py_XDECREF(pValue);
+ Py_XDECREF(pTb);
+
+ if (pRes == NULL) {
+ return "General Error in Python Callback";
+ }
+
+ pName = PyString_FromString("string");
+ PyObject *pString = PyImport_Import(pName);
+ Py_DECREF(pName);
+
+ if (pString == NULL) {
+ return "General Error in Python Callback";
+ }
+
+ pName = PyString_FromString("join");
+ PyObject *pErr = PyObject_CallMethodObjArgs(pString, pName, pRes, NULL);
+ Py_DECREF(pName);
+
+ Py_DECREF(pString);
+ Py_DECREF(pRes);
+
+ if (pErr == NULL) {
+ return "General Error in Python Callback";
+ }
+
+ QString str(PyString_AsString(pErr));
+ Py_DECREF(pErr);
+
+ return str;
+}
+
+QString getErrOutputFile(FQTermWindow *lp) {
+ // file name
+ QString str2;
+ str2.setNum(long(lp));
+ str2 += ".err";
+ // path
+ return getPath(USER_CONFIG) + str2;
+}
+
+// copy current artcle for back compatible use only
+// for new coder please use getArticle
+static PyObject *fqterm_copyArticle(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ FQTermWindow *termWindow_ = (FQTermWindow*)lp;
+
+ QStringList strList;
+ QString strArticle;
+ QReadWriteLock& bufferLock = termWindow_->getSession()->getBufferLock();
+ QReadLocker locker(&bufferLock);
+ while (1) {
+ // check it there is duplicated string
+ // it starts from the end in the range of one screen height
+ // so this is a non-greedy match
+ QString strTemp;
+ termWindow_->getSession()->getBuffer()->getTextLineInTerm(0)->getAllPlainText(strTemp);
+ strTemp = strTemp.trimmed();
+ int i = 0;
+ int start = 0;
+ for (QStringList::Iterator it = strList.end();
+ it != strList.begin() && i < termWindow_->getSession()->getBuffer()->getNumRows() - 1; // not exceeeding the last screen
+ --it, i++) {
+ if (*it != strTemp) {
+ continue;
+ }
+ QStringList::Iterator it2 = it;
+ bool dup = true;
+ // match more to see if its duplicated
+ for (int j = 0; j <= i; j++, it2++) {
+ QString str1;
+ termWindow_->getSession()->getBuffer()->getTextLineInTerm(j)->getAllPlainText(str1);
+ if (*it2 != str1.trimmed()) {
+ dup = false;
+ break;
+ }
+ }
+ if (dup) {
+ // set the start point
+ start = i + 1;
+ break;
+ }
+ }
+ // add new lines
+ for (i = start; i < termWindow_->getSession()->getBuffer()->getNumRows() - 1; i++) {
+ QString tmp;
+ termWindow_->getSession()->getBuffer()->getTextLineInTerm(i)->getAllPlainText(tmp);
+ strList += tmp.trimmed();
+ }
+
+ // the end of article
+ QString testEnd;
+ termWindow_->getSession()->getBuffer()->getTextLineInTerm(termWindow_->getSession()->getBuffer()->getNumRows() - 1)->getAllPlainText(testEnd);
+ if (testEnd.indexOf("%") == -1) {
+ break;
+ }
+ // continue
+ termWindow_->writeString_ts(" ");
+
+ // TODO: fixme
+ if (!termWindow_->getSession()->getWaitCondition().wait(&bufferLock, 10000)) {
+ // // timeout
+ break;
+ }
+ }
+#if defined(_OS_WIN32_) || defined(Q_OS_WIN32)
+ strArticle = strList.join("\r\n");
+#else
+ strArticle = strList.join("\n");
+#endif
+
+ PyObject *py_text = PyString_FromString(strArticle.toUtf8());
+
+ Py_INCREF(py_text);
+ return py_text;
+}
+
+static PyObject *fqterm_getArticle(PyObject *, PyObject *args) {
+ long lp;
+ int timeout;
+ int succeed = 1;
+
+ if (!PyArg_ParseTuple(args, "li", &lp, &timeout)) {
+ return NULL;
+ }
+ FQTermWindow *termWindow_ = (FQTermWindow*)lp;
+
+ QStringList strList;
+ QString strArticle;
+ QReadWriteLock& bufferLock = termWindow_->getSession()->getBufferLock();
+ while (!bufferLock.tryLockForRead()) {}
+ while (1) {
+ // check it there is duplicated string
+ // it starts from the end in the range of one screen height
+ // so this is a non-greedy match
+ QString strTemp;
+ termWindow_->getSession()->getBuffer()->getTextLineInTerm(0)->getAllPlainText(strTemp);
+ strTemp = strTemp.trimmed();
+
+ int i = 0;
+ int start = 0;
+ for (QStringList::Iterator it = strList.end();
+ it != strList.begin() && i < termWindow_->getSession()->getBuffer()->getNumRows() - 1; // not exceeeding the last screen
+ --it, i++) {
+ if (it == strList.end() || *it != strTemp) {
+ continue;
+ }
+ QStringList::Iterator it2 = it;
+ bool dup = true;
+ // match more to see if its duplicated
+ for (int j = 0; j <= i && it2 != strList.end(); j++, it2++) {
+ QString str1;
+ termWindow_->getSession()->getBuffer()->getTextLineInTerm(j)->getAllPlainText(str1);
+ if (*it2 != str1.trimmed()) {
+ dup = false;
+ break;
+ }
+ }
+ if (dup) {
+ // set the start point
+ start = i + 1;
+ break;
+ }
+ }
+ // add new lines
+ for (i = start; i < termWindow_->getSession()->getBuffer()->getNumRows() - 1; i++) {
+ QString tmp;
+ termWindow_->getSession()->getBuffer()->getTextLineInTerm(i)->getAllPlainText(tmp);
+ strList += tmp.trimmed();
+ }
+
+ // the end of article
+ QString testEnd;
+ termWindow_->getSession()->getBuffer()->getTextLineInTerm(termWindow_->getSession()->getBuffer()->getNumRows() - 1)->getAllPlainText(testEnd);
+ if (testEnd.indexOf("%") == -1) {
+ break;
+ }
+ // continue
+ termWindow_->writeString_ts(" ");
+
+ // TODO: fixme
+ if (!termWindow_->getSession()->getWaitCondition().wait(&bufferLock, timeout)) { // timeout
+ succeed = 0;
+ break;
+ }
+ }
+ bufferLock.unlock();
+ if (succeed)
+ strArticle = strList.join(OS_NEW_LINE);
+
+ PyObject *py_res = Py_BuildValue("si", (const char*)strArticle.toUtf8().data(),
+ succeed);
+
+ Py_INCREF(py_res);
+
+ return py_res;
+
+}
+
+static PyObject *fqterm_formatError(PyObject *, PyObject *args) {
+ long lp;
+
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ QString strErr;
+ QString filename = getErrOutputFile((FQTermWindow*)lp);
+
+ QDir d;
+ if (d.exists(filename)) {
+ QFile file(filename);
+ file.open(QIODevice::ReadOnly);
+ QTextStream is(&file);
+ while (!is.atEnd()) {
+ strErr += is.readLine(); // line of text excluding '\n'
+ strErr += '\n';
+ }
+ file.close();
+ d.remove(filename);
+ }
+
+ if (!strErr.isEmpty()) {
+ ((FQTermWindow*)lp)->getPythonErrorMessage() = strErr;
+ // TODO: fixme
+ //qApp->postEvent((FQTermWindow*)lp, new QCustomEvent(PYE_ERROR));
+ } else {
+ // TODO: fixme
+ //qApp->postEvent((FQTermWindow*)lp, new QCustomEvent(PYE_FINISH));
+ }
+
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+// caret x
+static PyObject *fqterm_caretX(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+ int x = ((FQTermWindow*)lp)->getSession()->getBuffer()->getCaretColumn();
+ PyObject *py_x = Py_BuildValue("i", x);
+ Py_INCREF(py_x);
+ return py_x;
+}
+
+// caret y
+static PyObject *fqterm_caretY(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+ int y = ((FQTermWindow*)lp)->getSession()->getBuffer()->getCaretRow();
+ PyObject *py_y = Py_BuildValue("i", y);
+ Py_INCREF(py_y);
+ return py_y;
+
+}
+
+// columns
+static PyObject *fqterm_columns(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ int numColumns = ((FQTermWindow*)lp)->getSession()->getBuffer()->getNumColumns();
+ PyObject *py_columns = Py_BuildValue("i", numColumns);
+
+ Py_INCREF(py_columns);
+ return py_columns;
+
+}
+
+// rows
+static PyObject *fqterm_rows(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ int rows = ((FQTermWindow*)lp)->getSession()->getBuffer()->getNumRows();
+ PyObject *py_rows = Py_BuildValue("i", rows);
+
+ Py_INCREF(py_rows);
+ return py_rows;
+}
+
+// sned string to server
+static PyObject *fqterm_sendString(PyObject *, PyObject *args) {
+ char *pstr;
+ long lp;
+
+ if (!PyArg_ParseTuple(args, "ls", &lp, &pstr)) {
+ return NULL;
+ }
+
+ ((FQTermWindow*)lp)->writeRawString_ts(U82U(pstr));
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+// input should be utf8.
+// same as above except parsing string first "\n" "^p" etc
+static PyObject *fqterm_sendParsedString(PyObject *, PyObject *args) {
+ char *pstr;
+ long lp;
+ int len;
+
+ if (!PyArg_ParseTuple(args, "ls", &lp, &pstr)) {
+ return NULL;
+ }
+ len = strlen(pstr);
+
+ ((FQTermWindow*)lp)->writeString_ts(U82U(pstr));
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+// get text at line
+static PyObject *fqterm_getText(PyObject *, PyObject *args) {
+ long lp;
+ int numRows;
+ if (!PyArg_ParseTuple(args, "li", &lp, &numRows)) {
+ return NULL;
+ }
+ QString str;
+ if (numRows < ((FQTermWindow*)lp)->getSession()->getBuffer()->getNumRows())
+ ((FQTermWindow*)lp)->getSession()->getBuffer()->getTextLineInTerm(numRows)->getAllPlainText(str);
+
+ PyObject *py_text = PyString_FromString(U2U8(str));
+
+ Py_INCREF(py_text);
+ return py_text;
+}
+
+// get text with attributes
+static PyObject *fqterm_getAttrText(PyObject *, PyObject *args) {
+ long lp;
+ int numRows;
+ if (!PyArg_ParseTuple(args, "li", &lp, &numRows)) {
+ return NULL;
+ }
+
+ QString str;
+ if (numRows < ((FQTermWindow*)lp)->getSession()->getBuffer()->getNumRows())
+ ((FQTermWindow*)lp)->getSession()->getBuffer()->getTextLineInTerm(numRows)->getAllAnsiText(str);
+
+ PyObject *py_text = PyString_FromString(U2U8(str));
+
+ Py_INCREF(py_text);
+ return py_text;
+}
+
+// is host connected
+static PyObject *fqterm_isConnected(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ bool connected = ((FQTermWindow*)lp)->isConnected();
+ PyObject *py_connected = Py_BuildValue("i", connected ? 1 : 0);
+
+ Py_INCREF(py_connected);
+ return py_connected;
+}
+
+// disconnect from host
+static PyObject *fqterm_disconnect(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ ((FQTermWindow*)lp)->disconnect();
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+// reconnect to host
+static PyObject *fqterm_reconnect(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ ((FQTermWindow*)lp)->getSession()->reconnect();
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+// bbs encoding 0-GBK 1-BIG5
+//FIXME: UTF8 and HKSCS
+static PyObject *fqterm_getBBSCodec(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ PyObject *py_codec = PyString_FromString(((FQTermWindow*)lp)
+ ->getSession()->param().serverEncodingID_ == 0 ? "GBK" : "Big5");
+ Py_INCREF(py_codec);
+
+ return py_codec;
+}
+
+// host address
+static PyObject *fqterm_getAddress(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ PyObject *py_addr = PyString_FromString(((FQTermWindow*)lp)
+ ->getSession()->param().hostAddress_.toLocal8Bit());
+ Py_INCREF(py_addr);
+ return py_addr;
+}
+
+// host port number
+static PyObject *fqterm_getPort(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ PyObject *py_port = Py_BuildValue("i", ((FQTermWindow*)lp)->getSession()->param().port_);
+ Py_INCREF(py_port);
+ return py_port;
+}
+
+// connection protocol 0-telnet 1-SSH1 2-SSH2
+static PyObject *fqterm_getProtocol(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ PyObject *py_port = Py_BuildValue("i", ((FQTermWindow*)lp)
+ ->getSession()->param().protocolType_);
+ Py_INCREF(py_port);
+ return py_port;
+}
+
+// key to reply msg
+static PyObject *fqterm_getReplyKey(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ PyObject *py_key = PyString_FromString(((FQTermWindow*)lp)
+ ->getSession()->param().replyKeyCombination_.toLocal8Bit());
+ Py_INCREF(py_key);
+ return py_key;
+}
+
+// url under mouse
+static PyObject *fqterm_getURL(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ PyObject *py_url = PyString_FromString(((FQTermWindow*)lp)->getSession()->getUrl().toUtf8().constData());
+ Py_INCREF(py_url);
+ return py_url;
+}
+
+// preview image link
+static PyObject *fqterm_previewImage(PyObject *, PyObject *args) {
+ long lp;
+ char *url;
+ if (!PyArg_ParseTuple(args, "ls", &lp, &url)) {
+ return NULL;
+ }
+
+ ((FQTermWindow*)lp)->getHttpHelper(url, true);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+
+}
+
+// convert string from UTF8 to specified encoding
+static PyObject *fqterm_fromUTF8(PyObject *, PyObject *args) {
+ char *str, *enc;
+ if (!PyArg_ParseTuple(args, "ss", &str, &enc)) {
+ return NULL;
+ }
+ QTextCodec *encodec = QTextCodec::codecForName(enc);
+ QTextCodec *utf8 = QTextCodec::codecForName("utf8");
+
+ PyObject *py_str = PyString_FromString(encodec->fromUnicode(utf8->toUnicode
+ (str)));
+ Py_INCREF(py_str);
+ return py_str;
+}
+
+// convert string from specified encoding to UTF8
+static PyObject *fqterm_toUTF8(PyObject *, PyObject *args) {
+ char *str, *enc;
+ if (!PyArg_ParseTuple(args, "ss", &str, &enc)) {
+ return NULL;
+ }
+ QTextCodec *encodec = QTextCodec::codecForName(enc);
+ QTextCodec *utf8 = QTextCodec::codecForName("utf8");
+
+ PyObject *py_str = PyString_FromString(utf8->fromUnicode(encodec->toUnicode
+ (str)));
+ Py_INCREF(py_str);
+ return py_str;
+}
+
+static PyObject *fqterm_wait(PyObject *, PyObject *args) {
+ long t;
+ if (!PyArg_ParseTuple(args, "l", &t)) {
+ return NULL;
+ }
+ SleeperThread::msleep(t);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyMethodDef fqterm_methods[] = {
+ {
+ "formatError", (PyCFunction)fqterm_formatError, METH_VARARGS,
+ "get the traceback info"
+ }
+
+ ,
+
+ {
+ "getArticle", (PyCFunction)fqterm_getArticle, METH_VARARGS,
+ "copy current article"
+ }
+
+ ,
+
+ {
+ "copyArticle", (PyCFunction)fqterm_copyArticle, METH_VARARGS,
+ "copy current article (obsolete)"
+ }
+
+ ,
+
+ {
+ "getText", (PyCFunction)fqterm_getText, METH_VARARGS, "get text at line#"
+ }
+
+ ,
+
+ {
+ "getAttrText", (PyCFunction)fqterm_getAttrText, METH_VARARGS,
+ "get attr text at line#"
+ }
+
+ ,
+
+ {
+ "sendString", (PyCFunction)fqterm_sendString, METH_VARARGS,
+ "send string to server"
+ }
+
+ ,
+
+ {
+ "sendParsedString", (PyCFunction)fqterm_sendParsedString, METH_VARARGS,
+ "send string with escape"
+ }
+
+ ,
+
+ {
+ "caretX", (PyCFunction)fqterm_caretX, METH_VARARGS, "caret x"
+ }
+
+ ,
+
+ {
+ "caretY", (PyCFunction)fqterm_caretY, METH_VARARGS, "caret y"
+ }
+
+ ,
+
+ {
+ "columns", (PyCFunction)fqterm_columns, METH_VARARGS, "screen width"
+ }
+
+ ,
+
+ {
+ "rows", (PyCFunction)fqterm_rows, METH_VARARGS, "screen height"
+ }
+
+ ,
+
+ {
+ "isConnected", (PyCFunction)fqterm_isConnected, METH_VARARGS,
+ "connected to server or not"
+ }
+
+ ,
+
+ {
+ "disconnect", (PyCFunction)fqterm_disconnect, METH_VARARGS,
+ "disconnect from server"
+ }
+
+ ,
+
+ {
+ "reconnect", (PyCFunction)fqterm_reconnect, METH_VARARGS, "reconnect"
+ }
+
+ ,
+
+ {
+ "getBBSCodec", (PyCFunction)fqterm_getBBSCodec, METH_VARARGS,
+ "get the bbs encoding, GBK or Big5"
+ }
+
+ ,
+
+ {
+ "getAddress", (PyCFunction)fqterm_getAddress, METH_VARARGS,
+ "get the bbs address"
+ }
+
+ ,
+
+ {
+ "getPort", (PyCFunction)fqterm_getPort, METH_VARARGS, "get the bbs port number"
+ }
+
+ ,
+
+ {
+ "getProtocol", (PyCFunction)fqterm_getProtocol, METH_VARARGS,
+ "get the bbs protocol, 0/1/2 TELNET/SSH1/SSH2"
+ }
+
+ ,
+
+ {
+ "getReplyKey", (PyCFunction)fqterm_getReplyKey, METH_VARARGS,
+ "get the key to reply messages"
+ }
+
+ ,
+
+ {
+ "getURL", (PyCFunction)fqterm_getURL, METH_VARARGS,
+ "get the url string under mouse"
+ }
+
+ ,
+
+ {
+ "previewImage", (PyCFunction)fqterm_previewImage, METH_VARARGS,
+ "preview the image link"
+ }
+
+ ,
+
+ {
+ "fromUTF8", (PyCFunction)fqterm_fromUTF8, METH_VARARGS,
+ "decode from utf8 to string in specified codec"
+ }
+
+ ,
+
+ {
+ "toUTF8", (PyCFunction)fqterm_toUTF8, METH_VARARGS,
+ "decode from string in specified codec to utf8"
+ }
+
+ ,
+
+ {
+ "wait", (PyCFunction)fqterm_wait, METH_VARARGS,
+ "wait for x ms"
+ }
+
+ ,
+
+ {
+ NULL, (PyCFunction)NULL, 0, NULL
+ }
+};
+
+
+
+FQTermPythonHelper::FQTermPythonHelper()
+ : mainThreadState_(NULL) {
+
+ // initialize Python
+ Py_Initialize();
+ // initialize thread support
+ PyEval_InitThreads();
+ // save a pointer to the main PyThreadState object
+ mainThreadState_ = PyThreadState_Get();
+ // add path
+ PyRun_SimpleString("import sys\n");
+ QString pathCmd;
+ pathCmd = "sys.path.insert(0,'";
+ pathCmd += getPath(RESOURCE)+"script')";
+ PyRun_SimpleString(fq_strdup(pathCmd.toUtf8().data()));
+
+ Py_InitModule4("fqterm", fqterm_methods,
+ NULL,(PyObject*)NULL,PYTHON_API_VERSION);
+ // release the lock
+ PyEval_ReleaseLock();
+}
+
+FQTermPythonHelper::~FQTermPythonHelper() {
+ // shut down the interpreter
+ PyInterpreterState * mainInterpreterState = mainThreadState_->interp;
+ // create a thread state object for this thread
+ PyThreadState * myThreadState = PyThreadState_New(mainInterpreterState);
+ PyThreadState_Swap(myThreadState);
+ PyEval_AcquireLock();
+ Py_Finalize();
+}
+
+} // namespace FQTerm
+
+#endif //HAVE_PYTHON \ No newline at end of file
diff --git a/src/fqterm/fqterm_python.h b/src/fqterm/fqterm_python.h
new file mode 100644
index 0000000..bad6b04
--- /dev/null
+++ b/src/fqterm/fqterm_python.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_PYTHON_H
+#define FQTERM_PYTHON_H
+
+#ifdef HAVE_PYTHON
+#include "fqterm.h"
+
+namespace FQTerm {
+
+class FQTermWindow;
+extern QString getException();
+extern QString getErrOutputFile(FQTermWindow*);
+extern PyMethodDef fqterm_methods[];
+
+class FQTermPythonHelper
+{
+public:
+ FQTermPythonHelper();
+ ~FQTermPythonHelper();
+ PyThreadState* getPyThreadState() {
+ return mainThreadState_;
+ }
+private:
+ PyThreadState * mainThreadState_;
+};
+
+} // namespace FQTerm
+
+#endif // HAVE_PYTHON
+
+#endif // FQTERM_PYTHON_H
+
diff --git a/src/fqterm/fqterm_screen.cpp b/src/fqterm/fqterm_screen.cpp
new file mode 100644
index 0000000..339e666
--- /dev/null
+++ b/src/fqterm/fqterm_screen.cpp
@@ -0,0 +1,1868 @@
+/****************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include <QApplication>
+#include <QPainter>
+#include <QScrollBar>
+#include <QShortcut>
+#include <QTextCharFormat>
+#include <QTimer>
+#include <QWheelEvent>
+#include <QKeySequence>
+#include <QRegion>
+#include <QPolygon>
+
+#include "fqterm_buffer.h"
+#include "fqterm_config.h"
+#include "fqterm_convert.h"
+#include "fqterm_frame.h"
+#include "fqterm_param.h"
+#include "fqterm_screen.h"
+#include "fqterm_session.h"
+#include "fqterm_text_line.h"
+#include "fqterm_window.h"
+#include "fqterm_wndmgr.h"
+#ifdef HAVE_PYTHON
+#include <Python.h>
+#endif //HAVE_PYTHON
+namespace FQTerm {
+/* ------------------------------------------------------------------------ */
+/* */
+/* Constructor/Destructor */
+/* */
+/* ------------------------------------------------------------------------ */
+
+FQTermScreen::FQTermScreen(QWidget *parent, FQTermSession *session)
+ : QWidget(parent),
+ scrollBarWidth_(15),
+ termBuffer_(session->getBuffer()),
+ cnLetterSpacing_(0.0),
+ spLetterSpacing_(0.0),
+ enLetterSpacing_(0.0),
+ cnFixedPitch_(false),
+ enFixedPitch_(false),
+ hasBackground_(false),
+ backgroundRenderOption_(0),
+ backgroundCoverage_(0),
+ backgroundAlpha_(0),
+ backgroundUseAlpha_(false) {
+ termWindow_ = (FQTermWindow*)parent;
+ session_ = session;
+ param_ = &session->param();
+ paintState_ = System;
+ isCursorShown_ = true;
+ is_light_background_mode_ = false;
+
+ setFocusPolicy(Qt::ClickFocus);
+ setAttribute(Qt::WA_InputMethodEnabled, true);
+ setMouseTracking(true);
+
+ setSchema();
+
+ initFontMetrics();
+
+ FQ_VERIFY(connect(termBuffer_, SIGNAL(bufferSizeChanged()),
+ this, SLOT(bufferSizeChanged())));
+
+ FQ_VERIFY(connect(termBuffer_, SIGNAL(termSizeChanged(int, int)),
+ this, SLOT(termSizeChanged(int, int))));
+
+ blinkTimer_ = new QTimer(this);
+ FQ_VERIFY(connect(blinkTimer_, SIGNAL(timeout()), this, SLOT(blinkEvent())));
+
+ cursorTimer_ = new QTimer(this);
+ FQ_VERIFY(connect(cursorTimer_, SIGNAL(timeout()),
+ this, SLOT(cursorEvent())));
+
+ // the scrollbar
+ scrollBar_ = new QScrollBar(this);
+ scrollBar_->setCursor(Qt::ArrowCursor);
+ bufferStart_ = 0;
+ bufferEnd_ = termBuffer_->getNumRows() - 1;
+ areLinesBlink_ = new bool[bufferEnd_ - bufferStart_ + 1];
+ scrollBar_->setRange(0, 0);
+ scrollBar_->setSingleStep(1);
+ scrollBar_->setPageStep(termBuffer_->getNumRows());
+ scrollBar_->setValue(0);
+ updateScrollBar();
+ FQ_VERIFY(connect(scrollBar_, SIGNAL(valueChanged(int)),
+ this, SLOT(scrollChanged(int))));
+
+ gotoPrevPage_ = new QShortcut(QKeySequence(tr("Shift+PageUp")),
+ this, SLOT(prevPage()));
+ gotoNextPage_ = new QShortcut(QKeySequence(tr("Shift+PageDown")),
+ this, SLOT(nextPage()));
+ gotoPrevLine_ = new QShortcut(QKeySequence(tr("Shift+Up")),
+ this, SLOT(prevLine()));
+ gotoNextLine_ = new QShortcut(QKeySequence(tr("Shift+Down")),
+ this, SLOT(nextLine()));
+
+ setAttribute(Qt::WA_OpaquePaintEvent, true);
+
+ // init variable
+ isBlinkScreen_ = false;
+ isBlinkCursor_ = true;
+
+
+ preedit_line_ = new PreeditLine(this, colors_);
+
+ tmp_im_query_ = new QString();
+}
+
+FQTermScreen::~FQTermScreen() {
+ delete [] areLinesBlink_;
+ delete blinkTimer_;
+ delete cursorTimer_;
+ //delete m_pCanvas;
+ //delete m_inputContent;
+
+ delete preedit_line_;
+
+ delete tmp_im_query_;
+}
+
+bool FQTermScreen::event(QEvent *e) {
+ switch(e->type()) {
+ case QEvent::KeyPress:
+ {
+ // forward all key press events to parant (FQTermWindow).
+ return false;
+ }
+ }
+ return this->QWidget::event(e);
+}
+
+// focus event received
+void FQTermScreen::focusInEvent(QFocusEvent*) {
+
+ gotoPrevPage_->setEnabled(true);
+ gotoNextPage_->setEnabled(true);
+ gotoPrevLine_->setEnabled(true);
+ gotoNextLine_->setEnabled(true);
+
+}
+
+// focus out
+void FQTermScreen::focusOutEvent(QFocusEvent*) {
+ gotoPrevPage_->setEnabled(false);
+ gotoNextPage_->setEnabled(false);
+ gotoPrevLine_->setEnabled(false);
+ gotoNextLine_->setEnabled(false);
+}
+
+void FQTermScreen::resizeEvent(QResizeEvent*) {
+ syncBufferAndScreen();
+}
+
+void FQTermScreen::syncBufferAndScreen() {
+ updateScrollBar();
+ updateBackgroundPixmap();
+
+ if (param_->isFontAutoFit_ == 1) {
+ updateFont();
+ } else if (param_->isFontAutoFit_ == 0) { //adjust column/row
+ int cx = clientRectangle_.width() / charWidth_;
+ int cy = clientRectangle_.height() / charHeight_;
+ if (param_->hostType_ == 0) {
+ if (cx < 80) cx = 80;
+ if (cy < 24) cy = 24;
+ } else {
+ if (cx < 10) cx = 10;
+ if (cy < 10) cy = 10;
+ }
+ session_->setTermSize(cx, cy);
+ //session_->writeStr("\0x5f");
+ } else {
+ session_->setTermSize(param_->numColumns_, param_->numRows_);
+ }
+}
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* Mouse */
+/* */
+/* ------------------------------------------------------------------------ */
+void FQTermScreen::enterEvent(QEvent *e) {
+ QApplication::sendEvent(termWindow_, e);
+}
+
+void FQTermScreen::leaveEvent(QEvent *e) {
+ QApplication::sendEvent(termWindow_, e);
+}
+
+void FQTermScreen::mousePressEvent(QMouseEvent *me) {
+
+ termWindow_->mousePressEvent(me);
+ setFocus();
+}
+
+void FQTermScreen::mouseMoveEvent(QMouseEvent *me) {
+#ifdef Q_OS_MACX
+ termWindow_->mouseMoveEvent(me);
+#else
+ termWindow_->mouseMoveEvent(me);
+ //QApplication::sendEvent(m_pWindow, me);
+#endif
+}
+
+void FQTermScreen::mouseReleaseEvent(QMouseEvent *me) {
+ termWindow_->mouseReleaseEvent(me);
+ //QApplication::sendEvent(m_pWindow, me);
+}
+
+void FQTermScreen::wheelEvent(QWheelEvent *we) {
+ if (FQTermPref::getInstance()->isWheelSupported_) {
+ QApplication::sendEvent(termWindow_, we);
+ } else {
+ QApplication::sendEvent(scrollBar_, we);
+ }
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* Font */
+/* */
+/* ------------------------------------------------------------------------ */
+
+void FQTermScreen::initFontMetrics() {
+ //issue 98
+ if (param_->isFontAutoFit_ == 1) {
+ englishFont_ = new QFont(param_->englishFontName_);
+ nonEnglishFont_ = new QFont(param_->otherFontName_);
+
+ updateFont();
+ } else {
+ englishFont_ = new QFont(param_->englishFontName_, qMax(8, param_->englishFontSize_));
+ nonEnglishFont_ = new QFont(param_->otherFontName_, qMax(8, param_->otherFontSize_));
+
+ setFontMetrics();
+ }
+
+ englishFont_->setWeight(QFont::Normal);;
+ nonEnglishFont_->setWeight(QFont::Normal);
+
+ // m_pFont->setStyleHint(QFont::System,
+ // m_pWindow->m_pFrame->m_pref.bAA ?
+ // QFont::PreferAntialias : QFont::NoAntialias);
+ updateFixedPitchInfo();
+}
+
+void FQTermScreen::updateFont() {
+ int nPixelSize;
+ int nIniSize =
+ qMax(8, qMin(clientRectangle_.height() / termBuffer_->getNumRows(),
+ clientRectangle_.width() *2 / termBuffer_->getNumColumns()));
+ //FIXME: WTF????
+ for (nPixelSize = nIniSize - 3; nPixelSize <= nIniSize + 3; nPixelSize++) {
+ englishFont_->setPixelSize(nPixelSize);
+ nonEnglishFont_->setPixelSize(nPixelSize);
+
+ setFontMetrics();
+ if ((termBuffer_->getNumRows() *charHeight_) > clientRectangle_.height() ||
+ (termBuffer_->getNumColumns() *charWidth_) > clientRectangle_.width()) {
+ while (nPixelSize > 5) {
+ nPixelSize--;
+ englishFont_->setPixelSize(nPixelSize);
+ nonEnglishFont_->setPixelSize(nPixelSize);
+
+ setFontMetrics();
+ //changed by dp to get larger font...
+ if ((termBuffer_->getNumRows()*charHeight_) <= clientRectangle_.height()
+ && (termBuffer_->getNumColumns() *charWidth_) <=
+ clientRectangle_.width()) {
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ englishFont_->setWeight(QFont::Normal);
+ nonEnglishFont_->setWeight(QFont::Normal);
+ setFontAntiAliasing(FQTermPref::getInstance()->openAntiAlias_);
+}
+
+void FQTermScreen::setFontMetrics() {
+
+ QFontMetrics nonEnglishFM(*nonEnglishFont_);
+ QFontMetrics englishFM(*englishFont_);
+
+ // FIXME: find a typical character for the current language.
+ int cn = nonEnglishFM.width(QChar(0x4e2D));
+ int en = englishFM.width('W');
+
+ int pix_size = nonEnglishFont_->pixelSize();
+ while (cn % 2 && pix_size > 10) {
+ nonEnglishFont_->setPixelSize(--pix_size);
+ nonEnglishFM = QFontMetrics(*nonEnglishFont_);
+ cn = nonEnglishFM.width(QChar(0x4e2D));
+ }
+
+ pix_size = englishFont_->pixelSize();
+ while (2 * en > cn + 1 && pix_size > 5) {
+ --pix_size;
+ englishFont_->setPixelSize(pix_size);
+ englishFM = QFontMetrics(*englishFont_);
+ en = englishFM.width('W');
+/*
+#ifndef __APPLE__
+ //FIXME: correctly draw chars with left/right bearing.
+ if ( - englishFM.leftBearing('W') - englishFM.rightBearing('W') > 0) {
+ en += - englishFM.leftBearing('W') - englishFM.rightBearing('W');
+ }
+#endif
+*/
+ }
+
+ charWidth_ = qMax(float(cn) / 2 , float(en));
+
+ charHeight_ = qMax(englishFM.height(), nonEnglishFM.height());
+ charHeight_ += param_->lineSpacing_;
+ //charWidth_ = ceil(qMax(charWidth_, charHeight_ * param_->charRatio_ / 100));
+ charWidth_ += param_->charSpacing_;
+
+ cnLetterSpacing_ = qMax(charWidth_ * 2 - cn, 0.0);
+ enLetterSpacing_ = qMax(charWidth_ - en, 0.0);
+
+ spLetterSpacing_ = qMax(charWidth_ - englishFM.width(' '), 0.0);
+
+ fontAscent_ = qMax(englishFM.ascent(), nonEnglishFM.ascent());
+ fontDescent_ = qMax(englishFM.descent(), nonEnglishFM.descent());
+
+ FQ_TRACE("font", 4) << "\nNon-English font:"
+ << "\nheight: " << nonEnglishFM.height()
+ << "\nascent: " << nonEnglishFM.ascent()
+ << "\ndescent: " << nonEnglishFM.descent();
+
+
+ FQ_TRACE("font", 4) << "\nEnglish font:"
+ << "\nheight: " << englishFM.height()
+ << "\nascent: " << englishFM.ascent()
+ << "\ndescent: " << englishFM.descent();
+
+ updateFixedPitchInfo();
+}
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* Colors */
+/* */
+/* ------------------------------------------------------------------------ */
+void FQTermScreen::setSchema() {
+ // the default color table
+ colors_[0] = Qt::black;
+ colors_[1] = Qt::darkRed;
+ colors_[2] = Qt::darkGreen;
+ colors_[3] = Qt::darkYellow;
+ colors_[4] = Qt::darkBlue;
+ colors_[5] = Qt::darkMagenta;
+ colors_[6] = Qt::darkCyan;
+ colors_[7] = Qt::darkGray;
+ colors_[8] = Qt::gray;
+ colors_[9] = Qt::red;
+ colors_[10] = Qt::green;
+ colors_[11] = Qt::yellow;
+ colors_[12] = Qt::blue;
+ colors_[13] = Qt::magenta;
+ colors_[14] = Qt::cyan;
+ colors_[15] = Qt::white;
+
+
+ hasBackground_ = false;
+ // if we have schema defined
+ if (QFile::exists(param_->schemaFileName_)) {
+ FQTermConfig *pConf = new FQTermConfig(param_->schemaFileName_);
+ for (int i = 0; i < 16; ++i) {
+ colors_[i].setNamedColor(pConf->getItemValue("color", QString("color%1").arg(i)));
+ }
+ originBackgroundPixmap_ = QPixmap(pConf->getItemValue("image", "name"));
+ //0 -- none 1 -- image
+ hasBackground_ = pConf->getItemValue("background", "type").toInt() ? 1 : 0;
+ backgroundRenderOption_ = pConf->getItemValue("image", "render").toInt();
+ backgroundCoverage_ = pConf->getItemValue("image", "cover").toInt();
+ backgroundUseAlpha_ = pConf->getItemValue("image", "usealpha").toInt();
+ backgroundAlpha_ = pConf->getItemValue("image", "alpha").toInt();
+
+ delete pConf;
+ }
+
+ // override schema using user defined Fg/Bg color
+ colors_[0] = param_->backgroundColor_;
+ colors_[7] = param_->foregroundColor_;
+}
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* Scrollbar */
+/* */
+/* ------------------------------------------------------------------------*/
+void FQTermScreen::prevPage() {
+ scrollLine(-termBuffer_->getNumRows());
+ setPaintState(NewData);
+ update();
+}
+
+void FQTermScreen::nextPage() {
+ scrollLine(termBuffer_->getNumRows());
+ setPaintState(NewData);
+ update();
+}
+
+void FQTermScreen::prevLine() {
+ scrollLine(-1);
+ setPaintState(NewData);
+ update();
+}
+
+void FQTermScreen::nextLine() {
+ scrollLine(1);
+ setPaintState(NewData);
+ update();
+}
+
+void FQTermScreen::scrollLine(int delta) {
+ bufferStart_ += delta;
+
+ if (bufferStart_ < 0) {
+ bufferStart_ = 0;
+ return ;
+ }
+ if (bufferStart_ > termBuffer_->getNumLines() - termBuffer_->getNumRows()) {
+ bufferStart_ = termBuffer_->getNumLines() - termBuffer_->getNumRows();
+ return ;
+ }
+
+ scrollBar_->setValue(bufferStart_);
+ bufferEnd_ = bufferStart_ + termBuffer_->getNumRows() - 1;
+
+ // notify session
+ session_->setScreenStart(bufferStart_);
+
+ for (int i = bufferStart_; i <= bufferEnd_; i++) {
+ session_->setLineAllChanged(i);
+ }
+}
+
+void FQTermScreen::scrollChanged(int value) {
+ if (bufferStart_ == value) {
+ return ;
+ }
+
+ if (value < 0) {
+ value = 0;
+ }
+ if (value > termBuffer_->getNumLines() - termBuffer_->getNumRows()) {
+ value = termBuffer_->getNumLines() - termBuffer_->getNumRows();
+ }
+
+ bufferStart_ = value;
+ bufferEnd_ = value + termBuffer_->getNumRows() - 1;
+
+ // notify session
+ session_->setScreenStart(bufferStart_);
+
+ for (int i = bufferStart_; i <= bufferEnd_; i++) {
+ //termBuffer_->at(i)->setChanged(-1, -1);
+ session_->setLineAllChanged(i);
+ }
+
+ setPaintState(NewData);
+ update();
+}
+
+void FQTermScreen::updateScrollBar() {
+ int numLeftPixels = 0; // ß¾
+ int numUpPixels = 0; // ϱ߾
+
+ switch (FQTermPref::getInstance()->termScrollBarPosition_) {
+ case 0:
+ scrollBar_->hide();
+ clientRectangle_ = QRect(numLeftPixels, numUpPixels,
+ rect().width() - numLeftPixels,
+ rect().height() - numUpPixels);
+ break;
+ case 1:
+ // LEFT
+ scrollBar_->setGeometry(0, 0, scrollBarWidth_, rect().height());
+ scrollBar_->show();
+ clientRectangle_ = QRect(scrollBarWidth_ + numLeftPixels, numUpPixels,
+ rect().width() - scrollBarWidth_ - numLeftPixels,
+ rect().height() - numUpPixels);
+ break;
+ case 2:
+ // RIGHT
+ scrollBar_->setGeometry(rect().width() - scrollBarWidth_, 0,
+ scrollBarWidth_, rect().height());
+ scrollBar_->show();
+ clientRectangle_ = QRect(numLeftPixels, numUpPixels,
+ rect().width() - scrollBarWidth_ - numLeftPixels,
+ rect().height() - numUpPixels);
+ break;
+ }
+ setPaintState(Repaint);
+ update();
+}
+
+void FQTermScreen::bufferSizeChanged() {
+ FQ_VERIFY(disconnect(scrollBar_, SIGNAL(valueChanged(int)),
+ this, SLOT(scrollChanged(int))));
+ scrollBar_->setRange(0, termBuffer_->getNumLines() - termBuffer_->getNumRows());
+ scrollBar_->setSingleStep(1);
+ scrollBar_->setPageStep(termBuffer_->getNumRows());
+
+ // FIXME: should not always move scroll bar to the bottom when
+ // buffer size is changed.
+ scrollBar_->setValue(termBuffer_->getNumLines() - termBuffer_->getNumRows());
+
+ bufferStart_ = scrollBar_->value();
+ bufferEnd_ = scrollBar_->value() + termBuffer_->getNumRows() - 1;
+
+ // notify session
+ session_->setScreenStart(bufferStart_);
+
+ FQ_VERIFY(connect(scrollBar_, SIGNAL(valueChanged(int)),
+ this, SLOT(scrollChanged(int))));
+
+ delete [] areLinesBlink_;
+ areLinesBlink_ = new bool[bufferEnd_ - bufferStart_ + 1];
+
+ scrollLine(0);
+}
+
+void FQTermScreen::termSizeChanged(int column, int row) {
+ FQ_TRACE("term", 3) << "The term size is changed to " << column << "x" << row;
+ syncBufferAndScreen();
+ bufferSizeChanged();
+ this->setPaintState(Repaint);
+ this->repaint();
+}
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* Display */
+/* */
+/* ------------------------------------------------------------------------ */
+
+//set pixmap background
+
+void FQTermScreen::updateBackgroundPixmap() {
+ if (!hasBackground_)
+ return;
+
+ switch (backgroundRenderOption_) {
+ case 0:
+ //tile
+ {
+ backgroundPixmap_ = QPixmap(clientRectangle_.size());
+ QPainter painter(&backgroundPixmap_);
+ painter.drawTiledPixmap(backgroundPixmap_.rect(), originBackgroundPixmap_);
+ }
+ break;
+ case 1:
+ //center
+ {
+ backgroundPixmap_ = QPixmap(clientRectangle_.size());
+ backgroundPixmap_.fill(colors_[0]);
+ QPainter painter(&backgroundPixmap_);
+ int x = (backgroundPixmap_.size() - originBackgroundPixmap_.size()).width() / 2;
+ int y = (backgroundPixmap_.size() - originBackgroundPixmap_.size()).height() / 2;
+ painter.drawPixmap(x, y, originBackgroundPixmap_);
+ }
+ break;
+ case 2:
+ //stretch
+ backgroundPixmap_ = originBackgroundPixmap_.scaled(clientRectangle_.size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ break;
+ }
+ /*
+ hasBackground_ = false;
+ backgroundPixmap_ = pixmap;
+ backgroundPixmapType_ = nType;
+ QPalette palette;
+
+ switch (nType) {
+ case 0:
+ // none
+ palette.setColor(backgroundRole(), colors_[0]);
+ setPalette(palette);
+ break;
+ case 1:
+ //{ // transparent{}
+ break;
+ case 2:
+ // tile
+ if (!pixmap.isNull())
+ palette.setBrush(backgroundRole(), QBrush(pixmap));
+ setPalette(palette);
+ // updateBackgroundPixmap( pixmap );
+ hasBackground_ = true;
+ break;
+ //}
+ case 3:
+ // center
+ if (!pixmap.isNull()) {
+ QPixmap pxmBg = QPixmap(size());
+ QPainter painter(&pxmBg);
+ pxmBg.fill(colors_[0]);
+ painter.drawPixmap((size().width() - pixmap.width()) / 2,
+ (size().height() - pixmap.height()) / 2,
+ pixmap.width(), pixmap.height(), pixmap);
+ palette.setBrush(backgroundRole(), QBrush(pxmBg));
+ setPalette(palette);
+ // updateBackgroundPixmap(pxmBg);
+ hasBackground_ = true;
+ break;
+ }
+ case 4:
+ // stretch
+ if (!pixmap.isNull()) {
+ float sx = (float)size().width() / pixmap.width();
+ float sy = (float)size().height() / pixmap.height();
+ QMatrix matrix;
+ matrix.scale(sx, sy);
+ palette.setBrush(backgroundRole(), QBrush(pixmap.transformed(matrix)));
+ setPalette(palette);
+ // updateBackgroundPixmap(pixmap.transformed( matrix ));
+ hasBackground_ = true;
+ break;
+ }
+ default:
+ palette.setColor(backgroundRole(), colors_[0]);
+ setPalette(palette);
+ // setBackgroundColor( m_color[0] );
+
+ }
+ */
+}
+
+void FQTermScreen::cursorEvent() {
+ if (isBlinkCursor_) {
+ setPaintState(Cursor);
+ isCursorShown_ = !isCursorShown_;
+ update();
+ }
+}
+
+void FQTermScreen::blinkEvent() {
+ if (hasBlinkText_) {
+ isBlinkScreen_ = !isBlinkScreen_;
+ setPaintState(Blink);
+ update();
+ }
+}
+
+void FQTermScreen::paintEvent(QPaintEvent *pe) {
+ FQ_TRACE("screen", 8) << "paintEvent " << pe->rect().x() << "," << pe->rect().y() << " "
+ << pe->rect().width() << "x" << pe->rect().height();
+ QPainter painter(this);
+ painter.setRenderHint(QPainter::Antialiasing, FQTermPref::getInstance()->openAntiAlias_);
+ painter.setRenderHint(QPainter::TextAntialiasing, FQTermPref::getInstance()->openAntiAlias_);
+ if (paintState_ == System) {
+ repaintScreen(pe, painter);
+ return;
+ }
+
+ if (testPaintState(Repaint)) {
+ FQ_TRACE("screen", 8) << "paintEvent " << "repaint";
+ repaintScreen(pe, painter);
+ clearPaintState(Repaint);
+ }
+
+ if (testPaintState(NewData)) {
+ if (termBuffer_->isLightBackgroundMode() != is_light_background_mode_) {
+ FQ_TRACE("screen", 8) << "paintEvent " << "new data repaint";
+ is_light_background_mode_ = termBuffer_->isLightBackgroundMode();
+ if (is_light_background_mode_) {
+ colors_[0] = param_->foregroundColor_;
+ colors_[7] = param_->backgroundColor_;
+ } else {
+ colors_[0] = param_->backgroundColor_;
+ colors_[7] = param_->foregroundColor_;
+ }
+ repaintScreen(pe, painter);
+ } else {
+ FQ_TRACE("screen", 8) << "paintEvent " << "new data refresh";
+ refreshScreen(painter);
+ }
+
+ clearPaintState(NewData);
+ }
+
+ if (testPaintState(Blink)) {
+ FQ_TRACE("screen", 8) << "paintEvent " << "blink";
+ blinkScreen(painter);
+ clearPaintState(Blink);
+ }
+
+ if (testPaintState(Cursor)) {
+ FQ_TRACE("screen", 8) << "paintEvent " << "cursor";
+ updateCursor(painter);
+ clearPaintState(Cursor);
+ }
+
+ if (testPaintState(Widget)) {
+ updateWidgetRect(painter);
+ clearPaintState(Widget);
+ }
+}
+
+void FQTermScreen::blinkScreen(QPainter &painter) {
+ painter.setBackground(QBrush(colors_[0]));
+
+ for (int index = bufferStart_; index <= bufferEnd_; index++) {
+ if (areLinesBlink_[index - bufferStart_]) {
+ const FQTermTextLine *pTextLine = termBuffer_->getTextLineInBuffer(index);
+ uint linelength = pTextLine->getWidth();
+ const unsigned char *attr = pTextLine->getAttributes();
+ for (uint i = 0; i < linelength; ++i) {
+ if (GETBLINK(attr[i])) {
+ int startx = i;
+ while (i < linelength && GETBLINK(attr[i])) {
+ ++i;
+ }
+ drawLine(painter, index, startx, i, false);
+ }
+ }
+ }
+ }
+}
+
+void FQTermScreen::updateCursor(QPainter &painter) {
+ if (termBuffer_->getCaretColumn() >= termBuffer_->getNumColumns()) {
+ // we only allow the cursor located beyond the terminal screen temporarily.
+ // just ignore this.
+ return;
+ }
+
+ bool isCursorShown = isCursorShown_;
+ if (FQTermPref::getInstance()->isBossColor_) {
+ isCursorShown = true;
+ }
+
+ if (termBuffer_->getCaretLine() <= bufferEnd_
+ && termBuffer_->getCaretLine() >= bufferStart_) {
+
+ if (!isCursorShown) {
+ const FQTermTextLine *pTextLine
+ = termBuffer_->getTextLineInBuffer(termBuffer_->getCaretLine());
+ if ((int)pTextLine->getWidth() > termBuffer_->getCaretColumn()) {
+ int startx = pTextLine->getCellBegin(termBuffer_->getCaretColumn());
+ int endx = pTextLine->getCellEnd(termBuffer_->getCaretColumn() + 1);
+ if ((int)pTextLine->getWidth() > endx) {
+ endx = pTextLine->getCellEnd(endx + 1);
+ }
+ drawLine(painter, termBuffer_->getCaretLine(), startx, endx,
+ termBuffer_->getCaretLine());
+ } else {
+ //painter.fillRect(mapToRect(termBuffer_->getCaretColumn(), termBuffer_->getCaretLine(), 1, 1),colors_[0]);
+ drawBackground(painter, mapToRect(termBuffer_->getCaretColumn(),termBuffer_->getCaretLine(), 1, 1), 0);
+ }
+ return;
+ }
+
+ QPoint pt = mapToPixel(QPoint(termBuffer_->getCaretColumn(),
+ termBuffer_->getCaretLine()));
+ switch (param_->cursorType_) {
+ case 0:
+ // block
+ {
+ int x = termBuffer_->getCaretColumn();
+ int y = termBuffer_->getCaretLine();
+ const FQTermTextLine *pTextLine = termBuffer_->getTextLineInBuffer(y);
+ if ((int)pTextLine->getWidth() > x) {
+
+ int startx = pTextLine->getCellBegin(x);
+ int endx = pTextLine->getCellEnd(x + 1);
+
+ drawLine(painter, termBuffer_->getCaretLine(), startx, endx,
+ termBuffer_->getCaretLine());
+
+ QRect rect = mapToRect(startx, termBuffer_->getCaretLine(), 1, 1);
+ rect.translate(0, 0);
+ painter.fillRect(rect, colors_[7]);
+ } else {
+ QRect rect = mapToRect(termBuffer_->getCaretColumn(),
+ termBuffer_->getCaretLine(), 1, 1);
+ rect.translate(0, 0);
+ painter.fillRect(rect,
+ colors_[7]);
+ }
+ }
+ break;
+ case 1:
+ // underline
+ painter.fillRect(pt.x(), pt.y() + 9 * charHeight_ / 10, charWidth_,
+ charHeight_ / 10, colors_[7]);
+ break;
+ case 2:
+ // I type
+ painter.fillRect(pt.x(), pt.y() + 1, charWidth_ / 5, charHeight_ - 1,
+ colors_[7]);
+ break;
+ default:
+ painter.fillRect(pt.x(), pt.y()+1,
+ charWidth_, charHeight_ - 1, colors_[7]);
+ }
+ }
+}
+
+
+// refresh the screen when
+// 1. received new contents form server
+// 2. scrolled by user
+void FQTermScreen::refreshScreen(QPainter &painter) {
+ FQ_FUNC_TIMER("screen_paint", 5);
+
+ if (cursorTimer_->isActive()) {
+ cursorTimer_->stop();
+ }
+
+ if (blinkTimer_->isActive()) {
+ blinkTimer_->stop();
+ }
+
+ hasBlinkText_ = false;
+ isCursorShown_ = true;
+
+ for (int index = bufferStart_; index <= bufferEnd_; index++) {
+
+ FQ_VERIFY(index < termBuffer_->getNumLines());
+
+ const FQTermTextLine *pTextLine = termBuffer_->getTextLineInBuffer(index);
+
+ if (pTextLine->hasBlink()) {
+ hasBlinkText_ = true;
+ areLinesBlink_[index - bufferStart_] = true;
+ } else {
+ areLinesBlink_[index - bufferStart_] = false;
+ }
+
+ unsigned int startx, endx;
+ if (!pTextLine->getDirtyCells(startx, endx)) {
+ continue;
+ }
+
+ /*
+ Finally get around this for pku & ytht, don't know why some weird things
+ happened when only erase and draw the changed part.
+ */
+ startx = pTextLine->getCellBegin(startx);
+
+ int len = -1;
+ if ((int)endx != -1) {
+ len = endx - startx;
+ } else {
+ len = pTextLine->getMaxCellCount() - startx;
+ }
+
+ QRect rect = mapToRect(startx, index, len, 1);
+
+ //painter.fillRect(rect ,QBrush(colors_[0]));
+ drawBackground(painter, rect, 0);
+
+ drawLine(painter, index, startx, endx);
+
+ session_->clearLineChanged(index);
+ }
+
+ updateMicroFocus();
+ if (termWindow_->isConnected()) {
+ updateCursor(painter);
+ }
+
+
+ if (termWindow_->isConnected()) {
+ cursorTimer_->start(1000);
+ }
+
+ if (hasBlinkText_) {
+ blinkTimer_->start(1000);
+ }
+}
+
+void FQTermScreen::repaintScreen(QPaintEvent *pe, QPainter &painter) {
+ FQ_FUNC_TIMER("screen_paint", 5);
+
+ //painter.setBackground(QBrush(colors_[0]));
+
+ FQ_TRACE("screen", 5) << "Client area: " << pe->rect().width()
+ << "x" << pe->rect().height();
+
+ QRect rect = pe->rect().intersect(clientRectangle_);
+ //painter.eraseRect(rect);
+ drawBackground(painter, rect, 0);
+ QPoint tlPoint = mapToChar(QPoint(rect.left(), rect.top()));
+
+ QPoint brPoint = mapToChar(QPoint(rect.right(), rect.bottom()));
+
+ for (int y = tlPoint.y(); y <= brPoint.y(); y++) {
+ drawLine(painter, y);
+ }
+ if (termWindow_->getUrlStartPoint() != termWindow_->getUrlEndPoint()) {
+ drawUnderLine(painter, termWindow_->getUrlStartPoint(), termWindow_->getUrlEndPoint());
+ }
+
+
+}
+
+/////////////////////////////////////////////////
+//TODO: change to a more powerful function
+FQTermScreen::TextRenderingType FQTermScreen::charRenderingType(const QChar& c) {
+ if (c == ' ') return HalfAndSpace;
+ if (c.unicode() > 0x7f && c.unicode() <= 0x2dff) {
+ return FullAndAlign;
+ } else if (c.unicode() > 0x2dff) {
+ if (cnFixedPitch_)
+ return FullNotAlign;
+ else
+ return FullAndAlign;
+ }
+ return HalfAndAlign;
+}
+
+static bool isColorBlock(const QChar& c) {
+ if (!FQTermPref::getInstance()->isAnsciiEnhance_) return false;
+ return ((c.unicode() >= 0x2581 && c.unicode() <= 0x258f) ||
+ (c.unicode() >= 0x25e2 && c.unicode() <= 0x25e5));
+}
+
+/////////////////////////////////////////////////
+// draw a line with the specialAtter if given.
+// modified by hooey to draw part of the line.
+void FQTermScreen::drawLine(QPainter &painter, int index, int startx, int endx,
+ bool complete) {
+ FQ_ASSERT(index < termBuffer_->getNumLines());
+
+ const FQTermTextLine *pTextLine = termBuffer_->getTextLineInBuffer(index);
+ const unsigned char *color = pTextLine->getColors();
+ const unsigned char *attr = pTextLine->getAttributes();
+
+ uint linelength = pTextLine->getWidth();
+ bool isSessionSelected = session_->isSelectedMenu(index);
+ bool isTransparent = isSessionSelected && param_->menuType_ == 2;
+
+ menuRect_ = QRect();
+ QString cstrText;
+
+ if (startx < 0) {
+ startx = 0;
+ }
+
+ if (endx > (long)linelength || endx < 0) {
+ endx = linelength;
+ }
+
+ if (complete == true && isSessionSelected) {
+ menuRect_ = drawMenuSelect(painter, index);
+ startx = 0;
+ endx = linelength;
+ }
+
+ startx = pTextLine->getCellBegin(startx);
+ endx = pTextLine->getCellEnd(endx);
+
+ bool isMonoSpace = true;
+ if (!cnFixedPitch_
+ || !enFixedPitch_) {
+ isMonoSpace = false;
+ }
+
+
+
+ for (unsigned i = startx; (long)i < endx;) {
+ startx = i;
+ unsigned char tempcp = color[i];
+ unsigned char tempea = attr[i];
+ unsigned cell_begin = pTextLine->getCellBegin(startx);
+ unsigned cell_end = pTextLine->getCellEnd(cell_begin + 1);
+ TextRenderingType temprt;
+ cstrText.clear();
+ pTextLine->getPlainText(cell_begin, cell_end, cstrText);
+ temprt = charRenderingType(cstrText[0]);
+ bool color_block = isColorBlock(cstrText[0]);
+
+ bool bSelected = termBuffer_->isSelected(
+ QPoint(i, index), param_->isRectSelect_);
+
+ // get str of the same attribute
+ while ((long)i < endx && tempcp == color[i] && tempea == attr[i] &&
+ bSelected == termBuffer_->isSelected(
+ QPoint(i, index), param_->isRectSelect_)) {
+ unsigned cellBegin = pTextLine->getCellBegin(i);
+ unsigned cellEnd = pTextLine->getCellEnd(cellBegin + 1);
+ cstrText.clear();
+ pTextLine->getPlainText(cellBegin, cellEnd, cstrText);
+ if (temprt != charRenderingType(cstrText[0])) {
+ break;
+ }
+ bool colorBlock = isColorBlock(cstrText[0]);
+ if (cell_end != cellEnd && colorBlock || color_block && !colorBlock) {
+ break;
+ }
+ ++i;
+ }
+
+ cell_end = pTextLine->getCellEnd(i);
+ cstrText.clear();
+ pTextLine->getPlainText(cell_begin, cell_end, cstrText);
+
+ unsigned j = i;
+ if (j > 0 && pTextLine->getCellBegin(j) == pTextLine->getCellBegin(j - 1)
+ && *(pTextLine->getColors() + j) != *(pTextLine->getColors() + j - 1)) {
+ j++;
+ }
+ for (; j < cell_end; ++j) {
+ cstrText.append((QChar)URC);
+ }
+
+ int text_width = cell_end - cell_begin;
+
+ bool draw_half_begin_char = false;
+
+ if (startx > 0 && pTextLine->getCellBegin(startx) == pTextLine->getCellBegin(startx - 1)
+ && *(pTextLine->getColors() + startx) != *(pTextLine->getColors() + startx - 1)) {
+//#if defined(WIN32)
+ draw_half_begin_char = true;
+//#else
+// startx++;
+//#endif
+ }
+
+ painter.setFont((temprt == HalfAndAlign || temprt == HalfAndSpace)?*englishFont_:*nonEnglishFont_);
+ if (isMonoSpace && temprt != FullAndAlign) {
+ QFont& font = (temprt == HalfAndAlign || temprt == HalfAndSpace)?*englishFont_:*nonEnglishFont_;
+ if (temprt == HalfAndAlign) {
+ font.setLetterSpacing(QFont::AbsoluteSpacing, enLetterSpacing_);
+ } else if (temprt == HalfAndSpace) {
+ font.setLetterSpacing(QFont::AbsoluteSpacing, spLetterSpacing_);
+ } else {
+ font.setLetterSpacing(QFont::AbsoluteSpacing, cnLetterSpacing_);
+ }
+ painter.setFont(font);
+ if (draw_half_begin_char) {
+ text_width--;
+ draw_half_begin_char = false;
+ }
+ drawStr(painter, cstrText, startx, index, text_width,
+ tempcp, tempea, isTransparent, bSelected);
+ font.setLetterSpacing(QFont::AbsoluteSpacing, 0.0);
+ } else if (temprt == FullNotAlign) {
+ nonEnglishFont_->setLetterSpacing(QFont::AbsoluteSpacing, cnLetterSpacing_);
+ painter.setFont(*nonEnglishFont_);
+ if (draw_half_begin_char) {
+ text_width--;
+ draw_half_begin_char = false;
+ }
+ drawStr(painter, cstrText, startx, index, text_width,
+ tempcp, tempea, isTransparent, bSelected);
+ nonEnglishFont_->setLetterSpacing(QFont::AbsoluteSpacing, 0.0);
+ } else if (temprt == HalfAndSpace) {
+ englishFont_->setLetterSpacing(QFont::AbsoluteSpacing, spLetterSpacing_);
+ painter.setFont(*englishFont_);
+ if (draw_half_begin_char) {
+ text_width--;
+ draw_half_begin_char = false;
+ }
+ drawStr(painter, cstrText, startx, index, text_width,
+ tempcp, tempea, isTransparent, bSelected);
+ englishFont_->setLetterSpacing(QFont::AbsoluteSpacing, 0.0);
+ }else {
+ englishFont_->setLetterSpacing(QFont::AbsoluteSpacing, enLetterSpacing_);
+ nonEnglishFont_->setLetterSpacing(QFont::AbsoluteSpacing, cnLetterSpacing_);
+ if (temprt == HalfAndAlign)
+ painter.setFont(*englishFont_);
+ else if (temprt == FullAndAlign)
+ painter.setFont(*nonEnglishFont_);
+ // Draw Characters one by one to fix the variable-width font
+ // display problem.
+ int offset = 0;
+ for (uint j = 0; (long)j < cstrText.length(); ++j) {
+ // TODO_UTF16: wrong character width here.
+ if (temprt == HalfAndAlign) {
+ drawStr(painter, (QString)cstrText.at(j),
+ startx + offset, index, 1,
+ tempcp, tempea,
+ isTransparent, bSelected);
+ offset++;
+ } else if (temprt == FullAndAlign){
+
+
+ int w = 2;
+ if (draw_half_begin_char) {
+ w--;
+ }
+ drawStr(painter, (QString)cstrText.at(j),
+ startx + offset, index, w,
+ tempcp, tempea,
+ isTransparent, bSelected);
+ if (draw_half_begin_char) {
+ draw_half_begin_char = false;
+ offset--;
+ }
+ offset += 2;
+
+ }
+ }
+ nonEnglishFont_->setLetterSpacing(QFont::AbsoluteSpacing, 0.0);
+ englishFont_->setLetterSpacing(QFont::AbsoluteSpacing, 0.0);
+ }
+ }
+}
+//
+// draw functions
+void FQTermScreen::drawStr(QPainter &painter, const QString &str,
+ int x, int y, int length,
+ unsigned char color, unsigned char attr,
+ bool transparent, bool selected) {
+ unsigned char cp = color;
+ unsigned char ea = attr;
+
+ // test bold mask or always highlighted
+ if (GETBRIGHT(ea) || param_->isAlwaysHighlight_) {
+ cp |= SET_FG_HIGHLIGHT(1);
+ }
+
+ // use 8-15 color
+ // test dim mask
+ if (GETDIM(ea)) {
+ }
+
+ // test underline mask
+ if (GETUNDERLINE(ea)) {
+ QFont font = painter.font();
+ font.setUnderline(true);
+ painter.setFont(font);
+ } else {
+ QFont font = painter.font();
+ font.setUnderline(false);
+ painter.setFont(font);
+ }
+ // test blink mask
+ if (GETBLINK(ea)){}
+ // test rapidblink mask
+ if (GETRAPIDBLINK(ea)){}
+ // test reverse mask
+ if (GETREVERSE(ea)) {
+ cp = GET_INVERSE_COLOR(cp);
+ }
+
+ if (selected) {
+ cp = GET_INVERSE_COLOR(cp);
+ }
+
+ // test invisible mask
+ if (GETINVISIBLE(ea)) {
+ }
+
+
+
+ int pen_color_index = GETFG(cp);
+ if (!param_->isAnsiColor_) {
+ if (GETBG(cp) != 0) {
+ pen_color_index = 0;
+ } else {
+ pen_color_index = 7;
+ }
+ }
+ painter.setPen(colors_[pen_color_index]);
+
+ int brush_color_index = GETBG(cp);
+ if (!param_->isAnsiColor_) {
+ if (GETBG(cp) != 0) {
+ brush_color_index = 7;
+ } else {
+ brush_color_index = 0;
+ }
+ }
+
+
+ QBrush brush(colors_[brush_color_index]);
+
+ // black on white without attr
+ if (FQTermPref::getInstance()->isBossColor_) {
+ painter.setPen(Qt::black);
+ brush = QBrush(Qt::white);
+ }
+
+ QPoint pt = mapToPixel(QPoint(x, y));
+ QRect rcErase = mapToRect(x, y, length, 1);
+
+ if (!menuRect_.intersects(rcErase)){
+ if (x == 0) {
+ rcErase.setLeft(rcErase.left() - 1);
+ }
+ //painter.fillRect(rcErase, brush);
+ drawBackground(painter, rcErase, brush_color_index);
+ if (x == 0) {
+ rcErase.setLeft(rcErase.left() + 1);
+ }
+ } else {
+ QRect rcKeep = menuRect_.intersected(rcErase);
+ rcKeep.setY(rcErase.y());
+ rcKeep.setHeight(rcErase.height());
+ if (rcErase.left() < rcKeep.left()) {
+ QPoint point = rcKeep.bottomLeft();
+ point.setX(point.x() + 1);
+ point.setY(point.y() + 1);
+ painter.fillRect(QRect(rcErase.topLeft(), point),
+ brush);
+ }
+ if (rcKeep.right() < rcErase.right()) {
+ QPoint point = rcErase.bottomRight();
+ point.setX(point.x() + 1);
+ point.setY(point.y() + 1);
+
+ painter.fillRect(QRect(rcKeep.topRight(), point),
+ brush);
+ }
+ }
+
+ if (!(isBlinkScreen_ && GETBLINK(attr))) {
+ FQ_TRACE("draw_text", 10) << "draw text: " << str;
+
+ QFontMetrics qm = painter.fontMetrics();
+ int font_height = qm.height();
+ int expected_font_height = rcErase.height();
+ int height_gap = expected_font_height - font_height;
+ int offset = (height_gap + 1)/2;
+ int ascent = qm.ascent() + offset;
+
+//#if defined(WIN32)
+ int verticalAlign = Qt::AlignVCenter;
+ switch(param_->alignMode_) {
+ case 0:
+ verticalAlign = Qt::AlignVCenter;
+ break;
+ case 1:
+ verticalAlign = Qt::AlignBottom;
+ break;
+ case 2:
+ verticalAlign = Qt::AlignTop;
+ break;
+ }
+ if (length > 2 || !isColorBlock(str[0])) {
+ painter.drawText(rcErase, Qt::AlignRight | verticalAlign, str);
+ } else {
+ //here length == 1 or == 2, isColorBlock == true, ensured in drawLine.
+ //when length == 1, we are drawing the second half of the block,
+ //otherwise the whole block.
+ //(c.unicode() >= 0x2581 && c.unicode() <= 0x258f)
+ //7 rectangles from shorter to taller (1/8 - 7/8 on the bottom)
+ //1 rectangle full
+ //7 rectangles from thicker to thinner (7/8 - 1/8 on the left)
+ //(c.unicode() >= 0x25e2 && c.unicode() <= 0x25e5)
+ //4 triangles bottom-right, bottom-left, top-left, top-right
+ QPolygon bound = rcErase;
+ QPolygon toDraw;
+ QRect rcFull = mapToRect(x, y, 2, 1);
+ rcFull.setBottom(rcFull.bottom() + 1);
+ rcFull.setRight(rcFull.right() + 1);
+ int unic = str[0].unicode();
+ if (unic >= 0x2581 && unic <= 0x2588) {
+ toDraw = QRect(rcFull.left(), rcFull.top() - rcFull.height() * (unic - 0x2581 + 1 - 8) / 8, rcFull.width(), rcFull.height() * (unic - 0x2581 + 1) / 8);
+ } else if (unic > 0x2588 && unic <= 0x258f) {
+ toDraw = QRect(rcFull.left(), rcFull.top(), rcFull.width() * (8 - unic + 0x2589 - 1) / 8, rcFull.height());
+ } else { //triangles
+ QVector<QPoint> points;
+ points.push_back(rcFull.topLeft());
+ points.push_back(rcFull.topRight());
+ points.push_back(rcFull.bottomRight());
+ points.push_back(rcFull.bottomLeft());
+ points.remove(unic - 0x25e2);
+ toDraw = points;
+ }
+ QBrush oldBrush = painter.brush();
+ painter.setBrush(colors_[pen_color_index]);
+ QPen oldPen = painter.pen();
+ painter.setPen(Qt::transparent);
+ painter.drawConvexPolygon(toDraw.intersected(bound));
+ painter.setBrush(oldBrush);
+ painter.setPen(oldPen);
+ }
+//#else
+// painter.drawText(pt.x(), pt.y() + ascent, str);
+//#endif
+ }
+}
+
+
+void FQTermScreen::eraseRect(QPainter &, int, int, int, int, short){
+ FQ_VERIFY(false);
+}
+
+void FQTermScreen::bossColor() {
+ if (FQTermPref::getInstance()->isBossColor_) {
+ colors_[0] = Qt::white;
+ colors_[7] = Qt::black;
+ QPalette palette;
+ palette.setColor(backgroundRole(), Qt::white);
+ setPalette(palette);
+
+ } else {
+ colors_[0] = param_->backgroundColor_;
+ colors_[7] = param_->foregroundColor_;
+ }
+
+
+ setPaintState(Repaint);
+ update();
+}
+
+QRect FQTermScreen::drawMenuSelect(QPainter &painter, int index) {
+ QRect rcSelect, rcMenu, rcInter;
+ // FIXME: what is this for
+/*
+ if (termBuffer_->isSelected(index)) {
+ bool is_rect_sel = param_->isRectSelect_;
+ rcSelect = mapToRect(termBuffer_->getSelectRect(index, is_rect_sel));
+ if (FQTermPref::getInstance()->isBossColor_) {
+ painter.fillRect(rcSelect, QBrush(colors_[0]));
+ } else {
+ painter.fillRect(rcSelect, QBrush(colors_[7]));
+ }
+ }
+*/
+ if (session_->isSelectedMenu(index)) {
+ rcMenu = mapToRect(session_->getMenuRect());
+ // m_pBand->setGeometry(rcMenu);
+ // m_pBand->show();
+ switch (param_->menuType_) {
+ case 0:
+ // underline
+ painter.fillRect(rcMenu.x(), rcMenu.y() + 10 * charHeight_ / 11,
+ rcMenu.width(), charHeight_ / 11, colors_[7]);
+ break;
+ case 2:
+ painter.fillRect(rcMenu, QBrush(FQTermPref::getInstance()->isBossColor_?colors_[0]:param_->menuColor_));
+ break;
+ }
+ }
+ return rcMenu;
+}
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* Auxilluary */
+/* */
+/* ------------------------------------------------------------------------ */
+
+QSize FQTermScreen::getScreenSize() const
+{
+ return QSize(termBuffer_->getNumColumns() * charWidth_, termBuffer_->getNumRows() * charHeight_);
+}
+
+QPoint FQTermScreen::mapToPixel(const QPoint &point) {
+ int dx = (getScreenSize().width() - clientRectangle_.width()) * FQTermPref::getInstance()->displayOffset_ / 100;
+ int dy = getVerticalSetting();
+ QPoint pt = clientRectangle_.topLeft();
+ pt.setX(pt.x() - dx);
+ pt.setY(pt.y() - dy);
+ QPoint pxlPoint;
+
+ pxlPoint.setX(point.x() *charWidth_ + pt.x());
+ pxlPoint.setY((point.y() - bufferStart_) *charHeight_ + pt.y());
+
+ return pxlPoint;
+}
+// mapToChar: get a position in the window and return the
+// corresponding char position
+QPoint FQTermScreen::mapToChar(const QPoint &point) {
+ int dx = (getScreenSize().width() - clientRectangle_.width()) * FQTermPref::getInstance()->displayOffset_ / 100;
+ int dy = getVerticalSetting();
+ QPoint pt = clientRectangle_.topLeft();
+ pt.setX(pt.x() - dx);
+ pt.setY(pt.y() - dy);
+ QPoint chPoint;
+ chPoint.setX(qMin(qMax(0, int((point.x() - pt.x()) / charWidth_)),
+ termBuffer_->getNumColumns() - 1));
+ chPoint.setY(qMin(qMax(0, int((point.y() - pt.y()) / charHeight_) + bufferStart_),
+ bufferEnd_));
+
+ //FIXME add bound check
+ return chPoint;
+}
+
+QRect FQTermScreen::mapToRect(int x, int y, int width, int height) {
+ QPoint pt = mapToPixel(QPoint(x, y));
+
+ if (width == -1) {
+ // to the end
+ return QRect(pt.x(), pt.y(), getScreenSize().width(), charHeight_ *height);
+ } else {
+ return QRect(pt.x(), pt.y(), width *charWidth_, charHeight_ *height);
+ }
+}
+
+QRect FQTermScreen::mapToRect(const QRect &rect) {
+ return mapToRect(rect.x(), rect.y(), rect.width(), rect.height());
+}
+
+// from KImageEffect::fade
+QImage &FQTermScreen::fade(QImage &img, float val, const QColor &color) {
+ if (img.width() == 0 || img.height() == 0) {
+ return img;
+ }
+
+ // We don't handle bitmaps
+ if (img.depth() == 1) {
+ return img;
+ }
+
+ unsigned char tbl[256];
+ for (int i = 0; i < 256; i++) {
+ tbl[i] = (int)(val *i + 0.5);
+ }
+
+ int red = color.red();
+ int green = color.green();
+ int blue = color.blue();
+
+ QRgb col;
+ int r, g, b, cr, cg, cb;
+
+ if (img.depth() <= 8) {
+ // pseudo color
+ for (int i = 0; i < img.numColors(); i++) {
+ col = img.color(i);
+ cr = qRed(col);
+ cg = qGreen(col);
+ cb = qBlue(col);
+ if (cr > red) {
+ r = cr - tbl[cr - red];
+ } else {
+ r = cr + tbl[red - cr];
+ }
+ if (cg > green) {
+ g = cg - tbl[cg - green];
+ } else {
+ g = cg + tbl[green - cg];
+ }
+ if (cb > blue) {
+ b = cb - tbl[cb - blue];
+ } else {
+ b = cb + tbl[blue - cb];
+ }
+ img.setColor(i, qRgba(r, g, b, qAlpha(col)));
+ }
+ } else {
+ // truecolor
+ for (int y = 0; y < img.height(); y++) {
+ QRgb *data = (QRgb*)img.scanLine(y);
+ for (int x = 0; x < img.width(); x++) {
+ col = *data;
+ cr = qRed(col);
+ cg = qGreen(col);
+ cb = qBlue(col);
+ if (cr > red) {
+ r = cr - tbl[cr - red];
+ } else {
+ r = cr + tbl[red - cr];
+ }
+ if (cg > green) {
+ g = cg - tbl[cg - green];
+ } else {
+ g = cg + tbl[green - cg];
+ }
+ if (cb > blue) {
+ b = cb - tbl[cb - blue];
+ } else {
+ b = cb + tbl[blue - cb];
+ }
+ *data++ = qRgba(r, g, b, qAlpha(col));
+ }
+ }
+ }
+
+ return img;
+}
+
+void FQTermScreen::inputMethodEvent(QInputMethodEvent *e) {
+ FQ_TRACE("ime", 5) << "Preedit: " << e->preeditString();
+ FQ_TRACE("ime", 5) << "Commit: " << e->commitString();
+
+ FQ_TRACE("ime", 8) << "Replace: " << e->replacementStart()
+ << ", " << e->replacementLength();
+
+ if (e->preeditString().size() > 0) {
+ nonEnglishFont_->setLetterSpacing(QFont::AbsoluteSpacing, 0.0);
+ preedit_line_->setPreeditText(e, nonEnglishFont_);
+ nonEnglishFont_->setLetterSpacing(QFont::AbsoluteSpacing, 0.0);
+ QPoint pt = mapToPixel(QPoint(termBuffer_->getCaretColumn(),
+ termBuffer_->getCaretLine()));
+ preedit_line_->move(pt);
+ preedit_line_->show();
+ preedit_line_->update();
+ } else {
+ preedit_line_->hide();
+ }
+
+ if (e->commitString().size() > 0) {
+ emit inputEvent(e->commitString());
+ }
+}
+
+QVariant FQTermScreen::inputMethodQuery(Qt::InputMethodQuery property) const {
+ FQ_TRACE("ime", 5) << "Query: " << property;
+
+ int row = termBuffer_->getCaretRow();
+ int col = termBuffer_->getCaretColumn();
+
+ switch (property) {
+ case Qt::ImMicroFocus:
+ // Here we must use (column + 1, row + 1) as the result,
+ // otherwise MS Pinyin or GPY won't work well.
+ return QVariant(
+ QRect((termBuffer_->getCaretColumn()) * charWidth_
+ + (preedit_line_->isVisible() ?
+ preedit_line_->getCaretOffset() : 0),
+ (termBuffer_->getCaretRow()) * charHeight_,
+ charWidth_, charHeight_));
+ case Qt::ImFont:
+ {
+ nonEnglishFont_->setLetterSpacing(QFont::AbsoluteSpacing, 0.0);
+ QVariant var(*nonEnglishFont_);
+ nonEnglishFont_->setLetterSpacing(QFont::AbsoluteSpacing, 0.0);
+ return var;
+ }
+ case Qt::ImCurrentSelection:
+ return QVariant(QString());
+ case Qt::ImCursorPosition:
+ case Qt::ImSurroundingText:
+ {
+ tmp_im_query_->clear();
+ const FQTermTextLine *line = termBuffer_->getTextLineInTerm(row);
+ line->getPlainText(0, line->getCellEnd(col), *tmp_im_query_);
+
+ // TODO_UTF16: here only BMP is considered.
+ if (Qt::ImCursorPosition) {
+ return QVariant(tmp_im_query_->size());
+ } else {
+ tmp_im_query_->clear();
+ line->getPlainText(0, line->getWidth(), *tmp_im_query_);
+ return QVariant(QString(*tmp_im_query_));
+ }
+ }
+ break;
+ default:
+ return QVariant();
+ }
+}
+
+void FQTermScreen::updateFixedPitchInfo() {
+ QFont cnFont(*nonEnglishFont_);
+ QFont enFont(*englishFont_);
+ int cnPixelSize = nonEnglishFont_->pixelSize() <= 5 ? 12 : nonEnglishFont_->pixelSize();
+ int enPixelSize = englishFont_->pixelSize() <= 5 ? 12 : englishFont_->pixelSize();
+ cnFont.setPixelSize(cnPixelSize);
+ enFont.setPixelSize(enPixelSize);
+ QString cnTestString = QString::fromUtf8("\xe5\x9c\xb0\xe6\x96\xb9\xe6\x94\xbf\xe5\xba\x9c");
+ cnFixedPitch_ = (QFontMetrics(cnFont).width(cnTestString) ==
+ cnTestString.length() * QFontMetrics(cnFont).width(cnTestString.at(0)));
+ QString enTestString = QString::fromUtf8("www.newsmth.net");
+ enFixedPitch_ = QFontInfo(enFont).fixedPitch() &&
+ (QFontMetrics(enFont).width(enTestString) == enTestString.length() * QFontMetrics(enFont).width(enTestString.at(0)));
+
+ FQ_TRACE("font", 10) << "\nenglish: " << enFixedPitch_
+ << "\n chinese: " << cnFixedPitch_;
+
+}
+
+void FQTermScreen::setTermFont(bool isEnglish, const QFont& font)
+{
+ QFont *&pFont = isEnglish?englishFont_:nonEnglishFont_;
+ delete pFont;
+ if (param_->isFontAutoFit_ == 1) {
+ pFont = new QFont(font.family());
+ pFont->setKerning(false);
+ } else {
+ pFont = new QFont(font);
+ pFont->setKerning(false);
+ setFontMetrics();
+ }
+ updateFixedPitchInfo();
+ emit termFontChange(isEnglish, font);
+}
+
+QFont FQTermScreen::termFont(bool isEnglish) {
+ return isEnglish?(*englishFont_):(*nonEnglishFont_);
+}
+
+void FQTermScreen::drawUnderLine(QPainter &painter, const QPoint& startPoint, const QPoint& endPoint) {
+ if (startPoint.y() == endPoint.y()) {
+ drawSingleUnderLine(painter, startPoint, endPoint);
+ } else {
+ drawSingleUnderLine(painter, startPoint, QPoint(termBuffer_->getNumColumns(), startPoint.y()));
+ drawSingleUnderLine(painter, QPoint(0, endPoint.y()), endPoint);
+ for (int i = startPoint.y() + 1; i < endPoint.y(); ++i) {
+ drawSingleUnderLine(painter, QPoint(0, i), QPoint(termBuffer_->getNumColumns(), i));
+ }
+ }
+}
+
+void FQTermScreen::drawSingleUnderLine(QPainter &painter, const QPoint& startPoint, const QPoint& endPoint) {
+ FQ_VERIFY(startPoint.y() == endPoint.y());
+ QPoint realStart = mapToPixel(startPoint);
+ QPoint realEnd = mapToPixel(endPoint);
+ painter.fillRect(realStart.x(), realStart.y() + 10 * charHeight_ / 11,
+ realEnd.x() - realStart.x(), charHeight_ / 11, FQTermPref::getInstance()->isBossColor_?colors_[0]:param_->menuColor_);
+}
+
+void FQTermScreen::setFontAntiAliasing( bool on /*= true*/ ) {
+ englishFont_->setStyleStrategy(on?QFont::PreferAntialias:QFont::NoAntialias);
+ nonEnglishFont_->setStyleStrategy(on?QFont::PreferAntialias:QFont::NoAntialias);
+}
+
+void FQTermScreen::widgetHideAt(const QRect& rect){
+ widgetRect_ = rect;
+ setPaintState(Widget);
+ update();
+}
+
+void FQTermScreen::updateWidgetRect(QPainter& painter) {
+
+
+
+ QRect rect = widgetRect_.intersect(clientRectangle_);
+ if (rect.isEmpty())
+ return;
+ drawBackground(painter, rect, 0);
+
+ QPoint tlPoint = mapToChar(QPoint(rect.left(), rect.top()));
+
+ QPoint brPoint = mapToChar(QPoint(rect.right(), rect.bottom()));
+
+ for (int y = tlPoint.y(); y <= brPoint.y(); y++) {
+ const FQTermTextLine *pTextLine = termBuffer_->getTextLineInBuffer(y);
+ int startx = qMin(tlPoint.x(),int(pTextLine->getWidth()));
+ int endx = qMin(brPoint.x(), int(pTextLine->getWidth()));
+ startx = pTextLine->getCellBegin(startx);
+ endx = pTextLine->getCellEnd(endx);
+ drawLine(painter, y, startx, endx);
+ }
+ widgetRect_ = QRect();
+}
+
+void FQTermScreen::drawBackgroundPixmap(QPainter& painter, const QRect& rect) {
+ if (!hasBackground_ ||
+ FQTermPref::getInstance()->isBossColor_ ||
+ backgroundPixmap_.isNull()) {
+ return;
+ }
+ if (backgroundCoverage_ == 1) { //Only padding, we do not draw screen background.
+ QRegion clip = rect;
+ QRect screenRect = mapToRect(0, termBuffer_->getNumLines() - termBuffer_->getNumRows(), termBuffer_->getNumColumns(), termBuffer_->getNumRows());
+ clip -= screenRect;
+ QVector<QRect> rects = clip.rects();
+ foreach(QRect r, rects) {
+ painter.drawPixmap(r, backgroundPixmap_, r);
+ }
+ return;
+ }
+ painter.drawPixmap(rect, backgroundPixmap_, rect);
+}
+
+int FQTermScreen::getVerticalSetting() const {
+ int dy = -1;
+ switch (FQTermPref::getInstance()->vsetting_)
+ {
+ case 0:
+ {
+ // Top
+ dy = 0;
+ break;
+ }
+ case 1:
+ {
+ // Middle
+ dy = (getScreenSize().height() - clientRectangle_.height()) / 2;
+ break;
+ }
+ case 2:
+ {
+ // Bottom
+ dy = (getScreenSize().height() - clientRectangle_.height());
+ break;
+ }
+ default:
+ {
+ // The logic should never get here
+ break;
+ }
+ }
+ return dy;
+}
+
+void FQTermScreen::drawBackground(QPainter& painter, const QRect& rect, int colorIndex) {
+
+ if (FQTermPref::getInstance()->isBossColor_) {
+ painter.fillRect(rect, Qt::white);
+ return;
+ }
+ if (hasBackground_ && !backgroundPixmap_.isNull()) {
+ if (colorIndex == 0 || (backgroundCoverage_ != 1 && backgroundUseAlpha_))
+ drawBackgroundPixmap(painter, rect);
+ if (backgroundCoverage_ == 1) { //Background only padding, we draw screen background.
+ QRegion clip = rect;
+ QRect screenRect = mapToRect(0, termBuffer_->getNumLines() - termBuffer_->getNumRows(), termBuffer_->getNumColumns(), termBuffer_->getNumRows());
+ clip &= screenRect;
+ QVector<QRect> rects = clip.rects();
+ foreach(QRect r, rects) {
+ painter.fillRect(r, colors_[colorIndex]);
+ }
+ } else {
+ if (backgroundUseAlpha_)
+ painter.setOpacity(double(backgroundAlpha_) / 100);
+ if (colorIndex != 0 || backgroundUseAlpha_)
+ painter.fillRect(rect, colors_[colorIndex]);
+ painter.setOpacity(1.0);
+ }
+ return;
+ }
+ painter.fillRect(rect, colors_[colorIndex]);
+}
+PreeditLine::PreeditLine(QWidget *parent,const QColor *colors)
+ : QWidget(parent),
+ pixmap_(new QPixmap()),
+ colors_(colors) {
+ //setFocusPolicy(Qt::NoFocus);
+ hide();
+}
+
+PreeditLine::~PreeditLine() {
+ delete pixmap_;
+}
+
+void PreeditLine::setPreeditText(QInputMethodEvent *e, const QFont *font) {
+ QString text = e->preeditString();
+
+ const QColor &white_color = colors_[7];
+ const QColor &black_color = colors_[0];
+
+ // MS Pinyin will add a white space '\u3000' in the end. Remove it.
+ text = text.trimmed();
+
+ QFontMetrics fm(*font);
+ QRect textRect = fm.boundingRect(text);
+
+ int width = textRect.width();
+ int height = textRect.height();
+
+ delete pixmap_;
+ pixmap_ = new QPixmap(width, height + 1); // add one pixel to shadow
+ // the original cursor on
+ // screen.
+ this->resize(width, height + 1);
+
+ QPainter painter(pixmap_);
+ painter.fillRect(textRect, QBrush(black_color));
+
+ painter.setFont(*font);
+ painter.setBackgroundMode(Qt::OpaqueMode);
+
+ // Parse attributes of the input method event.
+ for (int i = 0; i < e->attributes().size(); ++i) {
+ const QInputMethodEvent::Attribute &a = e->attributes().at(i);
+ switch(a.type) {
+ case QInputMethodEvent::Cursor:
+ FQ_TRACE("ime", 10) << "Cursor: " << a.start << ", " << a.length;
+ {
+ painter.setPen(white_color);
+
+ int caret_begin = fm.boundingRect(text.left(a.start)).right();
+
+ painter.drawLine(caret_begin, 0, caret_begin, height);
+ painter.drawLine(caret_begin + 1, 0, caret_begin + 1, height);
+
+ caret_offset_ = caret_begin;
+ }
+ break;
+ case QInputMethodEvent::TextFormat:
+ {
+ if (a.start + a.length > text.size()) {
+ // index over flow. ignore it.
+ break;
+ }
+
+ const QString &sub_text = text.mid(a.start, a.length);
+
+ int x = fm.boundingRect(text.left(a.start)).width();
+
+ QTextCharFormat f =
+ qvariant_cast<QTextFormat>(a.value).toCharFormat();
+
+ // Hack here.
+ // If the background() is of style Qt::SolidPattern,
+ // we consider this segment of text is highlighted.
+ // Otherwise it's normal preedit text.
+ if (f.background().style() == Qt::SolidPattern) {
+ QBrush bg(white_color);
+ bg.setStyle(Qt::SolidPattern);
+
+ painter.setBackground(bg);
+ painter.setPen(black_color);
+ } else {
+ QBrush bg(black_color);
+ bg.setStyle(Qt::SolidPattern);
+
+ painter.setBackground(bg);
+ painter.setPen(white_color);
+ }
+
+ // Draw the text;
+ painter.drawText(x, fm.ascent(), sub_text);
+
+ FQ_TRACE("ime", 10) << "Sub-text: " << sub_text;
+ FQ_TRACE("ime", 10) << "Format: " << a.start << ", " << a.length;
+ FQ_TRACE("ime", 10) << "Background: " << f.background();
+ FQ_TRACE("ime", 10) << "Pen: " << f.textOutline();
+ }
+ break;
+ case QInputMethodEvent::Language:
+ FQ_TRACE("ime", 10) << "Language: " << a.start << ", " << a.length;
+ break;
+ case QInputMethodEvent::Ruby:
+ FQ_TRACE("ime", 10) << "Ruby: " << a.start << ", " << a.length;
+ break;
+ }
+ }
+
+ // Draw a line under the preedit text.
+ QPen pen(white_color);
+ pen.setStyle(Qt::DashLine);
+ painter.setPen(pen);
+ painter.drawLine(0, height - 1, width, height - 1);
+}
+
+void PreeditLine::paintEvent(QPaintEvent *e) {
+ QWidget::paintEvent(e);
+ QPainter p(this);
+ p.drawPixmap(QPointF(0, 0), *pixmap_, e->rect());
+}
+
+} // namespace FQTerm
+
+#include "fqterm_screen.moc"
diff --git a/src/fqterm/fqterm_screen.h b/src/fqterm/fqterm_screen.h
new file mode 100644
index 0000000..5c65142
--- /dev/null
+++ b/src/fqterm/fqterm_screen.h
@@ -0,0 +1,281 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SCREEN_H
+#define FQTERM_SCREEN_H
+
+#include <QWidget>
+#include <QVector>
+#include <QList>
+#include "fqterm_param.h"
+#include "fqterm_convert.h"
+
+class QTextCodec;
+class QColor;
+class QPainter;
+class QInputMethodEvent;
+class QPixmap;
+class QScrollBar;
+class QShortcut;
+
+namespace FQTerm {
+
+class FQTermWindow;
+class FQTermBuffer;
+class FQTermSession;
+class FQTermParam;
+
+class PreeditLine: public QWidget {
+public:
+ PreeditLine(QWidget *parent,const QColor *colors);
+ ~PreeditLine();
+
+ void setPreeditText(QInputMethodEvent *e, const QFont *font);
+
+ void paintEvent(QPaintEvent * event);
+
+ int getCaretOffset() const {return caret_offset_;}
+
+private:
+ QPixmap *pixmap_;
+ int caret_offset_;
+
+ const QColor *colors_;
+};
+
+class FQTermScreen: public QWidget {
+ Q_OBJECT;
+ public:
+
+ enum PaintState {
+ System = 0, Repaint = 1, NewData = 2, Blink = 4, Cursor = 8, Widget = 16
+ };
+ enum MouseState {
+ Enter, Press, Move, Release, Leave
+ };
+
+ FQTermScreen(QWidget *parent, FQTermSession *session);
+ ~FQTermScreen();
+
+ void setSchema();
+ void setTermFont(bool isEnglish, const QFont& font);
+
+ QFont termFont(bool isEnglish);
+
+
+ void setPaintState(PaintState ps) {
+ paintState_ |= ps;
+ }
+
+ void clearPaintState(PaintState ps) {
+ paintState_ &= ~ps;
+ }
+
+ bool testPaintState(PaintState ps) {
+ return paintState_ & ps;
+ }
+
+
+ /*void clearPaintState() {
+ paintState_ = None;
+ }*/
+ // Buffer cell coordinate to screen pixel.
+ int getBufferStart() {return bufferStart_;}
+ QPoint mapToPixel(const QPoint &);
+
+ // Screen pixel coordinate to buffer cell coordinate.
+ QPoint mapToChar(const QPoint &);
+
+ // Buffer cell coordinate to screen pixel.
+ QRect mapToRect(int x, int y, int width, int height);
+ QRect mapToRect(const QRect &);
+ private:
+ int paintState_;
+ void updateWidgetRect(QPainter& painter);
+ void refreshScreen(QPainter &painter);
+ void blinkScreen(QPainter &painter);
+ void updateCursor(QPainter &painter);
+ void repaintScreen(QPaintEvent *pe, QPainter &painter);
+ void syncBufferAndScreen();
+ void updateBackgroundPixmap();
+ void drawBackground(QPainter& painter, const QRect& rect, int colorIndex);
+ void drawBackgroundPixmap(QPainter& painter, const QRect& rect);
+ int getVerticalSetting() const;
+
+ signals:
+ // 0 - enter 1 - press 2 - move 3 - release 4 - leave
+ void mouseAction(int, QMouseEvent*);
+ void inputEvent(const QString&);
+ void termFontChange(bool isEnglish, QFont font);
+
+ public slots:
+ void bufferSizeChanged();
+ void termSizeChanged(int column, int row);
+ void bossColor();
+ void updateScrollBar();
+ void setFontAntiAliasing(bool on = true);
+ void widgetHideAt(const QRect& rect);
+
+
+ protected:
+ void initFontMetrics();
+
+ bool event(QEvent *e);
+
+ void resizeEvent(QResizeEvent*);
+ void focusInEvent(QFocusEvent*);
+ void focusOutEvent(QFocusEvent*);
+
+ void paintEvent(QPaintEvent*);
+
+ // mouse
+ void enterEvent(QEvent*);
+ void leaveEvent(QEvent*);
+ void mousePressEvent(QMouseEvent*);
+ void mouseMoveEvent(QMouseEvent*);
+ void mouseReleaseEvent(QMouseEvent*);
+ void wheelEvent(QWheelEvent*);
+
+ // display
+ void eraseRect(QPainter &, int, int, int, int, short);
+ void drawStr(QPainter &painter, const QString &str,
+ int x, int y, int length,
+ unsigned char color, unsigned char attr,
+ bool transparent, bool selected = false);
+ void drawLine(QPainter &, int index, int startx = -1, int endx = -1,
+ bool complete = true);
+ void drawCaret(QPainter &, bool);
+ QRect drawMenuSelect(QPainter &, int);
+ void drawUnderLine(QPainter &, const QPoint& startPoint, const QPoint& endPoint);
+
+ // auxiluary
+ int getPosX(int xChar) {
+ return xChar *charWidth_;
+ }
+ int getPosY(int yLine) {
+ return yLine *charHeight_;
+ }
+
+ //screen size, in pixel.
+ QSize getScreenSize() const;
+
+
+
+ void updateFont();
+ void setFontMetrics();
+
+ QImage &fade(QImage &, float, const QColor &);
+
+ void inputMethodEvent(QInputMethodEvent *e);
+ QVariant inputMethodQuery(Qt::InputMethodQuery property)const;
+
+
+ protected slots:
+ void blinkEvent();
+ void cursorEvent();
+ void scrollChanged(int);
+ void prevPage();
+ void nextPage();
+ void prevLine();
+ void nextLine();
+ void scrollLine(int);
+ protected:
+ void drawSingleUnderLine(QPainter &, const QPoint& startPoint, const QPoint& endPoint);
+
+ QRect clientRectangle_; // the display area
+ QRect menuRect_;
+ QRect widgetRect_; //we need to redraw this rect since a widget just disappeared.
+
+ int scrollBarWidth_;
+
+ QScrollBar *scrollBar_;
+
+ QTimer *blinkTimer_;
+ QTimer *cursorTimer_;
+
+ bool isBlinkScreen_;
+ bool isBlinkCursor_;
+ bool hasBlinkText_;
+
+ FQTermWindow *termWindow_;
+ FQTermSession *session_;
+ const FQTermBuffer *termBuffer_;
+ FQTermParam *param_;
+
+ bool is_light_background_mode_;
+
+ QColor colors_[16];
+ QFont *englishFont_;
+ QFont *nonEnglishFont_;
+
+ double fontAscent_, fontDescent_;
+ double charWidth_, charHeight_;
+ double cnLetterSpacing_;
+ double enLetterSpacing_;
+ double spLetterSpacing_;
+
+ void updateFixedPitchInfo();
+ bool cnFixedPitch_;
+ bool enFixedPitch_;
+ int lineSpacing_; // for future
+
+ bool *areLinesBlink_;
+ bool isCursorShown_;
+
+ // background
+ bool hasBackground_;
+ QPixmap backgroundPixmap_;
+ QPixmap originBackgroundPixmap_;
+ //0 -- tile 1 -- center 2 -- stretch
+ int backgroundRenderOption_;
+ //0 -- Whole screen, 1 -- Only padding
+ int backgroundCoverage_;
+ bool backgroundUseAlpha_;
+ int backgroundAlpha_;
+
+
+ // the range of the buffer's lines to be displayed
+ int bufferStart_;
+ int bufferEnd_;
+
+ QShortcut *gotoPrevPage_;
+ QShortcut *gotoNextPage_;
+ QShortcut *gotoPrevLine_;
+ QShortcut *gotoNextLine_;
+
+ FQTermConvert encodingConverter_;
+
+ PreeditLine *preedit_line_;
+
+ QString *tmp_im_query_;
+
+ //TODO: change to bit field
+ enum TextRenderingType{
+ HalfAndAlign, FullAndAlign, FullNotAlign, HalfAndSpace
+ };
+ TextRenderingType charRenderingType(const QChar& c);
+
+ friend class FQTermWindow;
+ // for test only
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SCREEN_H
diff --git a/src/fqterm/fqterm_scriptengine.cpp b/src/fqterm/fqterm_scriptengine.cpp
new file mode 100644
index 0000000..efab413
--- /dev/null
+++ b/src/fqterm/fqterm_scriptengine.cpp
@@ -0,0 +1,488 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+
+
+
+#include "fqterm_scriptengine.h"
+#include "fqterm_window.h"
+#include "fqterm_screen.h"
+#include "fqterm_session.h"
+#include "fqterm_buffer.h"
+#include "common.h"
+#include "fqterm_path.h"
+
+#ifdef HAVE_PYTHON
+#include <Python.h>
+#endif
+
+#include <QString>
+#include <QDir>
+#include <QMessageBox>
+#include <QTime>
+#include <QTimer>
+#include <QFile>
+#include <QPoint>
+#include <QCursor>
+#include <QFileInfo>
+#include <QScriptContext>
+#include <QScriptContextInfo>
+namespace FQTerm {
+
+
+template <typename Tp>
+QScriptValue qScriptValueFromQObject(QScriptEngine *engine, Tp &qobject) {
+ return engine->newQObject(qobject);
+}
+
+template <typename Tp>
+void qScriptValueToQObject(const QScriptValue &value, Tp &qobject) {
+ qobject = qobject_cast<Tp>(value.toQObject());
+}
+
+template <typename Tp>
+int qScriptRegisterQObjectMetaType(
+ QScriptEngine *engine, const QScriptValue &prototype = QScriptValue()
+ ) {
+ return qScriptRegisterMetaType<Tp>(engine, qScriptValueFromQObject,
+ qScriptValueToQObject, prototype);
+}
+
+
+FQTermScriptEngine::FQTermScriptEngine(FQTermWindow* parent)
+: QObject(parent),
+ window_(parent),
+ engine_(NULL),
+ articleCopyThread_(NULL),
+ timerIDCount_(0) {
+ FQ_VERIFY(window_);
+ session_ = window_->getSession();
+ buffer_ = window_->getSession()->getBuffer();
+ screen_ = window_->getScreen();
+ articleCopyThread_ = new ArticleCopyThread(*session_, session_->getWaitCondition(), session_->getBufferLock());
+ FQ_VERIFY(connect(articleCopyThread_, SIGNAL(articleCopied(int, const QString)),
+ this, SLOT(articleCopied(int, const QString))));
+ engine_ = new QScriptEngine();
+ engine_->globalObject().setProperty(
+ "fq_session", engine_->newQObject(session_));
+ engine_->globalObject().setProperty(
+ "fq_window", engine_->newQObject(window_));
+ engine_->globalObject().setProperty(
+ "fq_buffer", engine_->newQObject(buffer_));
+ engine_->globalObject().setProperty(
+ "fq_screen", engine_->newQObject(screen_));
+ engine_->globalObject().setProperty(
+ "fqterm", engine_->newQObject(this));
+}
+
+FQTermScriptEngine::~FQTermScriptEngine() {
+ engine_->abortEvaluation();
+ delete engine_;
+}
+
+void FQTermScriptEngine::runScript( const QString& filename ) {
+ QFile file(filename);
+ if (!file.open(QIODevice::ReadOnly)) {
+ FQ_TRACE("script", 0) << "Unable to open the script file: " << filename;
+ QMessageBox::warning(window_, tr("FQTerm"),
+ tr("Unable to open the script file\n") + filename,
+ QMessageBox::Close);
+ return;
+ }
+
+ QString script = QString::fromUtf8(file.readAll());
+ QFileInfo fileInfo(filename);
+ QScriptValue result = engine_->evaluate(script, fileInfo.absoluteFilePath());
+ if (engine_->hasUncaughtException()) {
+ int line = engine_->uncaughtExceptionLineNumber();
+ FQ_TRACE("script", 0) << "uncaught exception at line " << line
+ << ":" << result.toString();
+ QMessageBox::warning(window_, tr("FQTerm"),
+ tr("uncaught exception at line ") + QString::number(line)
+ + ":\n" + result.toString(),
+ QMessageBox::Close);
+ }
+}
+
+void FQTermScriptEngine::stopScript() {
+ //all loops should be stopped here.
+ articleCopied_ = true;
+ engine_->abortEvaluation();
+}
+
+void FQTermScriptEngine::msgBox( const QString& msg ) {
+ QMessageBox::warning(window_, tr("FQTerm"),
+ msg,
+ QMessageBox::Close);
+}
+
+int FQTermScriptEngine::caretX() {
+ return buffer_->getCaretColumn();
+}
+
+int FQTermScriptEngine::caretY() {
+ return buffer_->getCaretRow();
+}
+
+int FQTermScriptEngine::columns() {
+ return buffer_->getNumColumns();
+}
+
+int FQTermScriptEngine::rows() {
+ return buffer_->getNumRows();
+}
+
+void FQTermScriptEngine::sendString(const QString& str) {
+ window_->writeRawString(str);
+}
+
+void FQTermScriptEngine::sendParsedString( const QString& str ){
+ window_->externInput(str);
+}
+
+QString FQTermScriptEngine::getText(int row) {
+ QString str;
+ if (row < rows())
+ buffer_->getTextLineInTerm(row)->getAllPlainText(str);
+ return str;
+}
+
+QString FQTermScriptEngine::getAttrText(int row) {
+ QString str;
+ if (row < rows())
+ buffer_->getTextLineInTerm(row)->getAllAnsiText(str);
+ return str;
+}
+
+bool FQTermScriptEngine::isConnected() {
+ return window_->isConnected();
+}
+
+void FQTermScriptEngine::disconnect() {
+ window_->disconnect();
+}
+
+void FQTermScriptEngine::reconnect() {
+ session_->reconnect();
+}
+
+//FIXME: UTF8 and HKSCS
+QString FQTermScriptEngine::getBBSCodec() {
+ return session_->param().serverEncodingID_ == 0 ? "GBK" : "Big5";
+}
+
+QString FQTermScriptEngine::getAddress() {
+ return session_->param().hostAddress_;
+}
+
+int FQTermScriptEngine::getPort() {
+ return session_->param().port_;
+}
+// connection protocol 0-telnet 1-SSH1 2-SSH2
+int FQTermScriptEngine::getProtocol() {
+ return session_->param().protocolType_;
+}
+
+QString FQTermScriptEngine::getReplyKey() {
+ return session_->param().replyKeyCombination_;
+}
+
+QString FQTermScriptEngine::getURL() {
+ return session_->getUrl();
+}
+
+QString FQTermScriptEngine::getIP() {
+ return session_->getIP();
+}
+
+void FQTermScriptEngine::previewImage(const QString& url) {
+ window_->getHttpHelper(url, true);
+}
+
+void FQTermScriptEngine::sleep(int ms) {
+ int originInterval = engine_->processEventsInterval();
+ engine_->setProcessEventsInterval(1);
+ QString busy_wait = "var start = new Date().getTime();\n"
+ "while(true) {if(new Date().getTime() - start > " + QString("%1").arg(ms) + ") break;}\n";
+ engine_->evaluate(busy_wait);
+ engine_->setProcessEventsInterval(originInterval);
+}
+
+//TODO: flags
+void FQTermScriptEngine::articleCopied(int state, const QString content) {
+ if (state == DAE_FINISH) {
+ articleCopied_ = true;
+ articleText_ = content;
+ } else /*if (state == DAE_TIMEOUT)*/ {
+ articleCopied_ = true;
+ articleText_ = "";
+ }
+}
+
+QString FQTermScriptEngine::copyArticle() {
+ articleCopied_ = false;
+ articleText_ = "";
+ articleCopyThread_->wait();
+ articleCopyThread_->start();
+ while(!articleCopied_) {
+ sleep(200);
+ }
+ return articleText_;
+}
+
+void FQTermScriptEngine::finalizeScript() {
+ engine_->setProcessEventsInterval(-1);
+ stopScript();
+ setParent(NULL);
+ //TODO: safe?
+ deleteLater();
+}
+
+void FQTermScriptEngine::writeFile( const QString& filename, const QString& str ) {
+ QFile file(filename);
+ file.open(QIODevice::WriteOnly);
+ file.write(U2U8(str));
+ file.close();
+}
+
+QString FQTermScriptEngine::readFile( const QString& filename ) {
+ QFile file(filename);
+ file.open(QIODevice::ReadOnly);
+ QString str = U82U(file.readAll());
+ file.close();
+ return str;
+}
+
+void FQTermScriptEngine::appendFile( const QString& filename, const QString& str ) {
+ QFile file(filename);
+ file.open(QIODevice::WriteOnly | QIODevice::Append);
+ file.write(U2U8(str));
+ file.close();
+}
+
+QStringList FQTermScriptEngine::readFolder( const QString& path ) {
+ return QDir(path).entryList(QDir::Files | QDir::NoSymLinks | QDir::NoDotAndDotDot | QDir::Readable);
+}
+
+QString FQTermScriptEngine::platform() {
+#if defined(WIN32)
+ return "Win";
+#elif defined(__unix__) && !defined(__APPLE__)
+ return "Linux";
+#else
+ return "Mac";
+#endif
+}
+
+bool FQTermScriptEngine::makePath( const QString& path ){
+ return QDir().mkpath(path);
+}
+
+QString FQTermScriptEngine::newLine() {
+ return OS_NEW_LINE;
+}
+
+void FQTermScriptEngine::openUrl(const QString & url) {
+ window_->openUrlImpl(url);
+}
+
+QString FQTermScriptEngine::getSelect(bool color_copy) {
+ return buffer_->getTextSelected(
+ session_->param().isRectSelect_,
+ color_copy,
+ window_->parseString((const char*)session_->param().escapeString_.toLatin1()));
+}
+
+QList<int> FQTermScriptEngine::mapToChar(int screenX, int screenY) {
+ QPoint charP(screen_->mapToChar(QPoint(screenX, screenY)));
+ QList<int> result;
+ result << charP.x() << charP.y() - screen_->getBufferStart();
+ return result;
+}
+
+int FQTermScriptEngine::charX(int screen_x) {
+ return screen_->mapToChar(QPoint(screen_x, 0)).x();
+}
+
+int FQTermScriptEngine::charY(int screen_y) {
+ return screen_->mapToChar(QPoint(0, screen_y)).y() - screen_->getBufferStart();
+}
+
+QString FQTermScriptEngine::getTextAt( int row, int column, int len ) {
+ if (column < 0 || column >= columns() ||
+ row < 0 || row >= rows())
+ return "";
+ if (column + len > columns() || len < 0) {
+ len = columns() - column;
+ }
+ QString result;
+ buffer_->getTextLineInTerm(row)->getPlainText(column, column + len, result);
+ return result;
+}
+
+QString FQTermScriptEngine::getAttrTextAt( int row, int column, int len ) {
+ if (column < 0 || column >= columns() ||
+ row < 0 || row >= rows())
+ return "";
+ if (column + len > columns() || len < 0) {
+ len = columns() - column;
+ }
+ QString result;
+ buffer_->getTextLineInTerm(row)->getAnsiText(column, column + len, result);
+ return result;
+}
+
+QString FQTermScriptEngine::getFullTextAt(int row, int column, int len) {
+ return getTextAt(row, buffer_->getTextLineInTerm(row)->getCellBegin(column), len);
+}
+
+QString FQTermScriptEngine::getFullAttrText(int row, int column, int len) {
+ return getAttrTextAt(row, buffer_->getTextLineInTerm(row)->getCellBegin(column), len);
+}
+
+int FQTermScriptEngine::mouseSX() {
+ return screen_->mapFromGlobal(QCursor::pos()).x();
+}
+
+int FQTermScriptEngine::mouseSY() {
+ return screen_->mapFromGlobal(QCursor::pos()).y();
+}
+
+int FQTermScriptEngine::screenX( int char_x ){
+ return screen_->mapToPixel(QPoint(char_x, 0)).x();
+}
+
+int FQTermScriptEngine::screenY( int char_y ){
+ return screen_->mapToPixel(QPoint(0, char_y + screen_->getBufferStart())).y();
+}
+
+bool FQTermScriptEngine::scriptCallback( const QString& func, const QScriptValueList& args ) {
+ QScriptValue f = engine_->globalObject().property("fqterm").property(func);
+ if (f.isFunction()) {
+ QScriptValue res = f.call(QScriptValue(), args);
+ if (!engine_->hasUncaughtException() && res.isBool()) {
+ return res.toBool();
+ } else {
+ return false;
+ }
+ }
+ return false;
+}
+
+bool FQTermScriptEngine::importFile( const QString& filename ) {
+ QFileInfo fileInfo(filename);
+ if (!fileInfo.isAbsolute()) {
+ //first search current running path.
+ if (engine_->currentContext() && engine_->currentContext()->parentContext()) {
+ QString runningFile = QScriptContextInfo(engine_->currentContext()->parentContext()).fileName();
+ if (!runningFile.isEmpty()) {
+ QFileInfo current(runningFile);
+ fileInfo = QFileInfo(current.absolutePath() + '/' + filename);
+ }
+ }
+ //then look in script folder.
+ if (!fileInfo.exists()) {
+ fileInfo = QFileInfo(getPath(RESOURCE) + "script/" + filename);
+ }
+ }
+ if (!fileInfo.exists()) {
+ return false;
+ }
+ fileInfo.makeAbsolute();
+ runScript(fileInfo.absoluteFilePath());
+ return true;
+}
+
+int FQTermScriptEngine::setInterval(int ms, const QScriptValue& func) {
+ return createTimer(ms, func, false);
+}
+
+
+void FQTermScriptEngine::clearInterval(int id) {
+ destroyTimer(id);
+}
+
+void FQTermScriptEngine::serverRedraw() {
+ sendParsedString("^L");
+}
+
+void FQTermScriptEngine::clientRedraw() {
+ window_->refreshScreen();
+}
+
+void FQTermScriptEngine::setMenuRect(int row, int column, int len) {
+ if (column < 0 || column >= columns() ||
+ row < 0 || row >= rows())
+ return ;
+ if (column + len > columns() || len < 0) {
+ len = columns() - column;
+ }
+ row += screen_->getBufferStart();
+ session_->setMenuRect(row, column, len);
+}
+
+int FQTermScriptEngine::setTimeout(int ms, const QScriptValue& func) {
+ return createTimer(ms, func, true);
+}
+
+void FQTermScriptEngine::clearTimeout(int id) {
+ destroyTimer(id);
+}
+
+int FQTermScriptEngine::createTimer(int ms, const QScriptValue& func, bool singleShot) {
+ QTimer* timer = new QTimer(this);
+ timer->setInterval(ms);
+ timer->setSingleShot(singleShot);
+ int id = timerIDCount_++;
+ if (timerTable_.find(id) != timerTable_.end()) {
+ //actually impossible!
+ destroyTimer(id);
+ }
+ timerTable_[id] = timer;
+ bool res = qScriptConnect(timer, SIGNAL(timeout()), QScriptValue(), func);
+ timer->start();
+ return id;
+}
+
+void FQTermScriptEngine::destroyTimer(int id) {
+ if (timerTable_.find(id) != timerTable_.end()) {
+ timerTable_[id]->stop();
+ delete timerTable_[id];
+ timerTable_.erase(id);
+ }
+}
+
+int FQTermScriptEngine::getUIEventInterval() {
+ return engine_->processEventsInterval();
+}
+
+void FQTermScriptEngine::setUIEventInterval(int ms) {
+ engine_->setProcessEventsInterval(ms);
+}
+
+bool FQTermScriptEngine::isAntiIdle() {
+ return session_->isAntiIdle();
+}
+
+bool FQTermScriptEngine::isAutoReply() {
+ return session_->isAutoReply();
+}
+} // namespace FQTerm
+
+#include "fqterm_scriptengine.moc" \ No newline at end of file
diff --git a/src/fqterm/fqterm_scriptengine.h b/src/fqterm/fqterm_scriptengine.h
new file mode 100644
index 0000000..70ca5cd
--- /dev/null
+++ b/src/fqterm/fqterm_scriptengine.h
@@ -0,0 +1,147 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+
+#ifndef FQTERM_SCRIPTENGINE_H
+#define FQTERM_SCRIPTENGINE_H
+
+#include "fqterm.h"
+#include <QObject>
+#include <QString>
+#include <QStringList>
+#include <QScriptEngine>
+#include <QScriptValue>
+#include <QList>
+#include <map>
+class QString;
+class QTimer;
+namespace FQTerm {
+class FQTermWindow;
+class FQTermSession;
+class FQTermScreen;
+class FQTermBuffer;
+class ArticleCopyThread;
+class FQTermScriptEngine : public QObject {
+ Q_OBJECT;
+public:
+ FQTermScriptEngine(FQTermWindow* parent);
+ ~FQTermScriptEngine();
+ QScriptEngine* getQtEngine() {return engine_;}
+ void runScript(const QString& filename);
+ void stopScript();
+ void finalizeScript();
+
+public:
+ bool scriptCallback(const QString& func, const QScriptValueList& args);
+public slots: //script apis
+ //ui functions.
+ void msgBox(const QString& msg);
+
+ //bbs ui functions
+ int caretX();
+ int caretY();
+ QString getText(int row);
+ QString getTextAt(int row, int column, int len);
+ //if we get from a column that contains the second part
+ //of a character with width == 2, we could still get it.
+ QString getFullTextAt(int row, int column, int len);
+ QString getAttrText(int row);
+ QString getAttrTextAt(int row, int column, int len);
+ QString getFullAttrText(int row, int column, int len);
+ void sendString(const QString& str);
+ void sendParsedString(const QString& str);
+ void serverRedraw();
+ void clientRedraw();
+ int columns();
+ int rows();
+ bool isConnected();
+ void disconnect();
+ void reconnect();
+ QString getBBSCodec();
+ QString getAddress();
+ int getPort();
+ int getProtocol();
+ QString getReplyKey();
+ QString getURL();
+ QString getIP();
+ void previewImage(const QString& url);
+ void sleep(int ms);
+ QString copyArticle();
+ void openUrl(const QString & url);
+ QString getSelect(bool color_copy);
+ QList<int> mapToChar(int screenX, int screenY);
+ //next 2 functions are map screen to char for x, y.
+ int charX(int screen_x);
+ int charY(int screen_y);
+ int screenX(int char_x);
+ int screenY(int char_y);
+ //mouse position is given in screen coordinate.
+ int mouseX() {return charX(mouseSX());}
+ int mouseY() {return charY(mouseSY());}
+
+ int mouseSX();
+ int mouseSY();
+
+ void setMenuRect(int row, int col, int len);
+
+ bool importFile(const QString& filename);
+
+ bool isAntiIdle();
+ bool isAutoReply();
+ //auxiliary functions.
+ //should be move to some other class.
+ //qt script provides so poor extensions to js.
+ void writeFile(const QString& filename, const QString& str);
+ void appendFile(const QString& filename, const QString& str);
+ QString readFile(const QString& filename);
+ QStringList readFolder(const QString& path);
+ QString platform();
+ bool makePath(const QString& path);
+ QString newLine();
+
+ //Timer
+ int setInterval(int ms, const QScriptValue& func);
+ void clearInterval(int id);
+ int setTimeout(int ms, const QScriptValue& func);
+ void clearTimeout(int id);
+
+ int getUIEventInterval();
+ void setUIEventInterval(int ms);
+private:
+ int createTimer(int ms, const QScriptValue& func, bool singleShot);
+ void destroyTimer(int id);
+
+private slots:
+ void articleCopied(int state, const QString content);
+private:
+ QScriptEngine* engine_;
+ FQTermWindow* window_;
+ FQTermSession* session_;
+ FQTermScreen* screen_;
+ FQTermBuffer* buffer_;
+ ArticleCopyThread* articleCopyThread_;
+ bool articleCopied_;
+ QString articleText_;
+ std::map<int, QTimer*> timerTable_;
+ int timerIDCount_;
+};
+
+
+}//namespace FQTerm
+#endif //FQTERM_SCRIPTENGINE_H \ No newline at end of file
diff --git a/src/fqterm/fqterm_window.cpp b/src/fqterm/fqterm_window.cpp
new file mode 100644
index 0000000..bb2c867
--- /dev/null
+++ b/src/fqterm/fqterm_window.cpp
@@ -0,0 +1,2531 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <QClipboard>
+#include <QDesktopServices>
+#include <QDialog>
+#include <QFileDialog>
+#include <QFontDialog>
+#include <QFontMetrics>
+#include <QInputDialog>
+#include <QImageReader>
+#include <QMenu>
+#include <QMessageBox>
+#include <QStatusBar>
+#include <QTextEdit>
+#include <QTimer>
+#include <QUrl>
+#include <QtScript/QScriptValue>
+#include <QMdiArea>
+#include <QMdiSubWindow>
+#include <QTemporaryFile>
+#include <QRegExp>
+#include <QNetworkProxy>
+#include "addrdialog.h"
+#include "articledialog.h"
+#include "msgdialog.h"
+#include "osdmessage.h"
+#include "popwidget.h"
+#include "progressBar.h"
+#include "common.h"
+#include "fqterm_buffer.h"
+#include "fqterm_canvas.h"
+#include "fqterm_config.h"
+#include "fqterm_convert.h"
+#include "fqterm_filedialog.h"
+#include "fqterm_frame.h"
+#include "fqterm_http.h"
+#include "fqterm_ip_location.h"
+#include "fqterm_param.h"
+#include "fqterm_path.h"
+#include "fqterm_screen.h"
+#include "fqterm_session.h"
+#include "fqterm_sound.h"
+#include "fqterm_window.h"
+#include "fqterm_wndmgr.h"
+#include "imageviewer.h"
+#include "sshlogindialog.h"
+#include "statusBar.h"
+#include "zmodemdialog.h"
+#ifdef HAVE_PYTHON
+#include <Python.h>
+#include "fqterm_python.h"
+#endif //HAVE_PYTHON
+#include "fqterm_scriptengine.h"
+
+
+namespace FQTerm {
+
+char FQTermWindow::directions_[][5] = {
+ // 4
+ "\x1b[1~", // 0 HOME
+ "\x1b[4~", // 1 END
+ "\x1b[5~", // 2 PAGE UP
+ "\x1b[6~", // 3 PAGE DOWN
+ // 3
+ "\x1b[A", // 4 UP
+ "\x1b[B", // 5 DOWN
+ "\x1b[D", // 6 LEFT
+ "\x1b[C" // 7 RIGHT
+};
+
+class FAQ: public QObject {
+ Q_OBJECT;
+ public slots:
+ FAQ() {a = 100;}
+
+ int get() {return a;}
+
+ private:
+ int a;
+};
+
+
+//constructor
+FQTermWindow::FQTermWindow(FQTermConfig *config, FQTermFrame *frame, FQTermParam param,
+ int addressIndex, QWidget *parent,
+ const char *name, Qt::WFlags wflags)
+ : QMainWindow(parent, wflags),
+ frame_(frame),
+ isSelecting_(false),
+ addressIndex_(addressIndex),
+ sound_(NULL),
+ isMouseClicked_(false),
+ blinkStatus_(true),
+ isUrlUnderLined_(false),
+#ifdef HAVE_PYTHON
+ // the system wide script
+ pythonScriptLoaded_(false),
+ // python thread module
+ pModule(NULL),
+ pDict(NULL),
+#endif
+ script_engine_(NULL),
+ externalEditor_(NULL) {
+ // isMouseX11_ = false;
+ session_ = new FQTermSession(config, param);
+ screen_ = new FQTermScreen(this, session_);
+
+ config_ = config;
+ zmodemDialog_ = new zmodemDialog(this);
+
+ externalEditor_ = new FQTermExternalEditor(this);
+
+ pageViewMessage_ = new PageViewMessage(this);
+ tabBlinkTimer_ = new QTimer;
+
+ setWindowIcon(QIcon("noicon"));
+ setWindowTitle(param.name_);
+ setMouseTracking(true);
+ setFocusProxy(screen_);
+ setCentralWidget(screen_);
+ addMenu();
+ setStatusBar(NULL);
+
+
+ FQ_VERIFY(connect(pageViewMessage_, SIGNAL(hideAt(const QRect&)),
+ screen_, SLOT(widgetHideAt(const QRect&))));
+
+ FQ_VERIFY(connect(frame_, SIGNAL(bossColor()),
+ screen_, SLOT(bossColor())));
+
+ FQ_VERIFY(connect(frame_, SIGNAL(fontAntiAliasing(bool)),
+ screen_, SLOT(setFontAntiAliasing(bool))));
+
+ FQ_VERIFY(connect(frame_, SIGNAL(changeLanguage()),
+ this, SLOT(recreateMenu())));
+ FQ_VERIFY(connect(frame_, SIGNAL(bossColor()),
+ screen_, SLOT(bossColor())));
+ FQ_VERIFY(connect(frame_, SIGNAL(updateScroll()),
+ screen_, SLOT(updateScrollBar())));
+
+ FQ_VERIFY(connect(screen_, SIGNAL(inputEvent(const QString&)),
+ session_, SLOT(handleInput(const QString&))));
+
+ FQ_VERIFY(connect(session_, SIGNAL(zmodemStateChanged(int, int, const char*)),
+ this, SLOT(ZmodemState(int, int, const char *))));
+ FQ_VERIFY(connect(zmodemDialog_, SIGNAL(canceled()),
+ session_, SLOT(cancelZmodem())));
+ FQ_VERIFY(connect(session_, SIGNAL(connectionClosed()),
+ this, SLOT(connectionClosed())));
+ FQ_VERIFY(connect(session_, SIGNAL(startAlert()), this, SLOT(startBlink())));
+ FQ_VERIFY(connect(session_, SIGNAL(stopAlert()), this, SLOT(stopBlink())));
+ // FQ_VERIFY(connect(session_->decoder_, SIGNAL(mouseMode(bool)),
+ // this, SLOT(setMouseMode(bool))));
+ FQ_VERIFY(connect(session_, SIGNAL(articleCopied(int, const QString)),
+ this, SLOT(articleCopied(int, const QString))));
+ FQ_VERIFY(connect(session_, SIGNAL(requestUserPwd(QString*, QString*, bool*)),
+ this, SLOT(requestUserPwd(QString *, QString *, bool *))));
+ //connect telnet signal to slots
+ // QVERIFY(connect(session_->telnet_, SIGNAL(readyRead(int)),
+ // this, SLOT(readReady(int))));
+ FQ_VERIFY(connect(session_, SIGNAL(sessionUpdated()),
+ this, SLOT(sessionUpdated())));
+ FQ_VERIFY(connect(session_, SIGNAL(bellReceived()), this, SLOT(beep())));
+ FQ_VERIFY(connect(session_, SIGNAL(onTitleSet(const QString&)), this, SLOT(onTitleSet(const QString&))));
+
+ FQ_VERIFY(connect(session_, SIGNAL(messageAutoReplied()),
+ this, SLOT(messageAutoReplied())));
+ FQ_VERIFY(connect(session_, SIGNAL(telnetStateChanged(int)),
+ this, SLOT(TelnetState(int))));
+ FQ_VERIFY(connect(session_, SIGNAL(errorMessage(QString)),
+ this, SLOT(showSessionErrorMessage(QString))));
+
+ FQ_VERIFY(connect(tabBlinkTimer_, SIGNAL(timeout()), this, SLOT(blinkTab())));
+
+ FQ_VERIFY(connect(externalEditor_, SIGNAL(done(const QString&)), this, SLOT(externalEditorDone(const QString&))));
+
+ FQ_VERIFY(connect(this, SIGNAL(writeStringSignal(const QString&)), this, SLOT(writeString(const QString&)), Qt::QueuedConnection));
+ FQ_VERIFY(connect(this, SIGNAL(writeRawStringSignal(const QString&)), this, SLOT(writeRawString(const QString&)), Qt::QueuedConnection));
+
+#if defined(WIN32)
+ popWindow_ = new popWidget(this, frame_);
+#else
+ popWindow_ = new popWidget(this);
+#endif
+
+ const QString &resource_dir = getPath(RESOURCE);
+
+ cursors_[FQTermSession::kHome] = QCursor(
+ QPixmap(resource_dir + "cursor/home.xpm"));
+ cursors_[FQTermSession::kEnd] = QCursor(
+ QPixmap(resource_dir + "cursor/end.xpm"));
+ cursors_[FQTermSession::kPageUp] = QCursor(
+ QPixmap(resource_dir + "cursor/pageup.xpm"));
+ cursors_[FQTermSession::kPageDown] = QCursor(
+ QPixmap(resource_dir + "cursor/pagedown.xpm"));
+ cursors_[FQTermSession::kUp] = QCursor(
+ QPixmap(resource_dir + "cursor/prev.xpm"));
+ cursors_[FQTermSession::kDown] = QCursor(
+ QPixmap(resource_dir + "cursor/next.xpm"));
+ cursors_[FQTermSession::kLeft] = QCursor(
+ QPixmap(resource_dir + "cursor/exit.xpm"), 0, 10);
+ cursors_[FQTermSession::kRight] = QCursor(
+ QPixmap(resource_dir + "cursor/hand.xpm"));
+ cursors_[FQTermSession::kNormal] = Qt::ArrowCursor;
+
+ script_engine_ = new FQTermScriptEngine(this);
+ if (session_->param().isAutoLoadScript_
+ && !session_->param().autoLoadedScriptFileName_.isEmpty()) {
+ const QString &filename = session_->param().autoLoadedScriptFileName_;
+#ifdef HAVE_PYTHON
+ if (filename.trimmed().endsWith(".py", Qt::CaseInsensitive)){
+ initPython(filename);
+ } else {
+ initPython("");
+#endif
+ runScript(filename);
+#ifdef HAVE_PYTHON
+ }
+ } else {
+ initPython("");
+#endif //HAVE_PYTHON
+ }
+ session_->setScriptListener(this);
+}
+
+FQTermWindow::~FQTermWindow() {
+#ifdef HAVE_PYTHON
+ finalizePython();
+#endif //HAVE_PYTHON
+ script_engine_->finalizeScript();
+ // delete telnet_;
+ delete session_;
+ delete popWindow_;
+ delete tabBlinkTimer_;
+ delete menu_;
+ delete urlMenu_;
+ delete screen_;
+ delete pageViewMessage_;
+ //delete script_engine_;
+}
+
+void FQTermWindow::addMenu() {
+ urlMenu_ = new QMenu(screen_);
+ urlMenu_->addAction(tr("Preview image"), this, SLOT(previewLink()));
+ urlMenu_->addAction(tr("Open link"), this, SLOT(openLink()));
+ urlMenu_->addAction(tr("Save As..."), this, SLOT(saveLink()));
+ urlMenu_->addAction(tr("Copy link address"), this, SLOT(copyLink()));
+ urlMenu_->addSeparator();
+ urlMenu_->addAction(tr("Share Selected Text and URL!"), this, SLOT(shareIt()));
+ const QString &resource_dir = getPath(RESOURCE);
+
+ menu_ = new QMenu(screen_);
+#if defined(__APPLE__)
+ // Please note that on MacOSX Qt::CTRL corresponds to Command key (apple key),
+ // while Qt::Meta corresponds to Ctrl key.
+ QKeySequence copy_shortcut(tr("Ctrl+C"));
+ QKeySequence paste_shortcut(tr("Ctrl+V"));
+#else
+ QKeySequence copy_shortcut(tr("Ctrl+Insert"));
+ QKeySequence paste_shortcut(tr("Shift+Insert"));
+#endif
+ menu_->addAction(QPixmap(resource_dir + "pic/copy.png"), tr("Copy"),
+ this, SLOT(copy()), copy_shortcut);
+ menu_->addAction(QPixmap(resource_dir + "pic/paste.png"), tr("Paste"),
+ this, SLOT(paste()), paste_shortcut);
+
+ menu_->addAction(QPixmap(resource_dir+"pic/get_article_fulltext.png"), tr("Copy Article"),
+ this, SLOT(copyArticle()));
+ menu_->addSeparator();
+
+ QMenu *fontMenu = new QMenu(menu_);
+ fontMenu->setTitle(tr("Font"));
+ fontMenu->setIcon(QPixmap(resource_dir + "pic/change_fonts.png"));
+ for (int i = 0; i < 2; ++i) {
+ QAction *act = fontMenu->addAction(
+ FQTermParam::getLanguageName(bool(i)) + tr(" Font"),
+ this, SLOT(setFont()));
+ act->setData(i);
+ }
+ menu_->addMenu(fontMenu);
+
+ menu_->addAction(QPixmap(resource_dir + "pic/ansi_color.png"), tr("Color"),
+ this, SLOT(setColor()));
+ menu_->addSeparator();
+ menu_->addAction(QPixmap(resource_dir + "pic/preferences.png"), tr("Setting"),
+ this, SLOT(setting()));
+ menu_->addSeparator();
+ menu_->addAction(tr("Open Selected As Url"), this, SLOT(openAsUrl()));
+ menu_->addAction(tr("Search Selected Text!"), this, SLOT(searchIt()));
+ menu_->addAction(tr("Share Selected Text and URL!"), this, SLOT(shareIt()));
+}
+
+void FQTermWindow::recreateMenu() {
+ delete urlMenu_;
+ delete menu_;
+ addMenu();
+}
+
+//close event received
+void FQTermWindow::closeEvent(QCloseEvent *clse) {
+ bool toClose = true;
+ if (isConnected() && FQTermPref::getInstance()->openWarnOnClose_) {
+ QMessageBox mb(tr("FQTerm"),
+ tr("Still connected, do you really want to exit?"),
+ QMessageBox::Warning, QMessageBox::Yes|QMessageBox::Default,
+ QMessageBox::No | QMessageBox::Escape, 0, this);
+ if (mb.exec() != QMessageBox::Yes) {
+ toClose = false;
+ }
+ }
+ if (toClose) {
+ session_->close();
+ } else {
+ clse->ignore();
+ return;
+ }
+ //We no longer save setting on close from r1036.
+ //saveSetting();
+}
+
+void FQTermWindow::blinkTab() {
+ emit blinkTheTab(this, blinkStatus_);
+ blinkStatus_ = !blinkStatus_;
+}
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* Mouse & Key */
+/* */
+/* ------------------------------------------------------------------------ */
+void FQTermWindow::enterEvent(QEvent*){}
+
+void FQTermWindow::leaveEvent(QEvent*) {
+ // TODO: code below doesn't work
+ // QPoint temp(0, 0);
+ // session_->setSelect(temp, temp, session_->isRectangleCopy_);
+ // QApplication::postEvent(screen_, new QPaintEvent(QRect(0, 0, 0, 0));
+ // &paintEvent);
+}
+
+void FQTermWindow::changeEvent(QEvent *e) {
+ if (e->type() == QEvent::WindowStateChange) {
+ QWindowStateChangeEvent *event = (QWindowStateChangeEvent*)(e);
+ Qt::WindowStates oldState = event->oldState();
+ if (!isMaximized()) {
+ emit refreshOthers(this);
+ }
+ if ( (oldState & Qt::WindowMinimized && !isMinimized()) ||
+ (!(oldState & Qt::WindowActive) && isActiveWindow())) {
+ forcedRepaintScreen();
+ }
+ if (oldState & Qt::WindowMaximized || isMaximized()) {
+ emit resizeSignal(this);
+ }
+ }
+}
+
+void FQTermWindow::resizeEvent(QResizeEvent *qResizeEvent)
+{
+ emit resizeSignal(this);
+}
+
+bool FQTermWindow::event(QEvent *qevent) {
+ bool res = false;
+ QKeyEvent *keyEvent;
+ switch(qevent->type()) {
+#ifdef __linux__
+ case QEvent::ShortcutOverride:
+ keyEvent = (QKeyEvent *)(qevent);
+ if(keyEvent->key() == Qt::Key_W &&
+ keyEvent->modifiers() == Qt::ControlModifier) {
+ keyEvent->accept();
+ res = true;
+ }
+ break;
+#endif
+ case QEvent::KeyPress:
+ keyEvent = (QKeyEvent *)(qevent);
+ if (keyEvent->key() == Qt::Key_Tab ||
+ keyEvent->key() == Qt::Key_Backtab) {
+ // Key_Tab and Key_Backtab are special, if we don't process them here,
+ // the default behavoir is to move focus. see QWidget::event.
+ keyPressEvent(keyEvent);
+ keyEvent->accept();
+ res = true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ res = res || QMainWindow::event(qevent);
+
+ if (qevent->type() == QEvent::HoverMove
+ || qevent->type() == QEvent::MouseMove
+ || qevent->type() == QEvent::Move) {
+ if (res) {
+ FQ_TRACE("wndEvent", 10) << "Accept event: " << qevent->type()
+ << " " << getEventName(qevent->type()) << ".";
+ } else {
+ FQ_TRACE("wndEvent", 10) << "Ignore event: " << qevent->type()
+ << " " << getEventName(qevent->type()) << ".";
+ }
+ } else {
+ if (res) {
+ FQ_TRACE("wndEvent", 9) << "Accept event: " << qevent->type()
+ << " " << getEventName(qevent->type()) << ".";
+ } else {
+ FQ_TRACE("wndEvent", 9) << "Ignore event: " << qevent->type()
+ << " " << getEventName(qevent->type()) << ".";
+ }
+ }
+ return res;
+}
+
+void FQTermWindow::mouseDoubleClickEvent(QMouseEvent *mouseevent) {
+ if (scriptMouseEvent(mouseevent))
+ return;
+}
+
+void FQTermWindow::mousePressEvent(QMouseEvent *mouseevent) {
+ if (scriptMouseEvent(mouseevent))
+ return;
+ // stop the tab blinking
+ stopBlink();
+
+ // Left Button for selecting
+ if (mouseevent->button() & Qt::LeftButton && !(mouseevent->modifiers())) {
+ startSelecting(mouseevent->pos());
+ }
+
+ // Right Button
+ if ((mouseevent->button() & Qt::RightButton)) {
+ if (mouseevent->modifiers() & Qt::ControlModifier) {
+ // on Url
+ if (!session_->getUrl().isEmpty()) {
+ previewLink();
+ }
+ return ;
+ }
+
+#ifdef __APPLE__
+ bool additional_modifier = (mouseevent->modifiers() & !Qt::MetaModifier);
+#else
+ bool additional_modifier = mouseevent->modifiers();
+#endif
+
+ if (!(additional_modifier)) {
+ // on Url
+ if (!session_->getUrl().isEmpty()) {
+ urlMenu_->popup(mouseevent->globalPos());
+ } else {
+ menu_->popup(mouseevent->globalPos());
+ }
+ return ;
+ }
+ }
+ // Middle Button for paste
+ if (mouseevent->button() &Qt::MidButton && !(mouseevent->modifiers())) {
+ if (isConnected())
+ // on Url
+ if (!session_->getUrl().isEmpty()) {
+ previewLink();
+ } else {
+ pasteHelper(false);
+ }
+ return ;
+ }
+
+ // If it is a click, there should be a press event and a release event.
+ isMouseClicked_ = true;
+
+ // xterm mouse event
+ //session_->sendMouseState(0, me->button(), me->state(), me->pos());
+}
+
+
+void FQTermWindow::mouseMoveEvent(QMouseEvent *mouseevent) {
+ bool mouseEventConsumed = scriptMouseEvent(mouseevent);
+ QPoint position = mouseevent->pos();
+ if (!mouseEventConsumed)
+ {
+
+ // selecting by leftbutton
+ if ((mouseevent->buttons() &Qt::LeftButton) && isSelecting_) {
+ onSelecting(position);
+ }
+ }
+ if (!(session_->param().isSupportMouse_ && isConnected())) {
+ return;
+ }
+
+ setCursorPosition(position);
+ setCursorType(position);
+
+
+ if (!mouseEventConsumed)
+ {
+ if (!isUrlUnderLined_ && session_->urlStartPoint() != session_->urlEndPoint()) {
+ isUrlUnderLined_ = true;
+ urlStartPoint_ = session_->urlStartPoint();
+ urlEndPoint_ = session_->urlEndPoint();
+ clientRect_ = QRect(QPoint(0, urlStartPoint_.y()), QSize(session_->getBuffer()->getNumColumns(), urlEndPoint_.y() - urlStartPoint_.y() + 1));
+ repaintScreen();
+
+ } else if (isUrlUnderLined_ && (session_->urlStartPoint() != urlStartPoint_ || session_->urlEndPoint() != urlEndPoint_)) {
+ clientRect_ = QRect(QPoint(0, urlStartPoint_.y()), QSize(session_->getBuffer()->getNumColumns(), urlEndPoint_.y() - urlStartPoint_.y() + 1));
+ urlStartPoint_ = QPoint();
+ urlEndPoint_ = QPoint();
+ repaintScreen();
+ isUrlUnderLined_ = false;
+
+ }
+ }
+}
+
+static bool isSupportedImage(const QString &name) {
+ static QList<QByteArray> image_formats =
+ QImageReader::supportedImageFormats();
+
+ return image_formats.contains(name.section(".", -1).toLower().toUtf8());
+}
+
+void FQTermWindow::mouseReleaseEvent(QMouseEvent *mouseevent) {
+ if (scriptMouseEvent(mouseevent))
+ return;
+ if (!isMouseClicked_) {
+ return ;
+ }
+ isMouseClicked_ = false;
+ // other than Left Button ignored
+ if (!(mouseevent->button() & Qt::LeftButton) ||
+ (mouseevent->modifiers() & Qt::KeyboardModifierMask)) {
+ // no local mouse event
+ //session_->sendMouseState(3, me->button(), me->state(), me->pos());
+ return ;
+ }
+
+ // Left Button for selecting
+ QPoint currentMouseCell = screen_->mapToChar(mouseevent->pos());
+ if (currentMouseCell != lastMouseCell_ && isSelecting_) {
+ finishSelecting(mouseevent->pos());
+ return ;
+ }
+ isSelecting_ = false;
+
+ if (!session_->param().isSupportMouse_ || !isConnected()) {
+ return ;
+ }
+
+ // url
+ QString url = session_->getUrl();
+ if (!url.isEmpty()) {
+ if (isSupportedImage(url)) {
+ previewLink();
+ } else {
+ openUrl(url);
+ }
+ return ;
+ }
+
+ processLClick(currentMouseCell);
+}
+
+void FQTermWindow::wheelEvent(QWheelEvent *wheelevent) {
+ if (scriptWheelEvent(wheelevent)) return;
+ int j = wheelevent->delta() > 0 ? 4 : 5;
+ if (!(wheelevent->modifiers())) {
+ if (FQTermPref::getInstance()->isWheelSupported_ && isConnected()) {
+ session_->writeStr(directions_[j]);
+ }
+ return ;
+ }
+ //session_->sendMouseState(j, Qt::NoButton, we->state(), we->pos());
+}
+
+//keyboard input event
+void FQTermWindow::keyPressEvent(QKeyEvent *keyevent) {
+ if (keyevent->isAutoRepeat() && !session_->getBuffer()->isAutoRepeatMode()) {
+ FQ_TRACE("sendkey", 5)
+ << "The terminal is set to not allow repeated key events.";
+ keyevent->accept();
+ return;
+ }
+ if (scriptKeyEvent(keyevent))
+ return;
+
+ keyevent->accept();
+
+ if (!isConnected()) {
+ if (keyevent->key() == Qt::Key_Return || keyevent->key() == Qt::Key_Enter) {
+ session_->reconnect();
+ }
+ return ;
+ }
+
+ // stop the tab blinking
+ stopBlink();
+ if (!session_->readyForInput()) {
+ return;
+ }
+ // message replying
+ session_->leaveIdle();
+
+ Qt::KeyboardModifiers modifier = QApplication::keyboardModifiers();
+ int key = keyevent->key();
+ sendKey(key, modifier, keyevent->text());
+}
+/*
+void FQTermWindow::focusInEvent (QFocusEvent *event) {
+ QMainWindow::focusInEvent(event);
+ screen_->setFocus(Qt::OtherFocusReason);
+}
+*/
+
+//connect slot
+void FQTermWindow::connectHost() {
+ pageViewMessage_->display(tr("Not connected"), screen_->mapToPixel(QPoint(1, 1)));
+ session_->setProxy(session_->param().proxyType_,
+ session_->param().isAuthentation_,
+ session_->param().proxyHostName_,
+ session_->param().proxyPort_,
+ session_->param().proxyUserName_,
+ session_->param().proxyPassword_);
+ session_->connectHost(session_->param().hostAddress_, session_->param().port_);
+ config_->setItemValue("global", "lastaddrindex", QString("%1").arg(addressIndex_));
+}
+
+bool FQTermWindow::isConnected() {
+ return session_->isConnected();
+}
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* Telnet State */
+/* */
+/* ------------------------------------------------------------------------ */
+
+void FQTermWindow::sessionUpdated() {
+ refreshScreen();
+ //send a mouse move event to make mouse-related change
+ QMouseEvent* me = new QMouseEvent(
+ QEvent::MouseMove, mapFromGlobal(QCursor::pos()),
+ QCursor::pos(), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
+ QApplication::postEvent(this, me);
+}
+
+void FQTermWindow::requestUserPwd(QString *user, QString *pwd, bool *isOK) {
+ SSHLoginDialog login(user, pwd, this);
+ *isOK = (login.exec() == QDialog::Accepted);
+}
+
+void FQTermWindow::ZmodemState(int type, int value, const char *status) {
+ QString strMsg;
+ //to be completed
+ switch (type) {
+ case RcvByteCount:
+ case SndByteCount:
+ zmodemDialog_->setProgress(value);
+ return;
+ case RcvTimeout:
+ /* receiver did not respond, aborting */
+ strMsg = QString(tr("Time out!"));
+ break;
+ case SndTimeout:
+ /* value is # of consecutive send timeouts */
+ strMsg = QString(tr("Time out after trying %1 times")).arg(value);
+ break;
+ case RmtCancel:
+ /* remote end has cancelled */
+ strMsg = QString(tr("Canceled by remote peer %1")).arg(status);
+ break;
+ case ProtocolErr:
+ /* protocol error has occurred, val=hdr */
+ strMsg = QString(
+ tr("Unhandled header %1 at state %2")).arg(value).arg(status);
+ break;
+ case RemoteMessage:
+ /* message from remote end */
+ strMsg = QString(tr("Msg from remote peer: %1")).arg(status);
+ break;
+ case DataErr:
+ /* data error, val=error count */
+ strMsg = QString(tr("Data errors %1")).arg(value);
+ break;
+ case FileErr:
+ /* error writing file, val=errno */
+ strMsg = QString(tr("Falied to write file"));
+ break;
+ case FileBegin:
+ /* file transfer begins, str=name */
+ FQ_TRACE("window", 1) << "Starting file " << status;
+ zmodemDialog_->setFileInfo(session_->bbs2unicode(status), value);
+ zmodemDialog_->setProgress(0);
+ zmodemDialog_->clearErrorLog();
+ zmodemDialog_->show();
+ zmodemDialog_->setModal(true);
+ return;
+ case FileEnd:
+ /* file transfer ends, str=name */
+ zmodemDialog_->hide();
+ return;
+ case FileSkip:
+ /* file being skipped, str=name */
+ strMsg = QString(tr("Skipping file %1")).arg(status);
+ break;
+ }
+ zmodemDialog_->addErrorLog(strMsg);
+}
+
+// telnet state slot
+void FQTermWindow::TelnetState(int state) {
+ switch (state) {
+ case TSRESOLVING:
+ pageViewMessage_->display(tr("Resolving host name"), screen_->mapToPixel(QPoint(1, 1)));
+ break;
+ case TSHOSTFOUND:
+ pageViewMessage_->display(tr("Host found"), screen_->mapToPixel(QPoint(1, 1)));
+ break;
+ case TSHOSTNOTFOUND:
+ pageViewMessage_->display(tr("Host not found"), screen_->mapToPixel(QPoint(1, 1)));
+ break;
+ case TSCONNECTING:
+ pageViewMessage_->display(tr("Connecting..."), screen_->mapToPixel(QPoint(1, 1)));
+ break;
+ case TSHOSTCONNECTED:
+ pageViewMessage_->display(tr("Connected"), screen_->mapToPixel(QPoint(1, 1)));
+ frame_->updateMenuToolBar();
+ break;
+ case TSPROXYCONNECTED:
+ pageViewMessage_->display(tr("Connected to proxy"), screen_->mapToPixel(QPoint(1, 1)));
+ break;
+ case TSPROXYAUTH:
+ pageViewMessage_->display(tr("Proxy authentation"), screen_->mapToPixel(QPoint(1, 1)));
+ break;
+ case TSPROXYFAIL:
+ pageViewMessage_->display(tr("Proxy failed"), screen_->mapToPixel(QPoint(1, 1)));
+ break;
+ case TSREFUSED:
+ pageViewMessage_->display(tr("Connection refused"), screen_->mapToPixel(QPoint(1, 1)));
+ break;
+ case TSREADERROR:
+ pageViewMessage_->display(tr("Error when reading from server"), screen_->mapToPixel(QPoint(1, 1)),
+ PageViewMessage::Error);
+ break;
+ case TSCLOSED:
+ pageViewMessage_->display(tr("Connection closed"), screen_->mapToPixel(QPoint(1, 1)));
+ break;
+ case TSCLOSEFINISH:
+ pageViewMessage_->display(tr("Connection close finished"), screen_->mapToPixel(QPoint(1, 1)));
+ break;
+ case TSCONNECTVIAPROXY:
+ pageViewMessage_->display(tr("Connect to host via proxy"), screen_->mapToPixel(QPoint(1, 1)));
+ break;
+ case TSEGETHOSTBYNAME:
+ pageViewMessage_->display(
+ tr("Error in gethostbyname"), screen_->mapToPixel(QPoint(1, 1)), PageViewMessage::Error);
+ break;
+ case TSEINIWINSOCK:
+ pageViewMessage_->display(
+ tr("Error in startup winsock"), screen_->mapToPixel(QPoint(1, 1)), PageViewMessage::Error);
+ break;
+ case TSERROR:
+ pageViewMessage_->display(
+ tr("Error in connection"), screen_->mapToPixel(QPoint(1, 1)), PageViewMessage::Error);
+ break;
+ case TSPROXYERROR:
+ pageViewMessage_->display(tr("Error in proxy"), screen_->mapToPixel(QPoint(1, 1)), PageViewMessage::Error);
+ break;
+ case TSWRITED:
+ break;
+ }
+}
+
+void FQTermWindow::showSessionErrorMessage(QString reason) {
+ if (reason == tr("User Cancel")) {
+ return;
+ }
+ QMessageBox::critical(this, tr("Session error"), reason);
+}
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* UI Slots */
+/* */
+/* ------------------------------------------------------------------------ */
+
+
+void FQTermWindow::copy() {
+ QClipboard *clipboard = QApplication::clipboard();
+
+ QString selected_text = session_->getBuffer()->getTextSelected(
+ session_->param().isRectSelect_,
+ session_->param().isColorCopy_,
+ parseString((const char*)session_->param().escapeString_.toLatin1()));
+
+ QByteArray cstrText = session_->unicode2bbs(selected_text);
+
+ // TODO_UTF16: avoid this replacement.
+ if (!FQTermPref::getInstance()->escapeString_.isEmpty()) {
+ cstrText.replace(
+ parseString((const char*)session_->param().escapeString_.toLatin1()),
+ parseString(FQTermPref::getInstance()->escapeString_.toLatin1()));
+ }
+ selected_text = session_->bbs2unicode(cstrText);
+
+ // TODO_UTF16: there are three modes: Clipboard, Selection, FindBuffer.
+ clipboard->setText(selected_text, QClipboard::Clipboard);
+ clipboard->setText(selected_text, QClipboard::Selection);
+}
+
+void FQTermWindow::paste() {
+ pasteHelper(true);
+}
+
+void FQTermWindow::writePasting(const QString& content)
+{
+ QByteArray cstrText = session_->unicode2bbs(content);
+
+ // TODO_UTF16: avoid this replacement.
+ if (!FQTermPref::getInstance()->escapeString_.isEmpty()) {
+ cstrText.replace(
+ parseString(FQTermPref::getInstance()->escapeString_.toLatin1()),
+ parseString((const char*)session_->param().escapeString_.toLatin1()));
+ }
+
+ if (session_->param().isAutoWrap_) {
+ // convert to unicode for word wrap
+ QString strText;
+ strText = session_->bbs2unicode(cstrText);
+ // insert '\n' as needed
+ for (uint i = 0; (long)i < strText.length(); i++) {
+ uint j = i;
+ uint k = 0, l = 0;
+ while ((long)j < strText.length() && strText.at(j) != QChar('\n')) {
+ if (FQTermPref::getInstance()->widthToWrapWord_ - (l - k) >= 0
+ && FQTermPref::getInstance()->widthToWrapWord_ - (l - k) < 2) {
+ strText.insert(j, QChar('\n'));
+ k = l;
+ j++;
+ break;
+ }
+ // double byte or not
+ if (strText.at(j).row() == '\0') {
+ l++;
+ } else {
+ l += 2;
+ }
+ j++;
+ }
+ i = j;
+ }
+
+ cstrText = session_->unicode2bbs(strText);
+ }
+
+ session_->write(cstrText, cstrText.length());
+}
+
+void FQTermWindow::pasteHelper(bool clip) {
+ if (!isConnected()) {
+ return ;
+ }
+
+ // TODO_UTF16: there are three modes: Clipboard, Selection, FindBuffer.
+ QClipboard *clipboard = QApplication::clipboard();
+
+ // TODO_UTF16: what's the termFrame_->clipboardEncodingID_?
+ /*
+ if (termFrame_->clipboardEncodingID_ == 0) {
+ if (clip) {
+ cstrText = U2G(clipboard->text(QClipboard::Clipboard));
+ }
+ else {
+ cstrText = U2G(clipboard->text(QClipboard::Selection));
+ }
+
+ if (session_->param().serverEncodingID_ == 1) {
+ char *str = encodingConverter_.G2B(cstrText, cstrText.length());
+ cstrText = str;
+ delete [] str;
+ }
+ } else {
+ if (clip) {
+ cstrText = U2B(clipboard->text(QClipboard::Clipboard));
+ } else {
+ cstrText = U2B(clipboard->text(QClipboard::Selection));
+ }
+
+ if (session_->param().serverEncodingID_ == 0) {
+ char *str = encodingConverter_.B2G(cstrText, cstrText.length());
+ cstrText = str;
+ delete [] str;
+ }
+ }
+ */
+
+ QString clipStr;
+
+ if (clip) {
+ clipStr = clipboard->text(QClipboard::Clipboard);
+ } else {
+ clipStr = clipboard->text(QClipboard::Selection);
+ }
+
+ writePasting(clipStr);
+}
+
+void FQTermWindow::openAsUrl() {
+ QString selected_text = session_->getBuffer()->getTextSelected(
+ session_->param().isRectSelect_,
+ session_->param().isColorCopy_,
+ parseString((const char*)session_->param().escapeString_.toLatin1()));
+ openUrl(selected_text);
+}
+
+void FQTermWindow::searchIt()
+{
+ script_engine_->runScript(getPath(RESOURCE) + "script/search.js");
+ QScriptValueList qvl;
+ qvl << FQTermPref::getInstance()->searchEngine_;
+ if (!script_engine_->scriptCallback("searchSelected", qvl)) {
+ //fall back to google.
+ QString selected_text = session_->getBuffer()->getTextSelected(
+ session_->param().isRectSelect_,
+ session_->param().isColorCopy_,
+ parseString((const char*)session_->param().escapeString_.toLatin1()));
+ QString searchUrl = "http://www.google.com/search?client=fqterm&rls=en&q=" + selected_text + "&sourceid=fqterm";
+ QByteArray url = QUrl(searchUrl).toEncoded();
+ openUrlImpl(url);
+ }
+}
+
+void FQTermWindow::shareIt()
+{
+ script_engine_->runScript(getPath(RESOURCE) + "script/weiboshare.js");
+}
+
+void FQTermWindow::fastPost()
+{
+ QClipboard *clipboard = QApplication::clipboard();
+ QString clipStr = clipboard->text(QClipboard::Clipboard);
+ QString lineEnd("\n");
+ QString postTitle = clipStr.left(clipStr.indexOf(lineEnd));
+
+ sendParsedString("^p");
+ writeRawString(postTitle);
+ writeRawString(QString("\n\n"));
+ writePasting(clipStr);
+ sendParsedString("^W\n");
+}
+
+
+void FQTermWindow::externalEditor() {
+ externalEditor_->start();
+}
+
+
+void FQTermWindow::externalEditorDone(const QString& str) {
+ QByteArray rawStr = session_->unicode2bbs_smart(str);
+ session_->write(rawStr, rawStr.length());
+}
+
+
+void FQTermWindow::copyArticle() {
+ if (!isConnected()) {
+ return ;
+ }
+
+ session_->copyArticle();
+}
+
+void FQTermWindow::setColor() {
+ addrDialog set(this, session_->param());
+
+ set.setCurrentTabIndex(addrDialog::Display);
+ int res = set.exec();
+ if (res != 0) {
+ updateSetting(set.param());
+ if (res == 2)
+ saveSetting(false);
+ }
+
+}
+
+void FQTermWindow::disconnect() {
+ session_->close();
+
+ connectionClosed();
+}
+
+void FQTermWindow::showIP(bool show) {
+ pageViewMessage_->hide();
+ if (!show) {
+ return;
+ }
+ QString country, city;
+ QString url = session_->getIP();
+ FQTermIPLocation *ipLocation = FQTermIPLocation::getInstance();
+
+ QRect screenRect = screen_->rect();
+ QPoint messagePos;
+ QRect globalIPRectangle = QRect(screen_->mapToRect(ipRectangle_));
+ QFontMetrics fm(qApp->font());
+ int charHeight = fm.height();
+
+ int midLine = (screenRect.top() + screenRect.bottom()) / 2;
+ int ipMidLine = (globalIPRectangle.top() + globalIPRectangle.bottom()) / 2;
+ if (ipMidLine < midLine) {
+ // "There is Plenty of Room at the Bottom." -- Feyman, 1959
+ messagePos.setY(globalIPRectangle.bottom() + 0.618 * charHeight);
+ } else {
+ messagePos.setY(globalIPRectangle.top()
+ - 0.618 * charHeight
+ - pageViewMessage_->size().height());
+ }
+
+ QString displayText;
+ if (ipLocation == NULL) {
+ displayText = tr("IP database file does NOT exist");
+ } else if (!ipLocation->getLocation(url, country, city)) {
+ displayText = tr("Invalid IP");
+ } else {
+ displayText = country + " " + city;
+ }
+
+ QRect messageSize(pageViewMessage_->displayCheck(displayText,
+ PageViewMessage::Info));
+ PageViewMessage::Alignment ali;
+ if (messageSize.width() + globalIPRectangle.left() >= screenRect.right()) {
+ //"But There is No Room at the Right" -- Curvelet, 2007
+ messagePos.setX(globalIPRectangle.right());
+ ali = PageViewMessage::TopRight;
+ } else {
+ messagePos.setX(globalIPRectangle.left());
+ ali = PageViewMessage::TopLeft;
+ }
+
+ pageViewMessage_->display(
+ displayText,
+ PageViewMessage::Info,
+ 0, messagePos, ali);
+}
+
+void FQTermWindow::runScript() {
+ // get the previous dir
+ QStringList fileList;
+ FQTermFileDialog fileDialog(config_);
+
+ fileList = fileDialog.getOpenNames("Choose a Javascript file", "JavaScript File (*.js)");
+
+ if (!fileList.isEmpty() && fileList.count() == 1) {
+ runScript(fileList.at(0));
+ }
+}
+
+void FQTermWindow::stopScript() {
+ script_engine_->stopScript();
+}
+
+void FQTermWindow::viewMessages() {
+ msgDialog msg(this);
+
+ QByteArray dlgSize =
+// frame_->config()->getItemValue("global", "msgdialog").toLatin1();
+ config_->getItemValue("global", "msgdialog").toLatin1();
+ const char *dsize = dlgSize.constData();
+ if (!dlgSize.isEmpty()) {
+ int x, y, cx, cy;
+ sscanf(dsize, "%d %d %d %d", &x, &y, &cx, &cy);
+ msg.resize(QSize(cx, cy));
+ msg.move(QPoint(x, y));
+ } else {
+ msg.resize(QSize(300, 500));
+ msg.move(QPoint(20,20));
+ }
+
+ msg.setMessageText(allMessages_);
+ msg.exec();
+
+ QString strSize = QString("%1 %2 %3 %4").arg(msg.x()).arg(msg.y()).arg
+ (msg.width()).arg(msg.height());
+// frame_->config()->setItemValue("global", "msgdialog", strSize);
+ config_->setItemValue("global", "msgdialog", strSize);
+}
+
+void FQTermWindow::setting() {
+ addrDialog set(this, session_->param());
+ int res = set.exec();
+ if (res != 0) {
+ updateSetting(set.param());
+ if (res == 2)
+ saveSetting(false);
+ }
+}
+
+void FQTermWindow::toggleAntiIdle() {
+ session_->setAntiIdle(!session_->isAntiIdle());
+}
+
+void FQTermWindow::toggleAutoReply() {
+ session_->setAutoReply(!session_->isAutoReply());
+}
+
+void FQTermWindow::toggleAutoReconnect() {
+ session_->setAutoReconnect(!session_->param().isAutoReconnect_);
+}
+
+void FQTermWindow::connectionClosed() {
+ stopBlink();
+
+ pageViewMessage_->display(tr("Connection closed"), screen_->mapToPixel(QPoint(1, 1)));
+
+ frame_->updateMenuToolBar();
+
+ setCursor(cursors_[FQTermSession::kNormal]);
+
+ refreshScreen();
+
+ if (!getSession()->param().isAutoReconnect_ && getSession()->param().isAutoCloseWin_) {
+ emit(connectionClosed(this));
+ }
+}
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* Events */
+/* */
+/* ------------------------------------------------------------------------ */
+
+void FQTermWindow::articleCopied(int e, const QString content) {
+ if (e == DAE_FINISH) {
+// articleDialog article(frame_->config(), this);
+ articleDialog article(config_, this);
+
+ // Fix focus-losing bug.
+ // dsize should be a pointer to a non-temprary object.
+ QByteArray dlgSize =
+// frame_->config()->getItemValue("global", "articledialog").toLatin1();
+ config_->getItemValue("global", "articledialog").toLatin1();
+
+ const char *dsize = dlgSize.constData();
+
+ if (!dlgSize.isEmpty()) {
+ int x, y, cx, cy;
+ sscanf(dsize, "%d %d %d %d", &x, &y, &cx, &cy);
+ article.resize(QSize(cx, cy));
+ article.move(QPoint(x, y));
+ } else {
+ article.resize(QSize(300, 500));
+ article.move(20,20);
+ }
+ article.articleText_ = content;
+
+ article.ui_.textBrowser->setPlainText(article.articleText_);
+ article.exec();
+ QString strSize = QString("%1 %2 %3 %4").arg(article.x()).arg(article.y())
+ .arg(article.width()).arg(article.height());
+// frame_->config()->setItemValue("global", "articledialog", strSize);
+ config_->setItemValue("global", "articledialog", strSize);
+ } else if (e == DAE_TIMEOUT) {
+ QMessageBox::warning(this, "timeout", "download article timeout, aborted");
+#ifdef HAVE_PYTHON
+ } else if (e == PYE_ERROR) {
+ QMessageBox::warning(this, "Python script error", pythonErrorMessage_);
+ } else if (e == PYE_FINISH) {
+ QMessageBox::information(this, "Python script finished",
+ "Python script file executed successfully");
+#endif //HAVE_PYTHON
+ }
+}
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* Aux Func */
+/* */
+/* ------------------------------------------------------------------------ */
+
+QByteArray FQTermWindow::parseString(const QByteArray &cstr, int *len) {
+ QByteArray parsed = "";
+
+ if (len != 0) {
+ *len = 0;
+ }
+
+ for (uint i = 0; (long)i < cstr.length(); i++) {
+ if (cstr.at(i) == '^') {
+ i++;
+ if ((long)i < cstr.length()) {
+ parsed += FQTERM_CTRL(cstr.at(i));
+ if (len != 0) {
+ *len = *len + 1;
+ }
+ }
+ } else if (cstr.at(i) == '\\') {
+ i++;
+ if ((long)i < cstr.length()) {
+ if (cstr.at(i) == 'n') {
+ parsed += CHAR_CR;
+ } else if (cstr.at(i) == 'r') {
+ parsed += CHAR_LF;
+ } else if (cstr.at(i) == 't') {
+ parsed += CHAR_TAB;
+ }
+ if (len != 0) {
+ *len = *len + 1;
+ }
+ }
+ } else {
+ parsed += cstr.at(i);
+ if (len != 0) {
+ *len = *len + 1;
+ }
+ }
+ }
+
+ return parsed;
+}
+
+void FQTermWindow::messageAutoReplied() {
+ pageViewMessage_->display("You have messages", PageViewMessage::Info, 0);
+}
+
+void FQTermWindow::saveSetting(bool ask /* = true*/) {
+ if (addressIndex_ == -1) {
+ return ;
+ }
+
+ //save these options silently
+ FQTermConfig pConf(getPath(USER_CONFIG) + "address.cfg");
+ FQTermParam param;
+ loadAddress(&pConf, addressIndex_, param);
+ param.isAutoCopy_ = session_->param().isAutoCopy_;
+ param.isAutoWrap_ = session_->param().isAutoWrap_;
+ param.isRectSelect_ = session_->param().isRectSelect_;
+ param.isColorCopy_ = session_->param().isColorCopy_;
+ saveAddress(&pConf, addressIndex_, param);
+ pConf.save(getPath(USER_CONFIG) + "address.cfg");
+
+ if (param == session_->param()) {
+ return;
+ }
+
+ QMessageBox mb("FQTerm", "Setting changed do you want to save it?",
+ QMessageBox::Warning, QMessageBox::Yes | QMessageBox::Default,
+ QMessageBox::No | QMessageBox::Escape, 0, this);
+ if (!ask || mb.exec() == QMessageBox::Yes) {
+ saveAddress(&pConf, addressIndex_, session_->param());
+ pConf.save(getPath(USER_CONFIG) + "address.cfg");
+ }
+}
+
+int FQTermWindow::externInput(const QByteArray &cstrText) {
+ QByteArray cstrParsed = parseString(cstrText);
+ return session_->write(cstrParsed, cstrParsed.length());
+}
+
+int FQTermWindow::externInput(const QString &cstrText) {
+ return externInput(session_->unicode2bbs_smart(cstrText));
+}
+
+int FQTermWindow::writeRawString(const QString& str) {
+ QByteArray rawStr = session_->unicode2bbs_smart(str);
+ return session_->write(rawStr, rawStr.length());
+}
+
+void FQTermWindow::sendParsedString(const char *str) {
+ int length;
+ QByteArray cstr = parseString(str, &length);
+ session_->write(cstr, length);
+}
+
+
+bool FQTermWindow::postQtScriptCallback(const QString& func, const QScriptValueList & args) {
+ return script_engine_->scriptCallback(func, args);
+}
+
+#ifdef HAVE_PYTHON
+bool FQTermWindow::postPythonCallback( const QString& func, PyObject* pArgs )
+{
+ return pythonCallback(func, pArgs);
+}
+#endif //HAVE_PYTHON
+
+// void FQTermWindow::setMouseMode(bool on) {
+// isMouseX11_ = on;
+// }
+
+// /* 0-left 1-middle 2-right 3-relsase 4/5-wheel
+// *
+// */
+// //void FQTermWindow::sendMouseState( int num,
+// // Qt::ButtonState btnstate, Qt::ButtonState keystate, const QPoint& pt )
+// void FQTermWindow::sendMouseState(int num, Qt::KeyboardModifier btnstate,
+// Qt::KeyboardModifier keystate, const QPoint &pt) {
+// /*
+// if(!m_bMouseX11)
+// return;
+//
+// QPoint ptc = screen_->mapToChar(pt);
+//
+// if(btnstate&Qt::LeftButton)
+// num = num==0?0:num;
+// else if(btnstate&Qt::MidButton)
+// num = num==0?1:num;
+// else if(btnstate&Qt::RightButton)
+// num = num==0?2:num;
+//
+// int state = 0;
+// if(keystate&Qt::ShiftModifier)
+// state |= 0x04;
+// if(keystate&Qt::MetaModifier)
+// state |= 0x08;
+// if(keystate&Qt::ControlModifier)
+// state |= 0x10;
+//
+// // normal buttons are passed as 0x20 + button,
+// // mouse wheel (buttons 4,5) as 0x5c + button
+// if(num>3) num += 0x3c;
+//
+// char mouse[10];
+// sprintf(mouse, "\033[M%c%c%c",
+// num+state+0x20,
+// ptc.x()+1+0x20,
+// ptc.y()+1+0x20);
+// m_pTelnet->write( mouse, strlen(mouse) );
+// */
+// }
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* Python Func */
+/* */
+/* ------------------------------------------------------------------------ */
+#ifdef HAVE_PYTHON
+
+
+void FQTermWindow::runPythonScript() {
+ QStringList fileList;
+ FQTermFileDialog fileDialog(config_);
+
+ fileList = fileDialog.getOpenNames("Choose a Python file", "Python File (*.py)");
+
+ if (!fileList.isEmpty() && fileList.count() == 1) {
+ runPythonScriptFile(fileList.at(0));
+ }
+}
+
+void FQTermWindow::runPythonScriptFile(const QString& file) {
+ QString str(QString("%1").arg(long(this)));
+ char* lp = fq_strdup(str.toUtf8().data());
+ char *argv[2]={lp,NULL};
+ // get the global python thread lock
+ PyEval_AcquireLock();
+
+ PyInterpreterState * mainInterpreterState = frame_->getPythonHelper()->getPyThreadState()->interp;
+
+ // create a thread state object for this thread
+ PyThreadState * myThreadState = PyThreadState_New(mainInterpreterState);
+ PyThreadState_Swap(myThreadState);
+
+
+ PySys_SetArgv(1, argv);
+
+ runPythonFile(file);
+
+ //Clean up this thread's python interpreter reference
+ PyThreadState_Swap(NULL);
+ PyThreadState_Clear(myThreadState);
+ PyThreadState_Delete(myThreadState);
+ PyEval_ReleaseLock();
+ free((void*)lp);
+}
+
+bool FQTermWindow::pythonCallback(const QString & func, PyObject* pArgs) {
+ if(!pythonScriptLoaded_) {
+ Py_DECREF(pArgs);
+ return false;
+ };
+
+ bool done = false;
+ // get the global lock
+ PyEval_AcquireLock();
+ // get a reference to the PyInterpreterState
+
+ //Python thread references
+
+ PyInterpreterState * mainInterpreterState = frame_->getPythonHelper()->getPyThreadState()->interp;
+ // create a thread state object for this thread
+ PyThreadState * myThreadState = PyThreadState_New(mainInterpreterState);
+ PyThreadState_Swap(myThreadState);
+
+ PyObject *pF = PyString_FromString(func.toUtf8());
+ PyObject *pFunc = PyDict_GetItem(pDict, pF);
+ Py_DECREF(pF);
+
+ if (pFunc && PyCallable_Check(pFunc))
+ {
+ PyObject *pValue = PyObject_CallObject(pFunc, pArgs);
+ Py_DECREF(pArgs);
+ if (pValue != NULL)
+ {
+ if (PyBool_Check(pValue) && pValue == Py_True)
+ done = true;
+ Py_DECREF(pValue);
+ }
+ else
+ {
+ //QMessageBox::warning(this,"Python script error", getException());
+ printf("%p: Python script error\n", this, getException().toUtf8().data());
+ }
+ }
+ else
+ {
+ PyErr_Print();
+ printf("Cannot find python %s callback function\n", func.toUtf8().data());
+ }
+
+ // swap my thread state out of the interpreter
+ PyThreadState_Swap(NULL);
+ // clear out any cruft from thread state object
+ PyThreadState_Clear(myThreadState);
+ // delete my thread state object
+ PyThreadState_Delete(myThreadState);
+ // release the lock
+ PyEval_ReleaseLock();
+
+ if (func == "autoReply")
+ startBlink();
+
+ return done;
+}
+
+
+int FQTermWindow::runPythonFile( const QString& file )
+{
+ QString buffer("def work_thread():\n"
+ "\ttry:\n\t\texecfile('");
+ buffer += QString(file).replace("\\", "\\\\");
+
+ /* Have to do it like this. PyRun_SimpleFile requires you to pass a
+ * stdio file pointer, but Vim and the Python DLL are compiled with
+ * different options under Windows, meaning that stdio pointers aren't
+ * compatible between the two. Yuk.
+ *
+ * Put the string "execfile('file')" into buffer. But, we need to
+ * escape any backslashes or single quotes in the file name, so that
+ * Python won't mangle the file name.
+ * ---- kafa
+ */
+
+ /* Put in the terminating "')" and a null */
+ buffer += "',{})\n\0";
+
+ buffer += QString("\texcept:\n"
+ "\t\texc, val, tb = sys.exc_info()\n"
+ "\t\tlines = traceback.format_exception(exc, val, tb)\n"
+ "\t\terr = string.join(lines)\n"
+ "\t\tprint err\n"
+ "\t\tf=open('%1','w')\n"
+ "\t\tf.write(err)\n"
+ "\t\tf.close()\n").arg(getErrOutputFile(this));
+
+ buffer += QString("\t\tfqterm.formatError(%1)\n").arg((long)this);
+ buffer += "\t\texit\n";
+
+ /* Execute the file */
+ PyRun_SimpleString("import thread,string,sys,traceback,fqterm");
+ PyRun_SimpleString(buffer.toUtf8());
+ PyRun_SimpleString( "thread.start_new_thread(work_thread,())\n");
+
+ return 0;
+}
+
+void FQTermWindow::initPython(const QString& file) {
+
+ // get the global python thread lock
+ PyEval_AcquireLock();
+
+ // get a reference to the PyInterpreterState
+ PyInterpreterState * mainInterpreterState = frame_->getPythonHelper()->getPyThreadState()->interp;
+
+
+
+ // create a thread state object for this thread
+ PyThreadState * myThreadState = PyThreadState_New(mainInterpreterState);
+ PyThreadState_Swap(myThreadState);
+
+ Py_InitModule4("fqterm", fqterm_methods,
+ NULL,(PyObject*)NULL,PYTHON_API_VERSION);
+
+ PyImport_AddModule("fqterm");
+
+ if(!file.isEmpty() )
+ {
+ QFileInfo info(file);
+ PyRun_SimpleString("import sys");
+ PyRun_SimpleString(QString("sys.path.append(\"%1/\")").arg(info.absolutePath()).toUtf8().data());
+ PyObject *pName = PyString_FromString(info.baseName().toUtf8().data());
+ pModule = PyImport_Import(pName);
+ //PyErr_Print();
+ Py_DECREF(pName);
+ if (pModule != NULL)
+ pDict = PyModule_GetDict(pModule);
+ else
+ {
+ //printf("Failed to PyImport_Import\n");
+ }
+
+ if(pDict != NULL )
+ pythonScriptLoaded_ = true;
+ else
+ {
+ //printf("Failed to PyModule_GetDict\n");
+ }
+ }
+
+ //Clean up this thread's python interpreter reference
+ PyThreadState_Swap(NULL);
+ PyThreadState_Clear(myThreadState);
+ PyThreadState_Delete(myThreadState);
+ PyEval_ReleaseLock();
+
+}
+
+void FQTermWindow::finalizePython()
+{
+ // get the global python thread lock
+ PyEval_AcquireLock();
+
+ // get a reference to the PyInterpreterState
+ PyInterpreterState * mainInterpreterState = frame_->getPythonHelper()->getPyThreadState()->interp;
+
+ // create a thread state object for this thread
+ PyThreadState * myThreadState = PyThreadState_New(mainInterpreterState);
+ PyThreadState_Swap(myThreadState);
+
+ //Displose of current python module so we can reload in constructor.
+ if(pModule!=NULL)
+ Py_DECREF(pModule);
+
+ //Clean up this thread's python interpreter reference
+ PyThreadState_Swap(NULL);
+ PyThreadState_Clear(myThreadState);
+ PyThreadState_Delete(myThreadState);
+ PyEval_ReleaseLock();
+}
+
+#endif //HAVE_PYTHON
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* HTTP Func */
+/* */
+/* ------------------------------------------------------------------------ */
+
+void FQTermWindow::openLink() {
+ QString url = session_->getUrl();
+ if (!url.isEmpty()) {
+ openUrlImpl(url);
+ }
+}
+
+void FQTermWindow::saveLink() {
+ QString url = session_->getUrl();
+ if (!url.isEmpty())
+ getHttpHelper(url, false);
+}
+
+void FQTermWindow::openUrl(QString url)
+{
+ QString caption = tr("URL Dialog");
+ QString strUrl = url;
+ QTextEdit *textEdit = new QTextEdit();
+ textEdit->setPlainText(strUrl);
+ //textEdit->setFocus();
+ textEdit->setTabChangesFocus(true);
+ textEdit->moveCursor(QTextCursor::End);
+
+
+ QPushButton *okButton = new QPushButton(tr("&Open URL"));
+ QPushButton *cancelButton = new QPushButton(tr("&Cancel"));
+// okButton->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+// cancelButton->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+
+
+ QGridLayout *layout = new QGridLayout;
+ layout->addWidget(textEdit, 0, 0, 1, -1);
+ layout->addWidget(okButton, 1, 3);
+ layout->addWidget(cancelButton, 1, 4);
+
+ QDialog dlg(this);
+
+ QFontMetrics fm(qApp->font());
+
+
+ connect(okButton, SIGNAL(pressed()), &dlg, SLOT(accept()));
+ connect(cancelButton, SIGNAL(pressed()), &dlg, SLOT(reject()));
+
+
+ dlg.setWindowTitle(caption);
+ dlg.setLayout(layout);
+ dlg.resize(fm.width(QString(30, 'W')), fm.height() * (fm.width(strUrl) / fm.width(QString(30, 'W')) + 5));
+ textEdit->clearFocus();
+ okButton->setFocus(Qt::TabFocusReason);
+ if (dlg.exec()) {
+ openUrlImpl(textEdit->toPlainText());
+ }
+}
+
+
+void FQTermWindow::openUrlImpl(QString url)
+{
+ const QString &httpBrowser = FQTermPref::getInstance()->httpBrowser_;
+ if (httpBrowser.isNull() || httpBrowser.isEmpty()) {
+#if QT_VERSION >= 0x040400
+ QDesktopServices::openUrl(QUrl::fromEncoded(url.toLocal8Bit()));
+#else
+ QDesktopServices::openUrl(url);
+#endif
+ } else {
+ runProgram(httpBrowser, url);
+ }
+}
+
+
+void FQTermWindow::previewLink() {
+ getHttpHelper(session_->getUrl(), true);
+}
+
+void FQTermWindow::copyLink() {
+ QString strUrl;
+ strUrl = session_->bbs2unicode(session_->getUrl().toLatin1());
+
+ QClipboard *clipboard = QApplication::clipboard();
+
+ clipboard->setText(strUrl, QClipboard::Selection);
+ clipboard->setText(strUrl, QClipboard::Clipboard);
+}
+
+void FQTermWindow::getHttpHelper(const QString &url, bool preview) {
+
+ const QString &strPool = FQTermPref::getInstance()->poolDir_;
+
+ FQTermHttp *http = new FQTermHttp(config_, this, strPool, session_->param().serverEncodingID_);
+ if (getSession()->param().proxyType_ != 0) {
+ QString host = getSession()->param().proxyHostName_;
+ int port = getSession()->param().proxyPort_;
+ bool auth = getSession()->param().isAuthentation_;
+ QString user = auth ? getSession()->param().proxyUserName_ : QString();
+ QString pass = auth ? getSession()->param().proxyPassword_ : QString();
+ switch (getSession()->param().proxyType_)
+ {
+ case 1:
+ case 2:
+ //no support in qt.
+ FQ_TRACE("network", 0) << "proxy type not supported by qt, download will not use proxy.";
+ break;
+ case 3:
+ http->setProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, host, port, user, pass));
+ break;
+ case 4:
+ http->setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, host, port, user, pass));
+ break;
+ }
+ }
+ FQTerm::StatusBar::instance()->newProgressOperation(http).setDescription(tr("Waiting header...")).setAbortSlot(http, SLOT(cancel())).setMaximum(100);
+ FQTerm::StatusBar::instance()->resetMainText();
+ FQTerm::StatusBar::instance()->setProgress(http, 0);
+
+ FQ_VERIFY(connect(http, SIGNAL(headerReceived(FQTermHttp *, const QString &)),
+ this, SLOT(startHttpDownload(FQTermHttp*,const QString&))));
+
+ FQ_VERIFY(connect(http,SIGNAL(done(QObject*)),this,SLOT(httpDone(QObject*))));
+
+ FQ_VERIFY(connect(http, SIGNAL(message(const QString &)),
+ pageViewMessage_, SLOT(showText(const QString &))));
+
+ FQ_VERIFY(connect(http, SIGNAL(done(QObject*)),
+ FQTerm::StatusBar::instance(),
+ SLOT(endProgressOperation(QObject*))));
+
+ FQ_VERIFY(connect(http, SIGNAL(percent(int)),
+ FQTerm::StatusBar::instance(), SLOT(setProgress(int))));
+
+ FQ_VERIFY(connect(http, SIGNAL(previewImage(const QString &, bool, bool)),
+ this, SLOT(httpPreviewImage(const QString &, bool, bool))));
+
+
+ http->getLink(url, preview);
+}
+
+void FQTermWindow::startHttpDownload(
+ FQTermHttp *pHttp, const QString &filedesp) {
+ FQTerm::StatusBar::instance()->newProgressOperation(pHttp).setDescription
+ (filedesp).setAbortSlot(pHttp, SLOT(cancel())).setMaximum(100);
+
+ FQTerm::StatusBar::instance()->resetMainText();
+}
+
+void FQTermWindow::httpDone(QObject *pHttp) {
+ pHttp->deleteLater();
+}
+
+void FQTermWindow::httpPreviewImage(const QString &filename, bool raiseViewer, bool done)
+{
+ if (config_->getItemValue("preference", "image").isEmpty() || done) {
+ previewImage(filename, raiseViewer);
+ }
+}
+
+void FQTermWindow::previewImage(const QString &filename, bool raiseViewer) {
+// QString strViewer = frame_->config()->getItemValue("preference", "image");
+ QString strViewer = config_->getItemValue("preference", "image");
+
+ if (strViewer.isEmpty()) {
+ frame_->viewImages(filename, raiseViewer);
+ } else if(raiseViewer) {
+ runProgram(strViewer, filename);
+ }
+
+}
+
+void FQTermWindow::beep() {
+ if (session_->param().isBeep_) {
+ if (session_->param().isBuzz_) {
+ frame_->buzz(this);
+ }
+ if (FQTermPref::getInstance()->beepSoundFileName_.isEmpty() ||
+ FQTermPref::getInstance()->openBeep_ == 3) {
+ qApp->beep();
+ }
+ else {
+ sound_ = NULL;
+
+ switch (FQTermPref::getInstance()->beepMethodID_) {
+ case 0:
+ sound_ =
+ new FQTermSystemSound(FQTermPref::getInstance()->beepSoundFileName_);
+ break;
+ case 1:
+ sound_ =
+ new FQTermExternalSound(FQTermPref::getInstance()->beepPlayerName_,
+ FQTermPref::getInstance()->beepSoundFileName_);
+ break;
+ }
+
+ if (sound_) {
+ sound_->start();
+ }
+ }
+ }
+
+ QString strMsg = session_->getMessage();
+ if (!strMsg.isEmpty()) {
+ allMessages_ += strMsg + "\n\n";
+ }
+
+ session_->setSendingMessage();
+}
+
+
+void FQTermWindow::onTitleSet(const QString& title) {
+ setWindowTitle(title);
+}
+
+
+void FQTermWindow::startBlink() {
+ if (FQTermPref::getInstance()->openTabBlinking_) {
+ if (!tabBlinkTimer_->isActive()) {
+ tabBlinkTimer_->start(500);
+ }
+ }
+}
+
+void FQTermWindow::stopBlink() {
+ if (tabBlinkTimer_->isActive()) {
+ tabBlinkTimer_->stop();
+ emit blinkTheTab(this, TRUE);
+ }
+}
+
+void FQTermWindow::setCursorType(const QPoint& mousePosition) {
+ QRect rcOld;
+ bool isUrl = false;
+ if (FQTermPref::getInstance()->openUrlCheck_) {
+ showIP(session_->isIP(ipRectangle_, rcOld));
+ if (session_->isUrl(urlRectangle_, rcOld)) {
+ setCursor(Qt::PointingHandCursor);
+ isUrl = true;
+ }
+ }
+ if (!isUrl) {
+ FQTermSession::CursorType cursorType =
+ session_->getCursorType(screen_->mapToChar(mousePosition));
+ setCursor(cursors_[cursorType]);
+ }
+}
+
+void FQTermWindow::setCursorPosition(const QPoint& mousePosition) {
+ // set cursor pos, repaint if state changed
+ QRect rc;
+ if (session_->setCursorPos(screen_->mapToChar(mousePosition), rc)) {
+ screen_->repaint(screen_->mapToRect(rc));
+
+ //re-check whether the cursor is still on the selected rectangle -- dp
+ QPoint localPos = mapFromGlobal(QCursor::pos()); //local.
+ if (!session_->getMenuRect().contains(screen_->mapToChar(localPos)))
+ {
+ QRect dummyRect;
+ rc = session_->getMenuRect();
+ session_->setCursorPos(screen_->mapToChar(localPos), dummyRect);
+ screen_->repaint(screen_->mapToRect(rc));
+ //restore the state.
+ session_->setCursorPos(screen_->mapToChar(mousePosition), dummyRect);
+ }
+ }
+}
+
+void FQTermWindow::refreshScreen() {
+ screen_->setPaintState(FQTermScreen::NewData);
+ screen_->update();
+}
+
+void FQTermWindow::repaintScreen() {
+
+ screen_->setPaintState(FQTermScreen::Repaint);
+ if (clientRect_ != QRect()) {
+ screen_->repaint(screen_->mapToRect(clientRect_));
+ } else {
+ screen_->repaint();
+ }
+ clientRect_ = QRect();
+// screen_->update(clientRect_);
+}
+
+void FQTermWindow::enterMenuItem() {
+ char cr = CHAR_CR;
+ QRect rc = session_->getMenuRect();
+ FQTermSession::PageState ps = session_->getPageState();
+ switch (ps) {
+ case FQTermSession::Menu:
+ case FQTermSession::MailMenu:
+ case FQTermSession::TOP10:
+ if (!rc.isEmpty()) {
+ char cMenu = session_->getMenuChar();
+ session_->write(&cMenu, 1);
+ session_->write(&cr, 1);
+ }
+ break;
+ case FQTermSession::ArticleList:
+ case FQTermSession::BoardList:
+ case FQTermSession::FriendMailList:
+ case FQTermSession::EliteArticleList:
+ if (!rc.isEmpty()) {
+ int n = rc.y() - session_->getBuffer()->getCaretLine();
+ // scroll lines
+ int cursorType = n>0?FQTermSession::kDown:FQTermSession::kUp;
+ n = qAbs(n);
+ while (n) {
+ session_->write(directions_[cursorType], 4);
+ n--;
+ }
+ }
+ session_->write(&cr, 1);
+ break;
+ default:
+ // TODO: process other PageState.
+ break;
+ }
+}
+
+void FQTermWindow::processLClick(const QPoint& cellClicked) {
+ int cursorType = session_->getCursorType(cellClicked);
+ switch(cursorType)
+ {
+ case FQTermSession::kHome:
+ case FQTermSession::kEnd:
+ case FQTermSession::kPageUp:
+ case FQTermSession::kPageDown:
+ session_->writeStr(directions_[cursorType]);
+ break;
+ case FQTermSession::kUp:
+ case FQTermSession::kDown:
+ case FQTermSession::kLeft:
+ session_->writeStr(directions_[cursorType]);
+ break;
+ case FQTermSession::kRight: //Hand
+ enterMenuItem();
+ break;
+ case FQTermSession::kNormal:
+ char cr = CHAR_CR;
+ session_->write(&cr, 1);
+ break;
+ }
+}
+
+void FQTermWindow::startSelecting(const QPoint& mousePosition) {
+ // clear the selected before
+ session_->clearSelect();
+ sessionUpdated();
+
+ // set the selecting flag
+ isSelecting_ = true;
+ lastMouseCell_ = screen_->mapToChar(mousePosition);
+}
+
+void FQTermWindow::onSelecting(const QPoint& mousePosition) {
+ if (mousePosition.y() < childrenRect().top()) {
+ screen_->scrollLine(-1);
+ }
+ if (mousePosition.y() > childrenRect().bottom()) {
+ screen_->scrollLine(1);
+ }
+
+ QPoint curMouseCell = screen_->mapToChar(mousePosition);
+ session_->setSelect(lastMouseCell_, curMouseCell);
+ sessionUpdated();
+}
+
+void FQTermWindow::finishSelecting(const QPoint& mousePosition) {
+ QPoint currentMouseCell = screen_->mapToChar(mousePosition);
+ session_->setSelect(currentMouseCell, lastMouseCell_);
+ refreshScreen();
+ if (session_->param().isAutoCopy_) {
+ copy();
+ }
+ isSelecting_ = false;
+}
+
+void FQTermWindow::sendKey(const int keyCode, const Qt::KeyboardModifiers modifier,
+ const QString &t) {
+ if (keyCode == Qt::Key_Shift || keyCode == Qt::Key_Control
+ || keyCode == Qt::Key_Meta || keyCode == Qt::Key_Alt) {
+ return;
+ }
+
+ int key = keyCode;
+ QString text = t;
+
+#ifdef __APPLE__
+ // On Mac, pressing Command Key (Apple Key) will set the ControlModifier flag.
+ bool alt_on = ((modifier & Qt::ControlModifier) || (modifier & Qt::AltModifier));
+ bool ctrl_on = (modifier & Qt::MetaModifier);
+#else
+ bool alt_on = ((modifier & Qt::MetaModifier) || (modifier & Qt::AltModifier));
+ bool ctrl_on = (modifier & Qt::ControlModifier);
+#endif
+ bool shift_on = (modifier & Qt::ShiftModifier);
+
+#ifdef __APPLE__
+ // Bullshit! Qt4.4.0 on Mac generates weird key evnets.
+ // fix them here.
+
+ if (ctrl_on) {
+ static const char char_map[][2] = {
+ {'@', '\x00'}, {'A', '\x01'}, {'B', '\x02'}, {'C', '\x03'}, {'D', '\x04'},
+ {'E', '\x05'}, {'F', '\x06'}, {'G', '\x07'}, {'H', '\x08'}, {'J', '\x0a'},
+ {'K', '\x0b'}, {'L', '\x0c'}, {'N', '\x0e'}, {'O', '\x0f'}, {'P', '\x10'},
+ {'Q', '\x11'}, {'R', '\x12'}, {'S', '\x13'}, {'T', '\x14'}, {'U', '\x15'},
+ {'V', '\x16'}, {'W', '\x17'}, {'X', '\x18'}, {'Y', '\x19'}, {'Z', '\x1a'},
+ {'\\', '\x1c'}, {']', '\x1d'}, {'^', '\x1e'}, {'_', '\x1f'}
+ };
+
+ const int num = sizeof(char_map)/2;
+
+ int expected_key = key;
+
+ for (int i = 0; i < num; ++i) {
+ const char *c = char_map[i];
+ if (c[0] == key) {
+ expected_key = c[1];
+ break;
+ }
+ }
+
+ if (expected_key != key) {
+ FQ_TRACE("sendkey", 5) << "translate the key code from "
+ << (int)key << "(" << (char)key << ")"
+ << " to "
+ << (int)expected_key
+ << "(" << (char)expected_key << ")"
+ << ", and change the text appropriately." ;
+ key = expected_key;
+ text.clear();
+ text.append((char) expected_key);
+ }
+ }
+
+ if (!ctrl_on && alt_on && !shift_on) {
+ if (text.size() == 0 && 0 <= key && key <= 128) {
+ FQ_TRACE("sendkey", 5)
+ << "add appropriate text according to the key code.";
+ text.append((char)key);
+ }
+ }
+
+ if (!ctrl_on && alt_on && shift_on) {
+ // fix the key code when both shift key and meta/alt key are pressed.
+ static const char char_map[][2] = {
+ {'`', '~'}, {'1', '!'}, {'2', '@'}, {'3', '#'}, {'4', '$'},
+ {'5', '%'}, {'6', '^'}, {'7', '&'}, {'8', '*'}, {'9', '('},
+ {'0', ')'}, {'-', '_'}, {'=', '+'}, {'[', '{'}, {']', '}'},
+ {'\\', '|'}, {';', ':'}, {'\'', '"'}, {',', '<'},{'.', '>'},
+ {'/', '?'}
+ };
+ const int num = sizeof(char_map)/2;
+
+ int expected_key = key;
+
+ for (int i = 0; i < num; ++i) {
+ const char *c = char_map[i];
+ if (c[0] == key) {
+ expected_key = c[1];
+ break;
+ }
+ }
+
+ if (expected_key != key) {
+ FQ_TRACE("sendkey", 5) << "translate the key code from "
+ << (int)key << "(" << (char)key << ")"
+ << " to "
+ << (int)expected_key
+ << "(" << (char)expected_key << ")";
+ key = expected_key;
+ }
+
+ if (text.size() == 0) {
+ text.append(key);
+ } else {
+ text[0] = key;
+ }
+ FQ_TRACE("sendkey", 5)
+ << "set the text for this key event as the keycode.";
+ }
+#endif
+
+ FQ_TRACE("sendkey", 5) << "(alt " << (alt_on? " on": "off")
+ << ", ctrl " << (ctrl_on? " on": "off")
+ << ", shift " << (shift_on? " on": "off") << ")"
+ << " key: " << key
+ << " text: " << (text.size() == 0 ? "NULL" : text)
+ << " (in hex: "
+ << dumpHexString << text.toStdString()
+ << dumpNormalString << ")";
+
+ if (session_->getBuffer()->isAnsiMode()) {
+ if (session_->getBuffer()->isCursorMode()) {
+ switch(key) {
+ case Qt::Key_Up:
+ session_->writeStr("\x1bOA");
+ return;
+ case Qt::Key_Down:
+ session_->writeStr("\x1bOB");
+ return;
+ case Qt::Key_Left:
+ session_->writeStr("\x1bOD");
+ return;
+ case Qt::Key_Right:
+ session_->writeStr("\x1bOC");
+ return;
+ }
+ } else {
+ switch(key) {
+ case Qt::Key_Up:
+ session_->writeStr("\x1b[A");
+ return;
+ case Qt::Key_Down:
+ session_->writeStr("\x1b[B");
+ return;
+ case Qt::Key_Left:
+ session_->writeStr("\x1b[D");
+ return;
+ case Qt::Key_Right:
+ session_->writeStr("\x1b[C");
+ return;
+ }
+ }
+ } else {
+ // VT52 mode
+ switch(key) {
+ case Qt::Key_Up:
+ // Do NOT change the parameter to "\x1bA".
+ session_->writeStr("\x1b" "A");
+ return;
+ case Qt::Key_Down:
+ // Do NOT change the parameter to "\x1bB".
+ session_->writeStr("\x1b" "B");
+ return;
+ case Qt::Key_Left:
+ // Do NOT change the parameter to "\x1bD".
+ session_->writeStr("\x1b" "D");
+ return;
+ case Qt::Key_Right:
+ // Do NOT change the parameter to "\x1bC".
+ session_->writeStr("\x1b" "C");
+ return;
+ }
+ }
+
+ if (!session_->getBuffer()->isNumericMode() &&
+ (modifier & Qt::KeypadModifier)) {
+ switch(key) {
+ case Qt::Key_0:
+ case Qt::Key_1:
+ case Qt::Key_2:
+ case Qt::Key_3:
+ case Qt::Key_4:
+ case Qt::Key_5:
+ case Qt::Key_6:
+ case Qt::Key_7:
+ case Qt::Key_8:
+ case Qt::Key_9:
+ {
+ char tmp[] = "\x1bOp";
+ tmp[2] = 'p' + key - Qt::Key_0;
+ session_->writeStr(tmp);
+ }
+ return;
+ case Qt::Key_Plus:
+ session_->writeStr("\x1bOl");
+ return;
+ case Qt::Key_Minus:
+ session_->writeStr("\x1bOm");
+ return;
+ case Qt::Key_Period:
+ session_->writeStr("\x1bOn");
+ return;
+ case Qt::Key_Asterisk:
+ session_->writeStr("\x1bOM");
+ return;
+ }
+ }
+
+ switch (key) {
+ case Qt::Key_Home:
+ session_->writeStr(directions_[0]);
+ return;
+ case Qt::Key_End:
+ session_->writeStr(directions_[1]);
+ return;
+ case Qt::Key_PageUp:
+ session_->writeStr(directions_[2]);
+ return;
+ case Qt::Key_PageDown:
+ session_->writeStr(directions_[3]);
+ return;
+ case Qt::Key_Up:
+ session_->writeStr(directions_[4]);
+ return;
+ case Qt::Key_Down:
+ session_->writeStr(directions_[5]);
+ return;
+ case Qt::Key_Left:
+ session_->writeStr(directions_[6]);
+ return;
+ case Qt::Key_Right:
+ session_->writeStr(directions_[7]);
+ return;
+ case Qt::Key_F1:
+ session_->writeStr("\x1b[11~");
+ return;
+ case Qt::Key_F2:
+ session_->writeStr("\x1b[12~");
+ return;
+ case Qt::Key_F3:
+ session_->writeStr("\x1b[13~");
+ return;
+ case Qt::Key_F4:
+ session_->writeStr("\x1b[14~");
+ return;
+ case Qt::Key_F5:
+ session_->writeStr("\x1b[15~");
+ return;
+ case Qt::Key_F6:
+ session_->writeStr("\x1b[17~");
+ return;
+ case Qt::Key_F7:
+ session_->writeStr("\x1b[18~");
+ return;
+ case Qt::Key_F8:
+ session_->writeStr("\x1b[19~");
+ return;
+ case Qt::Key_F9:
+ session_->writeStr("\x1b[20~");
+ return;
+ case Qt::Key_F10:
+ session_->writeStr("\x1b[21~");
+ return;
+ case Qt::Key_F11:
+ session_->writeStr("\x1b[23~");
+ return;
+ case Qt::Key_F12:
+ session_->writeStr("\x1b[24~");
+ return;
+ }
+
+ if (text.length() > 0) {
+ if (alt_on) {
+ // Use ESC to emulate Alt-XX key.
+ session_->writeStr("\x1b");
+ }
+
+ if (ctrl_on) {
+ switch(key) {
+ case Qt::Key_At: // Ctrl-@
+ case Qt::Key_Space: // Ctrl-SPACE
+ // send NULL
+ session_->write("\x0", 1);
+ return;
+ case Qt::Key_AsciiCircum: // Ctrl-^
+ case Qt::Key_AsciiTilde: // Ctrl-~
+ case Qt::Key_QuoteLeft: // Ctrl-`
+ // send RS
+ session_->write("\x1e", 1);
+ return;
+ case Qt::Key_Underscore: // Ctrl-_
+ case Qt::Key_Question: // Ctrl-?
+ // send US
+ session_->write("\x1f", 1);
+ return;
+ }
+ }
+
+ if (key == Qt::Key_Backspace) {
+ if (shift_on) {
+ session_->writeStr("\x1b[3~");
+ } else {
+ if (session_->param().backspaceType_ == 0)
+ session_->writeStr("\x08");
+ else
+ session_->writeStr("\x7f");
+ }
+ return;
+ }
+
+ if (key == Qt::Key_Delete) {
+ if (shift_on) {
+ if (session_->param().backspaceType_ == 0)
+ session_->writeStr("\x08");
+ else
+ session_->writeStr("\x7f");
+ } else {
+ session_->writeStr("\x1b[3~");
+ }
+ return;
+ }
+
+ if (key == Qt::Key_Return) {
+ if (session_->getBuffer()->isNewLineMode()) {
+ session_->write("\r\n", 2);
+ } else {
+ session_->write("\r", 1);
+ }
+ return;
+ }
+
+ QByteArray cstrTmp = session_->unicode2bbs_smart(text);
+ session_->write(cstrTmp, cstrTmp.length());
+ }
+ return;
+}
+
+void FQTermWindow::forcedRepaintScreen() {
+ QResizeEvent *re = new QResizeEvent(screen_->size(), screen_->size());
+ QApplication::postEvent(screen_, re);
+}
+
+void FQTermWindow::updateSetting(const FQTermParam& param) {
+ session_->updateSetting(param);
+ screen_->setTermFont(true,
+ QFont(param.englishFontName_,
+ param.englishFontSize_));
+ screen_->setTermFont(false,
+ QFont(param.otherFontName_,
+ param.otherFontSize_));
+ screen_->setSchema();
+
+ setWindowTitle(param.name_);
+
+ forcedRepaintScreen();
+}
+
+void FQTermWindow::setFont()
+{
+ bool isEnglish =
+ ((QAction*)(sender()))->data().toBool();
+ setFont(isEnglish);
+}
+
+void FQTermWindow::setFont(bool isEnglish) {
+ bool ok;
+ QString& fontName = isEnglish?session_->param().englishFontName_:session_->param().otherFontName_;
+ int& fontSize = isEnglish?session_->param().englishFontSize_:session_->param().otherFontSize_;
+ QFont font(fontName, fontSize);
+ font = QFontDialog::getFont(&ok, font, this, tr("Font Selector")
+#ifdef __APPLE__
+, QFontDialog::DontUseNativeDialog
+#endif
+ );
+ if (ok == true) {
+ if (FQTermPref::getInstance()->openAntiAlias_) {
+ font.setStyleStrategy(QFont::PreferAntialias);
+ }
+ screen_->setTermFont(isEnglish, font);
+ fontName = font.family();
+ fontSize = font.pointSize();
+ forcedRepaintScreen();
+ }
+}
+
+
+void FQTermWindow::runScript(const QString &filename) {
+ script_engine_->runScript(filename);
+}
+
+//-----------
+static int translateQtModifiers(Qt::KeyboardModifiers modifiers) {
+ int state = 0;
+ if (modifiers &Qt::AltModifier) {
+ state |= SBS_ALT;
+ }
+ if (modifiers &Qt::ControlModifier) {
+ state |= SBS_CTRL;
+ }
+ if (modifiers &Qt::ShiftModifier) {
+ state |= SBS_SHIFT;
+ }
+ return state;
+}
+
+static int translateQtButton(Qt::MouseButtons btnstate) {
+ int state = 0;
+ if(btnstate&Qt::LeftButton)
+ state |= SBS_LEFT_BUTTON;
+ if(btnstate&Qt::RightButton)
+ state |= SBS_RIGHT_BUTTON;
+ if(btnstate&Qt::MidButton)
+ state |= SBS_MID_BUTTON;
+ return state;
+}
+
+bool FQTermWindow::scriptKeyEvent( QKeyEvent *keyevent ){
+ bool res = false;
+ int state = 0;
+ state |= translateQtModifiers(keyevent->modifiers());
+
+ res = postScriptCallback(SFN_KEY_EVENT
+#ifdef HAVE_PYTHON
+ ,Py_BuildValue("liii", this, SKET_KEY_PRESS, state, keyevent->key())
+#endif //HAVE_PYTHON
+ ,QScriptValueList() << SKET_KEY_PRESS << state << keyevent->key());
+ return res;
+}
+
+bool FQTermWindow::scriptMouseEvent(QMouseEvent *mouseevent){
+ int type = SMET_UNKOWN;
+ switch (mouseevent->type())
+ {
+ case QEvent::MouseButtonPress:
+ type = SMET_MOUSE_PRESS;
+ break;
+ case QEvent::MouseButtonRelease:
+ type = SMET_MOUSE_RELEASE;
+ break;
+ case QEvent::MouseButtonDblClick:
+ type = SMET_MOUSE_DBCLICK;
+ break;
+ case QEvent::MouseMove:
+ type = SMET_MOUSE_MOVE;
+ break;
+ }
+
+ int delta = 0;
+ int state=0;
+
+ state |= translateQtButton(mouseevent->button());
+ state |= translateQtModifiers(mouseevent->modifiers());
+
+ QPoint ptc = screen_->mapToChar(mouseevent->pos());
+ ptc.setY(ptc.y() - screen_->getBufferStart());
+ int res = postScriptCallback(SFN_MOUSE_EVENT
+#ifdef HAVE_PYTHON
+ ,Py_BuildValue("liiiii", this, type, state, ptc.x(), ptc.y(),delta)
+#endif //HAVE_PYTHON
+ ,QScriptValueList() << type << state << ptc.x() << ptc.y() << delta);
+ return res;
+}
+
+bool FQTermWindow::scriptWheelEvent( QWheelEvent *wheelevent ) {
+ int type = SMET_WHEEL;
+ int delta = 0;
+ int state=0;
+ state |= translateQtModifiers(wheelevent->modifiers());
+ QPoint ptc = screen_->mapToChar(wheelevent->pos());
+ ptc.setY(ptc.y() - screen_->getBufferStart());
+ int res = postScriptCallback(SFN_MOUSE_EVENT
+#ifdef HAVE_PYTHON
+ ,Py_BuildValue("liiiii", this, type, state, ptc.x(), ptc.y(),wheelevent->delta())
+#endif //HAVE_PYTHON
+ ,QScriptValueList() << type << state << ptc.x() << ptc.y() << wheelevent->delta());
+ return res;
+}
+
+const QString FQTermExternalEditor::textEditName_ = "external editor input";
+
+FQTermExternalEditor::FQTermExternalEditor(QWidget* parent)
+: QObject(parent),
+ editorProcess_(NULL),
+ started_(false) {
+ editorProcess_ = new QProcess(this);
+ FQ_VERIFY(connect(editorProcess_, SIGNAL(stateChanged(QProcess::ProcessState)),
+ this, SLOT(stateChanged(QProcess::ProcessState))));
+ clearTempFileContent();
+}
+
+FQTermExternalEditor::~FQTermExternalEditor() {
+ editorProcess_->kill();
+ QFile::remove(getTempFilename());
+ delete editorProcess_;
+}
+
+void FQTermExternalEditor::execDialog() {
+ QDialog *dialog = new QDialog((QWidget *)parent());
+ QGridLayout *layout = new QGridLayout(dialog);
+ QTextEdit *text = new QTextEdit(dialog);
+ text->setObjectName(textEditName_);
+ layout->addWidget(text);
+ QBoxLayout *rowLayout = new QBoxLayout(QBoxLayout::LeftToRight, dialog);
+ layout->addLayout(rowLayout, 1, 0, Qt::AlignHCenter);
+ QPushButton *ok = new QPushButton(tr("OK"), dialog);
+ QPushButton *cancel = new QPushButton(tr("Cancel"), dialog);
+ rowLayout->addWidget(ok);
+ rowLayout->addWidget(cancel);
+ FQ_VERIFY(connect(ok, SIGNAL(clicked()),
+ dialog, SLOT(accept())));
+ FQ_VERIFY(connect(cancel, SIGNAL(clicked()),
+ dialog, SLOT(reject())));
+ FQ_VERIFY(connect(dialog, SIGNAL(accepted()),
+ this, SLOT(readDialogData())));
+ FQ_VERIFY(connect(dialog, SIGNAL(rejected()),
+ this, SLOT(closeDialog())));
+ dialog->setModal(true);
+ dialog->exec();
+}
+
+void FQTermExternalEditor::readDialogData() {
+ QDialog *dialog = (QDialog*)sender();
+ QTextEdit* edit = (QTextEdit*)dialog->findChild<QTextEdit*>(textEditName_);
+ if (edit) {
+ emit done(edit->toPlainText());
+ }
+ closeDialog();
+}
+
+void FQTermExternalEditor::closeDialog() {
+ sender()->deleteLater();
+}
+
+void FQTermExternalEditor::start() {
+ if (FQTermPref::getInstance()->externalEditor_.isEmpty()) {
+ execDialog();
+ return;
+ }
+ if (started_)
+ return;
+ started_ = true;
+ if (FQTermPref::getInstance()->externalEditorArg_.isEmpty()) {
+ editorProcess_->start(FQTermPref::getInstance()->externalEditor_, QStringList() << getTempFilename());
+ } else {
+ FQ_TRACE("editor", 5) << FQTermPref::getInstance()->externalEditorArg_.arg(getTempFilename());
+ editorProcess_->start(FQTermPref::getInstance()->externalEditor_ + " " + FQTermPref::getInstance()->externalEditorArg_.arg(getTempFilename()));
+ }
+}
+
+
+QString FQTermExternalEditor::getTempFilename() {
+ return getPath(USER_CONFIG) + "tmp_do_not_use.txt";
+}
+
+void FQTermExternalEditor::clearTempFileContent() {
+ QFile file(getTempFilename());
+ file.open(QIODevice::Truncate | QIODevice::WriteOnly);
+ file.write("\xEF\xBB\xBF");
+ file.flush();
+ file.close();
+}
+
+void FQTermExternalEditor::stateChanged( QProcess::ProcessState state ) {
+ //FQ_TRACE("editor", 0) << "stateChanged: " << state << editorProcess_->readAllStandardOutput() << editorProcess_->readAllStandardError();
+ if (!started_ || state != QProcess::NotRunning)
+ return;
+ QFile file(getTempFilename());
+ file.open(QIODevice::ReadOnly);
+ QString result = U82U(file.readAll());
+ file.close();
+#if !defined(WIN32) && !defined(__APPLE__)
+ if (result.endsWith(OS_NEW_LINE)) {
+ result.resize(result.size() - 1);
+ }
+#endif
+ emit done(result);
+ clearTempFileContent();
+ started_ = false;
+}
+} // namespace FQTerm
+#include "fqterm_window.moc"
diff --git a/src/fqterm/fqterm_window.h b/src/fqterm/fqterm_window.h
new file mode 100644
index 0000000..011bf86
--- /dev/null
+++ b/src/fqterm/fqterm_window.h
@@ -0,0 +1,345 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_WINDOW_H
+#define FQTERM_WINDOW_H
+
+#include <QMainWindow>
+#include <QCursor>
+#include <QString>
+#include <QProcess>
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "fqterm_param.h"
+#include "fqterm_config.h"
+#include "fqterm_convert.h"
+#include "fqterm_session.h"
+
+class QCloseEvent;
+class QEvent;
+class QKeyEvent;
+class QMouseEvent;
+class QMouseEvent;
+class QProgressBar;
+class QWheelEvent;
+
+namespace FQTerm {
+
+//class QProgressDialog;
+class PageViewMessage;
+class FQTermConfig;
+class FQTermImage;
+class FQTermFrame;
+class FQTermHttp;
+class FQTermScreen;
+class FQTermSession;
+class FQTermSound;
+class FQTermWindow;
+class popWidget;
+class zmodemDialog;
+class FQTermScriptEngine;
+
+class FQTermExternalEditor : public QObject {
+ Q_OBJECT;
+public:
+ FQTermExternalEditor(QWidget* parent);
+ ~FQTermExternalEditor();
+ void start();
+signals:
+ void done(const QString&);
+public slots:
+ void stateChanged(QProcess::ProcessState state);
+protected slots:
+ void readDialogData();
+ void closeDialog();
+private:
+ void execDialog();
+ QString getTempFilename();
+ void clearTempFileContent();
+
+ static const QString textEditName_;
+ bool started_;
+ QProcess* editorProcess_;
+};
+
+class FQTermWindow : public QMainWindow,
+ public FQTermScriptEventListener {
+ friend class FQTermScreen;
+
+ Q_OBJECT;
+ public:
+ FQTermWindow(FQTermConfig *, FQTermFrame *frame, FQTermParam param, int addr = -1, QWidget
+ *parent = 0, const char *name = 0, Qt::WFlags wflags = Qt::Window);
+ ~FQTermWindow();
+
+ void connectHost();
+ bool isConnected();
+
+ void disconnect();
+ //redraw the dirty lines
+ void refreshScreen();
+ //repaint a dirty rectangle.
+ void repaintScreen();
+ //force a repaint by sending a resize event
+ void forcedRepaintScreen();
+ void viewMessages();
+ void toggleAutoReply();
+ void toggleAntiIdle();
+ void toggleAutoReconnect();
+ void setFont(bool isEnglish);
+ void saveSetting(bool ask = true);
+
+ void runScript(const QString & filename);
+ int externInput(const QByteArray &);
+ int externInput(const QString &);
+ void getHttpHelper(const QString &, bool);
+
+ void openUrl(QString url);
+ void openUrlImpl(QString url);
+
+ FQTermSession * getSession() const { return session_; }
+ FQTermScreen * getScreen() const {return screen_;}
+ QPoint getUrlStartPoint() const { return urlStartPoint_; }
+ QPoint getUrlEndPoint() const { return urlEndPoint_; }
+
+ //FQTermScriptEventListener
+private:
+ virtual bool postQtScriptCallback(const QString& func, const QScriptValueList & args = QScriptValueList());
+#ifdef HAVE_PYTHON
+ virtual bool postPythonCallback(const QString& func, PyObject* pArgs);
+#endif //HAVE_PYTHON
+
+public:
+ virtual long windowID() {return long(this);}
+ //end FQTermScriptEventListener
+
+signals:
+ void resizeSignal(FQTermWindow*);
+ void refreshOthers(FQTermWindow*);
+ void blinkTheTab(FQTermWindow*, bool);
+ void connectionClosed(FQTermWindow*);
+ public slots:
+ // ui
+ void copy();
+ void paste();
+ void openAsUrl();
+ void searchIt();
+ void shareIt();
+ void externalEditor();
+ void fastPost();
+ void copyArticle();
+ void setting();
+ void setColor();
+ void runScript();
+ void stopScript();
+
+ void sendParsedString(const char*);
+ void showIP(bool show = true);
+
+ void beep();
+ void startBlink();
+ void stopBlink();
+ void onTitleSet(const QString& title);
+
+ void connectionClosed();
+
+ void messageAutoReplied();
+
+ void pasteHelper(bool);
+
+ QByteArray parseString(const QByteArray &, int *len = 0);
+
+ // void sendMouseState(int, Qt::KeyboardModifier, Qt::KeyboardModifier, const
+ // QPoint &);
+
+
+ protected slots:
+ void setFont();
+ void recreateMenu();
+
+ //refresh screen & reset cursor position
+ void sessionUpdated();
+
+ void requestUserPwd(QString *userName, QString *password, bool *isOK);
+
+ void TelnetState(int);
+ void ZmodemState(int, int, const char *);
+ void showSessionErrorMessage(QString);
+
+ void blinkTab();
+
+ void externalEditorDone(const QString& str);
+
+ //http menu
+ void previewLink();
+ void saveLink();
+ void openLink();
+ void copyLink();
+ void previewImage(const QString &filename, bool raiseViewer);
+ void httpPreviewImage(const QString &filename, bool raiseViewer, bool done);
+ void startHttpDownload(FQTermHttp *, const QString &filedesp);
+
+ void httpDone(QObject*);
+
+ // decode
+ // void setMouseMode(bool);
+ void articleCopied(int e, const QString content);
+
+
+ protected:
+ bool event(QEvent*);
+
+ void resizeEvent(QResizeEvent *);
+ void mouseDoubleClickEvent(QMouseEvent*);
+ void mouseMoveEvent(QMouseEvent*);
+ void mousePressEvent(QMouseEvent*);
+ void mouseReleaseEvent(QMouseEvent*);
+ void wheelEvent(QWheelEvent*);
+ void enterEvent(QEvent*);
+ void leaveEvent(QEvent*);
+ void changeEvent(QEvent*);
+ void closeEvent(QCloseEvent*);
+ void keyPressEvent(QKeyEvent*);
+ //void focusInEvent (QFocusEvent *);
+
+ private:
+ FQTermFrame *frame_;
+ FQTermScreen *screen_;
+ FQTermSession *session_;
+ QString allMessages_;
+ // before calling repaintScreen(), pls
+ // fill this rectangle.
+ QRect clientRect_;
+ QPoint urlEndPoint_;
+ QPoint urlStartPoint_;
+
+ QMenu *menu_;
+ QMenu *urlMenu_;
+
+ static char directions_[][5];
+ QCursor cursors_[9];
+
+ FQTermConvert encodingConverter_;
+
+ // mouse select
+ QPoint lastMouseCell_;
+ bool isSelecting_;
+
+ // address setting
+ int addressIndex_;
+
+ // url rect
+ QRect urlRectangle_;
+
+ //ip rect
+ QRect ipRectangle_;
+
+ // play sound
+ FQTermSound *sound_;
+
+
+ FQTermConfig *config_;
+ zmodemDialog *zmodemDialog_;
+
+ //osd
+ PageViewMessage *pageViewMessage_;
+
+ popWidget *popWindow_;
+ QTimer *tabBlinkTimer_;
+
+ bool isMouseClicked_;
+ bool blinkStatus_;
+
+ bool isUrlUnderLined_;
+
+ FQTermScriptEngine *script_engine_;
+ FQTermExternalEditor *externalEditor_;
+ private:
+ void addMenu();
+
+ void setCursorPosition(const QPoint& mousePosition);
+ //set cursor type according to the content
+ //show ip location info if openUrlCheck is set
+ void setCursorType(const QPoint& mousePosition);
+
+
+ void enterMenuItem();
+ void processLClick(const QPoint& cellClicked);
+
+ void startSelecting(const QPoint& mousePosition);
+ void onSelecting(const QPoint& mousePosition);
+ void finishSelecting(const QPoint& mousePosition);
+
+ void updateSetting(const FQTermParam& param);
+
+ void sendKey(const int key, const Qt::KeyboardModifiers modifier,
+ const QString &text);
+
+ bool scriptKeyEvent(QKeyEvent *keyevent);
+ bool scriptMouseEvent(QMouseEvent *mouseevent);
+ bool scriptWheelEvent(QWheelEvent *wheelevent);
+
+ void writePasting(const QString& content);
+
+
+signals:
+ //these 2 signals are connected to corresponding slots to
+ //make write thread safe.
+ int writeStringSignal(const QString& str);
+ int writeRawStringSignal(const QString& str);
+public slots:
+ //for script
+ int writeString(const QString& str) {return externInput(str);}
+ int writeRawString(const QString& str);
+public:
+ void writeString_ts(const QString& str) {emit writeStringSignal(str);}
+ void writeRawString_ts(const QString& str) {emit writeRawStringSignal(str);}
+
+
+
+//python support
+#ifdef HAVE_PYTHON
+public:
+ QString getPythonErrorMessage() {
+ return pythonErrorMessage_;
+ }
+ void runPythonScript();
+ void runPythonScriptFile(const QString&);
+
+protected:
+ bool pythonCallback(const QString &, PyObject*);
+ int runPythonFile(const QString& file);
+ void initPython(const QString& file);
+ void finalizePython();
+ //void sendMouseState(int, ButtonState, ButtonState, const QPoint&);
+private:
+ PyObject *pModule, *pDict;
+ bool pythonScriptLoaded_;
+ QString pythonErrorMessage_;
+#endif
+
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_WINDOW_H
+
diff --git a/src/fqterm/fqterm_wndmgr.cpp b/src/fqterm/fqterm_wndmgr.cpp
new file mode 100644
index 0000000..0e90b1c
--- /dev/null
+++ b/src/fqterm/fqterm_wndmgr.cpp
@@ -0,0 +1,381 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+/////////////////////////////////////////////////////////////////
+//TODO: This class has too many overlap with MDI Area.
+//It should inherit the QMdiArea...
+/////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+
+#include <QApplication>
+#include <QEvent>
+#include <QKeyEvent>
+#include <QIcon>
+#include <QKeySequence>
+#include <QMdiArea>
+#include <QMdiSubWindow>
+#include <QTabBar>
+#include <QMouseEvent>
+#include <QMenu>
+#include <QMessageBox>
+#include <QToolButton>
+#include "fqterm_frame.h"
+#include "fqterm_path.h"
+#include "fqterm_screen.h"
+#include "fqterm_trace.h"
+#include "fqterm_window.h"
+#include "fqterm_wndmgr.h"
+#ifdef HAVE_PYTHON
+#include <Python.h>
+#endif //HAVE_PYTHON
+namespace FQTerm {
+
+//constructor
+FQTermWndMgr::FQTermWndMgr(QWidget *parent, const char *name)
+ : QMdiArea(parent),
+ subWindowMax_(true),
+ subWindowSize_(640, 480),
+ tabBar_(NULL)
+ {
+ tabBar_ = new FQTermTabBar(this);
+ tabBar_->setShape(QTabBar::RoundedSouth);
+ FQ_VERIFY(connect(tabBar_, SIGNAL(currentChanged(int)),
+ this, SLOT(activateTheWindow(int))));
+ FQ_VERIFY(connect(tabBar_, SIGNAL(rightClicked(int,const QPoint&)),
+ this, SLOT(onTabRightClicked(int,const QPoint&))));
+ FQ_VERIFY(connect(tabBar_, SIGNAL(doubleClicked(int,const QPoint&)),
+ this, SLOT(onTabDoubleClicked(int,const QPoint&))));
+ setObjectName(name);
+ termFrame_ = (FQTermFrame*)parent;
+ isAfterRemoved_ = false;
+}
+
+//destructor
+FQTermWndMgr::~FQTermWndMgr(){}
+
+
+//remove window-tab-iconset
+bool FQTermWndMgr::closeWindow(FQTermWindow *mw) {
+ FQ_FUNC_TRACE("wndmgr", 3);
+ QMdiSubWindow* subWindow = FQToMDI(mw);
+ if (subWindow) {
+ return subWindow->close();
+ }
+ return false;
+}
+
+bool FQTermWndMgr::closeAllWindow() {
+ FQ_FUNC_TRACE("wndmgr", 3);
+
+ bool anyConnected = false;
+
+ for (int i = 0; i < subWindowList().size(); ++i) {
+ FQTermWindow * window = (FQTermWindow *)(subWindowList()[i]->widget());
+ if (window->isConnected()) {
+ anyConnected = true;
+ break;
+ }
+ }
+
+ bool warn = FQTermPref::getInstance()->openWarnOnClose_;
+ if (anyConnected && warn) {
+ QMessageBox mb(tr("FQTerm"),
+ tr("Still connected, do you really want to exit?"),
+ QMessageBox::Warning, QMessageBox::Yes|QMessageBox::Default,
+ QMessageBox::No | QMessageBox::Escape, 0, this);
+ if (mb.exec() != QMessageBox::Yes) {
+ return false;
+ }
+ }
+ FQTermPref::getInstance()->openWarnOnClose_ = false;
+ while (count() > 0) {
+ bool closed = subWindowList().at(0)->close();
+ if (!closed) {
+ FQTermPref::getInstance()->openWarnOnClose_ = warn;
+ return false;
+ }
+ }
+ FQTermPref::getInstance()->openWarnOnClose_ = warn;
+ return true;
+}
+
+
+
+//active the window when switch the tab
+void FQTermWndMgr::activateTheWindow(int n) {
+ FQ_FUNC_TRACE("wndmgr", 3);
+
+ if (n < 0 || n >= count() || subWindowList().at(n) == activeSubWindow())
+ return;
+
+ QMdiSubWindow *subWindow = subWindowList().at(n);
+
+ // Fix the refresh bug by send PaintEvent to session screen.
+ //subWindow->setFocus();
+ setActiveSubWindow(subWindow);
+
+}
+
+//blink the tab when message come in
+void FQTermWndMgr::blinkTheTab(FQTermWindow *mw, bool bVisible) {
+ FQ_FUNC_TRACE("wndmgr", 10);
+ static QIcon a_icon(getPath(RESOURCE) + "pic/tabpad.png");
+ static QIcon b_icon(getPath(RESOURCE) + "pic/transp.png");
+
+ //find where it is
+ QMdiSubWindow* subWindow = FQToMDI(mw);
+ if (!subWindow)
+ return;
+ int n = subWindowList().indexOf(subWindow);
+ QIcon *icon = icons_.at(n);
+ //FIXME: QIcon::Automatic
+ if (bVisible) {
+ icon->addFile(getPath(RESOURCE) + "pic/tabpad.png");
+
+ tabBar_->setTabIcon(n, a_icon);
+ } else {
+ //,QIcon::Automatic);
+ icon->addFile(getPath(RESOURCE) + "pic/transp.png");
+ tabBar_->setTabIcon(n, b_icon);
+ }
+ //,QIcon::Automatic);
+
+
+
+
+ tabBar_->update();
+}
+
+//return the number of connected window
+int FQTermWndMgr::count() {
+ return subWindowList().count();
+}
+
+FQTermWindow *FQTermWndMgr::activeWindow() {
+ return MDIToFQ(activeSubWindow());
+}
+
+
+bool FQTermWndMgr::afterRemove() {
+ if (isAfterRemoved_) {
+ isAfterRemoved_ = false;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void FQTermWndMgr::refreshAllExcept(FQTermWindow *termWindow) {
+ for (int i = 0; i < subWindowList().count(); ++i) {
+ FQTermWindow * window = (FQTermWindow *)(subWindowList()[i]->widget());
+ if (window != termWindow) {
+ window->repaintScreen();
+ }
+ }
+}
+
+
+FQTermWindow* FQTermWndMgr::newWindow( const FQTermParam &param, FQTermConfig* config, QIcon* icon, int index /*= -1*/ )
+{
+ FQTermWindow *window = new FQTermWindow(config, termFrame_, param, index, this, 0);
+ //add window-tab-icon to window manager
+
+
+ QMdiSubWindow* subWindow = addSubWindow(window);
+ subWindow->setAttribute(Qt::WA_OpaquePaintEvent);
+ subWindow->setAttribute(Qt::WA_DeleteOnClose);
+
+ icons_.append(icon);
+ if (count() == 1) {
+ termFrame_->enableMenuToolBar(true);
+ }
+ //if no this call, the tab wont display untill you resize the window
+ int idx = tabBar_->addTab(*icon, window->windowTitle());
+ tabBar_->updateGeometry();
+ tabBar_->update();
+
+ subWindow->resize(subWindowSize_);
+ if (subWindowMax_) {
+ subWindow->setWindowFlags(Qt::SubWindow | Qt::CustomizeWindowHint | Qt::WindowMinMaxButtonsHint);
+ subWindow->showMaximized();
+ } else {
+ subWindow->setWindowFlags(Qt::SubWindow | (Qt::CustomizeWindowHint
+ | Qt::WindowMinMaxButtonsHint
+ | Qt::WindowSystemMenuHint));
+ subWindow->show();
+ }
+ tabBar_->setTabData(idx, qVariantFromValue((QObject*)window));
+ FQ_VERIFY(connect(window, SIGNAL(destroyed(QObject*)),
+ this ,SLOT(onSubWindowClosed(QObject*))));
+ FQ_VERIFY(connect(window, SIGNAL(resizeSignal(FQTermWindow*)),
+ this, SLOT(subWindowResized(FQTermWindow*))));
+ FQ_VERIFY(connect(this, SIGNAL(subWindowActivated(QMdiSubWindow*)),
+ this, SLOT(onSubWindowActivated(QMdiSubWindow*))));
+ FQ_VERIFY(connect(window, SIGNAL(blinkTheTab(FQTermWindow*, bool)),
+ this, SLOT(blinkTheTab(FQTermWindow*, bool))));
+ FQ_VERIFY(connect(window, SIGNAL(refreshOthers(FQTermWindow*)),
+ this, SLOT(refreshAllExcept(FQTermWindow*))));
+ FQ_VERIFY(connect(window, SIGNAL(connectionClosed(FQTermWindow*)),
+ this, SLOT(closeWindow(FQTermWindow*)), Qt::QueuedConnection));
+ return window;
+}
+
+void FQTermWndMgr::onSubWindowClosed(QObject* obj) {
+
+ for (int i = 0; i < tabBar_->count(); ++i) {
+ if (tabBar_->tabData(i) == qVariantFromValue(obj)) {
+ if (count() == 0) {
+ termFrame_->enableMenuToolBar(false);
+ }
+ if (i == tabBar_->currentIndex())
+ isAfterRemoved_ = true;
+ tabBar_->removeTab(i);
+ icons_.removeAt(i);
+ }
+ }
+
+}
+
+//---------------------------
+//record subwindows' size
+//---------------------------
+void
+FQTermWndMgr::subWindowResized(FQTermWindow *mw) {
+ QMdiSubWindow* subWindow = FQToMDI(mw);
+ if (!subWindow)
+ return;
+ Qt::WindowFlags wfs = subWindow->windowFlags();
+
+ if (!(subWindowMax_ = subWindow->isMaximized())){
+ if (!subWindow->isMinimized()) {
+ subWindowSize_ = subWindow->frameSize();
+ }
+ subWindow->setWindowFlags(wfs | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint);
+ }
+ else {
+ subWindow->setWindowFlags(wfs & ~Qt::WindowSystemMenuHint);
+ }
+
+}
+
+void FQTermWndMgr::cascade() {
+ QSize oldSize = subWindowSize_;
+ cascadeSubWindows();
+ foreach(QMdiSubWindow* subWindow, subWindowList()) {
+ if (subWindow) {
+ subWindow->resize(oldSize);
+ }
+ }
+}
+
+void FQTermWndMgr::tile() {
+ tileSubWindows();
+}
+
+void FQTermWndMgr::activateNextWindow() {
+ activateTheWindow((activeWindowIndex() + 1) % count());
+}
+
+void FQTermWndMgr::activatePrevWindow() {
+ activateTheWindow((activeWindowIndex() - 1 + count()) % count());
+}
+
+FQTermWindow * FQTermWndMgr::nthWindow(int n) {
+ return (FQTermWindow *)(subWindowList()[n]->widget());
+}
+
+void FQTermWndMgr::onSubWindowActivated(QMdiSubWindow * subWindow) {
+ int n = subWindowList().indexOf(subWindow);
+ if (n == -1)
+ return;
+ FQTermWindow* mw = MDIToFQ(subWindow);
+ if (mw->isMaximized() &&
+ afterRemove()) {
+ mw->showNormal();
+ mw->showMaximized();
+ }
+ if (tabBar_->currentIndex() != n) {
+ FQ_VERIFY(disconnect(this, SIGNAL(subWindowActivated(QMdiSubWindow*)),
+ this, SLOT(onSubWindowActivated(QMdiSubWindow*))));
+ tabBar_->setCurrentIndex(n);
+ FQ_VERIFY(connect(this, SIGNAL(subWindowActivated(QMdiSubWindow*)),
+ this, SLOT(onSubWindowActivated(QMdiSubWindow*))));
+ }
+ termFrame_->updateMenuToolBar();
+}
+
+void FQTermWndMgr::onTabRightClicked(int index, const QPoint& p) {
+ QMenu* menu = FQToMDI(nthWindow(index))->systemMenu();
+ menu->popup(p);
+}
+
+void FQTermWndMgr::onTabDoubleClicked(int index, const QPoint& p) {
+ closeWindow(nthWindow(index));
+}
+
+FQTermWindow* FQTermWndMgr::MDIToFQ( QMdiSubWindow* subWindow )
+{
+ if (!subWindowList().contains(subWindow))
+ return NULL;
+ return (FQTermWindow*)subWindow->widget();
+}
+
+QMdiSubWindow* FQTermWndMgr::FQToMDI( FQTermWindow* window )
+{
+ for (int i = 0; i < subWindowList().count(); ++i) {
+ if ((FQTermWindow*)(subWindowList()[i]->widget()) == window) {
+ return subWindowList()[i];
+ }
+ }
+ return NULL;
+}
+
+int FQTermWndMgr::FQToIndex( FQTermWindow* window )
+{
+ return subWindowList().indexOf(FQToMDI(window));
+}
+
+bool FQTermWndMgr::event( QEvent* e ) {
+ if (e->type() == QEvent::ShortcutOverride) {
+ QKeyEvent* ke = (QKeyEvent*)e;
+ if (ke->key() == Qt::Key_W && ke->modifiers() == Qt::ControlModifier) {
+ ke->accept();
+ return true;
+ }
+ }
+ return QMdiArea::event(e);
+}
+void FQTermTabBar::mouseReleaseEvent( QMouseEvent * me ) {
+ int index = tabAt(me->pos());
+ if (index != -1 && me->button() == Qt::RightButton && me->modifiers() == Qt::NoModifier) {
+ emit rightClicked(index, mapToGlobal(me->pos()));
+ }
+}
+
+void FQTermTabBar::mouseDoubleClickEvent( QMouseEvent * me ) {
+ int index = tabAt(me->pos());
+ if (index != -1 && me->button() == Qt::LeftButton && me->modifiers() == Qt::NoModifier) {
+ emit doubleClicked(index, mapToGlobal(me->pos()));
+ }
+}
+} // namespace FQTerm
+
+#include "fqterm_wndmgr.moc"
diff --git a/src/fqterm/fqterm_wndmgr.h b/src/fqterm/fqterm_wndmgr.h
new file mode 100644
index 0000000..5038d8f
--- /dev/null
+++ b/src/fqterm/fqterm_wndmgr.h
@@ -0,0 +1,115 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_WND_MGR_H
+#define FQTERM_WND_MGR_H
+
+#include <QString>
+#include <QList>
+#include <map>
+#include <utility>
+#include <QMdiArea>
+#include <QMdiSubWindow>
+#include <QTabBar>
+
+class QEvent;
+class QIcon;
+class QSize;
+class FQTermConfig;
+namespace FQTerm {
+
+class FQTermWindow;
+class FQTermFrame;
+
+class FQTermTabBar : public QTabBar {
+ Q_OBJECT;
+public:
+ FQTermTabBar(QWidget *parent = 0) : QTabBar(parent) {}
+protected:
+ virtual void mouseReleaseEvent(QMouseEvent * me);
+ virtual void mouseDoubleClickEvent(QMouseEvent * me);
+signals:
+ void rightClicked(int index, const QPoint& p);
+ void doubleClicked(int index, const QPoint& p);
+};
+
+class FQTermWndMgr: public QMdiArea {
+ Q_OBJECT;
+ public:
+ FQTermWndMgr(QWidget *parent = 0, const char *name = 0);
+ ~FQTermWndMgr();
+
+ QTabBar* tabBar() {return tabBar_;}
+
+ FQTermWindow* newWindow(const FQTermParam &param, FQTermConfig* config, QIcon* icon, int index = -1);
+ bool closeAllWindow();
+
+
+
+ FQTermWindow *activeWindow();
+ int activeWindowIndex() {
+ return FQToIndex(activeWindow());
+ }
+ FQTermWindow *nthWindow(int n);
+ int count();
+
+ //sub-window position & size
+
+ bool getSubWindowMax() const { return subWindowMax_; }
+ void setSubWindowMax(bool val) { subWindowMax_ = val; }
+ QSize getSubWindowSize() const { return subWindowSize_; }
+ void setSubWindowSize(QSize val) { subWindowSize_ = val; }
+
+ public slots:
+ bool closeWindow(FQTermWindow *mw);
+ void onSubWindowClosed(QObject* obj);
+ //record subwindows' size changes
+ void subWindowResized(FQTermWindow *);
+ void activateTheWindow(int n);
+ void activateNextWindow();
+ void activatePrevWindow();
+ void refreshAllExcept(FQTermWindow *mw);
+ void blinkTheTab(FQTermWindow *mw, bool bVisible);
+ void cascade();
+ void tile();
+
+protected:
+
+ QList<QIcon *> icons_;
+ FQTermFrame *termFrame_;
+ bool isAfterRemoved_;
+ QSize subWindowSize_;
+ bool subWindowMax_;
+ FQTermTabBar* tabBar_;
+
+ FQTermWindow* MDIToFQ(QMdiSubWindow* subWindow);
+ QMdiSubWindow* FQToMDI(FQTermWindow* window);
+ int FQToIndex(FQTermWindow* window);
+ bool afterRemove();
+ bool event(QEvent* e);
+protected slots:
+ void onSubWindowActivated(QMdiSubWindow * subWindow);
+ void onTabRightClicked(int index, const QPoint& p);
+ void onTabDoubleClicked(int index, const QPoint& p);
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_WND_MGR_H
diff --git a/src/fqterm/main.cpp b/src/fqterm/main.cpp
new file mode 100644
index 0000000..40969fd
--- /dev/null
+++ b/src/fqterm/main.cpp
@@ -0,0 +1,135 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <stdlib.h>
+
+#if defined(WIN32)
+#include <windows.h>
+#include <shellapi.h>
+#else
+#include <sys/stat.h>
+#include <errno.h>
+#include <locale.h>
+#endif
+
+#if defined(FQTERM_USE_STATIC_QT)
+ // You can change the definition of FQTERM_USE_STATIC_QT in
+ // fqterm/CMakeLists.txt.{linux, macos, win32}.
+
+ // static link Qt4 plugins.
+ void loadNecessaryQtPlugins() {}
+ #include <QtPlugin>
+ Q_IMPORT_PLUGIN(qkrcodecs)
+ Q_IMPORT_PLUGIN(qcncodecs)
+ Q_IMPORT_PLUGIN(qjpcodecs)
+ Q_IMPORT_PLUGIN(qtwcodecs)
+ Q_IMPORT_PLUGIN(qjpeg)
+ Q_IMPORT_PLUGIN(qgif)
+ Q_IMPORT_PLUGIN(qmng)
+#else
+ // dynamic link Qt4 plugins.
+ #include <QPluginLoader>
+ void loadNecessaryQtPlugins() {
+ static QPluginLoader qkrcodecsLoader( "qkrcodecs" );
+ static QPluginLoader qcncodecsLoader( "qcncodecs" );
+ static QPluginLoader qjpcodecsLoader( "qjpcodecs" );
+ static QPluginLoader qtwcodecsLoader( "qtwcodecs" );
+ static QPluginLoader qjpegLoader("qjpeg");
+ static QPluginLoader qgifLoader("qgif");
+ static QPluginLoader qmngLoader("qmng");
+
+ qkrcodecsLoader.load();
+ qcncodecsLoader.load();
+ qjpcodecsLoader.load();
+ qtwcodecsLoader.load();
+ qjpegLoader.load();
+ qgifLoader.load();
+ qmngLoader.load();
+ }
+#endif
+
+#include <QApplication>
+#include <QTranslator>
+#include <QFontDatabase>
+#include <QTextCodec>
+
+#include "fqterm.h"
+#include "fqterm_app.h"
+#include "fqterm_frame.h"
+#include "fqterm_path.h"
+#include "fqterm_trace.h"
+#include "fqterm_config.h"
+#include "fqterm_param.h"
+#include "fqterm_text_line.h"
+
+
+
+
+int main(int argc, char **argv) {
+#if defined(WIN32)
+#else
+ QApplication::setGraphicsSystem("raster");
+#endif
+ FQTerm::FQTermApplication a(argc, argv);
+ // Set trace categories and level.
+ FQTerm::setMaxTraceLevel(1);
+ for (int i = 1; i < argc; ++i) {
+ QString str(argv[i]);
+ bool ok;
+ int max_level = str.toInt(&ok, 0);
+
+ if (ok) {
+ FQTerm::setMaxTraceLevel(max_level);
+ } else {
+ FQTerm::addAllowedCategory(argv[i]);
+ }
+ }
+
+ using namespace FQTerm;
+
+ loadNecessaryQtPlugins();
+
+ // char buf[] = "\xc8\xb8";
+ // QString ucs2 = QTextCodec::codecForName("Big5")->toUnicode(buf);
+ // QVector<uint> ucs4 = ucs2.toUcs4();
+ // QByteArray utf8 = ucs2.toUtf8();
+ // const char *utf8c = utf8.constData();
+
+ // FQ_TRACE("text", 0) << "\n" << dumpHexString << std::string(buf, sizeof(buf) - 1)
+ // << dumpNormalString << " \n-->"
+ // << dumpNormalString << "\nucs4 " << ucs4.size() << " " << ucs4[0]
+ // << dumpNormalString << "\nucs2 " << ucs2.size() << " " << ucs2.at(0).unicode()
+ // << dumpNormalString << "\nutf8 " << dumpHexString << utf8c;
+ //return 0;
+
+ if (!iniSettings()) {
+ return -1;
+ }
+
+ FQTermFrame *mw = new FQTermFrame();
+ mw->setWindowTitle("FQTerm " + QString(FQTERM_VERSION_STRING));
+ mw->setWindowIcon(QPixmap(getPath(RESOURCE) + "pic/fqterm.png"));
+ mw->show();
+ a.setQuitOnLastWindowClosed(false);
+ FQ_VERIFY(a.connect(mw, SIGNAL(destroyed(QObject*)), &a, SLOT(mainWindowDestroyed(QObject*)), Qt::QueuedConnection));
+ FQ_VERIFY(a.connect(&a, SIGNAL(saveData()), mw, SLOT(saveSetting())));
+ int res = a.exec();
+ return res;
+}
diff --git a/src/protocol/CMakeLists.txt b/src/protocol/CMakeLists.txt
new file mode 100644
index 0000000..c515590
--- /dev/null
+++ b/src/protocol/CMakeLists.txt
@@ -0,0 +1,65 @@
+set(export_SRCS
+ fqterm_socket.cpp
+ fqterm_socket.h
+ fqterm_ssh_socket.h
+ fqterm_ssh_socket.cpp
+)
+
+set(internal_SRCS
+ internal/crc32.h
+ internal/fqterm_serialization.h
+ internal/fqterm_ssh_auth.h
+ internal/fqterm_ssh_buffer.h
+ internal/fqterm_ssh_cipher.h
+ internal/fqterm_ssh_const.h
+ internal/fqterm_ssh_des.h
+ internal/fqterm_ssh_hash.h
+ internal/fqterm_ssh_kex.h
+ internal/fqterm_ssh2_kex.h
+ internal/fqterm_ssh_mac.h
+ internal/fqterm_ssh_md5.h
+ internal/fqterm_ssh_packet.h
+ internal/fqterm_ssh1_packet.h
+ internal/fqterm_ssh2_packet.h
+ internal/fqterm_ssh_rsa.h
+ internal/fqterm_ssh_channel.h
+ internal/fqterm_ssh_types.h
+ internal/fqterm_ssh_pubkey.h
+ internal/crc32.cpp
+ internal/fqterm_ssh_auth.cpp
+ internal/fqterm_ssh_buffer.cpp
+ internal/fqterm_ssh_des.cpp
+ internal/fqterm_ssh_kex.cpp
+ internal/fqterm_ssh2_kex.cpp
+ internal/fqterm_ssh_mac.cpp
+ internal/fqterm_ssh_md5.cpp
+ internal/fqterm_ssh_packet.cpp
+ internal/fqterm_ssh1_packet.cpp
+ internal/fqterm_ssh2_packet.cpp
+ internal/fqterm_ssh_rsa.cpp
+ internal/fqterm_ssh_channel.cpp
+)
+
+qt4_automoc(
+ ${export_SRCS}
+ ${internal_SRCS}
+)
+
+include_directories(
+ ${QT_INCLUDE_DIR}
+ ${QT_QTCORE_INCLUDE_DIR}
+ ${QT_QTNETWORK_INCLUDE_DIR}
+ ${OPENSSL_INCLUDE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/internal
+ ${CMAKE_CURRENT_SOURCE_DIR}/../common
+ ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+add_library(fqterm_protocol
+ ${export_SRCS}
+ ${internal_SRCS}
+)
+
+add_dependencies(fqterm_protocol
+ fqterm_common
+)
diff --git a/src/protocol/fqterm_socket.cpp b/src/protocol/fqterm_socket.cpp
new file mode 100644
index 0000000..131044a
--- /dev/null
+++ b/src/protocol/fqterm_socket.cpp
@@ -0,0 +1,672 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <QByteArray>
+#include <QTcpSocket>
+#include <QProcess>
+
+#include "fqterm.h"
+#include "fqterm_socket.h"
+#include "fqterm_trace.h"
+
+#if !defined(Q_OS_BSD4) && !defined(_OS_FREEBSD_) \
+ && !defined(Q_OS_MACX) && !defined(Q_OS_DARWIN)
+#include <malloc.h>
+#endif
+
+namespace FQTerm {
+
+/* hack from wget/http.c */
+#define BASE64_LENGTH(len) (4 * (((len) + 2) / 3))
+static void base64_encode(const char *s, char *store, int length);
+static char *basic_authentication_encode(const char *user, const char *passwd,
+ const char *header);
+static int parse_http_status_line(const char *line, const char
+ **reason_phrase_ptr);
+
+const char wingate_enter = 'J' &0x1f;
+
+//==============================================================================
+//FQTermSocketPrivate
+
+//==============================================================================
+FQTermSocketPrivate::FQTermSocketPrivate(QObject *parent)
+ : QObject(parent) {
+ m_socket = new QTcpSocket(this);
+
+ // proxy related
+ proxy_type = NOPROXY;
+ proxy_state = 0;
+ bauth = false;
+
+ FQ_VERIFY(connect(m_socket, SIGNAL(connected()), this, SLOT(socketConnected())));
+ FQ_VERIFY(connect(m_socket, SIGNAL(hostFound()), this, SIGNAL(hostFound())));
+ FQ_VERIFY(connect(m_socket, SIGNAL(disconnected()), this, SIGNAL(connectionClosed())));
+
+ FQ_VERIFY(connect(m_socket, SIGNAL(readyRead()), this, SLOT(socketReadyRead())));
+ FQ_VERIFY(connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SIGNAL(error(QAbstractSocket::SocketError))));
+}
+
+FQTermSocketPrivate::~FQTermSocketPrivate() {
+ delete m_socket;
+}
+
+void FQTermSocketPrivate::setProxy(int nProxyType, bool bAuth, const QString &strProxyHost,
+ quint16 uProxyPort, const QString &strProxyUsr,
+ const QString &strProxyPwd) {
+ proxy_type = nProxyType;
+ if (proxy_type == NOPROXY) {
+ return ;
+ }
+ bauth = bAuth;
+ proxy_host = strProxyHost;
+ proxy_port = uProxyPort;
+ proxy_usr = strProxyUsr;
+ proxy_pwd = strProxyPwd;
+}
+
+void FQTermSocketPrivate::socketConnected() {
+ QByteArray strPort;
+ QByteArray command(9, 0);
+
+ char *proxyauth;
+ char *request;
+ int len = 0;
+
+ switch (proxy_type) {
+ case NOPROXY:
+ // no proxy
+ emit connected();
+ return ;
+ case WINGATE:
+ // Wingate Proxy
+ strPort.setNum(port);
+ writeBlock(host.toLocal8Bit());
+ writeBlock(" ");
+ writeBlock(strPort);
+ writeBlock(&wingate_enter); // CTRL+J
+ emit socketState(TSHOSTCONNECTED);
+ return ;
+ case SOCKS4:
+ // Socks4 Proxy
+ command.resize(9);
+ command[0] = '\x04';
+ command[1] = '\x01';
+ memcpy(command.data() + 2, &addr_host.sin_port, 2);
+ memcpy(command.data() + 4, &addr_host.sin_addr, 4);
+ writeBlock(command);
+ proxy_state = 1;
+ emit socketState(TSPROXYCONNECTED);
+ return ;
+ case SOCKS5:
+ // Socks5 Proxy
+ if (bauth) {
+ command.resize(4);
+ command[0] = '\x05';
+ command[1] = '\x02';
+ command[2] = '\x02';
+ command[3] = '\x00';
+ writeBlock(command);
+ }
+ else {
+ command.resize(3);
+ command[0] = '\x05';
+ command[1] = '\x01';
+ command[2] = '\x00';
+ writeBlock(command);
+ }
+ proxy_state = 1;
+ emit socketState(TSPROXYCONNECTED);
+ return ;
+ case HTTP:
+ proxyauth = NULL;
+ if (bauth) {
+ proxyauth = basic_authentication_encode(proxy_usr.toLocal8Bit(),
+ proxy_pwd.toLocal8Bit(), "Proxy-Authorization");
+ }
+
+ len = proxyauth != NULL ? strlen(proxyauth): 0;
+
+ request = new char[host.length() + len + 81];
+
+ sprintf(request, "CONNECT %s:%u HTTP/1.0\r\n""%s\r\n", host.toLatin1().constData(), port,
+ proxyauth != NULL ? proxyauth : "");
+
+
+ writeBlock(request);
+ delete [] request;
+ free(proxyauth);
+ proxy_state = 1;
+ emit socketState(TSPROXYCONNECTED);
+ return ;
+ default:
+ emit socketState(TSHOSTCONNECTED);
+ return ;
+ }
+}
+
+void FQTermSocketPrivate::socketReadyRead() {
+ if (proxy_type == NOPROXY || proxy_state == 0) {
+ emit readyRead();
+ }
+
+ int nbytes, nread;
+ QByteArray from_socket;
+ // get the data size
+ nbytes = bytesAvailable();
+ if (nbytes <= 0) {
+ return ;
+ }
+
+ //resize input buffer
+ from_socket.resize(0);
+
+ //read data from socket to from_socket
+ from_socket = readBlock(nbytes);
+ nread = from_socket.size();
+ //do some checks
+ if (nread <= 0) {
+ FQ_TRACE("socket", 0) << "Failed to read socket: " << nread << " <= 0";
+ return ;
+ }
+ if (nread > nbytes) {
+ FQ_TRACE("socket", 0) << "Overflow when reading socket: "
+ << " nread = " << nread
+ << " > nbytes = " << nbytes;
+ return ;
+ }
+
+ // Socks4 Proxy Reply
+ if (proxy_type == SOCKS4 && proxy_state == 1) {
+ if (nread != 8) {
+ emit socketState(TSPROXYERROR);
+ return ;
+ }
+
+ if (from_socket.at(1) == 90) {
+ emit connected();
+ } else {
+ emit socketState(TSPROXYFAIL);
+ }
+ proxy_state = 0;
+ return ;
+ }
+
+ // HTTP Proxy Reply
+ if (proxy_type == HTTP && proxy_state != 0) {
+ const char *error;
+ int statcode = parse_http_status_line(from_socket.data(), &error);
+ if (statcode >= 200 && statcode < 300) {
+ emit connected();
+ } else {
+ emit socketState(TSPROXYFAIL);
+ }
+ proxy_state = 0;
+ return ;
+ }
+
+ // Socks5 Proxy Reply
+ if (proxy_type == SOCKS5 && proxy_state != 0) {
+ socks5_reply(from_socket, nread);
+ return ;
+ }
+}
+
+void FQTermSocketPrivate::flush() {
+ m_socket->flush();
+}
+
+/////////////////////////////////////////////////////
+//originally version from qhostaddress.cpp, qt4.3.2, --dp
+static bool isIp4(const QString& address)
+{
+ QStringList ipv4 = address.split(QLatin1String("."));
+ if (ipv4.count() != 4)
+ return false;
+
+ for (int i = 0; i < 4; ++i) {
+ bool ok = false;
+ uint byteValue = ipv4.at(i).toUInt(&ok);
+ if (!ok || byteValue > 255)
+ return false;
+
+ }
+
+ return true;
+}
+/////////////////////////////////////////////////////////
+
+void FQTermSocketPrivate::connectToHost(const QString &hostname, quint16 portnumber) {
+ host = hostname;
+ port = portnumber;
+ addr_host.sin_port = htons(portnumber);
+
+ if (proxy_type == NOPROXY) {
+ m_socket->connectToHost(host, port);
+ } else {
+ //get ip addr from name
+ struct hostent *hostent;
+#if defined(_OS_WIN32_) || defined(Q_OS_WIN32)
+ WSADATA wsd;
+ if (WSAStartup(0x202, &wsd) != 0) {
+ emit socketState(TSEINIWINSOCK);
+ WSACleanup();
+ return ;
+ }
+#endif
+ // QHostAddress ha(host);
+ //ipv4 address check -- dp
+ if(isIp4(host)) {
+ hostent = gethostbyaddr( host.toLocal8Bit(), host.length(), AF_INET );
+ FQ_TRACE("ssh", 1) << "by addr";
+ } else {
+ hostent = gethostbyname(host.toLocal8Bit());
+ FQ_TRACE("ssh", 1) << "by name";
+ }
+
+ if (hostent == NULL) {
+ emit socketState(TSEGETHOSTBYNAME);
+ return ;
+ }
+ //now only ipv4 support
+ memcpy(&addr_host.sin_addr, hostent->h_addr, 4);
+ m_socket->connectToHost(proxy_host, proxy_port);
+ }
+
+}
+
+void FQTermSocketPrivate::close() {
+ m_socket->close();
+}
+
+QByteArray FQTermSocketPrivate::readBlock(unsigned long maxlen) {
+ return m_socket->read(maxlen);
+}
+
+long FQTermSocketPrivate::writeBlock(const QByteArray &data) {
+ return m_socket->write(data);
+}
+
+unsigned long FQTermSocketPrivate::bytesAvailable() {
+ return m_socket->bytesAvailable();
+}
+
+/*------------------------------------------------------------------------
+ * connect command for socks5
+ *------------------------------------------------------------------------
+ */
+void FQTermSocketPrivate::socks5_connect() {
+ QByteArray command(10, 0);
+ command[0] = '\x05';
+ command[1] = '\x01';
+ command[2] = '\x00';
+ command[3] = '\x01';
+ memcpy(command.data() + 4, &addr_host.sin_addr, 4);
+ memcpy(command.data() + 8, &addr_host.sin_port, 2);
+ writeBlock(command);
+}
+
+/*------------------------------------------------------------------------
+ * authentation command for socks5
+ *------------------------------------------------------------------------
+ */
+void FQTermSocketPrivate::socks5_auth() {
+ int ulen = proxy_usr.length();
+ int plen = proxy_pwd.length();
+ QByteArray command(3+ulen + plen, 0);
+ sprintf((char*)command.data(), " %s %s", proxy_usr.toLocal8Bit().data(),
+ proxy_pwd.toLocal8Bit().data());
+ command[0] = '\x01';
+ command[1] = ulen;
+ command[2+ulen] = plen;
+ writeBlock(command);
+}
+
+/*------------------------------------------------------------------------
+ * reply from socks5
+ *------------------------------------------------------------------------
+ */
+void FQTermSocketPrivate::socks5_reply(const QByteArray &from_socket, int nread) {
+ if (proxy_state == 1) { // Socks5 Proxy Replay 1
+ if (nread != 2) {
+ proxy_state = 0;
+ emit socketState(TSPROXYERROR);
+ return ;
+ }
+ switch (from_socket.at(1)) {
+ case '\x00':
+ // no authentation needed
+ socks5_connect();
+ proxy_state = 3;
+ emit socketState(TSCONNECTVIAPROXY);
+ return ;
+ case '\x02':
+ //need user/password
+ socks5_auth();
+ proxy_state = 2;
+ emit socketState(TSPROXYAUTH);
+ return ;
+ case '\xff':
+ proxy_state = 0;
+ emit socketState(TSPROXYFAIL);
+ return ;
+ default:
+ proxy_state = 0;
+ emit socketState(TSPROXYFAIL);
+ return ;
+ }
+ } else if (proxy_state == 2) { //Socks5 Proxy Replay 2
+ if (nread != 2) {
+ proxy_state = 0;
+ emit socketState(TSPROXYERROR);
+ return ;
+ }
+
+
+ if (from_socket.at(1) != '\00') {
+ proxy_state = 0;
+ emit socketState(TSPROXYFAIL);
+ return ;
+ }
+ socks5_connect();
+ proxy_state = 3;
+ emit socketState(TSCONNECTVIAPROXY);
+ return ;
+ } else if (proxy_state == 3) { //Socks5 Proxy Replay 3
+ proxy_state = 0;
+ if (nread != 10) {
+ emit socketState(TSPROXYERROR);
+ return ;
+ }
+ if (from_socket.at(1) != '\00') {
+ emit socketState(TSPROXYFAIL);
+ return ;
+ }
+ emit connected();
+ return ;
+ } else {
+ proxy_state = 0;
+ return ;
+ }
+}
+
+/* hack from wget/http.c */
+/* How many bytes it will take to store LEN bytes in base64. */
+#define BASE64_LENGTH(len) (4 * (((len) + 2) / 3))
+
+/* Encode the string S of length LENGTH to base64 format and place it
+ to STORE. STORE will be 0-terminated, and must point to a writable
+ buffer of at least 1+BASE64_LENGTH(length) bytes. */
+static void base64_encode(const char *s, char *store, int length) {
+ /* Conversion table. */
+ static char tbl[64] = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
+ 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', '+', '/'
+ };
+ int i;
+ unsigned char *p = (unsigned char*)store;
+
+ /* Transform the 3x8 bits to 4x6 bits, as required by base64. */
+ for (i = 0; i < length; i += 3) {
+ *p++ = tbl[s[0] >> 2];
+ *p++ = tbl[((s[0] &3) << 4) + (s[1] >> 4)];
+ *p++ = tbl[((s[1] &0xf) << 2) + (s[2] >> 6)];
+ *p++ = tbl[s[2] &0x3f];
+ s += 3;
+ }
+ /* Pad the result if necessary... */
+ if (i == length + 1) {
+ *(p - 1) = '=';
+ } else if (i == length + 2) {
+ *(p - 1) = *(p - 2) = '=';
+ }
+ /* ...and zero-terminate it. */
+ *p = '\0';
+}
+
+/* Create the authentication header contents for the `Basic' scheme.
+ This is done by encoding the string `USER:PASS' in base64 and
+ prepending `HEADER: Basic ' to it. */
+static char *basic_authentication_encode(const char *user, const char *passwd,
+ const char *header) {
+ char *t1, *t2, *res;
+ int len1 = strlen(user) + 1+strlen(passwd);
+ int len2 = BASE64_LENGTH(len1);
+
+ t1 = (char*)alloca(len1 + 1);
+ sprintf(t1, "%s:%s", user, passwd);
+ t2 = (char*)alloca(1+len2);
+ base64_encode(t1, t2, len1);
+ res = (char*)malloc(len2 + 11+strlen(header));
+ sprintf(res, "%s: Basic %s\r\n", header, t2);
+
+ return res;
+}
+
+/* Parse the HTTP status line, which is of format:
+
+ HTTP-Version SP Status-Code SP Reason-Phrase
+
+ The function returns the status-code, or -1 if the status line is
+ malformed. The pointer to reason-phrase is returned in RP. */
+static int parse_http_status_line(const char *line, const char
+ **reason_phrase_ptr) {
+ /* (the variables must not be named `major' and `minor', because
+ that breaks compilation with SunOS4 cc.) */
+ int mjr, mnr, statcode;
+ const char *p;
+
+ *reason_phrase_ptr = NULL;
+
+ /* The standard format of HTTP-Version is: `HTTP/X.Y', where X is
+ major version, and Y is minor version. */
+ if (strncmp(line, "HTTP/", 5) != 0) {
+ return -1;
+ }
+ line += 5;
+
+ /* Calculate major HTTP version. */
+ p = line;
+ for (mjr = 0; QChar(*line).isDigit(); line++) {
+ mjr = 10 * mjr + (*line - '0');
+ }
+ if (*line != '.' || p == line) {
+ return -1;
+ }
+ ++line;
+
+ /* Calculate minor HTTP version. */
+ p = line;
+ for (mnr = 0; QChar(*line).isDigit(); line++) {
+ mnr = 10 * mnr + (*line - '0');
+ }
+ if (*line != ' ' || p == line) {
+ return -1;
+ }
+ /* Wget will accept only 1.0 and higher HTTP-versions. The value of
+ minor version can be safely ignored. */
+ if (mjr < 1) {
+ return -1;
+ }
+ ++line;
+
+ /* Calculate status code. */
+ if (!(QChar(*line).isDigit() && QChar(line[1]).isDigit() && QChar(line[2])
+ .isDigit())) {
+ return -1;
+ }
+ statcode = 100 *(*line - '0') + 10 *(line[1] - '0') + (line[2] - '0');
+
+ /* Set up the reason phrase pointer. */
+ line += 3;
+ /* RFC2068 requires SPC here, but we allow the string to finish
+ here, in case no reason-phrase is present. */
+ if (*line != ' ') {
+ if (! *line) {
+ *reason_phrase_ptr = line;
+ } else {
+ return -1;
+ }
+ } else {
+ *reason_phrase_ptr = line + 1;
+ }
+
+ return statcode;
+}
+
+
+//==============================================================================
+//FQTermTelnetSocket
+//==============================================================================
+
+FQTermTelnetSocket::FQTermTelnetSocket()
+ : FQTermSocket() {
+ private_socket_ = new FQTermSocketPrivate();
+ FQ_VERIFY(connect(private_socket_, SIGNAL(connected()), this, SIGNAL(connected())));
+ FQ_VERIFY(connect(private_socket_, SIGNAL(hostFound()), this, SIGNAL(hostFound())));
+ FQ_VERIFY(connect(private_socket_, SIGNAL(connectionClosed()), this, SIGNAL(connectionClosed())));
+ FQ_VERIFY(connect(private_socket_, SIGNAL(delayedCloseFinished()),
+ this, SIGNAL(delayedCloseFinished())));
+ FQ_VERIFY(connect(private_socket_, SIGNAL(readyRead()), this, SIGNAL(readyRead())));
+ FQ_VERIFY(connect(private_socket_, SIGNAL(error(QAbstractSocket::SocketError)), this, SIGNAL(error(QAbstractSocket::SocketError))));
+ FQ_VERIFY(connect(private_socket_, SIGNAL(socketState(int)), this, SIGNAL(socketState(int))));
+}
+
+FQTermTelnetSocket::~FQTermTelnetSocket() {
+ delete private_socket_;
+}
+
+void FQTermTelnetSocket::flush() {
+ private_socket_->flush();
+}
+
+void FQTermTelnetSocket::setProxy(int nProxyType, bool bAuth,
+ const QString &strProxyHost,
+ quint16 uProxyPort,
+ const QString &strProxyUsr,
+ const QString &strProxyPwd) {
+ private_socket_->setProxy(nProxyType, bAuth, strProxyHost, uProxyPort, strProxyUsr,
+ strProxyPwd);
+}
+
+void FQTermTelnetSocket::connectToHost(const QString &host, quint16 port) {
+ private_socket_->connectToHost(host, port);
+}
+
+void FQTermTelnetSocket::close() {
+ private_socket_->close();
+}
+
+QByteArray FQTermTelnetSocket::readBlock(unsigned long maxlen) {
+ return private_socket_->readBlock(maxlen);
+}
+
+long FQTermTelnetSocket::writeBlock(const QByteArray &data) {
+ return private_socket_->writeBlock(data);
+}
+
+unsigned long FQTermTelnetSocket::bytesAvailable() {
+ return private_socket_->bytesAvailable();
+}
+
+
+FQTermLocalSocket::FQTermLocalSocket( const QString& shell_bin ) : shell_bin_(shell_bin)
+{
+ shell_process_ = new QProcess();
+ shell_process_->setProcessChannelMode(QProcess::MergedChannels);
+ FQ_VERIFY(connect(shell_process_, SIGNAL(started()), this, SIGNAL(connected())));
+ FQ_VERIFY(connect(shell_process_, SIGNAL(stateChanged(QProcess::ProcessState)), this , SLOT(stateChanged(QProcess::ProcessState))));
+ FQ_VERIFY(connect(shell_process_, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(finished(int, QProcess::ExitStatus))));
+ //FQ_VERIFY(connect(shell_process_, SIGNAL(delayedCloseFinished()), this, SIGNAL(delayedCloseFinished())));
+ FQ_VERIFY(connect(shell_process_, SIGNAL(readyRead()), this, SIGNAL(readyRead())));
+ //TODO: Error
+ //FQ_VERIFY(connect(shell_process_, SIGNAL(error(QAbstractSocket::SocketError)), this, SIGNAL(error(QAbstractSocket::SocketError))));
+ //FQ_VERIFY(connect(shell_process_, SIGNAL(socketState(int)), this, SIGNAL(socketState(int))));
+}
+
+FQTermLocalSocket::~FQTermLocalSocket()
+{
+ delete shell_process_;
+}
+
+void FQTermLocalSocket::connectToHost( const QString &host, quint16 port )
+{
+ shell_process_->start("E:/yxl/test.exe"/*C:/Windows/System32/cmd.exeshell_bin*/, QIODevice::ReadWrite | QIODevice::Unbuffered);
+}
+
+void FQTermLocalSocket::close()
+{
+ shell_process_->close();
+}
+
+QByteArray FQTermLocalSocket::readBlock( unsigned long maxlen )
+{
+ return shell_process_->read(maxlen);
+}
+
+long FQTermLocalSocket::writeBlock( const QByteArray &data )
+{
+ int count = shell_process_->write(data);
+
+ //char c;
+// shell_process_->getChar(&c);
+// shell_process_->ungetChar(c);
+ if (bytesAvailable())
+ {
+ emit readyRead();
+ }
+ return count;
+}
+
+unsigned long FQTermLocalSocket::bytesAvailable()
+{
+ return shell_process_->bytesAvailable();
+}
+
+void FQTermLocalSocket::finished( int exitCode, QProcess::ExitStatus exitStatus )
+{
+ emit connectionClosed();
+}
+void FQTermLocalSocket::stateChanged(QProcess::ProcessState newState)
+{
+ switch(newState)
+ {
+ case QProcess::NotRunning:
+ break;
+ case QProcess::Starting:
+ emit hostFound();
+ shell_process_->write("dir\n");
+ break;
+ case QProcess::Running:
+ break;
+
+ }
+}
+
+
+} // namespace FQTerm
+
+#include "fqterm_socket.moc"
diff --git a/src/protocol/fqterm_socket.h b/src/protocol/fqterm_socket.h
new file mode 100644
index 0000000..2d6240b
--- /dev/null
+++ b/src/protocol/fqterm_socket.h
@@ -0,0 +1,196 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SOCKET_H
+#define FQTERM_SOCKET_H
+
+// _OS_X_ not defined if i dont include it
+#include <QGlobalStatic>
+
+// different
+#if defined(Q_OS_WIN32) || defined(_OS_WIN32_)
+
+#include <winsock2.h>
+
+#elif defined(Q_OS_BSD4) || defined(_OS_FREEBSD_) \
+ || defined(Q_OS_MACX) || defined(Q_OS_DARWIN)
+
+#include <netdb.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#else
+
+#include <netdb.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <arpa/inet.h>
+
+#endif
+
+#include <QAbstractSocket>
+#include <QString>
+#include <QStringList>
+#include <QProcess>
+
+class QTcpSocket;
+namespace FQTerm {
+/*
+ * Socket with proxy support.
+ *
+ */
+class FQTermSocketPrivate: public QObject {
+
+ Q_OBJECT;
+ public:
+ FQTermSocketPrivate(QObject *parent_ = 0);
+
+ ~FQTermSocketPrivate();
+
+ void flush();
+ void setProxy(int nProxyType, bool bAuth, const QString &strProxyHost,
+ quint16 uProxyPort, const QString &strProxyUsr,
+ const QString &strProxyPwd);
+ void connectToHost(const QString &hostname, quint16 portnumber);
+ void close();
+ QByteArray readBlock(unsigned long maxlen);
+ long writeBlock(const QByteArray &data);
+ unsigned long bytesAvailable();
+
+ signals:
+ void connected();
+ void hostFound();
+ void connectionClosed();
+ void delayedCloseFinished();
+ void readyRead();
+ void error(QAbstractSocket::SocketError);
+ void socketState(int);
+
+ protected slots:
+ void socketConnected();
+ void socketReadyRead();
+
+ protected:
+ // socks5 function
+ void socks5_connect();
+ void socks5_auth();
+ void socks5_reply(const QByteArray &, int);
+
+ private:
+ // proxy
+ int proxy_type;
+ QString proxy_host;
+ QString proxy_usr;
+ quint16 proxy_port;
+ QString proxy_pwd;
+ QString host;
+ quint16 port;
+ int proxy_state;
+ bool bauth;
+
+ struct sockaddr_in addr_host;
+
+ QTcpSocket *m_socket;
+};
+
+// Virtual base class for FQTermTelnetSocket and FQTermSSHSocket
+class FQTermSocket: public QObject {
+
+ Q_OBJECT;
+ public:
+ FQTermSocket(QObject *parent = 0): QObject(parent) {}
+
+ virtual ~FQTermSocket() {}
+
+ virtual void flush() = 0;
+ virtual void setProxy(int nProxyType, bool bAuth,
+ const QString &strProxyHost,
+ quint16 uProxyPort,
+ const QString &strProxyUsr,
+ const QString &strProxyPwd) = 0;
+ virtual void connectToHost(const QString &host, quint16 port) = 0;
+ virtual void close() = 0;
+ virtual QByteArray readBlock(unsigned long maxlen) = 0;
+ virtual long writeBlock(const QByteArray &data) = 0;
+ virtual unsigned long bytesAvailable() = 0;
+ virtual bool readyForInput() {return true;}
+ virtual bool setTermSize(int col, int row) {return 0;}
+ signals:
+ void sshAuthOK();
+ void connected();
+ void hostFound();
+ void connectionClosed();
+ void delayedCloseFinished();
+ void readyRead();
+ void error(QAbstractSocket::SocketError);
+ void errorMessage(QString);
+ void socketState(int);
+ void requestUserPwd(QString *user, QString *pwd, bool *isOK);
+};
+
+class FQTermTelnetSocket: public FQTermSocket {
+ private:
+ FQTermSocketPrivate *private_socket_;
+
+ public:
+ FQTermTelnetSocket();
+
+ ~FQTermTelnetSocket();
+
+ void flush();
+ void setProxy(int nProxyType, bool bAuth, const QString &strProxyHost,
+ quint16 uProxyPort, const QString &strProxyUsr,
+ const QString &strProxyPwd);
+ void connectToHost(const QString &host, quint16 port);
+ void close();
+ QByteArray readBlock(unsigned long maxlen);
+ long writeBlock(const QByteArray &data);
+ unsigned long bytesAvailable();
+};
+
+class FQTermLocalSocket: public FQTermSocket {
+ Q_OBJECT;
+private:
+ QString shell_bin_;
+ QProcess* shell_process_;
+public:
+ FQTermLocalSocket(const QString& shell_bin);
+ ~FQTermLocalSocket();
+ void flush(){}
+ void setProxy(int nProxyType, bool bAuth, const QString &strProxyHost,
+ quint16 uProxyPort, const QString &strProxyUsr,
+ const QString &strProxyPwd){}
+ void connectToHost(const QString &host, quint16 port);
+ void close();
+ QByteArray readBlock(unsigned long maxlen);
+ long writeBlock(const QByteArray &data);
+ unsigned long bytesAvailable();
+
+public slots:
+ void stateChanged(QProcess::ProcessState newState);
+ void finished (int exitCode, QProcess::ExitStatus exitStatus);
+};
+
+
+
+} // namespace FQTerm
+
+#endif // FQTERM_SOCKET_H
diff --git a/src/protocol/fqterm_ssh_socket.cpp b/src/protocol/fqterm_ssh_socket.cpp
new file mode 100644
index 0000000..4c1e77a
--- /dev/null
+++ b/src/protocol/fqterm_ssh_socket.cpp
@@ -0,0 +1,352 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_ssh_socket.h"
+#include "fqterm_ssh_packet.h"
+#include "fqterm_ssh1_packet.h"
+#include "fqterm_ssh2_packet.h"
+#include "fqterm_ssh_buffer.h"
+#include "fqterm_ssh_rsa.h"
+#include "fqterm_ssh_kex.h"
+#include "fqterm_ssh2_kex.h"
+#include "fqterm_ssh_const.h"
+#include "fqterm_ssh_auth.h"
+#include "fqterm_ssh_channel.h"
+#include "fqterm_trace.h"
+#include <QString>
+namespace FQTerm {
+
+#define V1STR "SSH-1.5-FQTermSSH\n"
+#define V2STR "SSH-2.0-FQTermSSH\n"
+#define SSH_V1_C "SSH-1.5-FQTermSSH"
+#define SSH_V2_C "SSH-2.0-FQTermSSH"
+
+FQTermSSHSocket::FQTermSSHSocket(int col, int row, const QString& termtype, const char *sshuser, const char *sshpasswd)
+ : termtype_(termtype) {
+ col_ = col;
+ row_ = row;
+ init_user_ = sshuser;
+ init_passwd_ = sshpasswd;
+
+ private_socket_ = new FQTermSocketPrivate();
+
+ input_buffer_ = NULL;
+ output_buffer_ = NULL;
+ socket_buffer_ = NULL;
+ packet_receiver_ = NULL;
+ packet_sender_ = NULL;
+ key_exchanger_ = NULL;
+ authentication_ = NULL;
+ ssh_channel_ = NULL;
+ ssh_version_ = 1;
+ is_channel_ok_ = false;
+ auth_ok_emitted_ = false;
+
+ FQ_VERIFY(connect(private_socket_, SIGNAL(hostFound()), this, SIGNAL(hostFound())));
+ FQ_VERIFY(connect(private_socket_, SIGNAL(connected()), this, SIGNAL(connected())));
+ FQ_VERIFY(connect(private_socket_, SIGNAL(connectionClosed()), this, SIGNAL(connectionClosed())));
+ FQ_VERIFY(connect(private_socket_, SIGNAL(delayedCloseFinished()), this, SIGNAL(delayedCloseFinished())));
+ FQ_VERIFY(connect(private_socket_, SIGNAL(error(QAbstractSocket::SocketError )), this, SIGNAL(error(QAbstractSocket::SocketError ))));
+ FQ_VERIFY(connect(private_socket_, SIGNAL(socketState(int)), this, SIGNAL(socketState(int))));
+
+ FQ_VERIFY(connect(private_socket_, SIGNAL(readyRead()), this, SLOT(socketReadyRead())));
+}
+
+FQTermSSHSocket::~FQTermSSHSocket() {
+ delete private_socket_;
+ delete input_buffer_;
+ delete output_buffer_;
+ delete socket_buffer_;
+ delete packet_receiver_;
+ delete packet_sender_;
+ delete key_exchanger_;
+ delete authentication_;
+ delete ssh_channel_;
+}
+
+void FQTermSSHSocket::init(int ssh_version) {
+ // Actually we could reuse these buffers, sender/receivers, and etc.
+ // but in that case reset methods should be added to all these classes.
+ // Guys lazy as me won't do that.
+
+ delete input_buffer_;
+ delete output_buffer_;
+ delete socket_buffer_;
+ delete packet_receiver_;
+ delete packet_sender_;
+ delete key_exchanger_;
+ delete authentication_;
+ delete ssh_channel_;
+
+ is_channel_ok_ = false;
+ auth_ok_emitted_ = false;
+
+ if (ssh_version == 1) {
+ input_buffer_ = new FQTermSSHBuffer(1024);
+ output_buffer_ = new FQTermSSHBuffer(1024);
+ socket_buffer_ = new FQTermSSHBuffer(1024);
+ packet_receiver_ = new FQTermSSH1PacketReceiver;
+ packet_sender_ = new FQTermSSH1PacketSender;
+ key_exchanger_ = new FQTermSSH1Kex(SSH_V1_C, server_name_.toAscii().constData());
+ authentication_ = new FQTermSSH1PasswdAuth(init_user_, init_passwd_);
+ ssh_channel_ = new FQTermSSH1Channel;
+
+ FQ_VERIFY(connect(packet_receiver_, SIGNAL(packetAvaliable(int)), this, SLOT(handlePacket(int))));
+ FQ_VERIFY(connect(packet_receiver_, SIGNAL(packetError(QString)), this, SLOT(handleError(QString))));
+
+ FQ_VERIFY(connect(packet_sender_, SIGNAL(dataToWrite()), this, SLOT(writeData())));
+
+ FQ_VERIFY(connect(key_exchanger_, SIGNAL(kexOK()), this, SLOT(kexOK())));
+ FQ_VERIFY(connect(key_exchanger_, SIGNAL(kexError(QString)), this, SLOT(handleError(QString))));
+ FQ_VERIFY(connect(key_exchanger_, SIGNAL(reKex()), packet_receiver_, SLOT(resetEncryption())));
+ FQ_VERIFY(connect(key_exchanger_, SIGNAL(reKex()), packet_sender_, SLOT(resetEncryption())));
+ FQ_VERIFY(connect(key_exchanger_, SIGNAL(startEncryption(const u_char*)), packet_receiver_, SLOT(startEncryption(const u_char*))));
+ FQ_VERIFY(connect(key_exchanger_, SIGNAL(startEncryption(const u_char*)), packet_sender_, SLOT(startEncryption(const u_char*))));
+
+ FQ_VERIFY(connect(authentication_, SIGNAL(requestUserPwd(QString *, QString *, bool *)), this, SIGNAL(requestUserPwd(QString *, QString *, bool *))));
+ FQ_VERIFY(connect(authentication_, SIGNAL(authOK()), this, SLOT(authOK())));
+ FQ_VERIFY(connect(authentication_, SIGNAL(authError(QString)), this, SLOT(handleError(QString))));
+
+ FQ_VERIFY(connect(ssh_channel_, SIGNAL(channelOK()), this, SLOT(channelOK())));
+ FQ_VERIFY(connect(ssh_channel_, SIGNAL(channelReadyRead(const char *, int)), this, SLOT(channelReadyRead(const char *, int))));
+
+ key_exchanger_->initKex(packet_receiver_, packet_sender_);
+ } else {
+ input_buffer_ = new FQTermSSHBuffer(1024);
+ output_buffer_ = new FQTermSSHBuffer(1024);
+ socket_buffer_ = new FQTermSSHBuffer(1024);
+ packet_receiver_ = new FQTermSSH2PacketReceiver;
+ packet_sender_ = new FQTermSSH2PacketSender;
+ key_exchanger_ = new FQTermSSH2Kex(SSH_V2_C, server_name_.toAscii().constData());
+ authentication_ = new FQTermSSH2PasswdAuth(init_user_, init_passwd_);
+ ssh_channel_ = new FQTermSSH2Channel;
+
+ FQ_VERIFY(connect(packet_receiver_, SIGNAL(packetAvaliable(int)), this, SLOT(handlePacket(int))));
+ FQ_VERIFY(connect(packet_receiver_, SIGNAL(packetError(QString)), this, SLOT(handleError(QString))));
+
+ FQ_VERIFY(connect(packet_sender_, SIGNAL(dataToWrite()), this, SLOT(writeData())));
+
+ FQ_VERIFY(connect(key_exchanger_, SIGNAL(kexOK()), this, SLOT(kexOK())));
+ FQ_VERIFY(connect(key_exchanger_, SIGNAL(kexError(QString)), this, SLOT(handleError(QString))));
+ FQ_VERIFY(connect(key_exchanger_, SIGNAL(reKex()), packet_receiver_, SLOT(resetEncryption())));
+ FQ_VERIFY(connect(key_exchanger_, SIGNAL(reKex()), packet_sender_, SLOT(resetEncryption())));
+
+ FQ_VERIFY(connect(key_exchanger_, SIGNAL(startEncryption(const u_char*)), packet_receiver_, SLOT(startEncryption(const u_char*))));
+ FQ_VERIFY(connect(key_exchanger_, SIGNAL(startEncryption(const u_char*)), packet_sender_, SLOT(startEncryption(const u_char*))));
+
+ FQ_VERIFY(connect(authentication_, SIGNAL(requestUserPwd(QString *, QString *, bool *)), this, SIGNAL(requestUserPwd(QString *, QString *, bool *))));
+ FQ_VERIFY(connect(authentication_, SIGNAL(authOK()), this, SLOT(authOK())));
+ FQ_VERIFY(connect(authentication_, SIGNAL(authError(QString)), this, SLOT(handleError(QString))));
+
+ FQ_VERIFY(connect(ssh_channel_, SIGNAL(channelOK()), this, SLOT(channelOK())));
+ FQ_VERIFY(connect(ssh_channel_, SIGNAL(channelReadyRead(const char *, int)), this, SLOT(channelReadyRead(const char *, int))));
+ FQ_VERIFY(connect(ssh_channel_, SIGNAL(channelError(QString)), this, SLOT(handleError(QString))));
+
+ key_exchanger_->initKex(packet_receiver_, packet_sender_);
+ }
+}
+
+void FQTermSSHSocket::kexOK() {
+ FQ_TRACE("sshsocket", 3) << "Key exchange completed!";
+ authentication_->initAuth(packet_receiver_, packet_sender_);
+}
+
+void FQTermSSHSocket::authOK() {
+ FQ_TRACE("sshsocket", 3) << "Auth completed!";
+ ssh_channel_->initChannel(packet_receiver_, packet_sender_, col_, row_, termtype_);
+}
+
+void FQTermSSHSocket::channelOK() {
+ FQ_TRACE("sshsocket", 3) << "Channel established!";
+ is_channel_ok_ = true;
+ //auth_ok_emitted_ = false;
+}
+
+void FQTermSSHSocket::channelReadyRead(const char *data, int len) {
+ input_buffer_->putRawData(data, len);
+ emit readyRead();
+}
+
+unsigned long FQTermSSHSocket::socketWriteBlock(const char *data, unsigned long len) {
+ QByteArray to_write(data, len);
+ return private_socket_->writeBlock(to_write);
+}
+
+void FQTermSSHSocket::socketReadyRead() {
+ if (!auth_ok_emitted_ && is_channel_ok_) {
+ auth_ok_emitted_ = true;
+ emit sshAuthOK();
+ }
+ unsigned long size;
+
+ switch (ssh_socket_state_) {
+ case BeforeSession:
+ {
+ QByteArray str;
+ int version;
+ size = private_socket_->bytesAvailable();
+ str = private_socket_->readBlock(size);
+
+ server_name_ = QString(str).trimmed(); // remove the newline
+ version = chooseVersion(str.data());
+
+ FQ_TRACE("sshsocket", 3) << "SSH server: " << server_name_;
+ FQ_TRACE("sshsocket", 3) << "SSH version chosen: " << version;
+
+ if (version == 1) {
+ init(1);
+ ssh_version_ = 1;
+ socketWriteBlock(V1STR, strlen(V1STR));
+ } else if (version == 2) {
+ init(2);
+ ssh_version_ = 2;
+ socketWriteBlock(V2STR, strlen(V2STR));
+ } else {
+ handleError(tr("Unknown SSH version. "
+ "Check if you set the right server and port."));
+ return ;
+ }
+ ssh_socket_state_ = SockSession;
+ private_socket_->flush();
+ break;
+ }
+ case SockSession:
+ parsePacket();
+ }
+}
+
+void FQTermSSHSocket::parsePacket() {
+ unsigned long size;
+ QByteArray data;
+ size = private_socket_->bytesAvailable();
+ data = private_socket_->readBlock(size);
+
+ socket_buffer_->putRawData(data.data(), size);
+ packet_receiver_->parseData(socket_buffer_);
+}
+
+int FQTermSSHSocket::chooseVersion(const QString &ver) {
+ QString verion = ver.mid(ver.indexOf("-") + 1);
+ verion = verion.left(verion.indexOf("-"));
+
+ if (verion == "1.99" || verion == "1.3" || verion == "1.5") {
+ return 1;
+ } else if (verion == "2.0") {
+ return 2;
+ } else {
+ return - 1;
+ }
+}
+
+void FQTermSSHSocket::connectToHost(const QString &host_name, quint16 port) {
+ ssh_socket_state_ = BeforeSession;
+ private_socket_->connectToHost(host_name, port);
+}
+
+void FQTermSSHSocket::writeData() {
+ socketWriteBlock((const char*)packet_sender_->output_buffer_->data(),
+ packet_sender_->output_buffer_->len());
+ private_socket_->flush();
+}
+
+void FQTermSSHSocket::handlePacket(int type) {
+ if (ssh_version_ == 1) {
+ switch (type) {
+ case SSH1_MSG_DISCONNECT:
+ char *reason;
+ reason = (char*)packet_receiver_->getString();
+ FQ_TRACE("sshsocket", 1) << "Disconnect because: " << reason;
+ delete [] reason;
+ break;
+ default:
+ return ;
+ }
+ } else {
+ // ssh_version_ == 2;
+ switch (type) {
+ case SSH2_MSG_DISCONNECT:
+ char *reason;
+ packet_receiver_->consume(4);
+ reason = (char*)packet_receiver_->getString();
+ FQ_TRACE("sshsocket", 1) << "Disconnect because: " << reason;
+ delete[] reason;
+ break;
+ default:
+ return ;
+ }
+ }
+}
+
+unsigned long FQTermSSHSocket::bytesAvailable() {
+ return input_buffer_->len();
+}
+
+QByteArray FQTermSSHSocket::readBlock(unsigned long size) {
+ QByteArray data(size, 0);
+ input_buffer_->getRawData(data.data(), size);
+ return data;
+}
+
+long FQTermSSHSocket::writeBlock(const QByteArray &data) {
+ if (!is_channel_ok_) return 0;
+
+ unsigned long size = data.size();
+ output_buffer_->putRawData(data.data(), size);
+ return size;
+}
+
+void FQTermSSHSocket::flush() {
+ if (!is_channel_ok_) return;
+
+ int size = output_buffer_->len();
+
+ ssh_channel_->sendData((const char *)output_buffer_->data(), size);
+
+ output_buffer_->consume(size);
+}
+
+void FQTermSSHSocket::close() {
+ private_socket_->close();
+}
+
+void FQTermSSHSocket::handleError(QString reason) {
+ close();
+
+ emit errorMessage(reason);
+ emit connectionClosed();
+}
+
+void FQTermSSHSocket::setProxy(int nProxyType, bool bAuth,
+ const QString &strProxyHost,
+ quint16 uProxyPort,
+ const QString &strProxyUsr,
+ const QString &strProxyPwd) {
+ private_socket_->setProxy(nProxyType, bAuth, strProxyHost,
+ uProxyPort, strProxyUsr, strProxyPwd);
+}
+
+bool FQTermSSHSocket::setTermSize(int col, int row) {
+ if (ssh_channel_ && is_channel_ok_)
+ ssh_channel_->changeTermSize(col, row);
+ return true;
+}
+} // namespace FQTerm
+
+#include "fqterm_ssh_socket.moc"
diff --git a/src/protocol/fqterm_ssh_socket.h b/src/protocol/fqterm_ssh_socket.h
new file mode 100644
index 0000000..aa6fef4
--- /dev/null
+++ b/src/protocol/fqterm_ssh_socket.h
@@ -0,0 +1,131 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_SOCKET_H
+#define FQTERM_SSH_SOCKET_H
+
+#include "fqterm_socket.h"
+
+
+namespace FQTerm {
+
+
+class FQTermSocketPrivate;
+
+class FQTermSSHPacketReceiver;
+
+class FQTermSSHPacketSender;
+
+class FQTermSSHBuffer;
+
+class FQTermSSHKex;
+
+class FQTermSSHAuth;
+
+class FQTermSSHChannel;
+
+
+class FQTermSSHSocket: public FQTermSocket {
+
+ Q_OBJECT;
+private:
+ enum FQTermSSHSocketState {
+
+ BeforeSession, SockSession
+ } ssh_socket_state_;
+
+ FQTermSocketPrivate *private_socket_;
+
+
+ FQTermSSHBuffer *input_buffer_;
+
+ FQTermSSHBuffer *output_buffer_;
+
+ FQTermSSHBuffer *socket_buffer_;
+
+
+ FQTermSSHPacketReceiver *packet_receiver_;
+
+ FQTermSSHPacketSender *packet_sender_;
+
+
+ FQTermSSHKex *key_exchanger_;
+
+ FQTermSSHAuth *authentication_;
+
+ FQTermSSHChannel *ssh_channel_;
+
+ bool is_channel_ok_;
+ bool auth_ok_emitted_;
+
+ QByteArray init_user_, init_passwd_;
+
+ QString server_name_;
+
+ int ssh_version_;
+ int col_;
+ int row_;
+ QString termtype_;
+ int chooseVersion(const QString &ver);
+ unsigned long socketWriteBlock(const char *data, unsigned long len);
+ void parsePacket();
+
+private slots:
+ void handlePacket(int type);
+ void writeData();
+ void kexOK();
+ void authOK();
+ void channelOK();
+ void channelReadyRead(const char *data, int len);
+ void socketReadyRead();
+ void handleError(QString);
+
+public:
+ FQTermSSHSocket(int col = 80, int row = 24, const QString& termtype = "vt100", const char *sshuser = NULL, const char *sshpasswd = NULL);
+
+ ~FQTermSSHSocket();
+
+
+ void setProxy(int nProxyType, //0-no proxy; 1-wingate; 2-sock4; 3-socks5
+ bool bAuth, // if authentation needed
+ const QString &strProxyHost, quint16 uProxyPort, const QString &strProxyUsr,
+ const QString &strProxyPwd);
+
+ void connectToHost(const QString &host_name, quint16 port);
+
+ void init(int ssh_version);
+
+ QByteArray readBlock(unsigned long size);
+ long writeBlock(const QByteArray &data);
+
+ virtual bool readyForInput() {return is_channel_ok_;}
+ virtual bool setTermSize(int col, int row);
+ unsigned long bytesAvailable();
+
+ void flush();
+ void close();
+
+};
+
+} // namespace FQTerm
+
+
+#endif //FQTERM_SSH_SOCKET_H
+
diff --git a/src/protocol/internal/crc32.cpp b/src/protocol/internal/crc32.cpp
new file mode 100644
index 0000000..2039ac8
--- /dev/null
+++ b/src/protocol/internal/crc32.cpp
@@ -0,0 +1,84 @@
+/* $OpenBSD: crc32.c,v 1.9 2003/02/12 21:39:50 markus Exp $ */
+
+/*
+ * Copyright (c) 2003 Markus Friedl. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "crc32.h"
+
+namespace FQTerm {
+static const u_int32_t crc32tab[] = {
+ 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL,
+ 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L,
+ 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L,
+ 0xf3b97148L, 0x84be41deL, 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L,
+ 0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
+ 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L,
+ 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, 0x35b5a8faL, 0x42b2986cL,
+ 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L,
+ 0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L,
+ 0xcfba9599L, 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
+ 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, 0x01db7106L,
+ 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L,
+ 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL,
+ 0x91646c97L, 0xe6635c01L, 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL,
+ 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
+ 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L,
+ 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, 0x4adfa541L, 0x3dd895d7L,
+ 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L,
+ 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL,
+ 0xbe0b1010L, 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
+ 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, 0x2eb40d81L,
+ 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL,
+ 0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L, 0xe3630b12L, 0x94643b84L,
+ 0x0d6d6a3eL, 0x7a6a5aa8L, 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L,
+ 0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
+ 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL,
+ 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, 0xd6d6a3e8L, 0xa1d1937eL,
+ 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL,
+ 0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L,
+ 0x316e8eefL, 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
+ 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, 0xb2bd0b28L,
+ 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL,
+ 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL,
+ 0x72076785L, 0x05005713L, 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L,
+ 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
+ 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L,
+ 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, 0x8f659effL, 0xf862ae69L,
+ 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L,
+ 0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL,
+ 0x40df0b66L, 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
+ 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, 0xcdd70693L,
+ 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L,
+ 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL
+};
+
+u_int32_t ssh_crc32(const u_char *buf, u_int32_t size) {
+ u_int32_t i, crc;
+
+ crc = 0;
+ for (i = 0; i < size; i++) {
+ crc = crc32tab[(crc ^ buf[i]) &0xff] ^ (crc >> 8);
+ } return crc;
+}
+
+} // namespace FQTerm
diff --git a/src/protocol/internal/crc32.h b/src/protocol/internal/crc32.h
new file mode 100644
index 0000000..ca95b89
--- /dev/null
+++ b/src/protocol/internal/crc32.h
@@ -0,0 +1,37 @@
+/* $OpenBSD: crc32.h,v 1.14 2003/02/12 21:39:50 markus Exp $ */
+
+/*
+ * Copyright (c) 2003 Markus Friedl. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SSH_CRC32_H
+#define SSH_CRC32_H
+#include "fqterm_ssh_types.h"
+
+namespace FQTerm {
+
+u_int32_t ssh_crc32(const u_char *, u_int32_t);
+
+} // namespace FQTerm
+
+#endif
diff --git a/src/protocol/internal/fqterm_serialization.h b/src/protocol/internal/fqterm_serialization.h
new file mode 100644
index 0000000..7a858c0
--- /dev/null
+++ b/src/protocol/internal/fqterm_serialization.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SERIALIZATION_H
+#define FQTERM_SERIALIZATION_H
+
+#if defined(WIN32)
+typedef unsigned __int16 u_int16_t;
+#else
+#include <arpa/inet.h>
+#endif
+
+namespace FQTerm {
+
+inline u_int16_t ntohu16(const unsigned char *buf) {
+ return (buf[0] << 8) | buf[1];
+}
+
+inline u_int32_t ntohu32(const unsigned char *buf) {
+ return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
+}
+
+inline void htonu32(unsigned char *buf, u_int32_t number) {
+ buf[0] = (number >> 24) & 0xFF;
+ buf[1] = (number >> 16) & 0xFF;
+ buf[2] = (number >> 8) & 0xFF;
+ buf[3] = number & 0xFF;
+}
+
+inline void htonu16(unsigned char *buf, u_int16_t number) {
+ buf[0] = (number >> 8 & 0xFF);
+ buf[1] = (number & 0xFF);
+}
+
+} // namespace FQTerm
+
+#endif // FQTERM_SERIALIZATION_H
diff --git a/src/protocol/internal/fqterm_ssh1_packet.cpp b/src/protocol/internal/fqterm_ssh1_packet.cpp
new file mode 100644
index 0000000..ded7fe4
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh1_packet.cpp
@@ -0,0 +1,148 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_trace.h"
+#include "fqterm_ssh_buffer.h"
+#include "fqterm_ssh1_packet.h"
+#include "fqterm_ssh_des.h"
+
+#include "fqterm_serialization.h"
+#include "crc32.h"
+
+namespace FQTerm {
+//==============================================================================
+//FQTermSSH1PacketSender
+//==============================================================================
+//==============================================================================
+//
+// SSH1 Packet Structure:
+// --------------------------------------------------------------------------
+// | length | padding | type | data | crc32 |
+// --------------------------------------------------------------------------
+// | uint32 | 1-7bytes | uchar | | 4bytes|
+// --------------------------------------------------------------------------
+// encrypt = padding + type + data + crc32
+// length = type + data + crc32
+//
+//==============================================================================
+
+void FQTermSSH1PacketSender::makePacket() {
+ int len, padding, i;
+ u_int32_t rand_val = 0;
+
+ delete output_buffer_;
+
+ len = buffer_->len() + 4; //CRC32
+ padding = 8-(len % 8);
+
+ output_buffer_ = new FQTermSSHBuffer(len + padding + 4); //pktlen and crc32
+ output_buffer_->putInt(len);
+
+ for (i = 0; i < padding; i++) {
+ if (i % 4 == 0) {
+ rand_val = rand(); // FIXME: rand() doesn't range from 0 to 2^32.
+ }
+
+ output_buffer_->putByte(rand_val &0xff);
+ rand_val >>= 8;
+ }
+
+ output_buffer_->putRawData((const char*)buffer_->data(), buffer_->len());
+ output_buffer_->putInt(ssh_crc32(output_buffer_->data() + 4, output_buffer_->len() - 4));
+
+ if (is_encrypt_) {
+ cipher_->encrypt(output_buffer_->data() + 4, output_buffer_->data() + 4, output_buffer_->len() - 4);
+ }
+
+}
+
+//==============================================================================
+//FQTermSSH1PacketReceiver
+//==============================================================================
+void FQTermSSH1PacketReceiver::parseData(FQTermSSHBuffer *input) {
+ u_int mycrc, gotcrc;
+ u_char *buf = NULL;
+ u_char *targetData = NULL;
+ u_char *sourceData = NULL;
+
+ // Get the length of the packet.
+ while (input->len() > 0) {
+ if (input->len() < 4) {
+ FQ_TRACE("ssh1packet", 3) << "The packet is too small.";
+ return ;
+ }
+ buf = input->data();
+ real_data_len_ = ntohu32(buf);
+
+ if (real_data_len_ > SSH_BUFFER_MAX) {
+ emit packetError(tr("parseData: The packet is too big"));
+ return ;
+ }
+
+ u_int total_len = (real_data_len_ + 8) &~7;
+ u_int padding_len = total_len - real_data_len_;
+
+ real_data_len_ -= 5;
+ buffer_->clear();
+
+ // Get the data of the packet.
+ if (input->len() - 4 < (long)total_len) {
+ FQ_TRACE("ssh1packet", 3) << "The packet is too small";
+ return ;
+ }
+
+ real_data_len_ = input->getInt() - 5;
+ targetData = new u_char[total_len];
+ sourceData = new u_char[total_len];
+ memset(targetData, 0, total_len);
+ memset(sourceData, 0, total_len);
+
+ input->getRawData((char*)sourceData, total_len);
+ if (is_decrypt_) {
+ cipher_->decrypt(sourceData, targetData, total_len);
+ } else {
+ memcpy(targetData, sourceData, total_len);
+ }
+
+ buffer_->putRawData((char*)targetData, total_len);
+
+ // Check the crc32.
+ buf = buffer_->data() + total_len - 4;
+ mycrc = ntohu32(buf);
+ gotcrc = ssh_crc32(buffer_->data(), total_len - 4);
+
+ if (mycrc != gotcrc) {
+ emit packetError(tr("parseData: bad CRC32"));
+ break;
+ }
+
+ // Drop the padding.
+ buffer_->consume(padding_len);
+
+ packet_type_ = buffer_->getByte();
+
+ emit packetAvaliable(packet_type_);
+
+ delete [] sourceData;
+ delete [] targetData;
+ }
+}
+
+} // namespace FQTerm
diff --git a/src/protocol/internal/fqterm_ssh1_packet.h b/src/protocol/internal/fqterm_ssh1_packet.h
new file mode 100644
index 0000000..a535635
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh1_packet.h
@@ -0,0 +1,40 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH1_PACKET_H
+#define FQTERM_SSH1_PACKET_H
+
+#include "fqterm_ssh_packet.h"
+
+namespace FQTerm {
+
+class FQTermSSH1PacketSender: public FQTermSSHPacketSender {
+protected:
+ virtual void makePacket();
+};
+
+class FQTermSSH1PacketReceiver: public FQTermSSHPacketReceiver {
+public:
+ virtual void parseData(FQTermSSHBuffer *input);
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SSH1_PACKET
diff --git a/src/protocol/internal/fqterm_ssh2_kex.cpp b/src/protocol/internal/fqterm_ssh2_kex.cpp
new file mode 100644
index 0000000..acae08d
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh2_kex.cpp
@@ -0,0 +1,394 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <vector>
+#include <string>
+#include <openssl/bn.h>
+#include <openssl/sha.h>
+#include <openssl/des.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+
+#include "fqterm_ssh2_kex.h"
+#include "fqterm_ssh_md5.h"
+#include "fqterm_trace.h"
+
+namespace FQTerm {
+
+static const int g = 2;
+static const int q = 128;
+static const unsigned char p[q]={
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+ 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+ 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+ 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+ 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+ 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+ 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+ 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+ 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+ 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+ 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+ 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+FQTermSSH2Kex::FQTermSSH2Kex(const char *V_C, const char *V_S)
+ : FQTermSSHKex(V_C, V_S) {
+ is_first_kex_ = true;
+ kex_state_ = FQTermSSH2Kex::BEFORE_KEXINIT;
+
+ I_C_len_ = 0;
+ I_C_ = NULL;
+ I_S_len_ = 0;
+ I_S_ = NULL;
+
+ bn_x_ = BN_new();
+ bn_e_ = BN_new();
+ bn_g_ = BN_new();
+ bn_p_ = BN_new();
+ ctx_ = BN_CTX_new();
+
+ bn_K_ = BN_new();
+ bn_f_ = BN_new();
+
+ BN_set_word(bn_g_, g);
+ BN_bin2bn(p, q, bn_p_);
+
+ session_id_ = NULL;
+}
+
+FQTermSSH2Kex::~FQTermSSH2Kex() {
+ delete[] I_C_;
+ delete[] I_S_;
+
+ BN_clear_free(bn_x_);
+ BN_clear_free(bn_e_);
+ BN_clear_free(bn_g_);
+ BN_clear_free(bn_p_);
+ BN_CTX_free(ctx_);
+
+ BN_clear_free(bn_K_);
+ BN_clear_free(bn_f_);
+
+ delete[] session_id_;
+}
+
+void FQTermSSH2Kex::initKex(FQTermSSHPacketReceiver *packetReceiver,
+ FQTermSSHPacketSender *packetSender) {
+ packet_receiver_ = packetReceiver;
+ packet_sender_ = packetSender;
+ packet_receiver_->disconnect(this);
+ FQ_VERIFY(connect(packet_receiver_, SIGNAL(packetAvaliable(int)),
+ this, SLOT(handlePacket(int))));
+ kex_state_ = FQTermSSH2Kex::BEFORE_KEXINIT;
+ emit reKex();
+}
+
+void FQTermSSH2Kex::handlePacket(int type) {
+ switch (kex_state_) {
+ case FQTermSSH2Kex::BEFORE_KEXINIT:
+ negotiateAlgorithms();
+ exchangeKey();
+ kex_state_ = FQTermSSH2Kex::WAIT_REPLY;
+ break;
+ case FQTermSSH2Kex::WAIT_REPLY:
+ if (verifyKey()) {
+ sendNewKeys();
+ kex_state_ = FQTermSSH2Kex::SESSIONKEY_SENT;
+ } else {
+ emit kexError(tr("Key exchange failed!"));
+ }
+ break;
+ case FQTermSSH2Kex::SESSIONKEY_SENT:
+ if (changeKeyAlg()) {
+ kex_state_ = FQTermSSH2Kex::KEYEX_OK;
+ emit kexOK();
+ }
+ break;
+ case FQTermSSH2Kex::KEYEX_OK:
+ // TODO: how about Key Re-Exchange (see RFC 4253, 9. Key Re-Exchange)
+ break;
+ }
+}
+
+void FQTermSSH2Kex::negotiateAlgorithms() {
+ FQ_FUNC_TRACE("ssh2kex", 10);
+
+ if (packet_receiver_->packetType() != SSH2_MSG_KEXINIT) {
+ emit kexError(tr("startKex: First packet is not SSH_MSG_KEXINIT"));
+ return ;
+ }
+
+ // 0. Backup the payload of this server packet.
+ I_S_len_ = packet_receiver_->packetDataLen() + 1; // add 1 bytes for packet type.
+ delete[] I_S_;
+ I_S_ = new char[I_S_len_];
+ I_S_[0] = SSH2_MSG_KEXINIT;
+ memcpy(I_S_ + 1, packet_receiver_->buffer_->data(), I_S_len_ - 1);
+
+ // 1. Parse server kex init packet
+ packet_receiver_->getRawData((char*)cookie_, 16);
+
+ std::vector<char> name_lists;
+ for (int i = 0; i < 10; ++i) {
+ int name_lists_len = packet_receiver_->getInt();
+ if (name_lists_len > 0) {
+ name_lists.resize(name_lists_len);
+ packet_receiver_->getRawData(&name_lists[0], name_lists_len);
+ FQ_TRACE("ssh2kex", 5) << "Algorithms: " << QString::fromAscii(&name_lists[0], name_lists_len);
+ } else {
+ FQ_TRACE("ssh2kex", 5) << "None Algorithms";
+ }
+ }
+
+ bool first_kex_packet_follows = packet_receiver_->getByte();
+ FQ_TRACE("ssh2kex", 5) << "first_kex_packet_follows: " << first_kex_packet_follows;
+
+ packet_receiver_->consume(4);
+
+ // 2. compose a kex init packet.
+ packet_sender_->startPacket(SSH2_MSG_KEXINIT);
+ packet_sender_->putRawData((const char*)cookie_, 16); // FIXME: generate new cookie_;
+ packet_sender_->putString("diffie-hellman-group1-sha1");
+ packet_sender_->putString("ssh-rsa");
+ packet_sender_->putString("3des-cbc");
+ packet_sender_->putString("3des-cbc");
+ packet_sender_->putString("hmac-sha1");
+ packet_sender_->putString("hmac-sha1");
+ packet_sender_->putString("none");
+ packet_sender_->putString("none");
+ packet_sender_->putString("");
+ packet_sender_->putString("");
+
+ packet_sender_->putByte(false);
+ packet_sender_->putInt(0);
+
+ // 3. backup the payload of this client packet.
+ I_C_len_ = packet_sender_->buffer_->len();
+ delete[] I_C_;
+ I_C_ = new char[I_C_len_];
+ memcpy(I_C_, packet_sender_->buffer_->data(), I_C_len_);
+
+ // 4. send packet to server
+ packet_sender_->write();
+}
+
+void FQTermSSH2Kex::exchangeKey() {
+ BN_rand(bn_x_, q, 0, -1);
+ BN_mod_exp(bn_e_, bn_g_, bn_x_, bn_p_, ctx_);
+
+ packet_sender_->startPacket(SSH2_MSG_KEXDH_INIT);
+ packet_sender_->putBN2(bn_e_);
+ packet_sender_->write();
+}
+
+static RSA *CreateRSAContext(unsigned char *host_key, int len);
+
+bool FQTermSSH2Kex::verifyKey() {
+ if (packet_receiver_->packetType() != SSH2_MSG_KEXDH_REPLY) {
+ emit kexError(tr("Expect a SSH_MSG_KEXDH_REPLY packet"));
+ return false;
+ }
+
+ // Extract data
+
+ int K_S_len = -1;
+ unsigned char *K_S = (unsigned char *)packet_receiver_->getString(&K_S_len);
+
+ packet_receiver_->getBN2(bn_f_);
+
+ int s_len = -1;
+ unsigned char *s = (unsigned char *)packet_receiver_->getString(&s_len);
+
+ BN_mod_exp(bn_K_, bn_f_, bn_x_, bn_p_, ctx_);
+
+ FQTermSSHBuffer *buffer = packet_sender_->output_buffer_;
+
+ buffer->clear();
+ buffer->putString(V_C_);
+ buffer->putString(V_S_);
+ buffer->putString(I_C_, I_C_len_);
+ buffer->putString(I_S_, I_S_len_);
+ buffer->putString((char *)K_S, K_S_len);
+ buffer->putSSH2BN(bn_e_);
+ buffer->putSSH2BN(bn_f_);
+ buffer->putSSH2BN(bn_K_);
+
+ SHA1(buffer->data(), buffer->len(), H_);
+
+ // Start verify
+ unsigned char s_H[SHA_DIGEST_LENGTH];
+ SHA1(H_, SHA_DIGEST_LENGTH, s_H);
+
+ // Ignore the first 15 bytes of the signature of H sent from server:
+ // algorithm_name_length[4], algorithm_name[7]("ssh-rsa") and signature_length[4].
+ RSA *rsactx = CreateRSAContext(K_S, K_S_len);
+ int sig_len = s_len - 15;
+ unsigned char *sig = s + 15;
+ int res = RSA_verify(NID_sha1, s_H, SHA_DIGEST_LENGTH,
+ sig, sig_len, rsactx);
+
+ RSA_free(rsactx);
+
+ delete K_S;
+ delete s;
+
+ return res == 1;
+}
+
+static RSA *CreateRSAContext(unsigned char *host_key, int len) {
+ FQTermSSHBuffer buffer(len);
+
+ buffer.putRawData((char *)host_key, len);
+
+ int algo_len = -1;
+ unsigned char *algo = (unsigned char *)buffer.getString(&algo_len);
+
+ FQ_VERIFY(std::string("ssh-rsa") == std::string((char *)algo));
+
+ int e_len = -1;
+ unsigned char *e = (unsigned char *)buffer.getString(&e_len);
+
+ int n_len = -1;
+ unsigned char *n = (unsigned char *)buffer.getString(&n_len);
+
+
+ RSA *rsa = RSA_new();
+ rsa->e = BN_new();
+ BN_bin2bn(e, e_len, rsa->e);
+
+ rsa->n = BN_new();
+ BN_bin2bn(n, n_len, rsa->n);
+
+ delete[] algo;
+ delete[] e;
+ delete[] n;
+
+ return rsa;
+}
+
+void FQTermSSH2Kex::sendNewKeys(){
+ packet_sender_->startPacket(SSH2_MSG_NEWKEYS);
+ packet_sender_->write();
+}
+
+bool FQTermSSH2Kex::changeKeyAlg() {
+ if (packet_receiver_->packetType() != SSH2_MSG_NEWKEYS) {
+ emit kexError(tr("Expect a SSH_MSG_NEWKEYS packet"));
+ return false;
+ }
+
+ if (session_id_ == NULL) {
+ session_id_ = new unsigned char[SHA_DIGEST_LENGTH];
+ memcpy(session_id_, H_, SHA_DIGEST_LENGTH);
+ }
+
+ packet_sender_->setEncryptionType(SSH_CIPHER_3DES);
+ packet_receiver_->setEncryptionType(SSH_CIPHER_3DES);
+
+ packet_sender_->setMacType(FQTERM_SSH_HMAC_SHA1);
+ packet_receiver_->setMacType(FQTERM_SSH_HMAC_SHA1);
+
+ // From RFC 4253 section 7.2:
+ // Initial IV client to server: HASH(K || H || "A" || session_id)
+ // (Here K is encoded as mpint and "A" as byte and session_id as raw
+ // data. "A" means the single character A, ASCII 65).
+ //
+ // Initial IV server to client: HASH(K || H || "B" || session_id)
+ //
+ // Encryption key client to server: HASH(K || H || "C" || session_id)
+ //
+ // Encryption key server to client: HASH(K || H || "D" || session_id)
+ //
+ // Integrity key client to server: HASH(K || H || "E" || session_id)
+ //
+ // Integrity key server to client: HASH(K || H || "F" || session_id)
+
+ int IV_c2s_len = packet_sender_->getIVSize();
+ unsigned char *IV_c2s = computeKey(IV_c2s_len, 'A');
+
+ int IV_s2c_len = packet_receiver_->getIVSize();
+ unsigned char *IV_s2c = computeKey(IV_s2c_len, 'B');
+
+ int key_c2s_len = packet_sender_->getKeySize();
+ unsigned char *key_c2s = computeKey(key_c2s_len, 'C');
+
+ int key_s2c_len = packet_receiver_->getKeySize();
+ unsigned char *key_s2c = computeKey(key_s2c_len, 'D');
+
+ int mac_key_c2s_len = packet_sender_->getMacKeySize();
+ unsigned char *mac_key_c2s = computeKey(mac_key_c2s_len, 'E');
+
+ int mac_key_s2c_len = packet_receiver_->getMacKeySize();
+ unsigned char *mac_key_s2c = computeKey(mac_key_s2c_len, 'F');
+
+
+ packet_sender_->startEncryption(key_c2s, IV_c2s);
+ packet_sender_->startMac(mac_key_c2s);
+
+ packet_receiver_->startEncryption(key_s2c, IV_s2c);
+ packet_receiver_->startMac(mac_key_s2c);
+
+
+ delete[] IV_c2s;
+ delete[] IV_s2c;
+ delete[] key_c2s;
+ delete[] key_s2c;
+ delete[] mac_key_c2s;
+ delete[] mac_key_s2c;
+
+ return true;
+}
+
+unsigned char *FQTermSSH2Kex::computeKey(int expected_len, char flag) {
+ unsigned char *key = new unsigned char[expected_len + SHA_DIGEST_LENGTH];
+
+ int len = 0;
+ SHA_CTX hash;
+
+ FQTermSSHBuffer K(BN_num_bytes(bn_K_) + 5);
+ K.putSSH2BN(bn_K_);
+
+ while (len < expected_len) {
+ SHA1_Init(&hash);
+ SHA1_Update(&hash, K.data(), K.len());
+ SHA1_Update(&hash, H_, SHA_DIGEST_LENGTH);
+
+ if (len == 0) {
+ SHA1_Update(&hash, &flag, 1);
+ SHA1_Update(&hash, session_id_, SHA_DIGEST_LENGTH);
+ } else {
+ SHA1_Update(&hash, key, len);
+ }
+
+ SHA1_Final(key + len, &hash);
+ len += SHA_DIGEST_LENGTH;
+ }
+
+ return key;
+}
+
+} // namespace FQTerm
+
+#include "fqterm_ssh2_kex.moc"
diff --git a/src/protocol/internal/fqterm_ssh2_kex.h b/src/protocol/internal/fqterm_ssh2_kex.h
new file mode 100644
index 0000000..671e094
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh2_kex.h
@@ -0,0 +1,105 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH2_KEX_H
+#define FQTERM_SSH2_KEX_H
+
+#include <openssl/sha.h>
+
+#include "fqterm_ssh_kex.h"
+
+namespace FQTerm {
+
+class FQTermSSHPacketReceiver;
+class FQTermSSHPacketSender;
+
+class FQTermSSH2Kex: public FQTermSSHKex {
+ Q_OBJECT;
+private:
+ enum FQTermSSH2KexState {
+ BEFORE_KEXINIT, WAIT_REPLY, SESSIONKEY_SENT, KEYEX_OK
+ } kex_state_;
+
+ /*
+ string V_C, the client's identification string (CR and LF
+ excluded)
+ string V_S, the server's identification string (CR and LF
+ excluded)
+ string I_C, the payload of the client's SSH_MSG_KEXINIT
+ string I_S, the payload of the server's SSH_MSG_KEXINIT
+ string K_S, the host key
+ mpint e, exchange value sent by the client
+ mpint f, exchange value sent by the server
+ mpint K, the shared secret
+ */
+
+ int I_C_len_;
+ char *I_C_;
+ int I_S_len_;
+ char *I_S_;
+
+ BIGNUM *bn_x_;
+ BIGNUM *bn_e_;
+ BIGNUM *bn_g_;
+ BIGNUM *bn_p_;
+ BN_CTX *ctx_;
+
+ BIGNUM *bn_K_;
+ BIGNUM *bn_f_;
+
+ unsigned char H_[SHA_DIGEST_LENGTH];
+
+ unsigned char *session_id_;
+
+
+
+
+ bool is_first_kex_;
+
+ FQTermSSHRSA *host_key_;
+ FQTermSSHRSA *server_key_;
+
+ u_char cookie_[16];
+ int server_flag_, ciphers_, auth_;
+// u_char session_id_[16];
+ u_char session_key_[32];
+
+ void negotiateAlgorithms();
+ void exchangeKey();
+ bool verifyKey();
+ void sendNewKeys();
+ bool changeKeyAlg();
+
+ unsigned char *computeKey(int len, char flag);
+
+public:
+ FQTermSSH2Kex(const char *V_C, const char *V_S);
+ ~FQTermSSH2Kex();
+
+ virtual void initKex(FQTermSSHPacketReceiver *packetReceiver,
+ FQTermSSHPacketSender *outputSender);
+
+public slots:
+ void handlePacket(int type);
+};
+
+} // namespace FQTerm
+
+#endif //FQTERM_SSH2_KEX_H
diff --git a/src/protocol/internal/fqterm_ssh2_packet.cpp b/src/protocol/internal/fqterm_ssh2_packet.cpp
new file mode 100644
index 0000000..d3094d3
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh2_packet.cpp
@@ -0,0 +1,267 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_trace.h"
+#include "fqterm_ssh_buffer.h"
+#include "fqterm_ssh2_packet.h"
+#include "fqterm_ssh_des.h"
+
+#include "fqterm_serialization.h"
+#include "crc32.h"
+
+namespace FQTerm {
+//==============================================================================
+//FQTermSSH2PacketSender
+//==============================================================================
+// SSH2 Packet Structure:
+// uint32 packet_length
+// byte padding_length
+// byte[n1] payload; n1 = packet_length - padding_length - 1
+// byte[n2] random padding; n2 = padding_length
+// byte[m] mac (Message Authentication Code - MAC); m = mac_length
+//==============================================================================
+
+void FQTermSSH2PacketSender::makePacket() {
+ FQ_TRACE("ssh2packet", 9) << "----------------------------Send "
+ << (is_encrypt_ ? "Encrypted": "plain")
+ << " Packet---->>>>>>>";
+
+ // 0. compress
+ if (is_compressed_) {
+ FQ_VERIFY(false);
+ }
+
+ // 1. compute the padding length for padding.
+ int non_padding_len = 4 + 1 + buffer_->len();
+
+ int padding_block_len = 8;
+ if (is_encrypt_ && cipher_->blockSize() > padding_block_len) {
+ padding_block_len = cipher_->blockSize();
+ }
+
+ int padding_len = padding_block_len - (non_padding_len % padding_block_len);
+ if (padding_len < 4) {
+ padding_len += padding_block_len;
+ }
+
+ // 2. renew the output buffer.
+ int total_len = non_padding_len + padding_len;
+ if (is_mac_) {
+ total_len += mac_->digestSize();
+ }
+
+ delete output_buffer_;
+ output_buffer_ = new FQTermSSHBuffer(total_len);
+
+ // 3. Fill the output buffer.
+ int packet_len = 1 + buffer_->len() + padding_len;
+
+ output_buffer_->putInt(packet_len);
+ output_buffer_->putByte(padding_len);
+ output_buffer_->putRawData((const char*)buffer_->data(), buffer_->len());
+
+ u_int32_t rand_val = 0;
+ for (int i = 0; i < padding_len; i++) {
+ if (i % 4 == 0) {
+ rand_val = rand(); // FIXME: rand() doesn't range from 0 to 2^32.
+ }
+ output_buffer_->putByte(rand_val & 0xff);
+ rand_val >>= 8;
+ }
+
+ // 4. Add MAC on the entire unencrypted packet,
+ // including two length fields, 'payload' and 'random padding'.
+ if (is_mac_) {
+ const unsigned char *packet = output_buffer_->data();
+ int len = output_buffer_->len();
+
+ FQTermSSHBuffer buffer(4 + len);
+ buffer.putInt(sequence_no_);
+ buffer.putRawData((const char *)packet, len);
+
+ std::vector<u_char> digest(mac_->digestSize());
+ mac_->getDigest(buffer.data(), buffer.len(), &digest[0]);
+
+ FQ_TRACE("ssh2packet", 9) << "Making packets...";
+ FQ_TRACE("ssh2packet", 9) << "Append MAC with sequence_no_" << sequence_no_;
+ FQ_TRACE("ssh2packet", 9) << "Compute MAC with "
+ << buffer.len() << " bytes data:\n"
+ << dumpHexString << std::string((char *)buffer.data(), buffer.len());
+ FQ_TRACE("ssh2packet", 9) << "MAC data "
+ << digest.size() << " bytes:\n"
+ << dumpHexString << std::string((const char *)&digest[0], digest.size());
+
+ output_buffer_->putRawData((const char *)&digest[0], digest.size());
+ }
+
+ if (is_compressed_) {
+ FQ_VERIFY(false);
+ }
+
+ if (is_encrypt_) {
+ // as RFC 4253:
+ // When encryption is in effect, the packet length, padding
+ // length, payload, and padding fields of each packet MUST be encrypted
+ // with the given algorithm.
+
+ u_char *data = output_buffer_->data();
+ int len = output_buffer_->len() - mac_->digestSize();
+
+ FQ_TRACE("ssh2packet", 9) << "An packet (without MAC) to be encrypted:"
+ << len << " bytes:\n"
+ << dumpHexString << std::string((const char *)data, len);
+
+ cipher_->encrypt(data, data, len);
+
+ FQ_TRACE("ssh2packet", 9) << "An encrypted packet (without MAC) made:"
+ << len << " bytes:\n"
+ << dumpHexString << std::string((const char *)data, len);
+ }
+
+ ++sequence_no_;
+}
+
+void FQTermSSH2PacketSender::setEncryptionType(int cipherType) {
+ cipher_type_ = cipherType;
+
+ delete cipher_;
+ cipher_ = NULL;
+
+ switch (cipher_type_) {
+ case SSH_CIPHER_3DES:
+ cipher_ = new FQTermSSH2TripleDESCBC;
+ break;
+ }
+}
+
+
+//==============================================================================
+//FQTermSSH2PacketReceiver
+//==============================================================================
+void FQTermSSH2PacketReceiver::parseData(FQTermSSHBuffer *input) {
+ FQ_TRACE("ssh2packet", 9) << "----------------------------Receive "
+ << (is_decrypt_ ? "Encrypted": "plain")
+ << " Packet----<<<<<<<";
+ while (input->len() > 0) {
+ // 1. Check the ssh packet
+ if (input->len() < 16
+ || (is_decrypt_ && input->len() < cipher_->blockSize())
+ || input->len() < last_expected_input_length_
+ ) {
+ FQ_TRACE("ssh2packet", 3)
+ << "Got an incomplete packet. Wait for more data.";
+ return ;
+ }
+
+ if (last_expected_input_length_ == 0) {
+ if (is_decrypt_) {
+ // decrypte the first block to get the packet_length field.
+ cipher_->decrypt(input->data(), input->data(), cipher_->blockSize());
+ }
+ } else {
+ // last_expected_input_length_ != 0
+ // indicates an incomplete ssh2 packet received last time,
+ // the first block of data is already decrypted at that time,
+ // so it must not be decrypted again.
+ }
+
+ int packet_len = ntohu32(input->data());
+
+ if (packet_len > SSH_BUFFER_MAX) {
+ emit packetError(tr("parseData: packet too big"));
+ return ;
+ }
+
+ int expected_input_len = 4 + packet_len + (is_mac_ ? mac_->digestSize() : 0);
+
+ if (input->len() < (long)expected_input_len) {
+ FQ_TRACE("ssh2packet", 3)
+ << "The packet is too small. Wait for more data.";
+ last_expected_input_length_ = expected_input_len;
+ return ;
+ } else {
+ last_expected_input_length_ = 0;
+ }
+
+ // 2. decrypte data.
+ if (is_decrypt_) {
+ // decrypte blocks left.
+ unsigned char *tmp = input->data() + cipher_->blockSize();
+ int left_len = expected_input_len - cipher_->blockSize() - mac_->digestSize();
+ cipher_->decrypt(tmp, tmp, left_len);
+ }
+
+ // 3. check MAC
+ if (is_mac_) {
+ int digest_len = mac_->digestSize();
+ std::vector<u_char> digest(digest_len);
+ mac_->getDigest(input->data(), expected_input_len - digest_len, &digest[0]);
+
+ u_char *received_digest = input->data() + expected_input_len - digest_len;
+
+ if (memcmp(&digest[0], received_digest, digest_len) == 0) {
+ FQ_TRACE("ssh2packet", 0) << "incorrect MAC.";
+ return ;
+ }
+ }
+
+ // 4. get every field of the ssh packet.
+ packet_len = input->getInt();
+
+ std::vector<u_char> data(packet_len);
+
+ input->getRawData((char*)&data[0], packet_len);
+ if (is_mac_) {
+ input->consume(mac_->digestSize());
+ }
+
+ int padding_len = data[0];
+
+ real_data_len_ = packet_len - 1 - padding_len;
+
+ buffer_->clear();
+ buffer_->putRawData((char*)&data[0] + 1, real_data_len_);
+
+ FQ_TRACE("ssh2packet", 9) << "Receive " << real_data_len_ << " bytes payload:\n"
+ << dumpHexString << std::string((char *)&data[0] + 1, real_data_len_);
+
+ // 5. notify others a ssh packet is parsed successfully.
+ packet_type_ = buffer_->getByte();
+ real_data_len_ -= 1;
+ emit packetAvaliable(packet_type_);
+
+ ++sequence_no_;
+ }
+}
+
+void FQTermSSH2PacketReceiver::setEncryptionType(int cipherType) {
+ cipher_type_ = cipherType;
+
+ delete cipher_;
+ cipher_ = NULL;
+
+ switch (cipher_type_) {
+ case SSH_CIPHER_3DES:
+ cipher_ = new FQTermSSH2TripleDESCBC;
+ break;
+ }
+}
+
+} // namespace FQTerm
diff --git a/src/protocol/internal/fqterm_ssh2_packet.h b/src/protocol/internal/fqterm_ssh2_packet.h
new file mode 100644
index 0000000..c460984
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh2_packet.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH2_PACKET_H
+#define FQTERM_SSH2_PACKET_H
+
+#include "fqterm_ssh_packet.h"
+
+namespace FQTerm {
+
+class FQTermSSH2PacketSender: public FQTermSSHPacketSender {
+ protected:
+ virtual void makePacket();
+
+ public:
+ virtual void setEncryptionType(int cipherType);
+};
+
+class FQTermSSH2PacketReceiver: public FQTermSSHPacketReceiver {
+ private:
+ // greater than 0 if last time an incomplete ssh2 packet received.
+ int last_expected_input_length_;
+ public:
+ FQTermSSH2PacketReceiver()
+ : last_expected_input_length_(0) {
+ }
+
+ virtual void parseData(FQTermSSHBuffer *input);
+ virtual void setEncryptionType(int cipherType);
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SSH2_PACKET
diff --git a/src/protocol/internal/fqterm_ssh_auth.cpp b/src/protocol/internal/fqterm_ssh_auth.cpp
new file mode 100644
index 0000000..d063d14
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_auth.cpp
@@ -0,0 +1,223 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QString>
+
+#include "fqterm_ssh_auth.h"
+#include "fqterm_ssh_packet.h"
+#include "fqterm_ssh_const.h"
+#include "fqterm_trace.h"
+
+namespace FQTerm {
+
+//==============================================================================
+//FQTermSSH1PasswdAuth
+//==============================================================================
+
+FQTermSSH1PasswdAuth::FQTermSSH1PasswdAuth(const char *sshuser,
+ const char *sshpasswd)
+ : FQTermSSHPasswdAuth(sshuser, sshpasswd) {
+ is_tried_ = false;
+ ssh_pw_auth_state_ = FQTermSSH1PasswdAuth::BEFORE_AUTH;
+}
+
+void FQTermSSH1PasswdAuth::initAuth(FQTermSSHPacketReceiver *packet,
+ FQTermSSHPacketSender *output) {
+ packet_receiver_ = packet;
+ packet_sender_ = output;
+ packet_receiver_->disconnect(this);
+ FQ_VERIFY(connect(packet_receiver_, SIGNAL(packetAvaliable(int)),
+ this, SLOT(handlePacket(int))));
+ packet_sender_->startPacket(SSH1_CMSG_USER);
+ user_name_.clear();
+ passwd_.clear();
+
+ if (!default_user_.isEmpty() && !default_passwd_.isEmpty()) {
+ user_name_ = default_user_;
+ passwd_ = default_passwd_;
+ }
+
+ while (user_name_.isEmpty()) {
+ bool isOK = false;
+ emit requestUserPwd(&user_name_, &passwd_, &isOK);
+ // SSHLoginDialog login(&d_user, &d_passwd);
+ if (!isOK) {
+ emit authError(tr("UserCancel"));
+ return ;
+ }
+ }
+
+ packet_sender_->putString(user_name_.toLatin1());
+ packet_sender_->write();
+ ssh_pw_auth_state_ = USER_SENT;
+ is_tried_ = false;
+}
+
+void FQTermSSH1PasswdAuth::handlePacket(int type) {
+ switch (ssh_pw_auth_state_) {
+ case BEFORE_AUTH:
+ FQ_TRACE("sshauth", 0) << "Auth: We should not be here.";
+ break;
+ case USER_SENT:
+ if (type == SSH1_SMSG_SUCCESS) {
+ ssh_pw_auth_state_ = AUTH_OK;
+ emit authOK();
+ break;
+ }
+ if (type != SSH1_SMSG_FAILURE) {
+ emit authError(tr("Strange response from server"));
+ break;
+ }
+ if (is_tried_) {
+ bool isOK = false;
+ emit requestUserPwd(&user_name_, &passwd_, &isOK);
+ // SSHLoginDialog login(&d_user, &d_passwd);
+ if (!isOK) {
+ emit authError(tr("User canceled"));
+ break;
+ }
+ is_tried_ = false;
+ }
+ packet_sender_->startPacket(SSH1_CMSG_AUTH_PASSWORD);
+ packet_sender_->putString(passwd_.toLatin1());
+ packet_sender_->write();
+ is_tried_ = true;
+ break;
+ case AUTH_OK:
+ break;
+ default:
+ return ;
+ }
+}
+
+//==============================================================================
+//FQTermSSH2PasswdAuth
+//==============================================================================
+
+FQTermSSH2PasswdAuth::FQTermSSH2PasswdAuth(const char *sshuser,
+ const char *sshpasswd)
+ : FQTermSSHPasswdAuth(sshuser, sshpasswd) {
+ is_tried_ = false;
+ ssh_pw_auth_state_ = FQTermSSH2PasswdAuth::SERVICE_ACCEPTED;
+}
+
+void FQTermSSH2PasswdAuth::initAuth(FQTermSSHPacketReceiver *packet,
+ FQTermSSHPacketSender *output) {
+ packet_receiver_ = packet;
+ packet_sender_ = output;
+ packet_receiver_->disconnect(this);
+ FQ_VERIFY(connect(packet_receiver_, SIGNAL(packetAvaliable(int)),
+ this, SLOT(handlePacket(int))));
+
+ packet_sender_->startPacket(SSH2_MSG_SERVICE_REQUEST);
+ packet_sender_->putString("ssh-userauth");
+ packet_sender_->write();
+
+ ssh_pw_auth_state_ = FQTermSSH2PasswdAuth::SERVICE_ACCEPTED;
+}
+
+void FQTermSSH2PasswdAuth::handlePacket(int type) {
+ switch (ssh_pw_auth_state_) {
+ case FQTermSSH2PasswdAuth::SERVICE_ACCEPTED:
+ sendUserPasswd();
+ ssh_pw_auth_state_ = FQTermSSH2PasswdAuth::USER_PASSWD_SENT;
+ break;
+ case FQTermSSH2PasswdAuth::USER_PASSWD_SENT:
+ if (check()) {
+ FQ_TRACE("ssh2passwdauth", 3) << "Auth OK.";
+
+ emit authOK();
+ ssh_pw_auth_state_ = FQTermSSH2PasswdAuth::AUTH_OK;
+ }
+ break;
+ case FQTermSSH2PasswdAuth::AUTH_OK:
+ break;
+ default:
+ return ;
+ }
+}
+
+bool FQTermSSH2PasswdAuth::check() {
+ switch(packet_receiver_->packetType()) {
+ case SSH2_MSG_USERAUTH_SUCCESS:
+ return true;
+ break;
+ case SSH2_MSG_USERAUTH_BANNER:
+ // TODO: just ignore banner messages.
+ break;
+ case SSH2_MSG_USERAUTH_FAILURE:
+ emit authError(tr("Authentication failed!"));
+ break;
+ default:
+ emit authError(tr("Unexpected packet"));
+ }
+
+ return false;
+}
+
+void FQTermSSH2PasswdAuth::sendUserPasswd() {
+ if (packet_receiver_->packetType() != SSH2_MSG_SERVICE_ACCEPT) {
+ emit authError(tr("Expect a SSH2_MSG_SERVICE_ACCEPT packet"));
+ return;
+ }
+
+ u_char *service_name = (u_char *)packet_receiver_->getString();
+
+ if (std::string((char *)service_name) != std::string("ssh-userauth")) {
+ emit authError(tr("Error when sending username and password."));
+ return;
+ }
+
+ delete[] service_name;
+
+ // byte SSH_MSG_USERAUTH_REQUEST
+ // string user name in ISO-10646 UTF-8 encoding [RFC3629]
+ // string service name in US-ASCII
+ // string method name in US-ASCII
+ // .... method specific fields
+ user_name_.clear();
+ passwd_.clear();
+
+ if (!default_user_.isEmpty() && !default_passwd_.isEmpty()) {
+ user_name_ = default_user_;
+ passwd_ = default_passwd_;
+ }
+
+ while (user_name_.isEmpty()) {
+ bool isOK = false;
+ emit requestUserPwd(&user_name_, &passwd_, &isOK);
+ if (!isOK) {
+ emit authError(tr("UserCancel"));
+ return ;
+ }
+ }
+
+ packet_sender_->startPacket(SSH2_MSG_USERAUTH_REQUEST);
+ packet_sender_->putString(user_name_.toLatin1());
+ packet_sender_->putString("ssh-connection");
+ packet_sender_->putString("password");
+ packet_sender_->putByte(false);
+ packet_sender_->putString(passwd_.toLatin1());
+ packet_sender_->write();
+}
+
+} // namespace FQTerm
+
+#include <fqterm_ssh_auth.moc>
diff --git a/src/protocol/internal/fqterm_ssh_auth.h b/src/protocol/internal/fqterm_ssh_auth.h
new file mode 100644
index 0000000..6152a71
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_auth.h
@@ -0,0 +1,112 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_AUTH_H
+#define FQTERM_SSH_AUTH_H
+
+#include <QObject>
+
+class QString;
+
+namespace FQTerm {
+
+class FQTermSSHPacketReceiver;
+class FQTermSSHPacketSender;
+
+class FQTermSSHAuth: public QObject {
+
+ Q_OBJECT;
+protected:
+ QString user_name_;
+ FQTermSSHPacketReceiver *packet_receiver_;
+ FQTermSSHPacketSender *packet_sender_;
+
+public:
+ FQTermSSHAuth(const char *sshuser = NULL)
+ : user_name_(sshuser) {
+ }
+
+ ~FQTermSSHAuth() {}
+
+ virtual void initAuth(FQTermSSHPacketReceiver *packet,
+ FQTermSSHPacketSender *output) = 0;
+public slots:
+ virtual void handlePacket(int type) = 0;
+
+signals:
+ void requestUserPwd(QString *user, QString *pwd, bool *isOK);
+ void authOK();
+ void authError(QString);
+};
+
+class FQTermSSHPasswdAuth: public FQTermSSHAuth {
+ Q_OBJECT;
+protected:
+ QString passwd_;
+ bool is_tried_;
+
+ QString default_user_;
+ QString default_passwd_;
+
+public:
+ FQTermSSHPasswdAuth(const char *sshuser, const char *sshpasswd)
+ : FQTermSSHAuth(sshuser),
+ passwd_(sshpasswd),
+ default_user_(sshuser),
+ default_passwd_(sshpasswd) {
+ }
+};
+
+class FQTermSSH1PasswdAuth: public FQTermSSHPasswdAuth {
+ Q_OBJECT;
+private:
+ enum FQTermSSH1PasswdAuthState {
+ BEFORE_AUTH, USER_SENT, PASS_SENT, AUTH_OK
+ } ssh_pw_auth_state_;
+
+public:
+ FQTermSSH1PasswdAuth(const char *sshuser, const char *sshpasswd);
+
+public slots:
+ void handlePacket(int type);
+ void initAuth(FQTermSSHPacketReceiver *packet, FQTermSSHPacketSender *output);
+};
+
+class FQTermSSH2PasswdAuth: public FQTermSSHPasswdAuth {
+ Q_OBJECT;
+private:
+ enum FQTermSSH2PasswdAuthState {
+ SERVICE_ACCEPTED, USER_PASSWD_SENT, PASS_SENT, AUTH_OK
+ } ssh_pw_auth_state_;
+
+ void sendUserPasswd();
+ bool check();
+
+public:
+ FQTermSSH2PasswdAuth(const char *sshuser, const char *sshpasswd);
+
+public slots:
+ void handlePacket(int type);
+ void initAuth(FQTermSSHPacketReceiver *packet, FQTermSSHPacketSender *output);
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SSH_AUTH_H
diff --git a/src/protocol/internal/fqterm_ssh_buffer.cpp b/src/protocol/internal/fqterm_ssh_buffer.cpp
new file mode 100644
index 0000000..d95497a
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_buffer.cpp
@@ -0,0 +1,302 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <vector>
+
+#include "fqterm_trace.h"
+#include "fqterm_ssh_buffer.h"
+#include "fqterm_serialization.h"
+
+namespace FQTerm {
+//==============================================================================
+// FQTermSSHBuffer
+//==============================================================================
+
+FQTermSSHBuffer::FQTermSSHBuffer(int size) {
+ alloc_size_ = size;
+ buffer_size_ = 0;
+ offset_ = 0;
+ buffer_ = new u_char[alloc_size_];
+}
+
+FQTermSSHBuffer::~FQTermSSHBuffer() {
+ delete [] buffer_;
+ offset_ = 0;
+ buffer_size_ = 0;
+ alloc_size_ = 0;
+}
+
+void FQTermSSHBuffer::ensure(int len) {
+ if (len <= (alloc_size_ - (offset_ + buffer_size_))) {
+ return ;
+ } else {
+ alloc_size_ = buffer_size_ + len;
+ rebuffer();
+ }
+}
+
+void FQTermSSHBuffer::rebuffer() {
+ u_char *newBuffer;
+ newBuffer = new u_char[alloc_size_];
+ memset(newBuffer, 0, alloc_size_);
+ memcpy(newBuffer, buffer_ + offset_, buffer_size_);
+ delete [] buffer_;
+ buffer_ = newBuffer;
+ offset_ = 0;
+}
+
+void FQTermSSHBuffer::clear() {
+ memset(buffer_, 0, alloc_size_);
+ offset_ = 0;
+ buffer_size_ = 0;
+}
+
+void FQTermSSHBuffer::consume(int len) {
+ if (len > buffer_size_) {
+ len = buffer_size_;
+ }
+
+ offset_ += len;
+ buffer_size_ -= len;
+}
+
+void FQTermSSHBuffer::putRawData(const char *data, int len) {
+ if (len < 0) {
+ FQ_TRACE("sshbuffer", 0) << "Write data error.";
+ }
+
+ ensure(len);
+ memcpy((buffer_ + offset_ + buffer_size_), data, len);
+ buffer_size_ += len;
+}
+
+void FQTermSSHBuffer::getRawData(char *data, int len) {
+ if (len <= buffer_size_ && len >= 0) {
+ memcpy(data, buffer_ + offset_, len);
+ consume(len);
+ } else {
+ FQ_TRACE("sshbuffer", 0) << "Read too many data: " << len << " bytes.";
+ }
+}
+
+//==============================================================================
+// Store an BIGNUM in the buffer with a 2-byte msb first bit count, followed by
+// (bits+7)/8 bytes of binary data, msb first.
+//==============================================================================
+
+void FQTermSSHBuffer::putSSH1BN(BIGNUM *bignum) {
+ int bits = BN_num_bits(bignum);
+ int bin_size = (bits + 7) / 8;
+ u_char *buf = new u_char[bin_size];
+ int oi;
+ u_char msg[2];
+
+ // Get the value of in binary
+ oi = BN_bn2bin(bignum, buf);
+ if (oi != bin_size) {
+ FQ_TRACE("sshbuffer", 0) << "BN_bn2bin() failed: oi = " << oi
+ << " != bin_size." << bin_size;
+ }
+
+ // Store the number of bits in the buffer in two bytes, msb first
+ htonu16(msg, bits);
+ putRawData((char*)msg, 2);
+ // Store the binary data.
+ putRawData((char*)buf, oi);
+
+ memset(buf, 0, bin_size);
+ delete [] buf;
+}
+
+
+
+void FQTermSSHBuffer::putSSH2BN(BIGNUM *bignum) {
+ // FIXME: support negative number and add error handling.
+
+ FQ_VERIFY(!bignum->neg); // currently we don't support negative big number.
+
+ if (BN_is_zero(bignum)) {
+ this->putInt(0);
+ } else {
+ u_int bytes = BN_num_bytes(bignum) + 1;
+
+ FQ_VERIFY(bytes >= 2); // currently we don't support big numbers so small
+
+ std::vector<u_char> buf(bytes);
+ buf[0] = 0;
+
+ int bin_len = BN_bn2bin(bignum, &buf[0] + 1);
+
+ FQ_VERIFY(bin_len == (int)bytes - 1);
+
+ u_int no_high_bit = (buf[1] & 0x80) ? 0 : 1;
+
+ this->putInt(bytes - no_high_bit);
+ this->putRawData((const char *)&buf[0] + no_high_bit, bytes - no_high_bit);
+ }
+}
+
+//==============================================================================
+// Retrieves a BIGNUM from the buffer.
+//==============================================================================
+
+void FQTermSSHBuffer::getSSH1BN(BIGNUM *bignum) {
+ int bits, bytes;
+ u_char buf[2];
+ u_char *bin;
+
+ // Get the number for bits.
+ getRawData((char*)buf, 2);
+ bits = ntohu16(buf);
+ // Compute the number of binary bytes that follow.
+ bytes = (bits + 7) / 8;
+ if (bytes > 8 *1024) {
+ FQ_TRACE("sshbuffer", 0) << "Can't handle BN of size " << bytes;
+ return ;
+ }
+ if (len() < bytes) {
+ FQ_TRACE("sshbuffer", 0) << "The input buffer is too small.";
+ return ;
+ }
+ bin = data();
+ BN_bin2bn(bin, bytes, bignum);
+ consume(bytes);
+}
+
+void FQTermSSHBuffer::getSSH2BN(BIGNUM *bignum) {
+ // FIXME: support negative numbers and error handling
+ int len;
+ unsigned char *hex_data = (unsigned char *)getString(&len);
+
+ FQ_VERIFY(!(len > 0 && (hex_data[0] & 0x80))); // don't support negative numbers.
+
+ FQ_VERIFY(len < 10240); // don't support so large numbers.
+
+ BIGNUM *res = BN_bin2bn(hex_data, len, bignum);
+
+ FQ_VERIFY(res != NULL);
+
+ delete hex_data;
+}
+
+u_short FQTermSSHBuffer::getWord() {
+ u_char buf[2];
+ u_short data;
+
+ getRawData((char*)buf, 2);
+ data = ntohu16(buf);
+ return data;
+}
+
+void FQTermSSHBuffer::putWord(u_short data) {
+ u_char buf[2];
+
+ htonu16(buf, data);
+ putRawData((char*)buf, 2);
+}
+
+u_int FQTermSSHBuffer::getInt() {
+ u_char buf[4];
+ u_int data;
+ getRawData((char*)buf, 4);
+ data = ntohu32(buf);
+ return data;
+}
+
+void FQTermSSHBuffer::putInt(u_int data) {
+ u_char buf[4];
+
+ htonu32(buf, data);
+ putRawData((char*)buf, 4);
+}
+
+//==============================================================================
+// Return a character from the buffer (0-255).
+//==============================================================================
+
+u_char FQTermSSHBuffer::getByte() {
+ u_char ch;
+
+ getRawData((char*) &ch, 1);
+ return ch;
+}
+
+//==============================================================================
+// Stores a character in the buffer.
+//==============================================================================
+
+void FQTermSSHBuffer::putByte(int data) {
+ u_char ch = data;
+
+ putRawData((char*) &ch, 1);
+}
+
+//==============================================================================
+// Stores an arbitrary binary string in the buffer.
+//==============================================================================
+
+void FQTermSSHBuffer::putString(const char *str, int len) {
+ if (str == NULL) {
+ FQ_TRACE("sshbuffer", 0) << "Can't put a null pointer string.";
+ return ;
+ }
+
+ if (len < 0) {
+ len = strlen(str);
+ }
+
+ putInt(len);
+ putRawData(str, len);
+}
+
+//==============================================================================
+// Return an arbitrary binary string from the buffer. The string cannot be
+// longer than 256k. The returned value points to memory allocated with new;
+// It is the responsibility of the calling function to free the data.
+//==============================================================================
+
+void *FQTermSSHBuffer::getString(int *length) {
+ u_char *data;
+ u_int len;
+
+ // Get the length.
+ len = getInt();
+ if ((long)len > buffer_size_) {
+ FQ_TRACE("sshbuffer", 0)
+ << "String length " << len
+ << " is greater than buffer size " << buffer_size_;
+ return 0;
+ }
+ // Allocate space for the string. Add one byte for a null character.
+ data = new u_char[len + 1];
+ // Get the string.
+ getRawData((char*)data, len);
+ // Append a null character to make processing easier.
+ data[len] = 0;
+ if (length != NULL) {
+ *length = len;
+ }
+ // return the length of the string.
+ return data;
+}
+
+} // namespace FQTerm
diff --git a/src/protocol/internal/fqterm_ssh_buffer.h b/src/protocol/internal/fqterm_ssh_buffer.h
new file mode 100644
index 0000000..e06872f
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_buffer.h
@@ -0,0 +1,83 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_BUFFER_H
+#define FQTERM_SSH_BUFFER_H
+
+#include <openssl/bn.h>
+#include <string.h>
+
+#include "fqterm_ssh_types.h"
+
+namespace FQTerm {
+
+#define SSH_BUFFER_MAX 10000000
+
+class FQTermSSHBuffer {
+ private:
+ u_char *buffer_;
+ int offset_;
+ int buffer_size_;
+ int alloc_size_;
+
+ void ensure(int len);
+ void rebuffer();
+
+ public:
+ FQTermSSHBuffer(int size);
+ ~FQTermSSHBuffer();
+
+ u_char *data() const {
+ return buffer_ + offset_;
+ }
+
+ int len() const {
+ return buffer_size_;
+ }
+
+ void consume(int len);
+
+ void clear();
+
+ void putRawData(const char *data, int len);
+ void getRawData(char *data, int len);
+
+ void putSSH1BN(BIGNUM *bignum);
+ void getSSH1BN(BIGNUM *bignum);
+
+ void putSSH2BN(BIGNUM *bignum);
+ void getSSH2BN(BIGNUM *bignum);
+
+ void putInt(u_int data);
+ u_int getInt();
+
+ void putWord(u_short data);
+ u_short getWord();
+
+ void putByte(int data);
+ u_char getByte();
+
+ void putString(const char *str, int len = -1);
+ void *getString(int *length = NULL);
+};
+
+} // namespace FQTerm
+
+#endif //FQTERM_SSH_BUFFER
diff --git a/src/protocol/internal/fqterm_ssh_channel.cpp b/src/protocol/internal/fqterm_ssh_channel.cpp
new file mode 100644
index 0000000..38a755a
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_channel.cpp
@@ -0,0 +1,439 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_ssh_channel.h"
+#include "fqterm_ssh_const.h"
+#include "fqterm_ssh_packet.h"
+#include "fqterm_trace.h"
+#include <QString>
+namespace FQTerm {
+
+//==============================================================================
+//FQTermSSH1Channel
+//==============================================================================
+
+FQTermSSH1Channel::FQTermSSH1Channel()
+ : FQTermSSHChannel() {
+ service_state_ = FQTermSSH1Channel::BEGIN_SERVICE;
+}
+
+void FQTermSSH1Channel::initChannel(FQTermSSHPacketReceiver *packet,
+ FQTermSSHPacketSender *output,
+ int col, int row, const QString& termtype) {
+ packet_receiver_ = packet;
+ packet_sender_ = output;
+ packet_receiver_->disconnect(this);
+ FQ_VERIFY(connect(packet_receiver_, SIGNAL(packetAvaliable(int)), this, SLOT(handlePacket(int))));
+ packet_sender_->startPacket(SSH1_CMSG_REQUEST_PTY);
+ // pty request is of no use in BBS, but we do this
+ packet_sender_->putString(termtype.toLatin1());
+ packet_sender_->putInt(row); // FIXME: hardcoded term size.
+ packet_sender_->putInt(col);
+ packet_sender_->putInt(0);
+ packet_sender_->putInt(0);
+ packet_sender_->putByte(0);
+ packet_sender_->write();
+ service_state_ = FQTermSSH1Channel::REQPTY_SENT;
+
+ is_closed_ = false;
+}
+
+void FQTermSSH1Channel::changeTermSize(int col, int row) {
+ packet_sender_->startPacket(SSH1_CMSG_WINDOW_SIZE);
+ packet_sender_->putInt(row);
+ packet_sender_->putInt(col);
+ packet_sender_->putInt(0);
+ packet_sender_->putInt(0);
+ packet_sender_->write();
+}
+
+void FQTermSSH1Channel::sendData(const char *data, int len) {
+ packet_sender_->startPacket(SSH1_CMSG_STDIN_DATA);
+ packet_sender_->putInt(len);
+ packet_sender_->putRawData(data, len);
+ packet_sender_->write();
+}
+
+void FQTermSSH1Channel::closeConnection(const char *reason) {
+ packet_sender_->startPacket(SSH1_MSG_DISCONNECT);
+ packet_sender_->putString(reason);
+ packet_sender_->write();
+ is_closed_ = true;
+}
+
+void FQTermSSH1Channel::handlePacket(int type) {
+ switch (service_state_) {
+ case BEGIN_SERVICE:
+ FQ_TRACE("sshchannel", 0) << "Channel: We should not be here";
+ break;
+ case REQPTY_SENT:
+ if (type != SSH1_SMSG_SUCCESS) {
+ emit channelError(tr("Server refused pty allocation!"));
+ }
+ packet_sender_->startPacket(SSH1_CMSG_EXEC_SHELL);
+ packet_sender_->write();
+ emit channelOK();
+ service_state_ = FQTermSSH1Channel::SERVICE_OK;
+ //emit msg to tell window we could process input.
+ break;
+ case SERVICE_OK:
+ switch (type) {
+ case SSH1_SMSG_STDOUT_DATA:
+ case SSH1_SMSG_STDERR_DATA:
+ {
+ const char *data = (const char *)packet_receiver_->buffer_->data() + 4;
+ int len = packet_receiver_->packetDataLen() - 4;
+ emit channelReadyRead(data, len);
+ }
+ break;
+ case SSH1_SMSG_X11_OPEN:
+ case SSH1_SMSG_AGENT_OPEN:
+ case SSH1_MSG_PORT_OPEN:
+ {
+ int i = packet_receiver_->getInt();
+ packet_sender_->startPacket(SSH1_MSG_CHANNEL_OPEN_FAILURE);
+ packet_sender_->putInt(i);
+ packet_sender_->write();
+ }
+ break;
+ case SSH1_SMSG_EXIT_STATUS:
+ packet_sender_->startPacket(SSH1_CMSG_EXIT_CONFIRMATION);
+ packet_sender_->write();
+ closeConnection("end");
+ is_closed_ = true;
+ break;
+ case SSH1_SMSG_SUCCESS:
+ case SSH1_SMSG_FAILURE:
+ break;
+ default:
+ FQ_TRACE("sshchannel", 0) << "Unimplemented message: "
+ << service_state_;
+ }
+ }
+}
+
+
+//==============================================================================
+//FQTermSSH2Channel
+//==============================================================================
+u_int32_t FQTermSSH2Channel::generateChannelID() {
+ static u_int32_t id = 0;
+ return id++;
+}
+
+FQTermSSH2Channel::FQTermSSH2Channel()
+ : FQTermSSHChannel(),
+ col_(80),
+ row_(24),
+ termtype_("vt100") {
+ channel_id_ = generateChannelID();
+ server_channel_id_ = 0xCCCCCCCC;
+ local_window_size_ = 0;
+ channel_state_ = FQTermSSH2Channel::BEGIN_CHANNEL;
+}
+
+void FQTermSSH2Channel::initChannel(FQTermSSHPacketReceiver *packet,
+ FQTermSSHPacketSender *output,
+ int col, int row, const QString& termtype) {
+ FQ_FUNC_TRACE("ssh2channel", 5);
+ col_ = col;
+ row_ = row;
+ termtype_ = termtype;
+ packet_receiver_ = packet;
+ packet_sender_ = output;
+ packet_receiver_->disconnect(this);
+ FQ_VERIFY(connect(packet_receiver_, SIGNAL(packetAvaliable(int)), this, SLOT(handlePacket(int))));
+
+ // byte SSH_MSG_CHANNEL_OPEN
+ // string channel type in US-ASCII only
+ // uint32 sender channel
+ // uint32 initial window size
+ // uint32 maximum packet size
+ // .... channel type specific data follows
+
+ packet_sender_->startPacket(SSH2_MSG_CHANNEL_OPEN);
+ packet_sender_->putString("session");
+ packet_sender_->putInt(channel_id_);
+ packet_sender_->putInt(MAX_LOCAL_WINDOW_SIZE); // TODO: what's the best window size?
+ packet_sender_->putInt(MAX_LOCAL_PACKET_SIZE); // TODO: what's the best maximum packet size?
+ packet_sender_->write();
+
+ server_window_size_ = 0;
+ server_max_packet_size_ = 0;
+ local_window_size_ = MAX_LOCAL_WINDOW_SIZE;
+
+ is_closed_ = false;
+}
+
+void FQTermSSH2Channel::changeTermSize(int col, int row) {
+ // byte SSH_MSG_CHANNEL_REQUEST
+ // uint32 recipient channel
+ // string "window-change"
+ // boolean FALSE
+ // uint32 terminal width, columns
+ // uint32 terminal height, rows
+ // uint32 terminal width, pixels
+ // uint32 terminal height, pixels
+
+ packet_sender_->startPacket(SSH2_MSG_CHANNEL_REQUEST);
+ packet_sender_->putInt(server_channel_id_);
+ packet_sender_->putString("window-change");
+ packet_sender_->putByte(false);
+ packet_sender_->putInt(col);
+ packet_sender_->putInt(row);
+ packet_sender_->putInt(640); // FIXME: hard-coded screen pixels.
+ packet_sender_->putInt(480);
+ packet_sender_->write();
+}
+
+void FQTermSSH2Channel::sendData(const char *data, int len) {
+ if (len > (int)server_window_size_ || len > (int)server_max_packet_size_) {
+ FQ_TRACE("ssh2channel", 3) << "Data length is greater than server's capacity: "
+ << "data length: " << len << ", "
+ << "server window: " << server_window_size_ << ", "
+ << "server packet max size: " << server_max_packet_size_;
+ return;
+ }
+
+ // byte SSH_MSG_CHANNEL_DATA
+ // uint32 recipient channel
+ // string data
+ packet_sender_->startPacket(SSH2_MSG_CHANNEL_DATA);
+ packet_sender_->putInt(server_channel_id_);
+ packet_sender_->putString(data, len);
+ packet_sender_->write();
+
+ server_window_size_ -= len;;
+
+ FQ_TRACE("ssh2channel", 5) << len
+ << " bytes data sent, server window size left: "
+ << server_window_size_;;
+}
+
+void FQTermSSH2Channel::closeConnection(const char *reason) {
+ packet_sender_->startPacket(SSH1_MSG_DISCONNECT);
+ packet_sender_->putString(reason);
+ packet_sender_->write();
+ is_closed_ = true;
+}
+
+void FQTermSSH2Channel::requestPty() {
+ if (packet_receiver_->packetType() == SSH2_MSG_CHANNEL_OPEN_FAILURE) {
+ // TODO: Here the error reason in the packet is ignored.
+ emit channelError(tr("Server refuces to open a channel."));
+ return;
+ }
+
+ if (packet_receiver_->packetType() != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {
+ emit channelError(tr("Server error when opening a channel."));
+ return;
+ }
+
+ FQ_TRACE("ssh2channel", 5) << "Channel open. Try to request a pty.";
+
+ // byte SSH_MSG_CHANNEL_OPEN_CONFIRMATION
+ // uint32 recipient channel
+ // uint32 sender channel
+ // uint32 initial window size
+ // uint32 maximum packet size
+ // .... channel type specific data follows
+ packet_receiver_->consume(4);
+ server_channel_id_ = packet_receiver_->getInt();
+ server_window_size_ = packet_receiver_->getInt();
+ server_max_packet_size_ = packet_receiver_->getInt();
+
+ // byte SSH_MSG_CHANNEL_REQUEST
+ // uint32 recipient channel
+ // string "pty-req"
+ // boolean want_reply
+ // string TERM environment variable value (e.g., vt100)
+ // uint32 terminal width, characters (e.g., 80)
+ // uint32 terminal height, rows (e.g., 24)
+ // uint32 terminal width, pixels (e.g., 640)
+ // uint32 terminal height, pixels (e.g., 480)
+ // string encoded terminal modes
+ packet_sender_->startPacket(SSH2_MSG_CHANNEL_REQUEST);
+ packet_sender_->putInt(server_channel_id_);
+ packet_sender_->putString("pty-req");
+ packet_sender_->putByte(true);
+ packet_sender_->putString(termtype_.toLatin1()); // TODO: hardcoded term type.
+ packet_sender_->putInt(col_); // FIXME: hardcoded screen parameters.
+ packet_sender_->putInt(row_);
+ packet_sender_->putInt(640);
+ packet_sender_->putInt(480);
+ packet_sender_->putString(""); // TODO: no modes sent.
+ packet_sender_->write();
+}
+
+
+void FQTermSSH2Channel::requestShell() {
+ if (packet_receiver_->packetType() != SSH2_MSG_CHANNEL_SUCCESS) {
+ emit channelError(tr("Server refused pty allocation!"));
+ }
+ FQ_TRACE("ssh2channel", 5) << "Pty allocated. Now try to request a shell.";
+ // byte SSH_MSG_CHANNEL_REQUEST
+ // uint32 recipient channel
+ // string "shell"
+ // boolean want reply
+ packet_sender_->startPacket(SSH2_MSG_CHANNEL_REQUEST);
+ packet_sender_->putInt(server_channel_id_);
+ packet_sender_->putString("shell");
+ packet_sender_->putByte(true);
+ packet_sender_->write();
+}
+
+void FQTermSSH2Channel::checkLocalWindowSize() {
+ if (local_window_size_ < MAX_LOCAL_WINDOW_SIZE/2) {
+ // byte SSH_MSG_CHANNEL_WINDOW_ADJUST
+ // uint32 recipient channel
+ // uint32 bytes to add
+ int inc = MAX_LOCAL_WINDOW_SIZE/2;
+ local_window_size_ += inc;
+
+ packet_sender_->startPacket(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
+ packet_sender_->putInt(server_channel_id_);
+ packet_sender_->putInt(inc);
+ packet_sender_->write();
+ }
+}
+
+void FQTermSSH2Channel::processChannelPacket() {
+ switch (packet_receiver_->packetType()) {
+ case SSH2_MSG_CHANNEL_WINDOW_ADJUST:
+ {
+ // byte SSH_MSG_CHANNEL_WINDOW_ADJUST
+ // uint32 recipient channel
+ // uint32 bytes to add
+ packet_receiver_->consume(4); // channel id is already checked.
+ int inc = packet_receiver_->getInt();
+ server_window_size_ += inc;
+ FQ_TRACE("ssh2channel", 5) << "Server window size increased from "
+ << server_window_size_ - inc
+ << " to " << server_window_size_;
+ }
+ break;
+ case SSH2_MSG_CHANNEL_DATA:
+ {
+ // byte SSH_MSG_CHANNEL_DATA
+ // uint32 recipient channel
+ // string data
+ packet_receiver_->consume(4);
+ int len = packet_receiver_->getInt();
+ const char *data = (const char *)packet_receiver_->buffer_->data();
+ local_window_size_ -= len;
+ checkLocalWindowSize();
+ emit channelReadyRead(data, len);
+ }
+ break;
+ case SSH2_MSG_CHANNEL_EXTENDED_DATA:
+ {
+ // byte SSH_MSG_CHANNEL_DATA
+ // uint32 recipient channel
+ // string data
+ packet_receiver_->consume(4);
+ int len = packet_receiver_->getInt();
+ const char *data = (const char *)packet_receiver_->buffer_->data();
+ local_window_size_ -= len;
+ checkLocalWindowSize();
+ emit channelReadyRead(data, len);
+ }
+ break;
+ case SSH2_MSG_CHANNEL_EOF:
+ case SSH2_MSG_CHANNEL_CLOSE:
+ // byte SSH_MSG_CHANNEL_EOF
+ // uint32 recipient channel
+ // FIXME: this error would cause the connection closed, while only the channel need be closed in ssh2.
+ emit channelError(tr("Channel closed by the server."));
+ break;
+ case SSH2_MSG_CHANNEL_REQUEST:
+ // byte SSH_MSG_CHANNEL_REQUEST
+ // uint32 recipient channel
+ // string "xon-xoff"
+ // boolean FALSE
+ // boolean client can do
+
+ // TODO: just ignore this message currently.
+ break;
+ }
+}
+
+void FQTermSSH2Channel::handlePacket(int type) {
+ // first check the channel id.
+ u_int32_t channel_id = ntohu32(packet_receiver_->buffer_->data());
+ if (channel_id != channel_id_) {
+ return;
+ }
+
+ switch (channel_state_) {
+ case FQTermSSH2Channel::BEGIN_CHANNEL:
+ requestPty();
+ channel_state_ = FQTermSSH2Channel::REQUEST_PTY_SENT;
+ break;
+ case FQTermSSH2Channel::REQUEST_PTY_SENT:
+ requestShell();
+ channel_state_ = FQTermSSH2Channel::REQUEST_SHELL_SENT;
+ break;
+ case FQTermSSH2Channel::REQUEST_SHELL_SENT:
+ switch (type) {
+ case SSH2_MSG_CHANNEL_REQUEST:
+ {
+ FQ_TRACE("ssh2channel", 8) << "SSH2_MSG_CHANNEL_REQUEST isn't supported, just send back a packet with SSH2_MSG_CHANNEL_SUCCESS if reply is needed.";
+
+ packet_receiver_->consume(4);
+ u_int32_t len = ntohu32(packet_receiver_->buffer_->data());
+ packet_receiver_->consume(4 + len);
+ bool replyNeeded = packet_receiver_->getByte();
+
+ if (replyNeeded) {
+ packet_sender_->startPacket(SSH2_MSG_CHANNEL_SUCCESS);
+ packet_sender_->putInt(server_channel_id_);
+ packet_sender_->write();
+ }
+ }
+ break;
+ case SSH2_MSG_CHANNEL_WINDOW_ADJUST:
+ {
+ packet_receiver_->consume(4);
+ u_int32_t inc = packet_receiver_->getInt();
+ server_window_size_ += inc;
+ }
+ break;
+ case SSH2_MSG_CHANNEL_SUCCESS:
+ emit channelOK();
+ channel_state_ = FQTermSSH2Channel::CHANNEL_OK;
+ //emit a msg to tell window we could process input.
+ break;
+ case SSH2_MSG_CHANNEL_FAILURE:
+ emit channelError(tr("Can't open a shell."));
+ break;
+ default:
+ emit channelError(tr("Unsupported packet."));
+ break;
+ }
+ break;
+ case FQTermSSH2Channel::CHANNEL_OK:
+ processChannelPacket();
+ break;
+ }
+}
+
+} // namespace FQTerm
+
+#include "fqterm_ssh_channel.moc"
diff --git a/src/protocol/internal/fqterm_ssh_channel.h b/src/protocol/internal/fqterm_ssh_channel.h
new file mode 100644
index 0000000..9922528
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_channel.h
@@ -0,0 +1,130 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_CHANNEL_H
+#define FQTERM_SSH_CHANNEL_H
+
+#include "fqterm_ssh_types.h"
+
+#include <QObject>
+
+namespace FQTerm {
+
+class FQTermSSHPacketReceiver;
+class FQTermSSHPacketSender;
+
+class FQTermSSHChannel: public QObject {
+ Q_OBJECT;
+protected:
+ bool is_closed_;
+
+ FQTermSSHPacketReceiver *packet_receiver_;
+ FQTermSSHPacketSender *packet_sender_;
+
+public:
+ FQTermSSHChannel(){}
+ virtual ~FQTermSSHChannel(){}
+ virtual void initChannel(FQTermSSHPacketReceiver *packet,
+ FQTermSSHPacketSender *output,
+ int col, int row, const QString& termtype) = 0;
+ virtual void closeConnection(const char *reason) = 0;
+
+ // TODO: it seems this function isn't used.
+ virtual void changeTermSize(int col, int row) = 0;
+
+ virtual void sendData(const char *data, int len) = 0;
+
+public slots:
+ virtual void handlePacket(int type) = 0;
+signals:
+ void channelOK();
+ void channelReadyRead(const char *data, int len);
+ void channelError(QString);
+};
+
+class FQTermSSH1Channel: public FQTermSSHChannel {
+ Q_OBJECT;
+private:
+ enum FQTermSSH1ChannelState {
+ BEGIN_SERVICE, REQPTY_SENT,
+ //REQCMD_SENT,
+ SERVICE_OK
+ } service_state_;
+
+public:
+ FQTermSSH1Channel();
+ virtual void initChannel(FQTermSSHPacketReceiver *packet, FQTermSSHPacketSender *output,
+ int col, int row, const QString& termtype);
+ virtual void closeConnection(const char *reason);
+ virtual void changeTermSize(int col, int row);
+ virtual void sendData(const char *data, int len);
+
+public slots:
+ virtual void handlePacket(int type);
+signals:
+ void channelReadyRead(const char *data, int len);
+};
+
+
+class FQTermSSH2Channel: public FQTermSSHChannel {
+ Q_OBJECT;
+private:
+ static u_int32_t generateChannelID();
+
+private:
+ int col_;
+ int row_;
+ QString termtype_;
+ enum FQTermSSH2ChannelState {
+ BEGIN_CHANNEL, REQUEST_PTY_SENT, REQUEST_SHELL_SENT, CHANNEL_OK
+ } channel_state_;
+
+ u_int32_t channel_id_;
+
+ enum {MAX_LOCAL_WINDOW_SIZE = 0x100000, MAX_LOCAL_PACKET_SIZE = 0x4000};
+
+ u_int32_t local_window_size_;
+
+ u_int32_t server_channel_id_;
+ u_int32_t server_window_size_; // connection packet window size;
+ u_int32_t server_max_packet_size_; // max size of each packet sent to server.
+
+ void requestPty();
+ void requestShell();
+ void processChannelPacket();
+ void checkLocalWindowSize();
+
+public:
+ FQTermSSH2Channel();
+ virtual void initChannel(FQTermSSHPacketReceiver *packet, FQTermSSHPacketSender *output,
+ int col, int row, const QString& termtype);
+ virtual void closeConnection(const char *reason);
+ virtual void changeTermSize(int col, int row);
+ virtual void sendData(const char *data, int len);
+
+public slots:
+ virtual void handlePacket(int type);
+signals:
+ void channelReadyRead(const char *data, int len);
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SSH_CHANNEL_H
diff --git a/src/protocol/internal/fqterm_ssh_cipher.h b/src/protocol/internal/fqterm_ssh_cipher.h
new file mode 100644
index 0000000..13bc9f3
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_cipher.h
@@ -0,0 +1,58 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_CIPHER_H
+#define FQTERM_SSH_CIPHER_H
+
+#include <stdlib.h>
+
+#include "fqterm_ssh_types.h"
+#include "fqterm_ssh_const.h"
+
+namespace FQTerm {
+
+class FQTermSSHCipher {
+protected:
+ const char *d_name;
+
+public:
+ FQTermSSHCipher() {
+ d_name = NULL;
+ }
+
+ virtual ~FQTermSSHCipher(){}
+
+ const char *name() const {
+ return d_name;
+ }
+
+ virtual int blockSize() const = 0;
+ virtual int getKeySize() const = 0;
+ virtual int getIVSize() const = 0;
+
+ virtual void setIV(const u_char *data) = 0;
+ virtual void setKey(const u_char *data) = 0;
+ virtual void encrypt(const u_char *source, u_char *dest, int len) = 0;
+ virtual void decrypt(const u_char *source, u_char *dest, int len) = 0;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SSH_CIPHER_H
diff --git a/src/protocol/internal/fqterm_ssh_const.h b/src/protocol/internal/fqterm_ssh_const.h
new file mode 100644
index 0000000..412760e
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_const.h
@@ -0,0 +1,146 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERMCONST_H
+#define FQTERMCONST_H
+
+namespace FQTerm {
+
+#define SSH_CIPHER_SSH2 -3
+#define SSH_CIPHER_ILLEGAL -2
+#define SSH_CIPHER_NOT_SET -1
+#define SSH_CIPHER_NONE 0
+#define SSH_CIPHER_IDEA 1
+#define SSH_CIPHER_DES 2
+#define SSH_CIPHER_3DES 3
+#define SSH_CIPHER_BROKEN_TSS 4
+#define SSH_CIPHER_BROKEN_RC4 5
+#define SSH_CIPHER_BLOWFISH 6
+#define SSH_CIPHER_RESERVED 7
+#define SSH_CIPHER_MAX 31
+
+#define SSH1_MSG_DISCONNECT 1
+#define SSH1_SMSG_PUBLIC_KEY 2
+#define SSH1_CMSG_SESSION_KEY 3
+#define SSH1_CMSG_USER 4
+#define SSH1_CMSG_AUTH_RSA 6
+#define SSH1_SMSG_AUTH_RSA_CHALLENGE 7
+#define SSH1_CMSG_AUTH_RSA_RESPONSE 8
+#define SSH1_CMSG_AUTH_PASSWORD 9
+#define SSH1_CMSG_REQUEST_PTY 10
+#define SSH1_CMSG_WINDOW_SIZE 11
+#define SSH1_CMSG_EXEC_SHELL 12
+#define SSH1_CMSG_EXEC_CMD 13
+#define SSH1_SMSG_SUCCESS 14
+#define SSH1_SMSG_FAILURE 15
+#define SSH1_CMSG_STDIN_DATA 16
+#define SSH1_SMSG_STDOUT_DATA 17
+#define SSH1_SMSG_STDERR_DATA 18
+#define SSH1_CMSG_EOF 19
+#define SSH1_SMSG_EXIT_STATUS 20
+#define SSH1_MSG_CHANNEL_OPEN_CONFIRMATION 21
+#define SSH1_MSG_CHANNEL_OPEN_FAILURE 22
+#define SSH1_MSG_CHANNEL_DATA 23
+#define SSH1_MSG_CHANNEL_CLOSE 24
+#define SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION 25
+#define SSH1_SMSG_X11_OPEN 27
+#define SSH1_CMSG_PORT_FORWARD_REQUEST 28
+#define SSH1_MSG_PORT_OPEN 29
+#define SSH1_CMSG_AGENT_REQUEST_FORWARDING 30
+#define SSH1_SMSG_AGENT_OPEN 31
+#define SSH1_MSG_IGNORE 32
+#define SSH1_CMSG_EXIT_CONFIRMATION 33
+#define SSH1_CMSG_X11_REQUEST_FORWARDING 34
+#define SSH1_CMSG_AUTH_RHOSTS_RSA 35
+#define SSH1_MSG_DEBUG 36
+#define SSH1_CMSG_REQUEST_COMPRESSION 37
+#define SSH1_CMSG_AUTH_TIS 39
+#define SSH1_SMSG_AUTH_TIS_CHALLENGE 40
+#define SSH1_CMSG_AUTH_TIS_RESPONSE 41
+#define SSH1_CMSG_AUTH_CCARD 70
+#define SSH1_SMSG_AUTH_CCARD_CHALLENGE 71
+#define SSH1_CMSG_AUTH_CCARD_RESPONSE 72
+#define SSH1_AUTH_TIS 5
+#define SSH1_PROTOFLAG_SCREEN_NUMBER 1
+#define SSH1_PROTOFLAGS_SUPPORTED 0
+
+
+#define SSH2_MSG_DISCONNECT 1
+#define SSH2_MSG_IGNORE 2
+#define SSH2_MSG_UNIMPLEMENTED 3
+#define SSH2_MSG_DEBUG 4
+#define SSH2_MSG_SERVICE_REQUEST 5
+#define SSH2_MSG_SERVICE_ACCEPT 6
+#define SSH2_MSG_KEXINIT 20
+#define SSH2_MSG_NEWKEYS 21
+#define SSH2_MSG_KEXDH_INIT 30
+#define SSH2_MSG_KEXDH_REPLY 31
+#define SSH2_MSG_KEX_DH_GEX_REQUEST_OLD 30
+#define SSH2_MSG_KEX_DH_GEX_GROUP 31
+#define SSH2_MSG_KEX_DH_GEX_INIT 32
+#define SSH2_MSG_KEX_DH_GEX_REPLY 33
+#define SSH2_MSG_KEX_DH_GEX_REQUEST 34
+#define SSH2_MSG_USERAUTH_REQUEST 50
+#define SSH2_MSG_USERAUTH_FAILURE 51
+#define SSH2_MSG_USERAUTH_SUCCESS 52
+#define SSH2_MSG_USERAUTH_BANNER 53
+#define SSH2_MSG_USERAUTH_PK_OK 60
+#define SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ 60
+#define SSH2_MSG_USERAUTH_INFO_REQUEST 60
+#define SSH2_MSG_USERAUTH_INFO_RESPONSE 61
+#define SSH2_MSG_GLOBAL_REQUEST 80
+#define SSH2_MSG_REQUEST_SUCCESS 81
+#define SSH2_MSG_REQUEST_FAILURE 82
+#define SSH2_MSG_CHANNEL_OPEN 90
+#define SSH2_MSG_CHANNEL_OPEN_CONFIRMATION 91
+#define SSH2_MSG_CHANNEL_OPEN_FAILURE 92
+#define SSH2_MSG_CHANNEL_WINDOW_ADJUST 93
+#define SSH2_MSG_CHANNEL_DATA 94
+#define SSH2_MSG_CHANNEL_EXTENDED_DATA 95
+#define SSH2_MSG_CHANNEL_EOF 96
+#define SSH2_MSG_CHANNEL_CLOSE 97
+#define SSH2_MSG_CHANNEL_REQUEST 98
+#define SSH2_MSG_CHANNEL_SUCCESS 99
+#define SSH2_MSG_CHANNEL_FAILURE 100
+#define SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1
+#define SSH2_DISCONNECT_PROTOCOL_ERROR 2
+#define SSH2_DISCONNECT_KEY_EXCHANGE_FAILED 3
+#define SSH2_DISCONNECT_HOST_AUTHENTICATION_FAILED 4
+#define SSH2_DISCONNECT_RESERVED 4
+#define SSH2_DISCONNECT_MAC_ERROR 5
+#define SSH2_DISCONNECT_COMPRESSION_ERROR 6
+#define SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE 7
+#define SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8
+#define SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9
+#define SSH2_DISCONNECT_CONNECTION_LOST 10
+#define SSH2_DISCONNECT_BY_APPLICATION 11
+#define SSH2_DISCONNECT_TOO_MANY_CONNECTIONS 12
+#define SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER 13
+#define SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14
+#define SSH2_DISCONNECT_ILLEGAL_USER_NAME 15
+#define SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED 1
+#define SSH2_OPEN_CONNECT_FAILED 2
+#define SSH2_OPEN_UNKNOWN_CHANNEL_TYPE 3
+#define SSH2_OPEN_RESOURCE_SHORTAGE 4
+#define SSH2_EXTENDED_DATA_STDERR 1
+
+} // namespace FQTerm
+
+#endif // FQTERMCONST_H
diff --git a/src/protocol/internal/fqterm_ssh_des.cpp b/src/protocol/internal/fqterm_ssh_des.cpp
new file mode 100644
index 0000000..603b6fe
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_des.cpp
@@ -0,0 +1,180 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <memory.h>
+#include <openssl/des.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+
+#include "fqterm_ssh_const.h"
+#include "fqterm_ssh_des.h"
+#include "fqterm_trace.h"
+
+namespace FQTerm {
+
+#define DES_ENCRYPT 1
+#define DES_DECRYPT 0
+
+//==============================================================================
+//FQTermSSH1DES3
+//==============================================================================
+
+FQTermSSH1DES3::FQTermSSH1DES3() {
+ d_name = "des3-cbc";
+
+ memset(d_IV1, 0, sizeof(d_IV1));
+ memset(d_IV2, 0, sizeof(d_IV2));
+ memset(d_IV3, 0, sizeof(d_IV3));
+}
+
+int FQTermSSH1DES3::blockSize() const {
+ return 8;
+}
+
+void FQTermSSH1DES3::decrypt(const u_char *source, u_char *dest, int len) {
+ DES_ncbc_encrypt(source, dest, len, &d_key3, &d_IV3, DES_DECRYPT);
+ DES_ncbc_encrypt(dest, dest, len, &d_key2, &d_IV2, DES_ENCRYPT);
+ DES_ncbc_encrypt(dest, dest, len, &d_key1, &d_IV1, DES_DECRYPT);
+}
+
+void FQTermSSH1DES3::encrypt(const u_char *source, u_char *dest, int len) {
+ DES_ncbc_encrypt(source, dest, len, &d_key1, &d_IV1, DES_ENCRYPT);
+ DES_ncbc_encrypt(dest, dest, len, &d_key2, &d_IV2, DES_DECRYPT);
+ DES_ncbc_encrypt(dest, dest, len, &d_key3, &d_IV3, DES_ENCRYPT);
+}
+
+int FQTermSSH1DES3::getKeySize() const {
+ return 3*DES_KEY_SZ;
+}
+
+int FQTermSSH1DES3::getIVSize() const {
+ return 0;
+}
+
+void FQTermSSH1DES3::setIV(const u_char *data) {
+ memset(d_IV1, 0, sizeof(d_IV1));
+ memset(d_IV2, 0, sizeof(d_IV2));
+ memset(d_IV3, 0, sizeof(d_IV3));
+}
+
+void FQTermSSH1DES3::setKey(const u_char *data) {
+ DES_cblock key;
+ memset(key, 0, sizeof(key));
+ memcpy(key, data, sizeof(key));
+ DES_set_key(&key, &d_key1);
+ data += 8;
+ memset(key, 0, sizeof(key));
+ memcpy(key, data, sizeof(key));
+ DES_set_key(&key, &d_key2);
+ data += 8;
+ memset(key, 0, sizeof(key));
+ memcpy(key, data, sizeof(key));
+ DES_set_key(&key, &d_key3);
+}
+
+
+//==================================================
+// TripleDES-CBC
+//==================================================
+
+FQTermSSH2TripleDESCBC::FQTermSSH2TripleDESCBC() {
+ d_name = "des3-cbc";
+ ctx_ = NULL;
+}
+
+FQTermSSH2TripleDESCBC::~FQTermSSH2TripleDESCBC() {
+ if (ctx_ != NULL) {
+ EVP_CIPHER_CTX_cleanup(ctx_);
+ delete ctx_;
+ }
+}
+
+
+int FQTermSSH2TripleDESCBC::blockSize() const {
+ return 8;
+}
+
+int FQTermSSH2TripleDESCBC::getKeySize() const {
+ return 24;
+}
+
+int FQTermSSH2TripleDESCBC::getIVSize() const {
+ return 8;
+}
+
+void FQTermSSH2TripleDESCBC::setIV(const u_char *data) {
+ memcpy(IV_, data, getIVSize());
+}
+
+void FQTermSSH2TripleDESCBC::setKey(const u_char *data) {
+ memcpy(key_, data, getKeySize());
+}
+
+void FQTermSSH2TripleDESCBC::encrypt(const u_char *source, u_char *dest, int len) {
+ FQ_TRACE("3DES_CBC", 9) << "Start encrypting";
+ FQ_TRACE("3DES_CBC", 9) << "data len:" << len;
+ FQ_TRACE("3DES_CBC", 9) << "Source: \n" << dumpHexString << std::string((char *)source, len);
+
+ int ret = 0;
+ if (ctx_ == NULL) {
+ // Lazy initialization.
+ ctx_ = new EVP_CIPHER_CTX;
+ EVP_CIPHER_CTX_init(ctx_);
+ ret = EVP_CipherInit(ctx_, EVP_des_ede3_cbc(), key_, IV_, 1);
+ FQ_VERIFY(ret == 1);
+ }
+
+ ret = EVP_Cipher(ctx_, dest, source, len);
+
+ FQ_VERIFY(ret == 1);
+
+ FQ_TRACE("3DES_CBC", 9) << "Dest: \n" << dumpHexString << std::string((char *)dest, len);
+
+ FQ_TRACE("3DES_CBC", 9) << "IV:\n" << dumpHexString << std::string((char *)IV_, getIVSize());
+ FQ_TRACE("3DES_CBC", 9) << "key:\n" << dumpHexString << std::string((char *)key_, getKeySize());
+
+}
+
+void FQTermSSH2TripleDESCBC::decrypt(const u_char *source, u_char *dest, int len) {
+ FQ_TRACE("3DES_CBC", 9) << "Start dencrypting";
+ FQ_TRACE("3DES_CBC", 9) << "data len:" << len;
+ FQ_TRACE("3DES_CBC", 9) << "Source: \n" << dumpHexString << std::string((char *)source, len);
+
+ int ret = 0;
+ if (ctx_ == NULL) {
+ // Lazy initialization.
+ ctx_ = new EVP_CIPHER_CTX;
+ EVP_CIPHER_CTX_init(ctx_);
+ ret = EVP_CipherInit(ctx_, EVP_des_ede3_cbc(), key_, IV_, 0);
+ FQ_VERIFY(ret == 1);
+ }
+
+ ret = EVP_Cipher(ctx_, dest, source, len);
+
+ FQ_VERIFY(ret == 1);
+
+ FQ_TRACE("3DES_CBC", 9) << "Dest: \n" << dumpHexString << std::string((char *)dest, len);
+
+ FQ_TRACE("3DES_CBC", 9) << "IV:\n" << dumpHexString << std::string((char *)IV_, getIVSize());
+ FQ_TRACE("3DES_CBC", 9) << "key:\n" << dumpHexString << std::string((char *)key_, getKeySize());
+}
+
+
+} // namespace FQTerm
diff --git a/src/protocol/internal/fqterm_ssh_des.h b/src/protocol/internal/fqterm_ssh_des.h
new file mode 100644
index 0000000..ba153f2
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_des.h
@@ -0,0 +1,74 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_DES_H
+#define FQTERM_SSH_DES_H
+
+#include <openssl/ssl.h>
+#include <openssl/des.h>
+
+#include "fqterm_ssh_cipher.h"
+#include "fqterm_ssh_types.h"
+
+namespace FQTerm {
+
+class FQTermSSH1DES3: public FQTermSSHCipher {
+ private:
+ DES_cblock d_IV1;
+ DES_cblock d_IV2;
+ DES_cblock d_IV3;
+ DES_key_schedule d_key1;
+ DES_key_schedule d_key2;
+ DES_key_schedule d_key3;
+ public:
+ FQTermSSH1DES3();
+
+ virtual int blockSize() const;
+ virtual int getKeySize() const;
+ virtual int getIVSize() const;
+ virtual void setIV(const u_char *data);
+ virtual void setKey(const u_char *data);
+ virtual void encrypt(const u_char *source, u_char *dest, int len);
+ virtual void decrypt(const u_char *source, u_char *dest, int len);
+};
+
+class FQTermSSH2TripleDESCBC: public FQTermSSHCipher {
+ private:
+ unsigned char IV_[8];
+ unsigned char key_[24];
+
+ EVP_CIPHER_CTX *ctx_;
+
+ public:
+ FQTermSSH2TripleDESCBC();
+ ~FQTermSSH2TripleDESCBC();
+
+ virtual int blockSize() const;
+ virtual int getKeySize() const;
+ virtual int getIVSize() const;
+ virtual void setIV(const u_char *data);
+ virtual void setKey(const u_char *data);
+ virtual void encrypt(const u_char *source, u_char *dest, int len);
+ virtual void decrypt(const u_char *source, u_char *dest, int len);
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SSH_DES_H
diff --git a/src/protocol/internal/fqterm_ssh_hash.h b/src/protocol/internal/fqterm_ssh_hash.h
new file mode 100644
index 0000000..b4679f4
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_hash.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_HASH_H
+#define FQTERM_SSH_HASH_H
+
+#include "fqterm_ssh_types.h"
+
+namespace FQTerm {
+
+class FQTermSSHHash {
+protected:
+ int d_digestLength;
+ int digestLength()const {
+ return d_digestLength;
+ }
+
+public:
+ FQTermSSHHash() {
+ d_digestLength = 0;
+ }
+ virtual ~FQTermSSHHash() {}
+
+ virtual void update(u_char *data, int len) = 0;
+ virtual void final(u_char *data) = 0;
+};
+
+} // namespace FQTerm
+
+#endif //FQTERM_SSH_HASH_H
diff --git a/src/protocol/internal/fqterm_ssh_kex.cpp b/src/protocol/internal/fqterm_ssh_kex.cpp
new file mode 100644
index 0000000..d27bf14
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_kex.cpp
@@ -0,0 +1,210 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_ssh_kex.h"
+#include "fqterm_ssh_md5.h"
+#include "fqterm_trace.h"
+
+namespace FQTerm {
+
+FQTermSSHKex::FQTermSSHKex(const char *V_C, const char *V_S) {
+ V_C_ = new char[strlen(V_C) + 1];
+ V_S_ = new char[strlen(V_S) + 1];
+
+ strcpy(V_C_, V_C);
+ strcpy(V_S_, V_S);
+}
+
+FQTermSSHKex::~FQTermSSHKex() {
+ delete[] V_C_;
+ delete[] V_S_;
+}
+
+
+//==============================================================================
+//FQTermSSH1Kex
+//==============================================================================
+
+FQTermSSH1Kex::FQTermSSH1Kex(const char *V_C, const char *V_S)
+ : FQTermSSHKex(V_C, V_S) {
+ is_first_kex_ = true;
+ kex_state_ = FQTermSSH1Kex::BEFORE_PUBLICKEY;
+}
+
+FQTermSSH1Kex::~FQTermSSH1Kex(){}
+
+void FQTermSSH1Kex::initKex(FQTermSSHPacketReceiver *packetReceiver,
+ FQTermSSHPacketSender *packetSender) {
+ packet_receiver_ = packetReceiver;
+ packet_sender_ = packetSender;
+ packet_receiver_->disconnect(this);
+ FQ_VERIFY(connect(packet_receiver_, SIGNAL(packetAvaliable(int)),
+ this, SLOT(handlePacket(int))));
+ kex_state_ = FQTermSSH1Kex::BEFORE_PUBLICKEY;
+ emit reKex();
+}
+
+void FQTermSSH1Kex::handlePacket(int type) {
+ switch (kex_state_) {
+ case FQTermSSH1Kex::BEFORE_PUBLICKEY:
+ makeSessionKey();
+ kex_state_ = FQTermSSH1Kex::SESSIONKEY_SENT;
+ break;
+ case FQTermSSH1Kex::SESSIONKEY_SENT:
+ if (type != SSH1_SMSG_SUCCESS) {
+ emit kexError(tr("Kex exchange failed!"));
+ break;
+ }
+ emit kexOK();
+ kex_state_ = FQTermSSH1Kex::KEYEX_OK;
+ break;
+ case FQTermSSH1Kex::KEYEX_OK:
+ break;
+ }
+}
+
+void FQTermSSH1Kex::makeSessionKey() {
+ int i;
+ BIGNUM *key;
+ u_int32_t rand_val;
+ int bits;
+ int rbits;
+
+ if (packet_receiver_->packetType() != SSH1_SMSG_PUBLIC_KEY) {
+ emit kexError(tr("startKex: First packet is not public key"));
+ return ;
+ }
+ packet_receiver_->getRawData((char*)cookie_, 8);
+
+ // Get the public key.
+ server_key_ = new FQTermSSHRSA;
+ bits = packet_receiver_->getInt();
+ packet_receiver_->getBN(server_key_->d_rsa->e);
+ packet_receiver_->getBN(server_key_->d_rsa->n);
+
+ rbits = BN_num_bits(server_key_->d_rsa->n);
+ if (bits != rbits) {
+ FQ_TRACE("sshkex", 0) << "Warning: Server lies about "
+ << "size of server public key: "
+ << "actual size: " << rbits
+ << " vs. anounced: " << bits;
+ FQ_TRACE("sshkex", 0) << "Warning: This may be due to "
+ << "an old implementation of ssh.";
+ }
+
+ // Get the host key.
+ host_key_ = new FQTermSSHRSA;
+ bits = packet_receiver_->getInt();
+ packet_receiver_->getBN(host_key_->d_rsa->e);
+ packet_receiver_->getBN(host_key_->d_rsa->n);
+
+ rbits = BN_num_bits(host_key_->d_rsa->n);
+ if (bits != rbits) {
+ FQ_TRACE("sshkex", 0) << "Warning: Server lies about "
+ << "size of server public key: "
+ << "actual size: " << rbits
+ << " vs. anounced: " << bits;
+ FQ_TRACE("sshkex", 0) << "Warning: This may be due to "
+ << "an old implementation of ssh.";
+ }
+
+ // Get protocol flags.
+ server_flag_ = packet_receiver_->getInt();
+ ciphers_ = packet_receiver_->getInt();
+ auth_ = packet_receiver_->getInt();
+
+ if ((ciphers_ &(1 << SSH_CIPHER_3DES)) == 0) {
+ FQ_VERIFY(false); // server do not support my cipher
+ }
+
+ makeSessionId();
+
+ // Generate an encryption key for the session. The key is a 256 bit
+ // random number, interpreted as a 32-byte key, with the least
+ // significant 8 bits being the first byte of the key.
+
+ for (i = 0; i < 32; i++) {
+ if (i % 4 == 0) {
+ rand_val = rand();
+ }
+
+ session_key_[i] = (rand_val &0xff);
+ rand_val >>= 8;
+ }
+
+ key = BN_new();
+
+ BN_set_word(key, 0);
+ for (i = 0; i < 32; i++) {
+ BN_lshift(key, key, 8);
+ if (i < 16) {
+ BN_add_word(key, session_key_[i] ^ session_id_[i]);
+ } else {
+ BN_add_word(key, session_key_[i]);
+ }
+ }
+
+ if (BN_cmp(server_key_->d_rsa->n, host_key_->d_rsa->n) < 0) {
+ server_key_->publicEncrypt(key, key);
+ host_key_->publicEncrypt(key, key);
+ } else {
+ host_key_->publicEncrypt(key, key);
+ server_key_->publicEncrypt(key, key);
+ }
+
+ delete host_key_;
+ delete server_key_;
+
+ packet_sender_->startPacket(SSH1_CMSG_SESSION_KEY);
+ packet_sender_->putByte(SSH_CIPHER_3DES);
+ packet_sender_->putRawData((const char*)cookie_, 8);
+ packet_sender_->putBN(key);
+
+ BN_free(key);
+
+ packet_sender_->putInt(1);
+ packet_sender_->write();
+
+ emit startEncryption(session_key_);
+}
+
+void FQTermSSH1Kex::makeSessionId() {
+ u_char *p;
+ FQTermSSHMD5 *md5;
+ int servlen, hostlen;
+
+ md5 = new FQTermSSHMD5;
+ servlen = BN_num_bytes(server_key_->d_rsa->n);
+ hostlen = BN_num_bytes(host_key_->d_rsa->n);
+
+ p = new u_char[servlen + hostlen];
+
+ BN_bn2bin(host_key_->d_rsa->n, p);
+ BN_bn2bin(server_key_->d_rsa->n, p + hostlen);
+ md5->update(p, servlen + hostlen);
+ md5->update(cookie_, 8);
+ md5->final(session_id_);
+ delete md5;
+ delete [] p;
+}
+
+} // namespace FQTerm
+
+#include "fqterm_ssh_kex.moc"
diff --git a/src/protocol/internal/fqterm_ssh_kex.h b/src/protocol/internal/fqterm_ssh_kex.h
new file mode 100644
index 0000000..b2f9c56
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_kex.h
@@ -0,0 +1,100 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_KEX_H
+#define FQTERM_SSH_KEX_H
+
+#include <openssl/bn.h>
+#include <QObject>
+
+#include "fqterm_ssh_types.h"
+#include "fqterm_ssh_rsa.h"
+#include "fqterm_ssh_packet.h"
+#include "fqterm_ssh_const.h"
+
+namespace FQTerm {
+
+class FQTermSSHPacketReceiver;
+class FQTermSSHPacketSender;
+
+class FQTermSSHKex: public QObject {
+ Q_OBJECT;
+protected:
+ FQTermSSHPacketReceiver *packet_receiver_;
+ FQTermSSHPacketSender *packet_sender_;
+
+ char *V_C_;
+ char *V_S_;
+public:
+ // Init with
+ // string V_C, the client's identification string (CR and LF
+ // excluded)
+ // string V_S, the server's identification string (CR and LF
+ // excluded)
+ FQTermSSHKex(const char *V_C, const char *V_S);
+ virtual ~FQTermSSHKex();
+
+ virtual void initKex(FQTermSSHPacketReceiver *packetReceiver,
+ FQTermSSHPacketSender *outputSender) = 0;
+
+public slots:
+ virtual void handlePacket(int type) = 0;
+
+signals:
+ void kexOK();
+ void reKex();
+ void kexError(QString);
+
+ void startEncryption(const u_char *sessionkey);
+
+};
+
+class FQTermSSH1Kex: public FQTermSSHKex {
+ Q_OBJECT;
+private:
+ enum FQTermSSH1KexState {
+ BEFORE_PUBLICKEY, SESSIONKEY_SENT, KEYEX_OK
+ } kex_state_;
+
+ bool is_first_kex_;
+
+ FQTermSSHRSA *host_key_;
+ FQTermSSHRSA *server_key_;
+
+ u_char cookie_[8];
+ int server_flag_, ciphers_, auth_;
+ u_char session_id_[16];
+ u_char session_key_[32];
+
+ void makeSessionId();
+ void makeSessionKey();
+
+public:
+ FQTermSSH1Kex(const char *V_C, const char *V_S);
+ ~FQTermSSH1Kex();
+ virtual void initKex(FQTermSSHPacketReceiver *packetReceiver,
+ FQTermSSHPacketSender *outputSender);
+
+ virtual void handlePacket(int type);
+};
+
+} // namespace FQTerm
+
+#endif //FQTERM_SSH_KEX_H
diff --git a/src/protocol/internal/fqterm_ssh_mac.cpp b/src/protocol/internal/fqterm_ssh_mac.cpp
new file mode 100644
index 0000000..e2d345f
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_mac.cpp
@@ -0,0 +1,53 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+
+#include "fqterm_trace.h"
+#include "fqterm_ssh_mac.h"
+#include "fqterm_ssh_packet.h"
+
+namespace FQTerm {
+
+void FQTermSSHSHA1::setKey(const unsigned char *key) {
+ memcpy(key_, key, keySize());
+}
+
+int FQTermSSHSHA1::keySize() const {
+ return SHA_DIGEST_LENGTH;
+}
+
+int FQTermSSHSHA1::digestSize() const {
+ return SHA_DIGEST_LENGTH;
+}
+
+void FQTermSSHSHA1::getDigest(const unsigned char *data, int len, unsigned char *digest) const {
+ unsigned int tmp;
+ HMAC(EVP_sha1(), key_, SHA_DIGEST_LENGTH, data, len, digest, &tmp);
+
+ FQ_TRACE("SHA1", 9) << "Key: \n" << dumpHexString << std::string((char *)key_, SHA_DIGEST_LENGTH);
+ FQ_TRACE("SHA1", 9) << "data len:" << len;
+ FQ_TRACE("SHA1", 9) << "data:\n" << dumpHexString << std::string((char *)data, len);
+ FQ_TRACE("SHA1", 9) << "digest len:" << tmp;
+ FQ_TRACE("SHA1", 9) << "digest:\n" << dumpHexString << std::string((char *)digest, tmp);
+}
+
+} // namespace FQTerm
diff --git a/src/protocol/internal/fqterm_ssh_mac.h b/src/protocol/internal/fqterm_ssh_mac.h
new file mode 100644
index 0000000..545909c
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_mac.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_MAC_H
+#define FQTERM_SSH_MAC_H
+
+#include <openssl/sha.h>
+
+namespace FQTerm {
+
+class FQTermSSHMac {
+public:
+ FQTermSSHMac() {}
+ virtual ~FQTermSSHMac() {}
+ virtual void setKey(const unsigned char *key) = 0;
+ virtual int keySize() const = 0;
+ virtual int digestSize() const = 0;
+ virtual void getDigest(const unsigned char *data, int len, unsigned char *digest) const = 0;
+};
+
+const int FQTERM_SSH_MAC_NONE = 0;
+const int FQTERM_SSH_HMAC_SHA1 = 1;
+
+class FQTermSSHSHA1: public FQTermSSHMac {
+ unsigned char key_[SHA_DIGEST_LENGTH];
+
+public:
+ virtual void setKey(const unsigned char *key);
+ virtual int keySize() const;
+ virtual int digestSize() const;
+ virtual void getDigest(const unsigned char *data, int len, unsigned char *digest) const;
+};
+
+
+} // namespace FQTerm
+
+#endif // FQTERM_SSH_MAC_H
diff --git a/src/protocol/internal/fqterm_ssh_md5.cpp b/src/protocol/internal/fqterm_ssh_md5.cpp
new file mode 100644
index 0000000..10713e9
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_md5.cpp
@@ -0,0 +1,36 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_ssh_md5.h"
+
+namespace FQTerm {
+
+//==============================================================================
+//FQTermSSHMD5
+//==============================================================================
+void FQTermSSHMD5::final(u_char *digest) {
+ MD5_Final(digest, &d_md5);
+}
+
+void FQTermSSHMD5::update(u_char *data, int len) {
+ MD5_Update(&d_md5, data, len);
+}
+
+} // namespace FQTerm
diff --git a/src/protocol/internal/fqterm_ssh_md5.h b/src/protocol/internal/fqterm_ssh_md5.h
new file mode 100644
index 0000000..abb8127
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_md5.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_MD5_H
+#define FQTERM_SSH_MD5_H
+
+#include <stdio.h>
+
+#include <openssl/md5.h>
+
+#include "fqterm_ssh_types.h"
+#include "fqterm_ssh_hash.h"
+
+namespace FQTerm {
+
+class FQTermSSHMD5: public FQTermSSHHash {
+protected:
+ MD5_CTX d_md5;
+public:
+ FQTermSSHMD5()
+ : FQTermSSHHash() {
+ d_digestLength = 16;
+ MD5_Init(&d_md5);
+ }
+ virtual ~FQTermSSHMD5() {}
+
+ void update(u_char *data, int len);
+ void final(u_char *digest);
+};
+
+} // namespace FQTerm
+
+#endif //FQTERM_SSH_MD5_H
diff --git a/src/protocol/internal/fqterm_ssh_packet.cpp b/src/protocol/internal/fqterm_ssh_packet.cpp
new file mode 100644
index 0000000..9c4ff6c
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_packet.cpp
@@ -0,0 +1,242 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_trace.h"
+#include "fqterm_ssh_buffer.h"
+#include "fqterm_ssh_packet.h"
+#include "fqterm_ssh_des.h"
+
+#include "fqterm_serialization.h"
+#include "crc32.h"
+
+namespace FQTerm {
+
+//==============================================================================
+//FQTermSSHPacketSender
+//==============================================================================
+
+FQTermSSHPacketSender::FQTermSSHPacketSender() {
+ buffer_ = new FQTermSSHBuffer(1024);
+ output_buffer_ = new FQTermSSHBuffer(1024);
+
+ is_encrypt_ = false;
+ cipher_type_ = SSH_CIPHER_NONE;
+ cipher_ = NULL;
+ setEncryptionType(SSH_CIPHER_3DES);
+
+ is_mac_ = false;
+ mac_type_ = FQTERM_SSH_MAC_NONE;
+ mac_ = NULL;
+
+ is_compressed_ = false;
+
+ sequence_no_ = 0;
+}
+
+FQTermSSHPacketSender::~FQTermSSHPacketSender() {
+ delete buffer_;
+ delete output_buffer_;
+ if (is_encrypt_) {
+ delete cipher_;
+ }
+}
+
+void FQTermSSHPacketSender::putRawData(const char *data, int len) {
+ buffer_->putRawData(data, len);
+}
+
+void FQTermSSHPacketSender::putByte(int data) {
+ buffer_->putByte(data);
+}
+
+void FQTermSSHPacketSender::putInt(u_int data) {
+ buffer_->putInt(data);
+}
+
+void FQTermSSHPacketSender::putString(const char *string, int len) {
+ buffer_->putString(string, len);
+}
+
+void FQTermSSHPacketSender::putBN(BIGNUM *bn) {
+ buffer_->putSSH1BN(bn);
+}
+
+void FQTermSSHPacketSender::putBN2(BIGNUM *bn) {
+ buffer_->putSSH2BN(bn);
+}
+
+void FQTermSSHPacketSender::startPacket(int pkt_type) {
+ buffer_->clear();
+ buffer_->putByte(pkt_type);
+}
+
+void FQTermSSHPacketSender::write() {
+ makePacket();
+ emit dataToWrite();
+}
+
+void FQTermSSHPacketSender::setEncryptionType(int cipherType) {
+ cipher_type_ = cipherType;
+
+ delete cipher_;
+ cipher_ = NULL;
+
+ switch (cipher_type_) {
+ case SSH_CIPHER_3DES:
+ cipher_ = new FQTermSSH1DES3;
+ break;
+ }
+}
+
+void FQTermSSHPacketSender::startEncryption(const u_char *key, const u_char *IV) {
+ is_encrypt_ = true;
+ cipher_->setIV(IV);
+ cipher_->setKey(key);
+}
+
+void FQTermSSHPacketSender::resetEncryption() {
+ is_encrypt_ = false;
+}
+
+void FQTermSSHPacketSender::setMacType(int macType) {
+ mac_type_ = macType;
+
+ delete mac_;
+ mac_ = NULL;
+
+ switch (mac_type_) {
+ case FQTERM_SSH_HMAC_SHA1:
+ mac_ = new FQTermSSHSHA1;
+ break;
+ }
+}
+
+void FQTermSSHPacketSender::startMac(const u_char *key) {
+ is_mac_ = true;
+ mac_->setKey(key);
+}
+
+void FQTermSSHPacketSender::resetMac() {
+ is_mac_ = false;
+}
+
+//==============================================================================
+//FQTermSSHPacketReceiver
+//==============================================================================
+
+FQTermSSHPacketReceiver::FQTermSSHPacketReceiver() {
+ buffer_ = new FQTermSSHBuffer(1024);
+
+ is_decrypt_ = false;
+ cipher_type_ = SSH_CIPHER_NONE;
+ cipher_ = NULL;
+ setEncryptionType(SSH_CIPHER_3DES);
+
+ is_mac_ = false;
+ mac_type_ = FQTERM_SSH_MAC_NONE;
+ mac_ = NULL;
+
+ is_compressed_ = false;
+
+ sequence_no_ = 0;
+}
+
+FQTermSSHPacketReceiver::~FQTermSSHPacketReceiver() {
+ delete buffer_;
+ if (is_decrypt_) {
+ delete cipher_;
+ }
+}
+
+void FQTermSSHPacketReceiver::getRawData(char *data, int length) {
+ buffer_->getRawData(data, length);
+}
+
+u_char FQTermSSHPacketReceiver::getByte() {
+ return buffer_->getByte();
+}
+
+u_int FQTermSSHPacketReceiver::getInt() {
+ return buffer_->getInt();
+}
+
+void *FQTermSSHPacketReceiver::getString(int *length) {
+ return buffer_->getString(length);
+}
+
+void FQTermSSHPacketReceiver::getBN(BIGNUM *bignum) {
+ buffer_->getSSH1BN(bignum);
+}
+
+void FQTermSSHPacketReceiver::getBN2(BIGNUM *bignum) {
+ buffer_->getSSH2BN(bignum);
+}
+
+void FQTermSSHPacketReceiver::consume(int len) {
+ buffer_->consume(len);
+}
+
+void FQTermSSHPacketReceiver::setEncryptionType(int cipherType) {
+ cipher_type_ = cipherType;
+
+ delete cipher_;
+ cipher_ = NULL;
+
+ switch (cipher_type_) {
+ case SSH_CIPHER_3DES:
+ cipher_ = new FQTermSSH1DES3;
+ break;
+ }
+}
+
+void FQTermSSHPacketReceiver::startEncryption(const u_char *key, const u_char *IV) {
+ is_decrypt_ = true;
+ cipher_->setIV(IV);
+ cipher_->setKey(key);
+}
+
+void FQTermSSHPacketReceiver::resetEncryption() {
+ is_decrypt_ = false;
+}
+
+void FQTermSSHPacketReceiver::setMacType(int macType) {
+ mac_type_ = macType;
+ delete mac_;
+ mac_ = NULL;
+
+ switch (mac_type_) {
+ case FQTERM_SSH_HMAC_SHA1:
+ mac_ = new FQTermSSHSHA1;
+ break;
+ }
+}
+
+void FQTermSSHPacketReceiver::startMac(const u_char *key) {
+ is_mac_ = true;
+ mac_->setKey(key);
+}
+
+void FQTermSSHPacketReceiver::resetMac() {
+ is_mac_ = false;
+}
+
+} // namespace FQTerm
+
+#include "fqterm_ssh_packet.moc"
diff --git a/src/protocol/internal/fqterm_ssh_packet.h b/src/protocol/internal/fqterm_ssh_packet.h
new file mode 100644
index 0000000..ed5a488
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_packet.h
@@ -0,0 +1,148 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_PACKET_H
+#define FQTERM_SSH_PACKET_H
+
+#include <openssl/bn.h>
+
+#include <QObject>
+
+#include "fqterm_ssh_types.h"
+#include "fqterm_ssh_buffer.h"
+#include "fqterm_ssh_mac.h"
+#include "fqterm_ssh_cipher.h"
+#include "fqterm_serialization.h"
+
+namespace FQTerm {
+
+class FQTermSSHPacketSender: public QObject {
+ Q_OBJECT;
+ public:
+ FQTermSSHBuffer *output_buffer_;
+ FQTermSSHBuffer *buffer_;
+
+ FQTermSSHPacketSender();
+ virtual ~FQTermSSHPacketSender();
+
+ void startPacket(int pkt_type);
+ void putByte(int data);
+ void putInt(u_int data);
+ void putString(const char *string, int len = -1);
+ void putRawData(const char *data, int length);
+ void putBN(BIGNUM *bignum);
+ void putBN2(BIGNUM *bignum);
+ void write();
+
+ int getIVSize() const { return cipher_->getIVSize();}
+ int getKeySize() const { return cipher_->getKeySize();}
+ int getMacKeySize() const { return mac_->keySize();}
+
+ public slots:
+ virtual void setEncryptionType(int cipherType);
+ void startEncryption(const u_char *key, const u_char *IV = NULL);
+ void resetEncryption();
+
+ void setMacType(int macType);
+ void startMac(const u_char *sessionkey);
+ void resetMac();
+
+ void enableCompress(int enable) {is_compressed_ = enable;};
+
+ signals:
+ void dataToWrite();
+
+ protected:
+ bool is_encrypt_;
+ int cipher_type_;
+ FQTermSSHCipher *cipher_;
+
+ bool is_mac_;
+ int mac_type_;
+ FQTermSSHMac *mac_;
+
+ bool is_compressed_;
+
+ u_int32_t sequence_no_;
+
+ virtual void makePacket() = 0;
+};
+
+class FQTermSSHPacketReceiver: public QObject {
+ Q_OBJECT;
+ public:
+ FQTermSSHBuffer *buffer_;
+
+ FQTermSSHPacketReceiver();
+ virtual ~FQTermSSHPacketReceiver();
+
+ int packetType()const {
+ return packet_type_;
+ }
+
+ u_char getByte();
+ u_int getInt();
+ void *getString(int *length = NULL);
+ void getRawData(char *data, int length);
+ void getBN(BIGNUM *bignum);
+ void getBN2(BIGNUM *bignum);
+ void consume(int len);
+
+ virtual int packetDataLen() const { return real_data_len_;}
+ int getIVSize() const { return cipher_->getIVSize();}
+ int getKeySize() const { return cipher_->getKeySize();}
+ int getMacKeySize() const { return mac_->keySize();}
+
+ virtual void parseData(FQTermSSHBuffer *input) = 0;
+ public slots:
+ virtual void setEncryptionType(int cipherType);
+ void startEncryption(const u_char *key, const u_char *IV = NULL);
+ void resetEncryption();
+
+ void setMacType(int macType);
+ void startMac(const u_char *sessionkey);
+ void resetMac();
+
+ void enableCompress(int enable) {is_compressed_ = enable;};
+
+ signals:
+ void packetAvaliable(int type);
+ void packetError(QString);
+
+ protected:
+ bool is_decrypt_;
+ int cipher_type_;
+ FQTermSSHCipher *cipher_;
+
+ bool is_mac_;
+ int mac_type_;
+ FQTermSSHMac *mac_;
+
+ bool is_compressed_;
+
+ int packet_type_;
+ int real_data_len_;
+
+ u_int32_t sequence_no_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SSH_PACKET
diff --git a/src/protocol/internal/fqterm_ssh_pubkey.h b/src/protocol/internal/fqterm_ssh_pubkey.h
new file mode 100644
index 0000000..0de957c
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_pubkey.h
@@ -0,0 +1,37 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_PUB_KEY_H
+#define FQTERM_SSH_PUB_KEY_H
+
+#include <openssl/bn.h>
+
+namespace FQTerm {
+
+class FQTermSSHPubKey {
+public:
+ FQTermSSHPubKey() {}
+ virtual ~FQTermSSHPubKey() {}
+ virtual void publicEncrypt(BIGNUM *, BIGNUM*) = 0;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SSH_PUB_KEY_H
diff --git a/src/protocol/internal/fqterm_ssh_rsa.cpp b/src/protocol/internal/fqterm_ssh_rsa.cpp
new file mode 100644
index 0000000..dd36898
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_rsa.cpp
@@ -0,0 +1,67 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QGlobalStatic>
+
+#include "fqterm_trace.h"
+#include "fqterm_ssh_types.h"
+#include "fqterm_ssh_rsa.h"
+
+namespace FQTerm {
+
+FQTermSSHRSA::FQTermSSHRSA() {
+ d_rsa = RSA_new();
+ d_rsa->n = BN_new();
+ d_rsa->e = BN_new();
+}
+
+FQTermSSHRSA::~FQTermSSHRSA() {
+ if (d_rsa != NULL) {
+ RSA_free(d_rsa);
+ }
+}
+
+void FQTermSSHRSA::publicEncrypt(BIGNUM *out, BIGNUM *in) {
+ u_char *inbuf, *outbuf;
+ int len, ilen, olen;
+
+ if (BN_num_bits(d_rsa->e) < 2 || !BN_is_odd(d_rsa->e)) {
+ FQ_VERIFY(false); // public_encrypt() exponent too small or not odd.
+ }
+
+ olen = BN_num_bytes(d_rsa->n);
+ outbuf = new u_char[olen];
+
+ ilen = BN_num_bytes(in);
+ inbuf = new u_char[ilen];
+ BN_bn2bin(in, inbuf);
+
+ if ((len = RSA_public_encrypt(ilen, inbuf, outbuf, d_rsa, RSA_PKCS1_PADDING)) <= 0) {
+ //RSA_PKCS1_PADDING = 1
+ FQ_VERIFY(false); // "rsa_public_encrypt() failed.
+ }
+
+ BN_bin2bn(outbuf, len, out);
+
+ delete [] outbuf;
+ delete [] inbuf;
+}
+
+} // namespace FQTerm
diff --git a/src/protocol/internal/fqterm_ssh_rsa.h b/src/protocol/internal/fqterm_ssh_rsa.h
new file mode 100644
index 0000000..bfe89ce
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_rsa.h
@@ -0,0 +1,41 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_RSA_H
+#define FQTERM_SSH_RSA_H
+
+#include <openssl/rsa.h>
+
+#include "fqterm_ssh_pubkey.h"
+
+namespace FQTerm {
+
+class FQTermSSHRSA: public FQTermSSHPubKey {
+public:
+ RSA *d_rsa;
+ FQTermSSHRSA();
+ virtual ~FQTermSSHRSA();
+
+ virtual void publicEncrypt(BIGNUM *, BIGNUM*);
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SSH_RSA_H
diff --git a/src/protocol/internal/fqterm_ssh_types.h b/src/protocol/internal/fqterm_ssh_types.h
new file mode 100644
index 0000000..c10bfac
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_types.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_TYPES_H
+#define FQTERM_SSH_TYPES_H
+
+#include <QGlobalStatic>
+#if !defined(Q_OS_WIN32) && !defined(_OS_WIN32_)
+#include <sys/types.h>
+#else
+typedef unsigned char u_char;
+typedef unsigned short u_short;
+typedef unsigned int u_int;
+typedef unsigned long u_long;
+
+#ifdef QT3_SUPPORT
+typedef Q_UINT32 u_int32_t;
+typedef Q_UINT64 u_int64_t;
+#else
+typedef quint32 u_int32_t;
+typedef quint64 u_int64_t;
+#endif // QT3_SUPPORT
+
+#endif // Q_OS_WIN32
+
+#endif // FQTERM_SSH_TYPES_H
diff --git a/src/terminal/CMakeLists.txt b/src/terminal/CMakeLists.txt
new file mode 100644
index 0000000..c3cf3db
--- /dev/null
+++ b/src/terminal/CMakeLists.txt
@@ -0,0 +1,46 @@
+set(export_SRCS
+ fqterm_buffer.h
+ fqterm_session.h
+ fqterm_text_line.h
+ fqterm_session.cpp
+ fqterm_buffer.cpp
+ fqterm_text_line.cpp
+)
+
+set(internal_SRCS
+ internal/fqterm_decode.h
+ internal/fqterm_telnet.h
+ internal/fqterm_zmodem.h
+ internal/fqterm_decode.cpp
+ internal/fqterm_telnet.cpp
+ internal/fqterm_zmodem.cpp
+)
+
+include_directories(
+ ${QT_INCLUDE_DIR}
+ ${QT_QTCORE_INCLUDE_DIR}
+ ${QT_QTGUI_INCLUDE_DIR}
+ ${QT_QTNETWORK_INCLUDE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/internal
+ ${CMAKE_CURRENT_SOURCE_DIR}/../common
+ ${CMAKE_CURRENT_SOURCE_DIR}/../utilities
+ ${CMAKE_CURRENT_SOURCE_DIR}/../protocol
+)
+
+QT4_AUTOMOC(
+ ${export_SRCS}
+ ${internal_SRCS}
+)
+
+add_library(fqterm_terminal
+ ${export_SRCS}
+ ${internal_SRCS}
+)
+
+add_dependencies(fqterm_terminal
+ fqterm_common
+ fqterm_protocol
+ fqterm_utilities
+)
diff --git a/src/terminal/fqterm_buffer.cpp b/src/terminal/fqterm_buffer.cpp
new file mode 100644
index 0000000..c00e079
--- /dev/null
+++ b/src/terminal/fqterm_buffer.cpp
@@ -0,0 +1,998 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <algorithm>
+#include <map>
+#include <vector>
+
+#include <QString>
+#include <QRect>
+#include <QRegExp>
+
+#include "fqterm.h"
+#include "common.h"
+#include "fqterm_buffer.h"
+#include "fqterm_text_line.h"
+
+namespace FQTerm {
+
+typedef std::vector<int> TabStops;
+
+/* staight from linux/drivers/char/consolemap.c, GNU GPL:ed */
+static const UTF16 VT_SPECIAL_GRAPHICS_TABLE[256]={
+ /* VT100 graphics mapped to Unicode */
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
+ 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
+ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
+ 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
+ 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
+ 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
+ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+ 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
+ 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+ 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
+ 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
+ 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x00a0,
+ 0x25c6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1,
+ 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x23ba,
+ 0x23bb, 0x2500, 0x23bc, 0x23bd, 0x251c, 0x2524, 0x2534, 0x252c,
+ 0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7, 0x007f,
+ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+ 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
+ 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
+ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
+ 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
+ 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
+ 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
+ 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
+ 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
+ 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
+ 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
+ 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
+ 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
+};
+
+FQTermBuffer::FQTermBuffer(int column, int row, int max_hist_line, bool is_bbs) {
+ tab_stops_ = new TabStops;
+ num_rows_ = row;
+ num_columns_ = column;
+ max_num_hist_lines_ = max_hist_line;
+ is_bbs_ = is_bbs;
+
+ num_hist_lines_ = 0;
+
+ while (text_lines_.count() < num_rows_) {
+ text_lines_.append(new FQTermTextLine(num_columns_));
+ }
+
+ top_row_ = 0;
+ bottom_row_ = num_rows_ - 1;
+
+ is_g0_used_ = true;
+
+ is_insert_mode_ = false;
+ is_ansi_mode_ = true;
+ is_newline_mode_ = false;
+ is_cursor_mode_ = false;
+ is_numeric_mode_ = true;
+ is_origin_mode_ = false;
+ is_autowrap_mode_ = false;
+ is_autorepeat_mode_ = true;
+ is_lightbg_mode_ = false;
+
+ selection_start_ = QPoint(-1, -1);
+ selection_end_ = QPoint(-1, -1);
+}
+
+FQTermBuffer::~FQTermBuffer(){
+ foreach(FQTermTextLine *line, text_lines_) {
+ delete line;
+ }
+
+ delete (TabStops *)tab_stops_;
+}
+
+FQTermBuffer::Caret::Caret()
+ : column_(0),
+ row_(0),
+ color_(NO_COLOR),
+ attr_(NO_ATTR),
+ G0_(ASCII_SET),
+ G1_(ASCII_SET) {
+}
+
+void FQTermBuffer::setTermSize(int col, int row) {
+ FQ_TRACE("term", 3) << "Change term size to "
+ << col << "x" << row;
+
+ if (num_columns_ == col && num_rows_ == row) {
+ return;
+ }
+
+ clearSelect();
+
+ if (num_rows_ < row) {
+ for (int i = 0; i < row - num_rows_; i++) {
+ text_lines_.append(new FQTermTextLine(col));
+ }
+ } else if (num_rows_ > row) {
+ for (int i = 0; i < num_rows_ - row; i++) {
+ delete text_lines_.takeLast();
+ }
+ }
+
+ num_columns_ = col;
+ num_rows_ = row;
+
+ top_row_ = 0;
+ bottom_row_ = num_rows_ - 1;
+
+ // TODO: how about saved caret column?
+ // TODO: why make last saved equal to current position?
+ last_saved_caret_.row_ = caret_.row_ = qMin(caret_.row_, row - 1);
+
+ for (int i = 0; i < text_lines_.size(); ++i) {
+ text_lines_.at(i)->setMaxCellCount(num_columns_);
+ }
+
+// this->clearArea(0, 0, num_columns_, num_rows_, 0, 0);
+ // this->moveCaretTo(0, 0);
+
+ moveCaretTo(qMin(caret_.column_, col - 1), qMin(caret_.row_, row - 1));
+
+ emit onSetTermSize(col, row);
+ emit termSizeChanged(num_columns_, num_rows_);
+}
+
+int FQTermBuffer::getNumColumns() const {
+ return num_columns_;
+}
+
+int FQTermBuffer::getNumRows() const {
+ return num_rows_;
+}
+
+int FQTermBuffer::getNumLines() const {
+ return num_rows_ + num_hist_lines_;
+}
+
+const FQTermTextLine *FQTermBuffer::getTextLineInBuffer(int line_index) const {
+ return text_lines_.value(line_index, NULL);
+}
+
+const FQTermTextLine *FQTermBuffer::getTextLineInTerm(int line_index) const {
+ return text_lines_.value(line_index + num_hist_lines_, NULL);
+}
+
+void FQTermBuffer::setCurrentAttr(unsigned char color, unsigned char attr) {
+ caret_.color_ = color;
+ caret_.attr_ = attr;
+}
+
+void FQTermBuffer::writeText(const QString &str, int charstate) {
+
+ QString cstr = str;
+
+ FQ_TRACE("term", 8) << "Add text: \"" << cstr << "\"";
+
+#if 0
+ if ((is_g0_used_ && caret_.G0_ == SPECIAL_GRAPHICS) ||
+ (!is_g0_used_ && caret_.G1_ == SPECIAL_GRAPHICS)) {
+
+ // FIXME: will this break the utf-16 sequence?
+ for (int i = 0; i < cstr.size(); ++i) {
+ if (cstr[i] >= 0137 && cstr[i] <= 0176) {
+ cstr[i] = VT_SPECIAL_GRAPHICS_TABLE[cstr.at(i).unicode()];
+ }
+ }
+ }
+#endif
+
+ // Insert the str into the buffer. Different pieces of text might be
+ // written into different lines.
+ while (!cstr.isEmpty()) {
+ FQTermTextLine *line = text_lines_.value(num_hist_lines_ + caret_.row_, NULL);
+
+ if (line == NULL) {
+ FQ_TRACE("error", 0) << "Error: setBuffer null line";
+ return ;
+ }
+
+ if (charstate & FQTermTextLine::SECONDPART) {
+ moveCaretOffset(-1, 0);
+ }
+
+ if (caret_.column_ >= (int)line->getMaxCellCount()) {
+ // move the caret to the next line.
+ moveCaretTo(0, caret_.row_ + 1, true);
+ continue;
+ }
+
+ if (caret_.column_ > (int)line->getWidth()) {
+ line->appendWhiteSpace(caret_.column_ - line->getWidth());
+ }
+
+ unsigned cell_begin = line->getCellBegin(caret_.column_);
+ int max_width = line->getMaxCellCount() - cell_begin;
+ int element_consumed = 0;
+ int width = get_str_width((const UTF16 *)cstr.data(), cstr.size(),
+ max_width, element_consumed);
+
+ if (width < 0) {
+ break;
+ }
+
+ if (is_insert_mode_) {
+ // FIXEME: How to move cursor if the entire line is wider than
+ // line->getMaxCellCount() after insertion?
+ line->insertText((UTF16 *)cstr.data(), element_consumed, cell_begin,
+ caret_.color_, caret_.attr_, charstate);
+ if ((int)line->getWidth() > num_columns_) {
+ line->deleteText(num_columns_, line->getWidth());
+ }
+ } else {
+ line->replaceText((UTF16 *)cstr.data(), element_consumed,
+ cell_begin, qMin(cell_begin + width, line->getWidth()),
+ caret_.color_, caret_.attr_, charstate);
+ }
+ moveCaretOffset(width, 0);
+
+ if (element_consumed == 0)
+ {
+ element_consumed = 1;
+ }
+
+ if (element_consumed == cstr.size()) {
+ break;
+ }
+
+ cstr.remove(0, element_consumed);
+ }
+}
+
+void FQTermBuffer::lineFeed() {
+ FQ_TRACE("term", 8) << "add a new line";
+ if (caret_.row_ == bottom_row_)
+ scrollLinesInTerm(top_row_, 1);
+ if (is_newline_mode_) {
+ moveCaretOffset(-caret_.column_, 1);
+ } else {
+ moveCaretOffset(0, 1);
+ }
+}
+
+void FQTermBuffer::tab() {
+ FQ_TRACE("term", 8) << "add a tab";
+ int x = getTabStop(caret_.column_);
+
+ moveCaretTo(x, caret_.row_);
+}
+
+int FQTermBuffer::getTabStop(int column) {
+
+ std::vector<int> &tabs = *(TabStops *)tab_stops_;
+
+ if (tabs.size() == 0) {
+ int res = ((caret_.column_) / 8 + 1) * 8;
+ return (res < num_columns_) ? res : num_columns_ - 1;
+ }
+
+ std::vector<int>::iterator it =
+ std::upper_bound(tabs.begin(), tabs.end(), column);
+
+ int res = num_columns_ - 1;
+
+ if (it != tabs.end() && *it < res) {
+ res = *it;
+ }
+
+ if (res > num_columns_ - 1) {
+ res = num_columns_ - 1;
+ }
+
+ return res;
+}
+
+void FQTermBuffer::addTabStop() {
+ // FIXME: what if the caret is located beyond the term temporarily.
+ int x = caret_.column_;
+
+ std::vector<int> &tabs = *(TabStops *)tab_stops_;
+
+ std::vector<int>::iterator it =
+ std::lower_bound(tabs.begin(), tabs.end(), x);
+
+ if (it == tabs.end() || *it != x) {
+ tabs.insert(it, x);
+ }
+}
+
+void FQTermBuffer::clearTabStop(bool clear_all) {
+ // FIXME: what if the caret is located beyond the term temporarily.
+ std::vector<int> &tabs = *(TabStops *)tab_stops_;
+
+ if (clear_all) {
+ tabs.clear();
+ return;
+ }
+
+ int x = caret_.column_;
+
+ std::vector<int>::iterator it =
+ std::lower_bound(tabs.begin(), tabs.end(), x);
+
+ if (it != tabs.end() && *it == x) {
+ tabs.erase(it);
+ }
+}
+
+void FQTermBuffer::setMargins(int top, int bottom) {
+ FQ_TRACE("term", 3) << "Set margins: [" << top << ", " << bottom << "]";
+
+ top_row_ = qMax(top, 0);
+ bottom_row_ = qMin(qMax(bottom, 0), num_rows_ - 1);
+
+ if (is_origin_mode_) {
+ moveCaretTo(0, top_row_);
+ } else {
+ moveCaretTo(0, 0);
+ }
+}
+
+void FQTermBuffer::moveCaretTo(int column, int row, bool scroll_if_necessary) {
+ if (row != caret_.row_)
+ emit caretChangeRow();
+
+ FQ_TRACE("term", 5) << "Move caret to (" << column << ", " << row << ")";
+
+ //If th
+
+ // detect index boundary
+ if (column >= num_columns_) {
+ column = num_columns_;
+ }
+ if (column < 0) {
+ column = 0;
+ }
+
+ int scroll_lines = 0;
+
+ int stop = is_origin_mode_ ? top_row_ : 0;
+ if (row < stop) {
+ scroll_lines = row - stop;
+ row = stop;
+ }
+
+ stop = is_origin_mode_ ? bottom_row_ : num_rows_ - 1;
+ if (row > stop) {
+ scroll_lines = row - stop;
+ row = stop;
+ }
+
+ // Set dirty flag for cells of the last caret position.
+ FQTermTextLine *line = text_lines_.value(num_hist_lines_ + caret_.row_, NULL);
+ if (0 <= caret_.column_ && caret_.column_ < (int)line->getWidth()) {
+ unsigned cell_begin = line->getCellBegin(caret_.column_);
+ unsigned cell_end = line->getCellBegin(caret_.column_ + 1);
+ line->setDirtyFlag(cell_begin, cell_end);
+ }
+
+ if (scroll_if_necessary) {
+ scrollLinesInTerm(top_row_, scroll_lines);
+ }
+
+ caret_.column_ = column;
+ caret_.row_ = row;
+}
+
+void FQTermBuffer::moveCaretOffset(int column_offset, int row_offset, bool scroll_if_necessary) {
+ if (caret_.column_ >= num_columns_) {
+ // it's only allowed that the caret_.column_ >= num_columns_
+ // temporarily when a sequence of normal text is received. if we
+ // found caret_.column_ is out of bounds in other case, we should
+ // correct it first.
+ if (is_bbs_) {
+ // but the BBS (newsmth.net) assumes that the caret could be
+ // located out of the screen :(
+ } else {
+ caret_.column_ = num_columns_ - 1;
+ }
+ }
+
+ if (caret_.column_ + column_offset < 0) {
+ column_offset = -caret_.column_;
+ }
+
+ moveCaretTo(caret_.column_ + column_offset, caret_.row_ + row_offset,
+ scroll_if_necessary);
+}
+
+void FQTermBuffer::changeCaretPosition(int coloumn, int row) {
+ if (is_origin_mode_) {
+ moveCaretTo(coloumn, row + top_row_);
+ } else {
+ moveCaretTo(coloumn, row);
+ }
+}
+
+void FQTermBuffer::saveCaret() {
+ FQ_TRACE("term", 5) << "save the caret.";
+ last_saved_caret_ = caret_;
+}
+
+void FQTermBuffer::restoreCaret() {
+ FQ_TRACE("term", 5) << "restore the caret.";
+ moveCaretTo(last_saved_caret_.column_, last_saved_caret_.row_);
+ caret_ = last_saved_caret_;
+}
+
+void FQTermBuffer::SelectVtCharacterSet(VtCharSet charset, bool G0) {
+ if (G0) {
+ caret_.G0_ = charset;
+ } else {
+ caret_.G1_ = charset;
+ }
+}
+
+void FQTermBuffer::invokeCharset(bool G0) {
+ if (G0) {
+ is_g0_used_ = true;
+ } else {
+ is_g0_used_ = false;
+ }
+}
+
+void FQTermBuffer::carriageReturn() {
+ FQ_TRACE("term", 8) << "carrige return";
+ moveCaretOffset(-caret_.column_, 0);
+}
+
+int FQTermBuffer::getCaretColumn() const {
+ return caret_.column_;
+}
+
+int FQTermBuffer::getCaretRow() const {
+ return caret_.row_;
+}
+
+int FQTermBuffer::getCaretLine() const {
+ return caret_.row_ + num_hist_lines_;
+}
+
+// erase functions
+void FQTermBuffer::eraseText(int cell_count) {
+ FQ_TRACE("term", 8) << "erase " << cell_count << " cell(s) of text";
+
+ const FQTermTextLine *line = text_lines_.at(caret_.row_ + num_hist_lines_);
+
+ int x = line->getWidth() - caret_.column_;
+
+ clearArea(caret_.column_, caret_.row_,
+ qMin(cell_count, x), 1,
+ caret_.color_, caret_.attr_);
+}
+
+void FQTermBuffer::deleteText(int cell_count) {
+ FQ_TRACE("term", 8) << "delete " << cell_count << " cell(s) of text";
+
+ FQTermTextLine *line = text_lines_.at(caret_.row_ + num_hist_lines_);
+
+ int x = line->getWidth() - caret_.column_;
+
+ if (cell_count >= x) {
+ line->deleteText(caret_.column_, line->getWidth());
+ } else {
+ line->deleteText(caret_.column_, caret_.column_ + cell_count);
+ }
+}
+
+void FQTermBuffer::fillScreenWith(char c) {
+ FQ_TRACE("term", 5) << "fill screen with '" << c << "'";
+ for (int i = 0; i < num_rows_; i++) {
+ FQTermTextLine *line = text_lines_[i + num_hist_lines_];
+ line->deleteAllText();
+ line->appendWhiteSpace(num_columns_, NO_COLOR, NO_ATTR, c);
+ }
+}
+
+void FQTermBuffer::insertSpaces(int count) {
+ FQ_TRACE("term", 8) << "insert " << count << " white space(s)";
+
+ FQTermTextLine *line = text_lines_.at(caret_.row_ + num_hist_lines_);
+
+ int x = line->getWidth() - caret_.column_;
+
+ if (count >= x) {
+ clearArea(caret_.column_, caret_.row_, x, caret_.row_,
+ caret_.color_, caret_.attr_);
+ } else {
+ line->insertWhiteSpace(count, caret_.column_, caret_.color_, caret_.attr_);
+ }
+}
+
+void FQTermBuffer::deleteLines(int line_count) {
+ FQ_TRACE("term", 8) << "delete " << line_count << " line(s)";
+
+ int y = bottom_row_ - caret_.row_;
+
+ if (line_count >= y) {
+ clearArea(0, caret_.row_, -1, y, caret_.color_, caret_.attr_);
+ } else {
+ scrollLinesInTerm(caret_.row_, line_count);
+ }
+}
+
+void FQTermBuffer::insertLines(int count) {
+ FQ_TRACE("term", 8) << "insert " << count << " line(s)";
+
+ int y = bottom_row_ - caret_.row_;
+
+ if (count >= y) {
+ clearArea(0, caret_.row_, -1, y, caret_.color_, caret_.attr_);
+ } else {
+ scrollLinesInTerm(caret_.row_, -count);
+ }
+}
+
+void FQTermBuffer::eraseToLineEnd() {
+ FQ_TRACE("term", 8) << "erase to line end";
+
+ clearArea(caret_.column_, caret_.row_, -1, 1, caret_.color_, caret_.attr_);
+}
+
+void FQTermBuffer::eraseToLineBegin() {
+ FQ_TRACE("term", 8) << "erase to line begin";
+ clearArea(0, caret_.row_, caret_.column_ + 1, 1, caret_.color_, caret_.attr_);
+}
+
+void FQTermBuffer::eraseEntireLine() {
+ FQ_TRACE("term", 8) << "erase entire line";
+ clearArea(0, caret_.row_, -1, 1, caret_.color_, caret_.attr_);
+}
+
+// Set a line of text on screen to have been changed from start to end.
+void FQTermBuffer::setLineChanged(int index, int cell_begin, int cell_end) {
+ FQ_ASSERT(0 <= index && index < num_rows_ + num_hist_lines_);
+ text_lines_[index]->setDirtyFlag(cell_begin, cell_end);
+}
+
+void FQTermBuffer::clearLineChanged(int index) {
+ FQ_ASSERT(0 <= index && index < num_rows_ + num_hist_lines_);
+ text_lines_[index]->clearDirtyFlag();
+}
+
+void FQTermBuffer::setLineAllChanged(int index) {
+ FQ_ASSERT(0 <= index && index < num_rows_ + num_hist_lines_);
+ text_lines_[index]->setAllDirty();
+}
+
+void FQTermBuffer::scrollLinesInTerm(int startRow, int numRows) {
+ if (numRows == 0 || startRow > bottom_row_) {
+ return ;
+ }
+ if (startRow < top_row_) {
+ startRow = top_row_;
+ }
+
+ // TODO: performance issue here. Reuse the old text lines.
+ if (numRows > 0) {
+ //We are scrolling the whole screen.
+ if (startRow == 0 && caret_.row_ == num_rows_ - 1) {
+ addHistoryLine(numRows);
+ } else {
+ // delete lines from startRow, insert lines on the bottom_row_.
+ while (numRows) {
+ delete text_lines_.takeAt(num_hist_lines_ + startRow);
+ text_lines_.insert(num_hist_lines_ + bottom_row_, new FQTermTextLine(num_columns_));
+ numRows--;
+ }
+ }
+ }
+
+ // TODO: performance issue here. Reuse the old text lines.
+ if (numRows < 0) {
+ // delete lines from bottom_row_, insert lines in the startRow.
+ while (numRows) {
+ delete text_lines_.takeAt(num_hist_lines_ + bottom_row_);
+ text_lines_.insert(num_hist_lines_ + startRow, new FQTermTextLine(num_columns_));
+ numRows++;
+ }
+ }
+
+ for (int i = num_hist_lines_ + startRow; i <= num_hist_lines_ + bottom_row_; i++) {
+ text_lines_.at(i)->setAllDirty();
+ }
+}
+
+void FQTermBuffer::eraseToTermEnd() {
+ FQ_TRACE("term", 8) << "erase to term end";
+
+ if (caret_.column_ == 0 && caret_.row_ == 0) {
+ eraseEntireTerm();
+ return ;
+ }
+
+ clearArea(caret_.column_, caret_.row_, -1, 1, caret_.color_, caret_.attr_);
+
+ if (caret_.row_ < bottom_row_) {
+ clearArea(0, caret_.row_ + 1,
+ -1, bottom_row_ - caret_.row_,
+ caret_.color_, caret_.attr_);
+ }
+}
+
+void FQTermBuffer::eraseToTermBegin() {
+ FQ_TRACE("term", 8) << "erase to term begin";
+ if (caret_.column_ == num_columns_ - 1 && caret_.row_ == num_rows_ - 1) {
+ eraseEntireTerm();
+ return ;
+ }
+
+ clearArea(0, caret_.row_, caret_.column_ + 1, 1, caret_.color_, caret_.attr_);
+ if (caret_.row_ > top_row_) {
+ clearArea(0, top_row_, -1, caret_.row_, caret_.color_, caret_.attr_);
+ }
+}
+
+void FQTermBuffer::eraseEntireTerm() {
+ FQ_TRACE("term", 8) << "erase entire term";
+ addHistoryLine(num_rows_);
+ clearArea(0, 0, num_columns_, num_rows_, caret_.color_, caret_.attr_);
+}
+
+// width = -1 : clear to end
+void FQTermBuffer::clearArea(int startColumn, int startRow,
+ int width, int height,
+ unsigned char color, unsigned char attr) {
+ QByteArray cstr;
+
+ FQTermTextLine *line;
+
+ if (startRow + height > num_rows_) {
+ height = num_rows_ - startRow;
+ }
+
+ for (int i = startRow; i < height + startRow; i++) {
+ line = text_lines_[i + num_hist_lines_];
+
+ int w = width;
+
+ if (startColumn < num_columns_) {
+ if (w == -1) {
+ w = num_columns_ - startColumn;
+ }
+
+ int endX = startColumn + w;
+ if (endX > (int)line->getWidth()) {
+ endX = line->getWidth();
+ }
+
+ if(startColumn>=endX)
+ {
+ continue;
+ }
+
+ line->replaceWithWhiteSpace(w, startColumn, endX, color, attr);
+ }
+ }
+}
+
+void FQTermBuffer::addHistoryLine(int n) {
+ bool is_full = (num_hist_lines_ == max_num_hist_lines_);
+
+ // TODO: performance issue. Reuse the old lines.
+ while (n) {
+ if (num_hist_lines_ == max_num_hist_lines_) {
+ delete text_lines_.takeFirst();
+ }
+
+ text_lines_.append(new FQTermTextLine(num_columns_));
+ num_hist_lines_ = qMin(num_hist_lines_ + 1, max_num_hist_lines_);
+ n--;
+ }
+
+ for (int i = num_hist_lines_ + 0; i < num_hist_lines_ + bottom_row_; i++) {
+ text_lines_.at(i)->setAllDirty();
+ }
+
+ if (!is_full) {
+ emit bufferSizeChanged();
+ }
+}
+
+void FQTermBuffer::startDecode() {
+ last_saved_caret_.column_ = caret_.column_;
+ last_saved_caret_.row_ = caret_.row_;
+}
+
+void FQTermBuffer::endDecode() {
+ if (last_saved_caret_.row_ < num_rows_) {
+ FQTermTextLine *line = text_lines_[last_saved_caret_.row_ + num_hist_lines_];
+
+ line->safelySetDirtyFlag(last_saved_caret_.column_,
+ last_saved_caret_.column_ + 1);
+ }
+
+ if (caret_.row_ < num_rows_) {
+ FQTermTextLine *line = text_lines_.at(caret_.row_ + num_hist_lines_);
+
+ line->safelySetDirtyFlag(caret_.column_, caret_.column_ + 1);
+ }
+
+ clearSelect();
+}
+
+void FQTermBuffer::setMode(TermMode mode) {
+ FQ_TRACE("term", 8) << "set mode " << mode;
+
+ switch (mode) {
+ case INSERT_MODE:
+ is_insert_mode_ = true;
+ break;
+ case CURSOR_MODE:
+ is_cursor_mode_ = true;
+ break;
+ case ANSI_MODE:
+ is_ansi_mode_ = true;
+ case NUMERIC_MODE:
+ is_numeric_mode_ = true;
+ break;
+ case SMOOTH_MODE:
+ is_smoothscroll_mode_ = true;
+ break;
+ case NEWLINE_MODE:
+ is_newline_mode_ = true;
+ break;
+ case ORIGIN_MODE:
+ is_origin_mode_ = true;
+ this->moveCaretTo(0, top_row_);
+ break;
+ case AUTOWRAP_MODE:
+ is_autowrap_mode_ = true;
+ break;
+ case AUTOREPEAT_MODE:
+ is_autorepeat_mode_ = true;
+ break;
+ case LIGHTBG_MODE:
+ is_lightbg_mode_ = true;
+ break;
+ default:
+ break;
+ }
+}
+
+void FQTermBuffer::resetMode(TermMode mode) {
+ FQ_TRACE("term", 8) << "reset mode " << mode;
+
+ switch (mode) {
+ case INSERT_MODE:
+ is_insert_mode_ = false;
+ break;
+ case CURSOR_MODE:
+ is_cursor_mode_ = false;
+ break;
+ case ANSI_MODE:
+ is_ansi_mode_ = false;
+ case NUMERIC_MODE:
+ is_numeric_mode_ = false;
+ break;
+ case SMOOTH_MODE:
+ is_smoothscroll_mode_ = false;
+ break;
+ case NEWLINE_MODE:
+ is_newline_mode_ = false;
+ break;
+ case ORIGIN_MODE:
+ is_origin_mode_ = false;
+ this->moveCaretTo(0, 0);
+ break;
+ case AUTOWRAP_MODE:
+ is_autowrap_mode_ = false;
+ break;
+ case AUTOREPEAT_MODE:
+ is_autorepeat_mode_ = false;
+ break;
+ case LIGHTBG_MODE:
+ is_lightbg_mode_ = false;
+ break;
+ default:
+ break;
+ }
+}
+
+void FQTermBuffer::setSelect(const QPoint &pt1, const QPoint &pt2) {
+ QPoint ptSelStart, ptSelEnd;
+
+ if (pt1.y() == pt2.y()) {
+ ptSelStart = pt1.x() < pt2.x() ? pt1 : pt2;
+ ptSelEnd = pt1.x() > pt2.x() ? pt1 : pt2;
+ } else {
+ ptSelStart = pt1.y() < pt2.y() ? pt1 : pt2;
+ ptSelEnd = pt1.y() > pt2.y() ? pt1 : pt2;
+ }
+
+ int y1 = ptSelStart.y();
+ int y2 = ptSelEnd.y();
+
+ if (!(selection_start_ == QPoint(-1, -1)
+ && selection_end_ == QPoint(-1, -1))) {
+ y1 = qMin(y1, selection_start_.y());
+ y2 = qMax(y2, selection_end_.y());
+ }
+
+ for (int i = y1; i <= y2; i++) {
+ text_lines_.value(i, NULL)->setAllDirty();
+ }
+
+ selection_start_ = ptSelStart;
+ selection_end_ = ptSelEnd;
+}
+
+void FQTermBuffer::clearSelect() {
+ if (selection_start_ == QPoint(-1, -1) && selection_end_ == QPoint(-1, -1)) {
+ return;
+ }
+
+ for (int i = selection_start_.y(); i <= selection_end_.y(); i++) {
+ text_lines_.value(i, NULL)->setAllDirty();
+ }
+
+ selection_start_ = selection_end_ = QPoint(-1, -1);
+}
+
+bool FQTermBuffer::isSelected(int line_index) const {
+ if (selection_start_ == QPoint(-1, -1) && selection_end_ == QPoint(-1, -1)) {
+ return false;
+ } else {
+ return line_index >= selection_start_.y() && line_index <= selection_end_.y();
+ }
+}
+
+bool FQTermBuffer::isSelected(const QPoint &cell, bool is_rect_sel) const {
+ if (selection_start_ == QPoint(-1, -1) && selection_end_ == QPoint(-1, -1)) {
+ return false;
+ }
+
+ if (cell.y() < 0 || cell.y() >= getNumLines()) {
+ return false;
+ }
+
+ int x1 = selection_start_.x();
+ int y1 = selection_start_.y();
+
+ int x2 = selection_end_.x();
+ int y2 = selection_end_.y();
+
+ if (cell.y() < y1 || cell.y() > y2)
+ return false;
+
+ const FQTermTextLine *line = this->getTextLineInBuffer(cell.y());
+
+ int cell_begin = 0;
+ int cell_end = cell.x() + 1;
+
+ if (is_rect_sel) {
+ int minx = qMin(x1, x2);
+ int maxx = qMax(x1, x2);
+ cell_begin = line->getCellBegin(qMin(minx, (int)line->getWidth()));
+ cell_end = line->getCellEnd(qMin(maxx + 1, (int)line->getWidth()));
+ } else {
+ if (cell.y() == y1) {
+ cell_begin = line->getCellBegin(qMin(x1, (int)line->getWidth()));
+ }
+ if (cell.y() == y2) {
+ cell_end = line->getCellEnd(qMin(x2 + 1, (int)line->getWidth()));
+ }
+ }
+
+ return cell_begin <= cell.x() && cell.x() < cell_end;
+}
+
+static void removeTrailSpace(QString &line) {
+ for (int last_non_space = line.size() - 1;
+ last_non_space >= 0; --last_non_space) {
+ QChar a = line.at(last_non_space);
+ if (!a.isSpace()) {
+ line.resize(last_non_space + 1);
+ break;
+ }
+
+ if (last_non_space == 0) {
+ line.resize(0);
+ }
+ }
+}
+
+
+QString FQTermBuffer::getTextSelected(bool is_rect_sel, bool is_color_copy,
+ const QByteArray &escape) const {
+ QString cstrSelect;
+ QString strTemp;
+
+ if (selection_start_ == QPoint(-1, -1) && selection_end_ == QPoint(-1, -1)) {
+ return cstrSelect;
+ }
+
+ QRect rc;
+
+ for (int i = selection_start_.y(); i <= selection_end_.y(); i++) {
+ strTemp.clear();
+ rc = getSelectRect(i, is_rect_sel);
+
+ FQTermTextLine *line = text_lines_.at(i);
+ unsigned cell_begin = qMax(rc.left(), 0);
+ unsigned cell_end = qMin(rc.right() + 1, (int)line->getWidth());
+ FQ_ASSERT(rc.left() + rc.width() == rc.right() + 1);
+
+ if (cell_begin < cell_end) {
+ cell_begin = line->getCellBegin(cell_begin);
+ cell_end = line->getCellEnd(cell_end);
+
+ if (is_color_copy) {
+ line->getAnsiText(cell_begin, cell_end, strTemp, escape);
+ } else {
+ line->getPlainText(cell_begin, cell_end, strTemp);
+ }
+ }
+
+ removeTrailSpace(strTemp);
+
+ cstrSelect += strTemp;
+
+ // add newline except the last line
+ if (i != selection_end_.y()) {
+ cstrSelect += OS_NEW_LINE;
+ }
+ }
+
+ return cstrSelect;
+}
+
+QRect FQTermBuffer::getSelectRect(int line_index, bool is_rect_sel) const {
+ FQ_ASSERT(isSelected(line_index));
+
+ if (is_rect_sel) {
+ return QRect(qMin(selection_start_.x(), selection_end_.x()), line_index,
+ abs(selection_end_.x() - selection_start_.x()) + 1, 1);
+ } else if (selection_start_.y() == selection_end_.y()) {
+ return QRect(selection_start_.x(), line_index,
+ qMin(selection_end_.x(), num_columns_) - selection_start_.x() + 1, 1);
+ } else if (line_index == selection_start_.y()) {
+ return QRect(selection_start_.x(), line_index,
+ qMax(0, num_columns_ - selection_start_.x()), 1);
+ } else if (line_index == selection_end_.y()) {
+ return QRect(0, line_index, qMin(num_columns_, selection_end_.x() + 1), 1);
+ } else {
+ return QRect(0, line_index, num_columns_, 1);
+ }
+}
+
+void FQTermBuffer::scrollTerm(int numRows) {
+ scrollLinesInTerm(caret_.row_, numRows);
+ moveCaretOffset(0, numRows);
+}
+
+
+} // namespace FQTerm
+
+#include "fqterm_buffer.moc"
diff --git a/src/terminal/fqterm_buffer.h b/src/terminal/fqterm_buffer.h
new file mode 100644
index 0000000..3e0ef6a
--- /dev/null
+++ b/src/terminal/fqterm_buffer.h
@@ -0,0 +1,297 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_BUFFER_H
+#define FQTERM_BUFFER_H
+
+#include <QList>
+#include <QObject>
+#include <QPoint>
+
+#include "fqterm_text_line.h"
+class QString;
+class QByteArray;
+class QRect;
+
+namespace FQTerm {
+
+class FQTermTextLine;
+
+/* Text buffer consists of characters in a matrix of cells.
+ *
+ * Buffer
+ * +--------------------------------+
+ * ||----> |
+ * || x |
+ * || |
+ * |V Y |
+ * | |
+ * . .
+ * . .
+ * . histroical lines .
+ * . .
+ * . .
+ * | |
+ * | |
+ * | |
+ * | |
+ * |+------------------------------+|
+ * |||----> ||
+ * ||| x ||
+ * ||| terminal ||
+ * ||V Y ||
+ * || ||
+ * || ||
+ * || | (caret) ||
+ * || ||
+ * || ||
+ * |+------------------------------+|
+ * +--------------------------------+
+ *
+ * Text buffer, to manage lines of characters with colors and
+ * attributes, caret positions, terminal size/margins, selection
+ * region, historical text lines, buffer write mode (insert or
+ * replace), and etc.
+ *
+ * Note: There are two coordinates, relative to terminal or entire
+ * buffer. When we use (column, row) it indicates terminal coordinate,
+ * while when we use (column, line) it indicates buffer coordinate.
+ * This rule applies both in variable names and function names.
+ **/
+class FQTermBuffer: public QObject {
+ Q_OBJECT;
+ public:
+ enum TermMode {
+ INSERT_MODE, /* otherwise replace mode */
+ ANSI_MODE, /* otherwise VT52 mode */
+ SMOOTH_MODE, /* otherwse jump mode */
+ NEWLINE_MODE, /* otherwise line feed mode */
+ CURSOR_MODE, /* otherwise reset cursor mode */
+ NUMERIC_MODE, /* otherwise application mode */
+ ORIGIN_MODE, /* otherwise absolute mode */
+ AUTOWRAP_MODE, /* otherwise non-autowrap mode */
+ AUTOREPEAT_MODE, /* otherwise non-autorepeat mode */
+ LIGHTBG_MODE, /* otherwise dark background mode */
+ };
+
+ enum VtCharSet {
+ UNITED_KINGDOM_SET,
+ ASCII_SET,
+ SPECIAL_GRAPHICS,
+ ALTERNATE_CHARACTER_ROM_STANDARD_CHARACTER_SET,
+ ALTERNATE_CHARACTER_ROM_SPECIAL_GRAPHICS
+ };
+
+ FQTermBuffer(int column, int row, int max_hist_line, bool is_bbs);
+ ~FQTermBuffer();
+
+ // Get text lines.
+ // Return null if the line_index is out of bound, return NULL.
+ const FQTermTextLine *getTextLineInBuffer(int line_index) const;
+ const FQTermTextLine *getTextLineInTerm(int line_index) const;
+
+ // Get number of columns and rows of the term, or lines of the
+ // entire buffer.
+ int getNumColumns() const;
+ int getNumRows() const;
+ int getNumLines() const;
+
+ // Set the size of the screen.
+ void setTermSize(int col, int row);
+ // set margins in term. (Generally speaking, most operations are
+ // restrictied in [top_row_, bottom_row_] of terminal.)
+ void setMargins(int top_row, int bottom_row);
+
+ // the caret's coordinate in term or buffer.
+ int getCaretColumn() const;
+ int getCaretRow() const;
+ int getCaretLine() const;
+
+ // Set current attribute.
+ void setCurrentAttr(unsigned char color, unsigned char attr);
+
+ // Below are a series of functions to modify the content of buffer.
+ // These functions will work from the current caret position.
+ // All the behaviours of these functions may be influenced by the
+ // mode of this buffer (is_insert_mode_, is_newline_mode_, and
+ // etc.).
+
+ void writeText(const QString &cstr, int charstate = FQTermTextLine::NORMAL);
+
+ void fillScreenWith(char c);
+
+ void insertSpaces(int count);
+ void insertLines(int count);
+
+ void deleteText(int cell_count);
+ void deleteLines(int line_count);
+
+ void eraseText(int cell_count);
+
+ void eraseToLineBegin();
+ void eraseToLineEnd();
+ void eraseEntireLine();
+
+ void eraseToTermBegin();
+ void eraseToTermEnd();
+ void eraseEntireTerm();
+
+ // Set a line of buffer to have been changed from start to end.
+ void setLineChanged(int index, int cell_begin, int cell_end);
+ void clearLineChanged(int index);
+ void setLineAllChanged(int index);
+
+ // Functions about caret.
+ // If the caret is moved, the cells of the position of the last caret will
+ // be marked as changed.
+ void moveCaretOffset(int coloumn_offset, int row_offset,
+ bool scroll_if_necessary = false);
+ void moveCaretTo(int coloumn, int row, bool scroll_if_necessary = false);
+ void changeCaretPosition(int coloumn, int row);
+ void saveCaret();
+ void restoreCaret();
+
+ void SelectVtCharacterSet(VtCharSet charset, bool G0);
+ void invokeCharset(bool G0);
+
+ // non-printing characters
+ void tab();
+ void carriageReturn();
+ void lineFeed();
+
+ void addTabStop();
+ void clearTabStop(bool clear_all);
+
+ // Select Mode (SM) and Reset Mode (RM) functions.
+ // See ANSI X3.64 Mode-Changing Parameters.
+ void setMode(TermMode);
+ void resetMode(TermMode);
+
+ bool isCursorMode() const { return is_cursor_mode_; }
+ bool isAnsiMode() const { return is_ansi_mode_; }
+ bool isNumericMode() const { return is_numeric_mode_; }
+ bool isAutoRepeatMode() const { return is_autorepeat_mode_; }
+ bool isLightBackgroundMode() const { return is_lightbg_mode_; }
+ bool isNewLineMode() const {return is_newline_mode_;}
+
+ // for test
+ void startDecode();
+ void endDecode();
+
+ // Functions about selection in buffer.
+ void setSelect(const QPoint &start_point, const QPoint &end_point);
+ void clearSelect();
+ bool isSelected(const QPoint &cell, bool isRectSel) const;
+ bool isSelected(int line_index) const;
+
+ QString getTextSelected(bool is_rect_sel, bool is_color_copy,
+ const QByteArray &escape) const;
+
+ // Get the rectangle of selected text of a certain line in buffer.
+ // Note: please ensure there exits any cell of the line line_index
+ // is selected.
+ QRect getSelectRect(int line_index, bool is_rect_sel) const;
+
+ //Scroll line && adjust caret pos.
+ //Scroll must occur at the line where caret is
+ void scrollTerm(int numRows);
+
+ signals:
+ void bufferSizeChanged();
+ void termSizeChanged(int column, int row);
+ void onSetTermSize(int col, int row);
+ void caretChangeRow();
+ private:
+ // Scroll lines between startRow and bottom_row_ (see setMargin()).
+ // num > 0 scroll up.
+ // num < 0 scroll down.
+ void scrollLinesInTerm(int startRow, int numRows);
+
+ // Replace a area of cells with spaces.
+ void clearArea(int startColumn, int startRow,
+ int width, int height,
+ unsigned char color, unsigned char attr);
+
+ // Append n empty lines to the buffer and make the first n lines of
+ // term historical.
+ void addHistoryLine(int n);
+
+ int getTabStop(int column);
+
+ struct Caret {
+ int column_, row_;
+ int color_, attr_;
+ VtCharSet G0_, G1_;
+
+ Caret();
+ };
+
+ // terminal size.
+ int num_columns_, num_rows_;
+
+ // term margins. (Generally speaking, most operations are
+ // restrictied in [top_row_, bottom_row_] of terminal.)
+ int top_row_, bottom_row_;
+
+ // Historical data length and max length.
+ int num_hist_lines_, max_num_hist_lines_;
+
+ // All lines of text, including both historical lines and lines in
+ // current terminal.
+ //
+ // Note: the number of historical lines, num_hist_lines, may
+ // increase from 0 to max_num_hist_lines_.
+ QList<FQTermTextLine *> text_lines_;
+
+ void *tab_stops_;
+
+ // The caret in terminal
+ Caret caret_;
+ Caret last_saved_caret_;
+
+ bool is_g0_used_; // is G0 or G1 charset used;
+
+ bool is_insert_mode_; // Is insert or replace mode.
+ bool is_ansi_mode_; // Is ansi or vt52 mode.
+ bool is_smoothscroll_mode_; // Is smooth or jump scrolling mode.
+ bool is_newline_mode_; // Is newline or linefeed mode.
+ bool is_cursor_mode_; // Is cursor key mode.
+ bool is_numeric_mode_; // Is numeric or application mode.
+ bool is_origin_mode_; // Is origin or absolute mode.
+ bool is_autowrap_mode_; // Is auto-wrap mode enabled.
+ bool is_autorepeat_mode_; // Is auto-repeat mode enabled.
+ bool is_lightbg_mode_; // Is ligth background or dark backgrond mode.
+
+ // Selection in buffer. If section start and end are in the same
+ // line, start.x should be equal to or less than end.x. Otherwise
+ // start.y should be less than end.y.
+ //
+ // If selection_start_ = selection_start_ = (-1, -1), the selection
+ // is empty.
+ QPoint selection_start_;
+ QPoint selection_end_;
+
+ // whether this buffer is used for a bbs session.
+ bool is_bbs_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_BUFFER_H
diff --git a/src/terminal/fqterm_session.cpp b/src/terminal/fqterm_session.cpp
new file mode 100644
index 0000000..6c5b513
--- /dev/null
+++ b/src/terminal/fqterm_session.cpp
@@ -0,0 +1,1648 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm.h"
+#include "common.h"
+#include "fqterm_trace.h"
+#include "fqterm_session.h"
+#include "fqterm_buffer.h"
+#include "fqterm_text_line.h"
+#include "fqterm_telnet.h"
+#include "fqterm_decode.h"
+#include "fqterm_zmodem.h"
+
+#ifdef HAVE_PYTHON
+#include <Python.h>
+#endif //HAVE_PYTHON
+
+#ifndef WIN32
+#include <unistd.h>
+#else
+#include <windows.h>
+#endif
+
+
+#include <QString>
+#include <QTimer>
+#include <QMutex>
+#include <QRegExp>
+#include <QtAlgorithms>
+#include <QChar>
+#include <QPair>
+#include <QReadLocker>
+#include <QWriteLocker>
+#include <QReadWriteLock>
+
+namespace FQTerm {
+
+const QString FQTermSession::endOfUrl[] = {
+ "ac","ad","ae","af","ag","ai","al","am","an","ao","aq","ar","as","at",
+ "au","aw","az","ba","bb","bd","be","bf","bg","bh","bi","bj","bm","bn","bo","br",
+ "bs","bt","bv","bw","by","bz","ca","cc","cd","cf","cg","ch","ci","ck","cl","cm",
+ "cn","co","uk","com","cr","cs","cu","cv","cx","cy","cz","de","dj","dk","dm",
+ "do","dz","ec","edu","ee","eg","eh","er","es","et","fi","fj","fk","fm","fo",
+ "fr","ga","gd","ge","gf","gg","gh","gi","gl","gm","gn","gov","gp","gq","aero",
+ "asia","biz","coop","eu","info","museum","name","pro","travel","gr","gs","gt",
+ "gu","gw","gy","hk","hm","hn","hr","ht","hu","id","ie","il","im","in","int",
+ "io","iq","ir","is","it","je","jm","jo","jp","ke","kg","kh","ki","km","kn","kp",
+ "kr","kw","ky","kz","la","lb","lc","li","lk","lr","ls","lt","lu","lv","ly","ma",
+ "mc","md","mg","mh","mil","mk","ml","mm","mn","mo","mp","mq","mr","ms","mt",
+ "mu","mv","mw","mx","my","mz","na","nc","ne","net","nf","ng","ni","nl","no",
+ "np","nr","nt","nu","nz","om","org","pa","pe","pf","pg","ph","pk","pl","pm",
+ "pn","pr","ps","pt","pw","py","qa","re","ro","ru","rw","sa","sb","sc","sd","se",
+ "sg","sh","si","sj","sk","sl","sm","sn","so","sr","sv","st","sy","sz","tc","td",
+ "tf","tg","th","tj","tk","tm","tn","to","tp","tr","tt","tv","tw","tz","ua","ug",
+ "uk","um","us","uy","uz","va","vc","ve","vg","vi","vn","vu","wf","ws","ye","yt",
+ "yu","za","zm","zw"
+};
+
+FQTermSession::FQTermSession(FQTermConfig *config, FQTermParam param) {
+ reconnectRetry_ = 0;
+ scriptListener_ = NULL;
+ param_ = param;
+ termBuffer_ = new FQTermBuffer(param_.numColumns_,
+ param_.numRows_,
+ param_.numScrollLines_,
+ param_.hostType_ == 0);
+
+ if (param.protocolType_ == 0) {
+ telnet_ = new FQTermTelnet(param_.virtualTermType_.toLatin1(),
+ param_.numRows_, param_.numColumns_, param.protocolType_, param.hostType_ );
+ } else if (param.protocolType_ == 3) {
+ telnet_ = new FQTermTelnet(param_.virtualTermType_.toLatin1(),
+ param_.numRows_, param_.numColumns_, param.protocolType_, param.hostType_ );
+ } else {
+#if defined(_NO_SSH_COMPILED)
+ QMessageBox::warning(this, "sorry",
+ "SSH support is not compiled, "
+ "FQTerm can only use Telnet!");
+ telnet_ = new FQTermTelnet(param_.virtualTermType_.toUtf8(),
+ param_.numRows_, param_.numColumns_, param.protocolType_, param.hostType_ );
+#else
+ telnet_ = new FQTermTelnet(param_.virtualTermType_.toUtf8(),
+ param_.numRows_, param_.numColumns_, param.protocolType_ , param.hostType_ ,
+ param_.sshUserName_.toUtf8(),
+ param_.sshPassword_.toUtf8());
+#endif
+ }
+
+ zmodem_ = new FQTermZmodem(config, telnet_, param.protocolType_, param.serverEncodingID_);
+ decoder_ = new FQTermDecode(termBuffer_, param.serverEncodingID_);
+ FQ_VERIFY(connect(decoder_, SIGNAL(enqReceived()), this, SLOT(onEnqReceived())));
+ FQ_VERIFY(connect(decoder_, SIGNAL(onTitleSet(const QString&)), this, SIGNAL(onTitleSet(const QString&))));
+
+ isConnected_ = false;
+#ifndef _NO_SSH_COMPILED
+ if (param.protocolType_ != 0) {
+ isSSHLogining_ = true;
+ } else {
+ isSSHLogining_ = false;
+ }
+#else
+ isSSHLogining_ = false;
+#endif
+ isTelnetLogining_ = false;
+ isIdling_ = false;
+ isSendingMessage_ = false;
+ isMouseX11_ = false;
+
+ idleTimer_ = new QTimer;
+ autoReplyTimer_ = new QTimer;
+
+ acThread_ = new ArticleCopyThread(*this, waitCondition_, bufferWriteLock_);
+
+ FQ_VERIFY(connect(decoder_, SIGNAL(mouseMode(bool)),
+ this, SLOT(setMouseMode(bool))));
+ FQ_VERIFY(connect(telnet_, SIGNAL(readyRead(int, int)),
+ this, SLOT(readReady(int, int))));
+ FQ_VERIFY(connect(telnet_, SIGNAL(TelnetState(int)),
+ this, SLOT(changeTelnetState(int))));
+ FQ_VERIFY(connect(telnet_, SIGNAL(errorMessage(QString)),
+ this, SIGNAL(errorMessage(QString))));
+ FQ_VERIFY(connect(telnet_, SIGNAL(requestUserPwd(QString*, QString*, bool*)),
+ this, SIGNAL(requestUserPwd(QString*, QString*, bool*))));
+
+ FQ_VERIFY(connect(telnet_, SIGNAL(onSSHAuthOK()),
+ this, SLOT(onSSHAuthOK())));
+
+
+
+ FQ_VERIFY(connect(termBuffer_, SIGNAL(onSetTermSize(int, int)),
+ telnet_, SLOT(windowSizeChanged(int, int))));
+
+ FQ_VERIFY(connect(zmodem_, SIGNAL(ZmodemState(int, int, const char *)),
+ this, SIGNAL(zmodemStateChanged(int, int, const char *))));
+
+ FQ_VERIFY(connect(idleTimer_, SIGNAL(timeout()), this, SLOT(onIdle())));
+ FQ_VERIFY(connect(autoReplyTimer_, SIGNAL(timeout()),
+ this, SLOT(onAutoReply())));
+
+ FQ_VERIFY(connect(acThread_, SIGNAL(articleCopied(int, const QString)),
+ this, SIGNAL(articleCopied(int, const QString))));
+
+ setAntiIdle(param_.isAntiIdle_);
+}
+
+FQTermSession::~FQTermSession() {
+ delete idleTimer_;
+ delete autoReplyTimer_;
+ delete acThread_;
+ delete termBuffer_;
+ delete telnet_;
+ delete zmodem_;
+ delete decoder_;
+}
+
+const QString FQTermSession::protocolPrefix[] = {
+ "http://", "https://", "mms://", "rstp://", "ftp://", "mailto:", "telnet://"
+};
+
+void FQTermSession::setScreenStart(int nStart) {
+ screenStartLineNumber_ = nStart;
+}
+
+bool FQTermSession::setCursorPos(const QPoint &pt, QRect &rc) {
+ QRect rectOld = getMenuRect();
+
+ cursorPoint_ = pt;
+
+ detectMenuRect();
+ QRect rectNew = getMenuRect();
+
+ rc = rectOld | rectNew;
+
+ return rectOld != rectNew;
+}
+
+QString FQTermSession::getMessage() {
+ const FQTermTextLine *line;
+ LineColorInfo colorInfo;
+ QString message;
+
+ getLineColorInfo(termBuffer_->getTextLineInTerm(0), &colorInfo);
+ if (!colorInfo.uniBackgroundColor) {
+ return message;
+ }
+
+ int i = 1;
+ termBuffer_->getTextLineInTerm(0)->getAllPlainText(message);
+
+ line = termBuffer_->getTextLineInTerm(i);
+ getLineColorInfo(line, &colorInfo);
+ while (colorInfo.uniBackgroundColor && colorInfo.hasBackgroundColor) {
+ message += "\n";
+ line->getAllPlainText(message);
+ i++;
+ line = termBuffer_->getTextLineInTerm(i);
+ getLineColorInfo(line, &colorInfo);
+ }
+ return message;
+}
+
+
+void FQTermSession::detectPageState() {
+ //for smth type bbs.
+ pageState_ = Undefined;
+ if (param_.hostType_ != 0) {
+ return;
+ }
+
+ const FQTermTextLine *line[4];
+ LineColorInfo colorInfo[4];
+ int lineIndex[4] = {0, 1, 2};
+ lineIndex[3] = termBuffer_->getNumRows() - 1;
+ for (int i = 0; i < 4; ++i) {
+ line[i] = termBuffer_->getTextLineInTerm(lineIndex[i]);
+ getLineColorInfo(line[i], colorInfo + i);
+ }
+
+ //TODO: Detect PageState in a clearer way.
+ if (!colorInfo[0].hasBackgroundColor) {
+ if (colorInfo[3].foregroundColorIndex.count() != 0 &&
+ colorInfo[3].hasBackgroundColor){
+ if (colorInfo[3].uniBackgroundColor) {
+ QString text;
+ line[3]->getAllPlainText(text);
+ if (text[0] != L'\x3010') {
+ pageState_ = Read;
+ } else {
+ pageState_ = Edit;
+ }
+ } else if (colorInfo[3].backgroundColorIndex.count() == 2 &&
+ colorInfo[3].backgroundColorIndex.at(0) == 4 &&
+ colorInfo[3].backgroundColorIndex.at(1) == 0){
+ pageState_ = Read;
+ }
+ }
+ return;
+ }
+
+ if (colorInfo[0].backgroundColorIndex.at(0) != 4
+ || !(colorInfo[3].hasBackgroundColor && colorInfo[3].backgroundColorIndex.at(0) == 4)) {
+ if (!colorInfo[3].hasBackgroundColor &&
+ colorInfo[0].foregroundColorIndex.count() == 4 &&
+ colorInfo[0].foregroundColorIndex.at(1) == 4 &&
+ colorInfo[0].foregroundColorIndex.at(2) == 7 &&
+ colorInfo[0].foregroundColorIndex.at(3) == 4){
+ pageState_ = TOP10;
+ }
+ return;
+ }
+
+ if (colorInfo[1].hasBackgroundColor && colorInfo[1].uniBackgroundColor) {
+ pageState_ = Message;
+ return;
+ }
+
+ if (colorInfo[0].uniBackgroundColor) {
+ if (!colorInfo[2].hasBackgroundColor ||
+ colorInfo[2].backgroundColorIndex.at(0) != 4 ||
+ colorInfo[2].backgroundColorIndex.count() > 3) {
+ pageState_ = Menu;
+ return;
+ }
+ }
+
+ if (!colorInfo[0].uniBackgroundColor &&
+ colorInfo[0].backgroundColorIndex.at(0) == 4 &&
+ !colorInfo[3].uniBackgroundColor) {
+ //announce, elite root
+ pageState_ = EliteArticleList;
+ return;
+ }
+
+ if (colorInfo[2].hasBackgroundColor &&
+ !colorInfo[2].uniBackgroundColor &&
+ colorInfo[2].backgroundColorIndex.at(0) == 4 &&
+ !colorInfo[3].uniBackgroundColor) {
+ pageState_ = EliteArticleList;
+ return;
+ }
+
+ if (colorInfo[0].foregroundColorIndex.indexOf(14) != -1) {
+ pageState_ = ArticleList;
+ return;
+ }
+
+ if (colorInfo[2].foregroundColorIndex.indexOf(7) != -1) {
+ QString text;
+ line[2]->getAllPlainText(text);
+ if (text[0] == ' ') {
+ pageState_ = BoardList;
+ } else {
+ pageState_ = MailMenu;
+ }
+ }
+
+}
+
+FQTermSession::CursorType FQTermSession::getCursorType(const QPoint &pt) {
+ if (screenStartLineNumber_ !=
+ (termBuffer_->getNumLines() - termBuffer_->getNumRows())) {
+ return kNormal;
+ }
+
+ QRect rc = getMenuRect();
+ CursorType nCursorType = kNormal;
+ switch (pageState_) {
+ case Undefined: // not recognized
+ if (rc.contains(pt)) {
+ //HAND
+ nCursorType = kRight;
+ } else {
+ nCursorType = kNormal;
+ }
+ break;
+ case Menu:
+ case MailMenu:
+ // menu
+ if (pt.x() < 5) {
+ // LEFT
+ nCursorType = kLeft;
+ } else if (rc.contains(pt)) {
+ // HAND
+ nCursorType = kRight;
+ } else {
+ nCursorType = kNormal;
+ }
+ break;
+ case ArticleList:
+ case BoardList:
+ case EliteArticleList:
+ case FriendMailList:
+ // list
+ if (pt.x() < 12) {
+ // LEFT
+ nCursorType = kLeft;
+ } else if (pt.y() - screenStartLineNumber_ < 3) {
+ // HOME
+ nCursorType = kHome;
+ } else if (pt.y() == termBuffer_->getNumLines() - 1) {
+ // END
+ nCursorType = kEnd;
+ } else if (pt.x() > termBuffer_->getNumColumns() - 16 &&
+ pt.y() - screenStartLineNumber_ <= termBuffer_->getNumRows() / 2) {
+ //PAGEUP
+ nCursorType = kPageUp;
+ } else if (pt.x() > termBuffer_->getNumColumns() - 16
+ && pt.y() - screenStartLineNumber_ >
+ termBuffer_->getNumRows() / 2) {
+ // PAGEDOWN
+ nCursorType = kPageDown;
+ } else if (rc.contains(pt)) {
+ // HAND
+ nCursorType = kRight;
+ } else {
+ nCursorType = kNormal;
+ }
+ break;
+ case Read:
+ // read
+ if (pt.x() < 12) {
+ // LEFT
+ nCursorType = kLeft;
+ } else if (pt.x() > (termBuffer_->getNumColumns() - 16) &&
+ (pt.y() - screenStartLineNumber_)
+ <= termBuffer_->getNumRows() / 2) {
+ // PAGEUP
+ nCursorType = kPageUp;
+ } else if (pt.x() > (termBuffer_->getNumColumns() - 16) &&
+ (pt.y() - screenStartLineNumber_)
+ > termBuffer_->getNumRows() / 2) {
+ // PAGEDOWN
+ nCursorType = kPageDown;
+ } else if (rc.contains(pt)) {
+ //HAND
+ nCursorType = kRight;
+ } else {
+ nCursorType = kNormal;
+ }
+ break;
+ case Edit:
+ // TODO: add action for kEdit state.
+ if (rc.contains(pt)) {
+ //HAND
+ nCursorType = kRight;
+ } else {
+ nCursorType = kNormal;
+ }
+ break;
+ case TOP10:
+ if (pt.x() < 12) {
+ nCursorType = kLeft;
+ } else if (rc.contains(pt)){
+ nCursorType = kRight;
+ }
+ break;
+ default:
+ FQ_TRACE("error", 2) << "Error, wrong PageState.";
+ break;
+ }
+
+ return nCursorType;
+}
+
+bool FQTermSession::isSelectedMenu(int line) {
+ // TODO: possible performance issue
+ QRect rect = getMenuRect();
+
+ // nothing selected
+ if (rect.isNull()) {
+ return false;
+ }
+
+ return line >= rect.bottom() && line <= rect.top();
+}
+
+bool FQTermSession::isSelectedMenu(const QPoint &pt) {
+ // TODO: possible performance issue
+ QRect rect = getMenuRect();
+
+ // nothing selected
+ if (rect.isNull()) {
+ return false;
+ }
+
+ return rect.contains(pt);
+}
+
+FQTermSession::PageState FQTermSession::getPageState() {
+ return pageState_;
+}
+
+char FQTermSession::getMenuChar() {
+ return menuChar_;
+}
+
+void FQTermSession::setMenuRect(int row, int col, int len) {
+ menuRect_ = QRect(col, row, len, 1);
+}
+
+QRect FQTermSession::detectMenuRect() {
+ QRect rect(0, 0, 0, 0);
+ menuRect_ = rect;
+ if (scriptListener_)
+ {
+ bool res = scriptListener_->postScriptCallback(SFN_DETECT_MENU
+#ifdef HAVE_PYTHON
+ ,Py_BuildValue("l", scriptListener_->windowID())
+#endif //HAVE_PYTHON
+ );
+ if (res) return menuRect_;
+ }
+ // current screen scrolled
+ if (screenStartLineNumber_ !=
+ (termBuffer_->getNumLines() - termBuffer_->getNumRows())) {
+ return rect;
+ }
+
+ const FQTermTextLine *line;
+ int menuStartLine = 8;
+ switch (pageState_) {
+ case Undefined: break;
+ case MailMenu:
+ menuStartLine = 7;
+ case Menu:
+ if (cursorPoint_.y() - screenStartLineNumber_ >= menuStartLine &&
+ cursorPoint_.x() > 5) {
+ line = termBuffer_->getTextLineInBuffer(cursorPoint_.y());
+ QString cstr;
+ int cell_end = line->getCellEnd(qMin(cursorPoint_.x(),
+ (int)line->getWidth()));
+ line->getPlainText(0, cell_end, cstr);
+
+ int base = cstr.lastIndexOf(" ");
+ if (base == -1) {
+ base = 0;
+ }
+
+ QRegExp reg("[a-zA-Z0-9][).\\]]");
+ char indexChar = cstr.indexOf(reg, base);
+ if (indexChar != -1) {
+ menuChar_ = cstr.at(indexChar).toLatin1();
+
+ QString strTmp = cstr.left(cstr.indexOf(reg, base));
+ int nMenuStart = get_str_width((const UTF16 *)strTmp.data(),
+ strTmp.size());
+ if (cstr[indexChar - 1] == '(' || cstr[indexChar - 1] == '[') {
+ nMenuStart--;
+ }
+
+ cstr.clear();
+ line->getAllPlainText(cstr);
+
+
+ reg = QRegExp("[^ ]");
+
+ int nMenuBaseLength = 20;
+ int cell_begin =
+ line->getCellBegin(
+ qMin(nMenuStart + nMenuBaseLength, (int)line->getWidth() - 1));
+ int char_begin = line->getCharBegin(cell_begin);
+ //last [^ ] until char_begin
+ strTmp = cstr.left(cstr.lastIndexOf(reg, char_begin) + 1);
+
+ int nMenuLength =
+ get_str_width((const UTF16 *)strTmp.data(), strTmp.size())
+ - nMenuStart;
+ if (nMenuLength == nMenuBaseLength + 1) {
+ strTmp = cstr.left(cstr.indexOf(" ", char_begin) + 1);
+ nMenuLength =
+ get_str_width((const UTF16 *)strTmp.data(), strTmp.size())
+ - nMenuStart; //base length is not enough
+ }
+
+ if (cursorPoint_.x() >= nMenuStart && cursorPoint_.x() <=
+ nMenuStart + nMenuLength) {
+ rect.setX(nMenuStart);
+ rect.setY(cursorPoint_.y());
+ rect.setWidth(nMenuLength);
+ rect.setHeight(1);
+ }
+ }
+ }
+ break;
+ case ArticleList:
+ case BoardList:
+ case FriendMailList:
+ case EliteArticleList:
+ if ((cursorPoint_.y() - screenStartLineNumber_) >= 3
+ && (cursorPoint_.y() - screenStartLineNumber_)
+ < termBuffer_->getNumRows() -1
+ && cursorPoint_.x() >= 12
+ && cursorPoint_.x() <= termBuffer_->getNumColumns() - 16) {
+ line = termBuffer_->getTextLineInBuffer(cursorPoint_.y());
+ //QString str = line->getText();
+ QString str;
+ line->getAllPlainText(str);
+
+ if (str.count(" ") != (int)str.length()) {
+ rect.setX(0);
+ rect.setY(cursorPoint_.y());
+ rect.setWidth(line->getWidth());
+ rect.setHeight(1);
+ }
+ }
+ break;
+ case Read:
+
+ break;
+ case Edit:
+ break;
+ case TOP10:
+ {
+ int ln = cursorPoint_.y() - screenStartLineNumber_;
+ if (ln >= 3 && (ln & 1) && ln <= 21 &&
+ cursorPoint_.x() >= 12 &&
+ cursorPoint_.x() <= termBuffer_->getNumColumns() - 8){
+ line = termBuffer_->getTextLineInBuffer(cursorPoint_.y());
+
+ QString str;
+ line->getAllPlainText(str);
+
+ if (str.count(" ") != (int)str.length()) {
+ if (ln == 21){
+ menuChar_ = '0';
+ } else {
+ menuChar_ = ((ln - 1) >> 1) + '0';
+ }
+
+ rect.setX(12);
+ rect.setY(cursorPoint_.y());
+ rect.setWidth(line->getWidth() - 20);
+ rect.setHeight(1);
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ menuRect_ = rect;
+ return rect;
+}
+
+bool FQTermSession::isIllChar(char ch) {
+ static char illChars[] = ";'\"[]<>^";
+ return ch > '~' || ch < '!' || strchr(illChars, ch) != NULL;
+}
+
+bool FQTermSession::isUrl(QRect &rcUrl, QRect &rcOld) {
+ return checkUrl(rcUrl, rcOld, false);
+}
+
+bool FQTermSession::isIP(QRect &rcUrl, QRect &rcOld) {
+ return checkUrl(rcUrl, rcOld, true);
+}
+
+QString FQTermSession::expandUrl(const QPoint& pt, QPair<int, int>& range)
+{
+ // int at = pt.x();
+ range.first = -1;
+ range.second = -2;
+ const FQTermTextLine *textLine = termBuffer_->getTextLineInBuffer(pt.y());
+ if (textLine == NULL || pt.x() > (int)textLine->getWidth()) {
+ return "";
+ }
+
+ QString text;
+ textLine->getAllPlainText(text);
+
+ int cell_begin = textLine->getCellBegin(pt.x());
+ int at = textLine->getCharBegin(cell_begin);
+ if (at >= text.length()) {
+ return "";
+ }
+
+ int start;
+ int end;
+ for (start = at; start >= 0 && !isIllChar(text.at(start).toLatin1());
+ start--) {
+ }
+ start++;
+ for (end = at; end < text.length() && !isIllChar(text.at(end).toLatin1());
+ end++) {
+ }
+ range.first = get_str_width((const UTF16 *)text.data(), start);
+ range.second = get_str_width((const UTF16 *)text.data(), end);
+ return text.mid(start, end - start);
+}
+
+
+bool FQTermSession::checkUrl(QRect &rcUrl, QRect &rcOld, bool checkIP) {
+
+
+
+ QPoint pt = cursorPoint_;
+ int at = pt.x();
+ rcOld = urlRect_;
+
+ if (at > urlRect_.left() && at < urlRect_.right() && urlRect_.y() == pt.y()) {
+ if ( (checkIP && !ip_.isEmpty()) ||
+ (!checkIP && !url_.isEmpty()) ) {
+ rcUrl = urlRect_;
+ return true;
+ }
+
+ }
+
+ QPoint urlStartPoint;
+ QPoint urlEndPoint;
+ urlStartPoint_ = QPoint();
+ urlEndPoint_ = QPoint();
+ urlRect_ = QRect(0, 0, -1, -1);
+ if (!checkIP) {
+ url_.clear();
+ } else {
+ ip_.clear();
+ }
+
+ QString urlText;
+ //phase 1: find all consecutive legal chars
+ QPair<int, int> range;
+ urlText = expandUrl(pt, range);
+ if (range.first < 0 || range.first >= range.second) {
+ return false;
+ }
+
+
+ QRect urlRect = QRect(range.first, pt.y(), range.second - range.first, 1);
+ urlStartPoint = QPoint(range.first, pt.y());
+ urlEndPoint = QPoint(range.second, pt.y());
+
+ if (range.second == termBuffer_->getNumColumns()) {
+ for (int i = pt.y() + 1; i < termBuffer_->getNumLines(); ++i) {
+ QString lineText = expandUrl(QPoint(0, i), range);
+ if (range.first == 0) {
+ urlText += lineText;
+ urlEndPoint.setY(urlEndPoint.y() + 1);
+ urlEndPoint.setX(range.second);
+ if (range.second == termBuffer_->getNumColumns()) {
+ continue;
+ }
+ }
+ break;
+ }
+ }
+
+ //phase 2: find protocol prefix for url
+ //if none, prefix to add is set to "mailto:" if '@' is found
+ //otherwise, the prefix is "http://" by default.
+ QString prefixToAdd;
+ int protocolIndex;
+ for (protocolIndex = 0; protocolIndex < ProtocolSupported; ++protocolIndex) {
+ int begin = urlText.indexOf(protocolPrefix[protocolIndex],
+ Qt::CaseInsensitive);
+ if (begin != -1 && begin <= at) {
+ prefixToAdd = protocolPrefix[protocolIndex];
+ urlText = urlText.mid(begin + protocolPrefix[protocolIndex].length());
+ urlStartPoint.setX(urlStartPoint.x() + begin);
+ break;
+ }
+ }
+ if (protocolIndex == ProtocolSupported) {
+ int begin = urlText.indexOf("://");
+ if (begin != -1) {
+ return false;
+ }
+ if (urlText.indexOf('@') != -1) {
+ prefixToAdd = protocolPrefix[Mailto];
+ } else {
+ prefixToAdd = protocolPrefix[Http];
+ }
+ }
+
+ //no point or duplicated points
+ if (urlText.indexOf("..") != -1 || urlText.indexOf('.') == -1) {
+ return false;
+ }
+
+ //phase 3: (for check ip) if there is a ':' before ip, there must be a '@'
+ int host_begin = qMax(urlText.lastIndexOf('@') + 1, 0);
+ int host_end = urlText.indexOf(':', host_begin);
+ if (host_end == -1) {
+ host_end = urlText.indexOf('/', host_begin);
+ }
+ if (host_end == -1) {
+ host_end = urlText.length();
+ }
+ if (host_begin >= host_end) {
+ return false;
+ }
+ if (checkIP && urlText[host_end - 1] == '*') {
+ urlText[host_end - 1] = '1';
+ }
+
+ for (int index = 0; index < urlText.length() && urlText.at(index) != '/';
+ index++) {
+ QChar cur(urlText.at(index));
+ if (!cur.isLetterOrNumber() && !QString("-_~:@.").contains(cur)) {
+ return false;
+ }
+ }
+
+ QString newIP;
+ newIP = urlText.mid(host_begin, host_end - host_begin);
+ QStringList ipv4 = newIP.split(QLatin1String("."));
+ bool isIPv4 = true;
+ if (ipv4.count() != 4){
+ isIPv4 = false;
+ }
+ foreach(QString domain, ipv4) {
+ bool ok;
+ int num = domain.toInt(&ok);
+ //won't tolerant spaces.
+ if (!ok || num < 0 || num > 255 || domain.length() > 3) {
+ isIPv4 = false;
+ break;
+ }
+ }
+
+ if (!checkIP){
+ QString lastName = ipv4.back();
+
+ int lastCharIndex = lastName.lastIndexOf(QRegExp("[a-zA-Z]"));
+ if (lastCharIndex == -1) {
+ if (!isIPv4) {
+ return false;
+ } else if (urlText == newIP) {
+ return false;
+ }
+ } else {
+ const QString *begin = endOfUrl;
+ const QString *end = endOfUrl + sizeof(endOfUrl) / sizeof(QString *);
+ if (qFind(begin, end, lastName) == end) {
+ return false;
+ }
+ }
+ url_ = prefixToAdd + urlText;
+ } else {
+ if (!isIPv4) {
+ return false;
+ }
+ ip_ = newIP;
+ }
+
+ urlRect_ = urlRect;
+ rcUrl = urlRect;
+ urlStartPoint_ = urlStartPoint;
+ urlEndPoint_ = urlEndPoint;
+ return true;
+}
+
+QString FQTermSession::getUrl() {
+ return url_;
+}
+
+QString FQTermSession::getIP() {
+ return ip_;
+}
+
+bool FQTermSession::isPageComplete() {
+ return termBuffer_->getCaretRow() == (termBuffer_->getNumRows() - 1)
+ && termBuffer_->getCaretColumn() == (termBuffer_->getNumColumns() - 1);
+}
+
+bool FQTermSession::isAntiIdle() {
+ return param_.isAntiIdle_;
+}
+
+void FQTermSession::setAntiIdle(bool antiIdle) {
+ param_.isAntiIdle_ = antiIdle;
+
+ // disabled
+ if (!param_.isAntiIdle_ && idleTimer_->isActive()) {
+ idleTimer_->stop();
+ }
+
+ // enabled
+ if (param_.isAntiIdle_) {
+ if (idleTimer_->isActive()) {
+ idleTimer_->stop();
+ }
+ idleTimer_->start(param_.maxIdleSeconds_ *1000);
+ }
+}
+
+void FQTermSession::setAutoReconnect(bool autoReconnect) {
+ param_.isAutoReconnect_ = autoReconnect;
+ reconnectRetry_ = 0;
+ if (autoReconnect && !isConnected_) {
+ reconnectProcess();
+ }
+}
+
+
+void FQTermSession::autoReplyMessage() {
+ if (autoReplyTimer_->isActive()) {
+ autoReplyTimer_->stop();
+ }
+ if (pageState_ != Message) {
+ return;
+ }
+ if (scriptListener_)
+ {
+ bool res = scriptListener_->postScriptCallback(SFN_AUTO_REPLY
+#ifdef HAVE_PYTHON
+ ,Py_BuildValue("l", scriptListener_->windowID())
+#endif //HAVE_PYTHON
+ );
+ if (res) return;
+ }
+ QByteArray cstrTmp = param_.replyKeyCombination_.toLocal8Bit();
+ QByteArray cstr = parseString(cstrTmp.isEmpty() ? QByteArray("^Z"): cstrTmp);
+ //cstr += m_param.m_strAutoReply.toLocal8Bit();
+ cstr += unicode2bbs(param_.autoReplyMessage_);
+ cstr += '\n';
+ telnet_->write(cstr, cstr.length());
+
+ emit messageAutoReplied();
+}
+
+QByteArray FQTermSession::parseString(const QByteArray &cstr, int *len) {
+ QByteArray parsed = "";
+
+ if (len != 0) {
+ *len = 0;
+ }
+
+ for (uint i = 0; (long)i < cstr.length(); i++) {
+ if (cstr.at(i) == '^') {
+ i++;
+ if ((long)i < cstr.length()) {
+ parsed += FQTERM_CTRL(cstr.at(i));
+ if (len != 0) {
+ *len = *len + 1;
+ }
+ }
+ } else if (cstr.at(i) == '\\') {
+ i++;
+ if ((long)i < cstr.length()) {
+ if (cstr.at(i) == 'n') {
+ parsed += CHAR_CR;
+ } else if (cstr.at(i) == 'r') {
+ parsed += CHAR_LF;
+ } else if (cstr.at(i) == 't') {
+ parsed += CHAR_TAB;
+ }
+ if (len != 0) {
+ *len = *len + 1;
+ }
+ }
+ } else {
+ parsed += cstr.at(i);
+ if (len != 0) {
+ *len = *len + 1;
+ }
+ }
+ }
+
+ return parsed;
+}
+
+void FQTermSession::reconnect() {
+ if (!isConnected_) {
+ telnet_->connectHost(param_.hostAddress_, param_.port_);
+ reconnectRetry_++;
+ }
+}
+
+void FQTermSession::reconnectProcess() {
+ if (!isConnected_ && param_.isAutoReconnect_ && (reconnectRetry_ < param_.retryTimes_ || param_.retryTimes_ == -1)) {
+ int interval = param_.reconnectInterval_ <= 0 ? 0 : param_.reconnectInterval_ * 1000;
+ QTimer::singleShot(interval, this, SLOT(reconnect()));
+ }
+}
+
+void FQTermSession::setMouseMode(bool on) {
+ isMouseX11_ = on;
+}
+
+void FQTermSession::doAutoLogin() {
+ if (!param_.preLoginCommand_.isEmpty()) {
+ QByteArray temp = parseString(param_.preLoginCommand_.toLatin1());
+ telnet_->write((const char*)(temp), temp.length());
+ }
+ if (!param_.userName_.isEmpty()) {
+ QByteArray temp = param_.userName_.toLocal8Bit();
+ telnet_->write((const char*)(temp), temp.length());
+ char ch = CHAR_CR;
+ telnet_->write(&ch, 1);
+ }
+ if (!param_.password_.isEmpty()) {
+ QByteArray temp = param_.password_.toLocal8Bit();
+ telnet_->write((const char*)(temp), temp.length());
+ char ch = CHAR_CR;
+ telnet_->write(&ch, 1);
+ }
+
+ // smth ignore continous input, so sleep 1 sec :)
+#if defined(_OS_WIN32_) || defined(Q_OS_WIN32)
+ Sleep(1000);
+#else
+ sleep(1);
+#endif
+
+ if (!param_.postLoginCommand_.isEmpty()) {
+ QByteArray temp = parseString(param_.postLoginCommand_.toLatin1());
+ telnet_->write((const char*)(temp), temp.length());
+ }
+ isTelnetLogining_ = false;
+}
+
+//read slot
+void FQTermSession::readReady(int size, int raw_size) {
+ FQ_ASSERT(size > 0 || raw_size > 0); // maybe raw_size is greater than 0.
+
+ raw_data_.resize(raw_size);
+ telnet_->read_raw(&raw_data_[0], raw_size);
+
+ // read raw buffer
+ int zmodem_consumed;
+ if (param_.enableZmodem_)
+ zmodem_->ZmodemRcv((uchar*)&raw_data_[0], raw_data_.size(), &(zmodem_->info),
+ zmodem_consumed);
+
+ if (zmodem_->transferstate == notransfer) {
+ //decode
+ if (size > 0) {
+ int last_size = telnet_data_.size();
+ telnet_data_.resize(last_size + size);
+ telnet_->read(&telnet_data_[0] + last_size, size);
+ int processed = 0;
+ {
+ while (!bufferWriteLock_.tryLockForWrite()) {}
+ //QWriteLocker locker(&bufferWriteLock_);
+ processed = decoder_->decode(&telnet_data_[0], telnet_data_.size());
+ bufferWriteLock_.unlock();
+ }
+ telnet_data_.erase(telnet_data_.begin(), telnet_data_.begin() + processed);
+ }
+
+ if (isTelnetLogining_) {
+ int n = termBuffer_->getCaretRow();
+ for (int y = n - 5; y < n + 5; y++) {
+ y = qMax(0, y);
+ const FQTermTextLine *pTextLine = termBuffer_->getTextLineInTerm(y);
+ if (pTextLine == NULL) {
+ continue;
+ }
+
+ // QString str = pTextLine->getText();
+ QString str;
+ pTextLine->getAllPlainText(str);
+
+ if (str.indexOf("guest") != -1 /*&& str.indexOf("new") != -1*/) {
+ doAutoLogin();
+ break;
+ }
+ }
+ }
+ // page complete when caret at the right corner
+ // this works for most but not for all
+ const FQTermTextLine *pTextLine =
+ termBuffer_->getTextLineInTerm(termBuffer_->getNumRows() - 1);
+
+ //QString strText = stripWhitespace(pTextLine->getText());
+ // TODO_UTF16: fixme! performance issue!
+ QString strText;
+ pTextLine->getAllPlainText(strText);
+
+ // TODO_UTF16: shall we disable trim?
+ strText = strText.trimmed();
+
+ if (termBuffer_->getCaretRow() == termBuffer_->getNumRows() - 1
+ && termBuffer_->getCaretColumn() >= (strText.length() - 1) / 2) {
+ waitCondition_.wakeAll();
+ }
+
+ //QToolTip::remove(this, screen_->mapToRect(m_rcUrl));
+
+ // message received
+ // 03/19/2003. the caret posion removed as a message judgement
+ // because smth.org changed
+ if (decoder_->bellReceive()) {
+ emit startAlert();
+ emit bellReceived();
+
+ bool bellConsumed = false;
+ if (scriptListener_) {
+ bellConsumed = scriptListener_->postScriptCallback(SFN_ON_BELL
+#ifdef HAVE_PYTHON
+ ,Py_BuildValue("l", scriptListener_->windowID())
+#endif //HAVE_PYTHON
+ );
+ }
+
+ if (isAutoReply() && !bellConsumed) {
+ // TODO: save messages
+ if (isIdling_) {
+ autoReplyMessage();
+ } else {
+ autoReplyTimer_->start(param_.maxIdleSeconds_ *1000 / 2);
+ }
+ }
+ }
+
+ // set page state
+ detectPageState();
+ if (scriptListener_) {
+ scriptListener_->postScriptCallback(SFN_DATA_EVENT
+#ifdef HAVE_PYTHON
+ ,Py_BuildValue("l", scriptListener_->windowID())
+#endif //HAVE_PYTHON
+ );
+ }
+ emit sessionUpdated();
+ }
+
+ if (zmodem_->transferstate == transferstop) {
+ zmodem_->transferstate = notransfer;
+ }
+}
+
+/* 0-left 1-middle 2-right 3-relsase 4/5-wheel
+ *
+ */
+//void FQTermWindow::sendMouseState( int num,
+// Qt::ButtonState btnstate, Qt::ButtonState keystate, const QPoint& pt )
+void FQTermSession::sendMouseState(int num, Qt::KeyboardModifier btnstate,
+ Qt::KeyboardModifier keystate, const QPoint &pt) {
+ /*
+ if(!m_bMouseX11)
+ return;
+
+ QPoint ptc = screen_->mapToChar(pt);
+
+ if(btnstate&Qt::LeftButton)
+ num = num==0?0:num;
+ else if(btnstate&Qt::MidButton)
+ num = num==0?1:num;
+ else if(btnstate&Qt::RightButton)
+ num = num==0?2:num;
+
+ int state = 0;
+ if(keystate&Qt::ShiftModifier)
+ state |= 0x04;
+ if(keystate&Qt::MetaModifier)
+ state |= 0x08;
+ if(keystate&Qt::ControlModifier)
+ state |= 0x10;
+
+ // normal buttons are passed as 0x20 + button,
+ // mouse wheel (buttons 4,5) as 0x5c + button
+ if(num>3) num += 0x3c;
+
+ char mouse[10];
+ sprintf(mouse, "\033[M%c%c%c",
+ num+state+0x20,
+ ptc.x()+1+0x20,
+ ptc.y()+1+0x20);
+ telnet_->write( mouse, strlen(mouse) );
+ */
+}
+
+void FQTermSession::cancelZmodem() {
+ zmodem_->zmodemCancel();
+}
+
+void FQTermSession::disconnect() {
+ telnet_->close();
+ finalizeConnection();
+}
+
+void FQTermSession::finalizeConnection() {
+ if (isConnected_) {
+ QString strMsg = "";
+ strMsg += "\n\n\n\r\n\r";
+ strMsg += "\x1b[17C\x1b[0m===========================================\n\r";
+ strMsg +=
+ "\x1b[17C Connection Closed, Press \x1b[1m\x1b[31;40mEnter\x1b[m\x1b[0m To Connect\n\r";
+ strMsg += "\x1b[17C===========================================\n";
+ decoder_->decode(strMsg.toLatin1(), strMsg.length());
+ }
+ isConnected_ = false;
+
+ if (autoReplyTimer_->isActive()) {
+ autoReplyTimer_->stop();
+ }
+
+ if (idleTimer_->isActive()) {
+ idleTimer_->stop();
+ }
+
+ emit connectionClosed();
+}
+
+// telnet state slot
+void FQTermSession::changeTelnetState(int state) {
+ switch (state) {
+ case TSRESOLVING:
+ break;
+ case TSHOSTFOUND:
+ break;
+ case TSHOSTNOTFOUND:
+ finalizeConnection();
+ break;
+ case TSCONNECTING:
+ break;
+ case TSHOSTCONNECTED:
+ isConnected_ = true;
+ reconnectRetry_ = 0;
+ if (param_.isAutoLogin_ && param_.protocolType_==0) {
+ isTelnetLogining_ = true;
+ }
+
+ break;
+ case TSPROXYCONNECTED:
+ break;
+ case TSPROXYAUTH:
+ break;
+ case TSPROXYFAIL:
+ disconnect();
+ break;
+ case TSREFUSED:
+ finalizeConnection();
+ break;
+ case TSREADERROR:
+ disconnect();
+ break;
+ case TSCLOSED:
+ finalizeConnection();
+ if (param_.isAutoReconnect_) {
+ reconnectProcess();
+ }
+ break;
+ case TSCLOSEFINISH:
+ finalizeConnection();
+ break;
+ case TSCONNECTVIAPROXY:
+ break;
+ case TSEGETHOSTBYNAME:
+ finalizeConnection();
+ break;
+ case TSEINIWINSOCK:
+ finalizeConnection();
+ break;
+ case TSERROR:
+ disconnect();
+ break;
+ case TSPROXYERROR:
+ disconnect();
+ break;
+ case TSWRITED:
+ // restart the idle timer
+ if (idleTimer_->isActive()) {
+ idleTimer_->stop();
+ }
+ if (param_.isAntiIdle_) {
+ idleTimer_->start(param_.maxIdleSeconds_ *1000);
+ }
+ isIdling_ = false;
+ break;
+ default:
+ break;
+ }
+
+ emit telnetStateChanged(state);
+}
+
+void FQTermSession::handleInput(const QString &text) {
+ if (text.length() > 0) {
+ QByteArray cstrTmp = unicode2bbs_smart(text);
+ telnet_->write(cstrTmp, cstrTmp.length());
+ }
+}
+
+QString FQTermSession::bbs2unicode(const QByteArray &text)
+{
+ return encoding2unicode(text, param_.serverEncodingID_);
+}
+
+QByteArray FQTermSession::unicode2bbs(const QString &text) {
+ return unicode2encoding(text, param_.serverEncodingID_);
+}
+
+
+QByteArray FQTermSession::unicode2bbs_smart(const QString &text) {
+ QByteArray strTmp;
+
+ switch(param_.serverEncodingID_)
+ {
+ case FQTERM_ENCODING_GBK:
+ if (FQTermPref::getInstance()->imeEncodingID_ == FQTERM_ENCODING_BIG5)
+ {
+ strTmp = U2B(text);
+ char* tmp = encodingConverter_.B2G(strTmp, strTmp.length());
+ strTmp = tmp;
+ delete []tmp;
+ }
+ else
+ {
+ strTmp = U2G(text);
+ }
+ break;
+ case FQTERM_ENCODING_BIG5:
+ if (FQTermPref::getInstance()->imeEncodingID_ == FQTERM_ENCODING_GBK)
+ {
+ strTmp = U2G(text);
+ char* tmp = encodingConverter_.G2B(strTmp, strTmp.length());
+ strTmp = tmp;
+ delete []tmp;
+ }
+ else
+ {
+ strTmp = U2B(text);
+ }
+ break;
+ case FQTERM_ENCODING_HKSCS:
+ if (FQTermPref::getInstance()->imeEncodingID_ == FQTERM_ENCODING_GBK)
+ {
+ strTmp = U2G(text);
+ char* tmp = encodingConverter_.G2B(strTmp, strTmp.length());
+ strTmp = tmp;
+ delete []tmp;
+ }
+ else
+ {
+ strTmp = U2H(text);
+ }
+ break;
+ case FQTERM_ENCODING_UTF8:
+ strTmp = U2U8(text);
+ break;
+ case FQTERM_ENCODING_UAO:
+ if (FQTermPref::getInstance()->imeEncodingID_ == FQTERM_ENCODING_GBK)
+ {
+ strTmp = U2G(text);
+ char* tmp = encodingConverter_.G2B(strTmp, strTmp.length());
+ strTmp = tmp;
+ delete []tmp;
+ }
+ else
+ {
+ strTmp = U2A(text);
+ }
+ break;
+ }
+
+ return strTmp;
+}
+
+
+void FQTermSession::onIdle() {
+ // do as autoreply when it is enabled
+ if (autoReplyTimer_->isActive() && param_.isAutoReply_) {
+ autoReplyMessage();
+ stopAlert();
+ return ;
+ }
+
+ isIdling_ = true;
+ // system script can handle that
+ if (scriptListener_) {
+ bool res = scriptListener_->postScriptCallback(SFN_ANTI_IDLE
+#ifdef HAVE_PYTHON
+ ,Py_BuildValue("l", scriptListener_->windowID())
+#endif //HAVE_PYTHON
+ );
+ if (res)
+ return;
+ }
+ // the default function
+ int length;
+ QByteArray cstr = parseString(param_.antiIdleMessage_.toLocal8Bit(), &length);
+ telnet_->write(cstr, length);
+}
+
+void FQTermSession::onAutoReply() {
+ // if AutoReply still enabled, then autoreply
+ if (param_.isAutoReply_) {
+ autoReplyMessage();
+ } else {
+ // else just stop the timer
+ autoReplyTimer_->stop();
+ }
+
+ stopAlert();
+}
+bool FQTermSession::isAutoReply() {
+ return param_.isAutoReply_;
+}
+
+void FQTermSession::setAutoReply(bool on) {
+ param_.isAutoReply_ = on;
+ if (!param_.isAutoReply_ && autoReplyTimer_->isActive()) {
+ autoReplyTimer_->stop();
+ }
+}
+
+int FQTermSession::write(const char *data, int len) {
+ return telnet_->write(data, len);
+}
+
+int FQTermSession::writeStr(const char *str) {
+ return write(str, strlen(str));
+}
+
+void FQTermSession::setProxy(int type, bool needAuth,
+ const QString &hostName, quint16 portNumber,
+ const QString &userName, const QString &password) {
+ telnet_->setProxy(type, needAuth, hostName, portNumber, userName, password);
+}
+
+void FQTermSession::connectHost(const QString &hostName, quint16 portNumber) {
+ telnet_->connectHost(hostName, portNumber);
+}
+
+void FQTermSession::close() {
+ telnet_->close();
+ finalizeConnection();
+}
+
+void FQTermSession::clearLineChanged(int index) {
+ termBuffer_->clearLineChanged(index);
+}
+
+void FQTermSession::setLineAllChanged(int index) {
+ termBuffer_->setLineAllChanged(index);
+}
+
+void FQTermSession::setTermSize(int col, int row) {
+ termBuffer_->setTermSize(col, row);
+ param_.numColumns_ = col;
+ param_.numRows_ = row;
+}
+
+FQTermBuffer *FQTermSession::getBuffer() const {
+ return termBuffer_;
+}
+
+void FQTermSession::setSelect(const QPoint &pt1, const QPoint &pt2) {
+ termBuffer_->setSelect(pt1, pt2);
+}
+
+void FQTermSession::clearSelect() {
+ termBuffer_->clearSelect();
+}
+
+void FQTermSession::leaveIdle() {
+ if (autoReplyTimer_->isActive()) {
+ autoReplyTimer_->stop();
+ }
+
+ if (idleTimer_->isActive()) {
+ idleTimer_->stop();
+ }
+
+ if (param_.isAntiIdle_) {
+ idleTimer_->start(param_.maxIdleSeconds_ * 1000);
+ }
+}
+
+void FQTermSession::copyArticle() {
+ if (!acThread_->isRunning()) {
+ acThread_->start();
+ }
+}
+
+void FQTermSession::getLineColorInfo(const FQTermTextLine * line,
+ LineColorInfo * colorInfo)
+{
+ colorInfo->backgroundColorIndex.clear();
+ colorInfo->foregroundColorIndex.clear();
+ colorInfo->hasBackgroundColor = false;
+ colorInfo->uniBackgroundColor = true;
+ colorInfo->uniForegroundColor = true;
+ colorInfo->hasForegroundColor = false;
+
+ if (!line || line->getWidth() == 0) {
+ return;
+ }
+
+ const unsigned char *color = line->getColors();
+ unsigned char background = GETBG(color[0]);
+ unsigned char foreground = GETFG(color[0]);
+ colorInfo->backgroundColorIndex.append(background);
+ colorInfo->foregroundColorIndex.append(foreground);
+ //for (int i = 0; i < color.length() / 2; i++) {
+ // TODO_UTF16: why use color.length()/2 formerly?
+ for (int i = 0; i < (int)line->getWidth(); i++) {
+ if (GETBG(color[i]) != background) {
+ colorInfo->uniBackgroundColor = false;
+ background = GETBG(color[i]);
+ colorInfo->backgroundColorIndex.append(background);
+ }
+ if (GETBG(color[i]) != GETBG(NO_COLOR)) {
+ colorInfo->hasBackgroundColor = true;
+ }
+ if (GETFG(color[i]) != foreground) {
+ colorInfo->uniForegroundColor = false;
+ foreground = GETFG(color[i]);
+ colorInfo->foregroundColorIndex.append(foreground);
+ }
+ if (GETFG(color[i]) != GETFG(NO_COLOR)) {
+ colorInfo->hasForegroundColor = true;
+ }
+ }
+}
+
+bool FQTermSession::readyForInput()
+{
+ return telnet_->readyForInput();
+}
+
+void FQTermSession::onEnqReceived() {
+ if (FQTermPref::getInstance()->replyENQ_)
+ telnet_->write(ANSWERBACK_MESSAGE, sizeof(ANSWERBACK_MESSAGE));
+}
+
+void FQTermSession::onSSHAuthOK() {
+ isSSHLogining_ = false;
+ //setTermSize(80, 24);
+ //setTermSize(param_.numColumns_, param_.numRows_);
+ telnet_->windowSizeChanged(param_.numColumns_, param_.numRows_);
+}
+
+void FQTermSession::updateSetting( const FQTermParam& p ) {
+ bool toggleAutoReconnect = (p.isAutoReconnect_ != param_.isAutoReconnect_);
+ param_ = p;
+ setTermSize(p.numColumns_, p.numRows_);
+ setAntiIdle(isAntiIdle());
+ if (toggleAutoReconnect)
+ setAutoReconnect(param_.isAutoReconnect_);
+}
+
+ArticleCopyThread::ArticleCopyThread(
+ FQTermSession &bbs, QWaitCondition &waitCondition, QReadWriteLock &bufferLock)
+ : session_(bbs),
+ waitCondition_(waitCondition),
+ lock_(bufferLock) {
+ FQ_VERIFY(connect(this, SIGNAL(writeSession(const QString&)),
+ &session_, SLOT(handleInput(const QString&)),
+ Qt::QueuedConnection));
+}
+
+ArticleCopyThread::~ArticleCopyThread() {
+}
+
+static void removeTrailSpace(QString &line) {
+ for (int last_non_space = line.size() - 1;
+ last_non_space >= 0; --last_non_space) {
+ QChar a = line.at(last_non_space);
+ if (!a.isSpace()) {
+ line.resize(last_non_space + 1);
+ break;
+ }
+
+ if (last_non_space == 0) {
+ line.resize(0);
+ }
+ }
+}
+
+
+///////////////////////////////////////
+//analyze last line when copy article
+static std::pair<int, int> ParseLastLine(QString str) {
+ int startLine = -1;
+ int endLine = -1;
+ int infoStart = str.indexOf('(', str.indexOf('(') + 1);
+ int infoEnd = str.indexOf(')', infoStart);
+ int infoSplit = str.indexOf('-', infoStart);
+ if (infoStart == -1 || infoEnd == -1 || infoSplit == -1) {
+ return std::make_pair(-1, -1);
+ }
+ bool ok = true;
+ startLine = str.mid(infoStart + 1, infoSplit - infoStart - 1).toInt(&ok);
+ if (!ok) {
+ return std::make_pair(-1, -1);
+ }
+ endLine = str.mid(infoSplit + 1, infoEnd - infoSplit - 1).toInt(&ok);
+ if (!ok) {
+ return std::make_pair(-1, -1);
+ }
+ return std::make_pair(startLine, endLine);
+}
+///////////////////////////////////////
+
+
+void ArticleCopyThread::run() {
+ QReadLocker locker(&lock_);
+
+ typedef std::vector<QString> Page;
+ const FQTermBuffer *buffer = session_.getBuffer();;
+ Page page;
+
+ QString firstPageLastLine;
+ buffer->getTextLineInTerm(buffer->getNumRows() - 1)->getAllPlainText(firstPageLastLine);
+ bool MultiPage = (firstPageLastLine.indexOf("%") != -1);
+ if (!MultiPage) {
+ emit writeSession("q");
+ emit writeSession("\n");
+ if (!waitCondition_.wait(&lock_, 10000)) {
+ emit articleCopied(DAE_TIMEOUT, "");
+ return;
+ }
+ buffer->getTextLineInTerm(buffer->getNumRows() - 1)->getAllPlainText(firstPageLastLine);
+ MultiPage = (firstPageLastLine.indexOf("%") != -1);
+ }
+
+ if (MultiPage) {
+ //session_.write("e", 1);
+ emit writeSession("e");
+ if (!waitCondition_.wait(&lock_, 10000)) {
+ emit articleCopied(DAE_TIMEOUT, "");
+ return;
+ }
+ QString LastPageLastLine;
+ buffer->getTextLineInTerm(buffer->getNumRows() - 1)->getAllPlainText(LastPageLastLine);
+ std::pair<int, int> range = ParseLastLine(LastPageLastLine);
+ if (range.first == -1 || range.second == -1) {
+ return;
+ }
+ page.resize(range.second);
+ for (int i = range.first; i <= range.second; ++i) {
+ QString strTemp;
+ buffer->getTextLineInTerm(i - range.first)->getAllPlainText(strTemp);
+ page[i - 1] = strTemp;
+ }
+ //session_.write("s", 1);
+ emit writeSession("s");
+ if (!waitCondition_.wait(&lock_, 10000)) {
+ emit articleCopied(DAE_TIMEOUT, "");
+ return;
+ }
+ }
+ else {
+ for (int i = 0; i < buffer->getNumRows() - 1; ++i) {
+ QString strTemp;
+ buffer->getTextLineInTerm(i)->getAllPlainText(strTemp);
+ page.push_back(strTemp);
+ }
+ }
+
+ while (MultiPage) {
+ // the end of article
+ int lineIndex = buffer->getNumRows() - 1;
+ //QByteArray lastLine = buffer->getLineInScreen(lineIndex)->getText();
+ QString lastLine;
+ buffer->getTextLineInTerm(lineIndex)->getAllPlainText(lastLine);
+
+ std::pair<int, int> range = ParseLastLine(lastLine);
+ if (range.first == -1 || range.second == -1) {
+ page.push_back(lastLine);
+ break;
+ }
+
+ // copy a page of lines exclude the last line.
+ for (int i = range.first; i <= range.second; ++i) {
+ QString strTemp;
+ buffer->getTextLineInTerm(i - range.first)->getAllPlainText(strTemp);
+ page[i - 1] = strTemp;
+ }
+
+
+ // wait for next page.
+ //session_.write(" ", 1);
+ emit writeSession(" ");
+ if (!waitCondition_.wait(&lock_, 10000)) {
+ emit articleCopied(DAE_TIMEOUT, "");
+ break;
+ }
+ }
+
+
+
+ QString articleText;
+
+ for (Page::iterator line = page.begin(); line != page.end(); ++line) {
+ removeTrailSpace(*line);
+ articleText += (*line);
+ articleText += (OS_NEW_LINE);
+ }
+
+ //qApp->postEvent(pWin, new QCustomEvent(DAE_FINISH));
+ emit articleCopied(DAE_FINISH, articleText);
+}
+
+} // namespace FQTerm
+
+#include "fqterm_session.moc"
diff --git a/src/terminal/fqterm_session.h b/src/terminal/fqterm_session.h
new file mode 100644
index 0000000..78aaa31
--- /dev/null
+++ b/src/terminal/fqterm_session.h
@@ -0,0 +1,344 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SESSION_H
+#define FQTERM_SESSION_H
+
+#include <vector>
+
+#include <QPoint>
+#include <QRect>
+#include <QObject>
+#include <QThread>
+#include <QString>
+#include <QWaitCondition>
+#include <QList>
+#include <QtScript/QScriptValue>
+#include <QReadWriteLock>
+#include "fqterm_param.h"
+#include "fqterm_config.h"
+#include "fqterm_convert.h"
+#ifdef HAVE_PYTHON
+#include <Python.h>
+#endif //HAVE_PYTHON
+
+class QRect;
+class QTimer;
+
+namespace FQTerm {
+
+class FQTermScriptEventListener {
+public:
+ bool postScriptCallback(const QString& func,
+#ifdef HAVE_PYTHON
+ PyObject* pArgs,
+#endif //HAVE_PYTHON
+ const QScriptValueList & args = QScriptValueList())
+ {
+ bool res = postQtScriptCallback(func, args);
+#ifdef HAVE_PYTHON
+ res = postPythonCallback(func, pArgs) || res;
+#endif //HAVE_PYTHON
+ return res;
+ }
+ virtual long windowID() = 0;
+ virtual ~FQTermScriptEventListener() {}
+private:
+ virtual bool postQtScriptCallback(const QString& func, const QScriptValueList & args = QScriptValueList()) = 0;
+#ifdef HAVE_PYTHON
+ virtual bool postPythonCallback(const QString& func, PyObject* pArgs) = 0;
+#endif //HAVE_PYTHON
+};
+
+struct LineColorInfo {
+ bool hasBackgroundColor;
+ bool hasForegroundColor;
+ bool uniBackgroundColor;
+ bool uniForegroundColor;
+ QList<unsigned char> backgroundColorIndex;
+ QList<unsigned char> foregroundColorIndex;
+};
+
+class FQTermConfig;
+class FQTermBuffer;
+class FQTermTextLine;
+class FQTermTelnet;
+class FQTermDecode;
+class FQTermZmodem;
+class ArticleCopyThread;
+
+class FQTermSession: public QObject {
+ Q_OBJECT;
+ public:
+ enum CursorType {
+ kHome = 0,
+ kEnd = 1,
+ kPageUp = 2,
+ kPageDown = 3,
+ kUp = 4,
+ kDown = 5,
+ kLeft = 6,
+ kRight = 7,
+ kNormal = 8
+ };
+
+ FQTermSession(FQTermConfig *, FQTermParam);
+ ~FQTermSession();
+
+ enum PageState {
+ Undefined = -1,
+ Menu = 0,
+ MailMenu = 1,
+ ArticleList = 2,
+ EliteArticleList = 3,
+ BoardList = 4,
+ FriendMailList = 5,
+ Message = 6,
+ Read = 7,
+ Edit = 8,
+ TOP10 = 9,
+ };
+
+ enum ProtocolIndex {
+ Http = 0,
+ Https = 1,
+ Mms = 2,
+ Rstp = 3,
+ Ftp = 4,
+ Mailto = 5,
+ Telnet = 6,
+ ProtocolSupported = 7
+ };
+
+ static const QString endOfUrl[];
+
+ static const QString protocolPrefix[];
+ PageState getPageState();
+
+ // Set current cursor postion to pt,
+ // return whether the selection rectangle is changed.
+ // the output parameter rc be a rectangle including both
+ // the new and the old selection region.
+ bool setCursorPos(const QPoint &pt, QRect &rc);
+ CursorType getCursorType(const QPoint &);
+
+ // Get the menu char detected in getSelectRect().
+ char getMenuChar();
+
+ // Get current selection rectangle.
+ // also detect the menu char if in kMenu page state.
+ QRect detectMenuRect();
+ QRect getMenuRect() {return menuRect_;}
+ void setMenuRect(int row, int col, int len);
+ // detect whether the given line or point is contained by current selection rectangle.
+ bool isSelectedMenu(int line);
+ bool isSelectedMenu(const QPoint &);
+ //selection.
+ void setSelect(const QPoint &pt1, const QPoint &pt2);
+ void clearSelect();
+
+ bool isUrl(QRect &, QRect &);
+ bool isIP(QRect &, QRect &);
+ QString getUrl();
+ QString getIP();
+
+
+
+ // Set current screen start line to help detect cursor type
+ // and select rectangle corresponding to current cursor postion.
+ void setScreenStart(int);
+
+
+
+ // Set a line of buffer to have been changed from start to end.
+ void clearLineChanged(int index);
+ void setLineAllChanged(int index);
+
+ bool isAntiIdle();
+ void setAntiIdle(bool antiIdle);
+ void leaveIdle();
+
+ bool isAutoReply();
+ void setAutoReply(bool autoReply);
+ QString getMessage();
+
+ void setAutoReconnect(bool autoReconnect);
+
+
+ bool readyForInput();
+ void setTermSize(int col, int row);
+
+ QWaitCondition& getWaitCondition() {return waitCondition_;};
+ //this function will do
+ //1. convert unicode to bbs encoding
+ //2. if there are some chars express same meaning in simplify/traditional
+ //Chinese, auto covert them by considering ime/bbs encoding.
+ QByteArray unicode2bbs_smart(const QString &);
+ QString bbs2unicode(const QByteArray &text);
+ QByteArray unicode2bbs(const QString &text);
+
+ // Write data raw data
+ int write(const char *data, int len);
+ int writeStr(const char *str);
+
+ // type: 0-no proxy; 1-wingate; 2-sock4; 3-socks5
+ // needAuth: if authentation needed
+ void setProxy(int type, bool needAuth,
+ const QString &hostname, quint16 portNumber,
+ const QString &username, const QString &password);
+ // User close the connection
+ void close();
+
+ bool isConnected() {return isConnected_;}
+ void setSendingMessage(bool sending = true) {isSendingMessage_ = sending;}
+ const QPoint& urlStartPoint() {return urlStartPoint_;}
+ const QPoint& urlEndPoint() {return urlEndPoint_;}
+
+ FQTermParam& param() {return param_;}
+ void updateSetting(const FQTermParam& p);
+ QReadWriteLock& getBufferLock() {return bufferWriteLock_;}
+
+ public:
+
+
+ public slots:
+ FQTermBuffer *getBuffer() const;
+ void connectHost(const QString &hostname, quint16 portnumber);
+ void reconnect();
+ void disconnect();
+
+ void cancelZmodem();
+ void changeTelnetState(int state);
+
+ void handleInput(const QString &text);
+
+ void copyArticle();
+
+ signals:
+ void messageAutoReplied();
+ void articleCopied(int state, const QString content);
+ void sessionUpdated();
+ void connectionClosed();
+ void bellReceived();
+ void onTitleSet(const QString&);
+ void startAlert();
+ void stopAlert();
+
+ void requestUserPwd(QString *user, QString *pwd, bool *isOK);
+
+ void telnetStateChanged(int state);
+ void zmodemStateChanged(int type, int value, const char *status);
+
+ void errorMessage(QString);
+
+private slots:
+ void readReady(int size, int raw_size);
+ void onIdle();
+ void onAutoReply();
+ void onEnqReceived();
+ void onSSHAuthOK();
+ void setMouseMode(bool on);
+
+private:
+ void sendMouseState(int, Qt::KeyboardModifier, Qt::KeyboardModifier, const QPoint &);
+ void getLineColorInfo(const FQTermTextLine * line, LineColorInfo * colorInfo);
+ bool isIllChar(char);
+ void detectPageState();
+ QString expandUrl(const QPoint& pt, QPair<int, int>& range);
+ bool checkUrl(QRect &, QRect &, bool);
+ QByteArray parseString(const QByteArray &cstr, int *len = 0);
+ void finalizeConnection();
+ bool isPageComplete();
+ void autoReplyMessage();
+ void reconnectProcess();
+ void doAutoLogin();
+
+private:
+ //this read-write lock will be locked as a writer's lock if the buffer is being changed
+ //so for a reader who wants to ensure thread-safe, he should lock
+ //this lock as a reader's lock.
+ mutable QReadWriteLock bufferWriteLock_;
+
+ FQTermParam param_;
+ FQTermConvert encodingConverter_;
+ bool isTelnetLogining_;
+ bool isSSHLogining_;
+
+ bool isIdling_;
+ bool isMouseX11_;
+ bool isConnected_;
+ bool isSendingMessage_;
+
+ QRect urlRect_;
+ QPoint urlStartPoint_;
+ QPoint urlEndPoint_;
+ QString url_;
+ QString ip_;
+ char menuChar_;
+ QRect menuRect_;
+ PageState pageState_;
+ QPoint cursorPoint_;
+ int screenStartLineNumber_;
+
+ FQTermZmodem *zmodem_;
+ FQTermDecode *decoder_;
+ FQTermTelnet *telnet_;
+ FQTermBuffer *termBuffer_;
+
+ QTimer *idleTimer_;
+ QTimer *autoReplyTimer_;
+
+ QWaitCondition waitCondition_;
+ ArticleCopyThread *acThread_;
+
+ std::vector<char> telnet_data_;
+ std::vector<char> raw_data_;
+
+ int reconnectRetry_;
+public:
+ void setScriptListener(FQTermScriptEventListener* pythonListener) {
+ scriptListener_ = pythonListener;
+ }
+private:
+ FQTermScriptEventListener* scriptListener_;
+};
+
+class ArticleCopyThread: public QThread {
+ Q_OBJECT;
+ public:
+ ArticleCopyThread(FQTermSession &bbs, QWaitCondition &waitCondition, QReadWriteLock &bufferLock);
+
+ ~ArticleCopyThread();
+
+ signals:
+ void articleCopied(int state, const QString content);
+ void writeSession(const QString&);
+ protected:
+ virtual void run();
+ private:
+ FQTermSession &session_;
+ QWaitCondition &waitCondition_;
+
+ QReadWriteLock &lock_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SESSION_H
diff --git a/src/terminal/fqterm_text_line.cpp b/src/terminal/fqterm_text_line.cpp
new file mode 100644
index 0000000..ed6d164
--- /dev/null
+++ b/src/terminal/fqterm_text_line.cpp
@@ -0,0 +1,541 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <stdio.h>
+#include <QRegExp>
+#include <QString>
+
+#include "fqterm.h"
+#include "fqterm_text_line.h"
+
+namespace FQTerm {
+
+#ifndef NDEBUG
+//#define TEXT_LINE_CHECK
+#else
+//#define TEXT_LINE_CHECK
+#endif
+
+#ifndef TEXT_LINE_CHECK
+void FQTermTextLine::verifyTextLine() const {}
+void FQTermTextLine::verifyCellRange(unsigned, unsigned) const {}
+#else
+void FQTermTextLine::verifyTextLine() const {
+ unsigned last_cell = 0;
+ unsigned cur_cell = last_cell;
+
+ if (cells_.size() == 0
+ || cell_colors_.size() == 0
+ || cell_attrs_.size() == 0
+ || chars_.size() == 0
+ ) {
+ FQ_VERIFY(cells_.size() == 0);
+ FQ_VERIFY(cell_colors_.size() == 0);
+ FQ_VERIFY(cell_attrs_.size() == 0);
+ FQ_VERIFY(chars_.size() == 0);
+ return;
+ }
+
+ FQ_VERIFY(max_cell_count_ < 65536);
+ FQ_VERIFY(chars_.size() < 65536);
+ FQ_VERIFY(cells_.size() <= max_cell_count_);
+ FQ_VERIFY(cells_.size() == cell_colors_.size());
+ FQ_VERIFY(cells_.size() == cell_attrs_.size());
+
+ const UTF16 *start = &chars_[0];
+ const UTF16 *end = start + chars_.size();
+
+ for (const UTF16 *p = start; p < end;) {
+ int w = mk_advace_at_least_one_cell(&p, end);
+
+ FQ_VERIFY(w >= 0); // should be valid unicode string.
+
+ cur_cell += w;
+
+ for (unsigned i = last_cell; i < cur_cell; ++i) {
+ unsigned char_end = p - start;
+ FQ_VERIFY(cells_[i] == char_end);
+ }
+
+ last_cell = cur_cell;
+ }
+
+ FQ_VERIFY(cur_cell == getWidth());
+ FQ_VERIFY(cells_.back() == chars_.size());
+}
+
+void FQTermTextLine::verifyCellRange(unsigned cell_begin, unsigned cell_end) const {
+ FQ_VERIFY(cell_begin <= cell_end);
+ FQ_VERIFY(cell_end <= getWidth());
+
+ unsigned real_cell_begin = getCellBegin(cell_begin);
+ FQ_VERIFY(real_cell_begin == cell_begin);
+
+ unsigned real_cell_end = getCellBegin(cell_end);
+ FQ_VERIFY(real_cell_end == cell_end);
+
+ unsigned char_begin = getCharBegin(cell_begin);
+ FQ_VERIFY(char_begin <= chars_.size());
+
+ unsigned char_end = getCharEnd(cell_end);
+ FQ_VERIFY(char_begin <= char_end);
+ FQ_VERIFY(char_end <= chars_.size());
+
+}
+
+#endif
+
+FQTermTextLine::FQTermTextLine(unsigned max_cell_count)
+ : max_cell_count_(max_cell_count),
+ dirty_cell_begin_(0),
+ dirty_cell_end_(max_cell_count),
+ stored_color_(0),
+ stored_attr_(0){
+ cells_.reserve(max_cell_count_);
+ cell_colors_.reserve(max_cell_count_);
+ cell_attrs_.reserve(max_cell_count_);
+ chars_.reserve(max_cell_count_);
+}
+
+FQTermTextLine::~FQTermTextLine() {
+}
+
+void FQTermTextLine::setMaxCellCount(unsigned max_cell_count) {
+ // FIXME: how about dirty flag?
+ max_cell_count_ = max_cell_count;
+
+ if (cells_.size() > max_cell_count_) {
+ // TODO_UTF16: what if an incomplete utf-16 byte left.
+ cells_.resize(max_cell_count_);
+ cell_colors_.resize(max_cell_count_);
+ cell_attrs_.resize(max_cell_count_);
+ chars_.resize(cells_.back());
+ }
+}
+
+// Whether this line of text contains blink characters.
+bool FQTermTextLine::hasBlink() const {
+ bool blink = false;
+
+ char tempea;
+ for (unsigned i = 0; i < cells_.size(); i++) {
+ tempea = cell_attrs_[i];
+ if (GETBLINK(tempea)) {
+ blink = true;
+ break;
+ }
+ }
+
+ return blink;
+}
+
+void FQTermTextLine::setDirtyFlag(unsigned cell_begin, unsigned cell_end) {
+#ifdef TEXT_LINE_CHECK
+ FQ_VERIFY(cell_begin <= cell_end);
+ FQ_VERIFY(cell_end <= max_cell_count_);
+#endif
+ if (dirty_cell_begin_ > cell_begin) {
+ dirty_cell_begin_ = cell_begin;
+ }
+
+ if (dirty_cell_end_ < cell_end) {
+ dirty_cell_end_ = cell_end;
+ }
+}
+
+void FQTermTextLine::safelySetDirtyFlag(unsigned cell_begin, unsigned cell_end) {
+ if (cell_end > max_cell_count_) cell_end = max_cell_count_;
+
+ if (cell_begin >= cell_end)
+ return;
+
+ setDirtyFlag(cell_begin, cell_end);
+}
+
+void FQTermTextLine::clearDirtyFlag() {
+ dirty_cell_begin_ = 0;
+ dirty_cell_end_ = 0;
+}
+
+bool FQTermTextLine::getDirtyCells(unsigned &cell_begin, unsigned &cell_end) const {
+ cell_begin = dirty_cell_begin_;
+ cell_end = dirty_cell_end_;
+ return dirty_cell_begin_ < dirty_cell_end_;
+}
+
+void FQTermTextLine::getPlainText(unsigned cell_begin, unsigned cell_end,
+ QString &result) const {
+ verifyCellRange(cell_begin, cell_end);
+
+ if (cells_.size() == 0 || cell_begin == cell_end) return;
+
+ unsigned char_begin = getCharBegin(cell_begin);
+ unsigned char_end = getCharEnd(cell_end);
+
+ result.insert(result.size(),
+ (QChar *) &chars_[char_begin],
+ char_end - char_begin);
+
+ typedef char Verify_QChar_Is_Two_Bytes[
+ (sizeof(QChar) == 2)? 1 : -1];
+}
+
+void FQTermTextLine::getAnsiText(unsigned cell_begin, unsigned cell_end,
+ QString &result,
+ const char *escape) const {
+ verifyCellRange(cell_begin, cell_end);
+
+ if (cells_.size() == 0 || cell_begin == cell_end) return;
+
+ unsigned cur_cell = cell_begin;
+ unsigned next_cell = cell_begin;
+
+ while (cur_cell < cell_end) {
+ unsigned char color = cell_colors_[cur_cell];
+ unsigned char attr = cell_attrs_[cur_cell];
+
+ for (next_cell = cur_cell;
+ next_cell < cell_end;
+ ++next_cell) {
+ if (!(cell_colors_[next_cell] == color
+ && cell_attrs_[next_cell] == attr)) {
+ if (next_cell > getCellBegin(next_cell)) {
+ continue;
+ } else {
+ break;
+ }
+ }
+
+ }
+
+ getAnsiCtrlSeq(color, attr, escape, result);
+ getPlainText(cur_cell, next_cell, result);
+ result += escape;
+ result += "0m";
+
+ cur_cell = next_cell;
+ }
+}
+
+
+void FQTermTextLine::appendWhiteSpace(
+ unsigned count, unsigned char color, unsigned char attr, UTF16 space) {
+ FQ_ASSERT(get_str_width(space) == 1);
+
+ cells_.reserve(getWidth() + count);
+ max_cell_count_ = qMax(max_cell_count_, getWidth() + count);
+
+ cell_colors_.reserve(getWidth() + count);
+ cell_attrs_.reserve(getWidth() + count);
+
+ setDirtyFlag(getWidth(), getWidth() + count);
+
+ chars_.insert(chars_.end(), count, space);
+ cell_colors_.insert(cell_colors_.end(), count, color);
+ cell_attrs_.insert(cell_attrs_.end(), count, attr);
+
+ int c = getCharEnd(getWidth());
+ for (unsigned i = 0; i < count; ++i) {
+ cells_.push_back(c + i + 1);
+ }
+
+ verifyTextLine();
+}
+
+void FQTermTextLine::insertWhiteSpace(unsigned count, unsigned cell_begin,
+ unsigned char color, unsigned char attr,
+ UTF16 space) {
+ FQ_ASSERT(get_str_width(space) == 1);
+
+ breakCell(cell_begin);
+
+ verifyCellRange(cell_begin, getWidth());
+
+ unsigned char_begin = getCharBegin(cell_begin);
+
+ max_cell_count_ = qMax(max_cell_count_, getWidth() + count);
+
+ chars_.insert(chars_.begin() + char_begin, count, space);
+ cell_colors_.insert(cell_colors_.begin() + cell_begin, count, color);
+ cell_attrs_.insert(cell_attrs_.begin() + cell_begin, count, attr);
+
+ cells_.insert(cells_.begin() + cell_begin, count, 0);
+ for (unsigned i = cell_begin; i < cell_begin + count; ++i) {
+ cells_[i] = char_begin + (i - cell_begin) + 1;
+ }
+ for (unsigned i = cell_begin + count; i < getWidth(); ++i) {
+ cells_[i] += count;
+ }
+
+ setDirtyFlag(cell_begin, this->getWidth());
+
+ verifyTextLine();
+}
+
+void FQTermTextLine::replaceWithWhiteSpace(
+ unsigned count, unsigned cell_begin, unsigned cell_end,
+ unsigned char color, unsigned char attr, UTF16 space) {
+ if(cell_end>cells_.size() || cell_begin>=cell_end)
+ return;
+ deleteText(cell_begin, cell_end);
+ insertWhiteSpace(count, cell_begin, color, attr, space);
+}
+
+
+
+void FQTermTextLine::insertText(const UTF16 *str, unsigned count,
+ unsigned cell_begin,
+ unsigned char color, unsigned char attr, int charstate) {
+ if (count == 0) return;
+
+ // Calculate how many cells should be occupied for str.
+ // TODO: avoid compute the width of str twice.
+ int width = get_str_width(str, count);
+
+ if (width == 0) {
+#ifdef TEXT_LINE_CHECK
+ //FQ_VERIFY(false);
+ //TODO: enable utf8 decoding
+#endif
+ return;
+ }
+
+ if (charstate & FQTermTextLine::FIRSTPART) {
+ stored_color_ = color;
+ stored_attr_ = attr;
+ width--;
+ count--;
+ if (width == 0 || count == 0) {
+ return;
+ }
+ }
+
+ breakCell(cell_begin);
+
+ verifyCellRange(cell_begin, getWidth());
+
+ unsigned char_begin = getCharBegin(cell_begin);
+
+ chars_.insert(chars_.begin() + char_begin, str, str + count);
+
+ // Insert colors.
+ cell_colors_.insert(cell_colors_.begin() + cell_begin, width, color);
+
+ // Insert attrs.
+ cell_attrs_.insert(cell_attrs_.begin() + cell_begin, width, attr);
+
+ if (charstate & FQTermTextLine::SECONDPART){
+ cell_colors_[cell_begin] = stored_color_;
+ cell_attrs_[cell_begin] = stored_attr_;
+ }
+
+
+ // Change the cells_ mapping to chars_.
+ cells_.insert(cells_.begin() + cell_begin, width, 0);
+ max_cell_count_ = qMax(max_cell_count_, getWidth());
+
+ unsigned last_cell = cell_begin;
+ unsigned cur_cell = last_cell;
+ for (const UTF16 *p = str; p < str +count;) {
+ int w = mk_advace_at_least_one_cell(&p, str + count);
+
+#ifdef TEXT_LINE_CHECK
+ // TODO_UTF16: FIXME: deal with decoding error.
+ FQ_VERIFY(w >= 0);
+#endif
+
+ cur_cell += w;
+
+ for (unsigned i = last_cell; i < cur_cell; ++i) {
+ cells_[i] = char_begin + (p - str);
+ }
+
+ last_cell = cur_cell;
+ }
+
+#ifdef TEXT_LINE_CHECK
+ FQ_VERIFY(cur_cell == cell_begin + width);
+#endif
+
+ for (unsigned i = cell_begin + width; i < cells_.size(); ++i) {
+ cells_[i] += count;
+ }
+
+
+
+ setDirtyFlag(cell_begin, cells_.size());
+
+ verifyTextLine();
+}
+
+void FQTermTextLine::deleteText(unsigned cell_begin, unsigned cell_end) {
+ if (cells_.size() == 0 || cell_begin == cell_end) return;
+
+ breakCell(cell_begin);
+ breakCell(cell_end);
+
+ verifyCellRange(cell_begin, cell_end);
+
+ setDirtyFlag(cell_begin, cells_.size());
+
+ unsigned char_begin = getCharBegin(cell_begin);
+ unsigned char_end = getCharEnd(cell_end);
+
+ chars_.erase(chars_.begin() + char_begin, chars_.begin() + char_end);
+
+ cells_.erase(cells_.begin() + cell_begin, cells_.begin() + cell_end);
+ cell_colors_.erase(cell_colors_.begin() + cell_begin,
+ cell_colors_.begin() + cell_end);
+ cell_attrs_.erase(cell_attrs_.begin() + cell_begin,
+ cell_attrs_.begin() + cell_end);
+
+ for (unsigned i = cell_begin; i < cells_.size(); ++i) {
+ cells_[i] -= (char_end - char_begin);
+ }
+
+ verifyTextLine();
+}
+
+void FQTermTextLine::deleteAllText() {
+ deleteText(0, getWidth());
+}
+
+void FQTermTextLine::replaceText(const UTF16 *str, unsigned count,
+ unsigned cell_begin, unsigned cell_end,
+ unsigned char color, unsigned char attr, int charstate) {
+ if (charstate & FQTermTextLine::FIRSTPART) {
+ stored_color_ = color;
+ stored_attr_ = attr;
+ count--;
+ if (count == 0)
+ {
+ return;
+ }
+ charstate &= ~FQTermTextLine::FIRSTPART;
+ }
+
+ deleteText(cell_begin, cell_end);
+ insertText(str, count, cell_begin, color, attr, charstate);
+
+ setDirtyFlag(cell_begin, cells_.size());
+}
+
+
+unsigned FQTermTextLine::getCellBegin(unsigned cell_begin) const {
+#ifdef TEXT_LINE_CHECK
+ FQ_VERIFY(cell_begin <= getWidth());
+#endif
+
+ if (cell_begin == cells_.size()) return cell_begin;
+
+ while(cell_begin > 0 && cells_[cell_begin - 1] == cells_[cell_begin]) {
+ --cell_begin;
+ }
+
+ return cell_begin;
+}
+
+unsigned FQTermTextLine::getCellEnd(unsigned cell_end) const {
+#ifdef TEXT_LINE_CHECK
+ FQ_VERIFY(cell_end <= getWidth());
+#endif
+
+ if (cell_end == 0) return cell_end;
+
+ while (cell_end < cells_.size() && cells_[cell_end - 1] == cells_[cell_end]) {
+ ++cell_end;
+ }
+
+ return cell_end;
+}
+
+unsigned FQTermTextLine::getCharBegin(unsigned cell_begin) const {
+#ifdef TEXT_LINE_CHECK
+ FQ_VERIFY(cell_begin == getCellBegin(cell_begin));
+#endif
+
+ if (cell_begin == 0) return 0;
+
+ return cells_[cell_begin - 1];
+}
+
+unsigned FQTermTextLine::getCharEnd(unsigned cell_end) const {
+#ifdef TEXT_LINE_CHECK
+ FQ_VERIFY(cell_end == getCellEnd(cell_end));
+#endif
+
+ if (cell_end == 0) return 0;
+
+ return cells_[cell_end - 1];
+}
+
+bool FQTermTextLine::breakCell(unsigned cell_begin) {
+ unsigned real_cell_begin = getCellBegin(cell_begin);
+ if (real_cell_begin == cell_begin) return false;
+
+ unsigned real_cell_end = getCellEnd(cell_begin);
+
+ verifyCellRange(real_cell_begin, real_cell_end);
+
+ unsigned cell_count = real_cell_end - real_cell_begin;
+
+ replaceWithWhiteSpace(cell_count, real_cell_begin, real_cell_end,
+ cell_colors_[cell_begin], cell_attrs_[cell_begin], URC);
+
+ return true;
+}
+
+void FQTermTextLine::getAnsiCtrlSeq(
+ unsigned char color, unsigned char attr,
+ const char *escape, QString &result) const {
+
+ int fg = GETFG(color) + 30;
+ int bg = GETBG(color) + 40;
+
+ result += escape;
+ result += QString("%1;%2").arg(fg).arg(bg);
+
+ if (GETBRIGHT(attr)) {
+ result += ";1";
+ }
+ if (GETDIM(attr)) {
+ result += ";2";
+ }
+ if (GETUNDERLINE(attr)) {
+ result += ";4";
+ }
+ if (GETBLINK(attr)) {
+ result += ";5";
+ }
+ if (GETRAPIDBLINK(attr)) {
+ result += ";6";
+ }
+ if (GETREVERSE(attr)) {
+ result += ";7";
+ }
+ if (GETINVISIBLE(attr)) {
+ result += ";8";
+ }
+
+ result += "m";
+}
+
+
+} // namespace FQTerm
diff --git a/src/terminal/fqterm_text_line.h b/src/terminal/fqterm_text_line.h
new file mode 100644
index 0000000..72ff4c0
--- /dev/null
+++ b/src/terminal/fqterm_text_line.h
@@ -0,0 +1,159 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_TEXTLINE_H
+#define FQTERM_TEXTLINE_H
+
+#include <vector>
+
+#include "fqwcwidth.h"
+#include "fqterm.h"
+class QString;
+
+namespace FQTerm {
+/*
+ A text line consists of several characters in a sequence of cells. A
+ character may occupy some cells, e.g. each English letter occupies
+ one cell, while a CJK character needs two.
+
+ This class is used to manipolate a text line, delete/replace
+ characters in a given cell range, insert characters before a cell,
+ and retrieve characters/colors/attributs of a gaven cell range.
+*/
+class FQTermTextLine {
+ public:
+ FQTermTextLine(unsigned max_cell_count);
+ ~FQTermTextLine();
+
+ enum CHARSTATE{NORMAL = 0x00, FIRSTPART = 0x01, SECONDPART = 0x02};
+ // Get the number of used cells.
+ unsigned getWidth() const {return cells_.size();}
+
+ void setMaxCellCount(unsigned max_cell_count);
+ unsigned getMaxCellCount() const { return max_cell_count_; }
+
+ // Whether this line of text contains blink characters.
+ bool hasBlink() const;
+
+ // Set/get the dirty flag, that indicates which cells have been
+ // modified.
+ void setDirtyFlag(unsigned cell_begin, unsigned cell_end);
+ void safelySetDirtyFlag(unsigned cell_begin, unsigned cell_end);
+ bool getDirtyCells(unsigned &cell_begin, unsigned &cell_end) const;
+ void clearDirtyFlag();
+ void setAllDirty() {setDirtyFlag(0, max_cell_count_);}
+
+ const unsigned char *getColors() const {
+ return cells_.size() == 0 ? NULL : &cell_colors_[0];
+ }
+
+ const unsigned char *getAttributes() const {
+ return cells_.size() == 0 ? NULL : &cell_attrs_[0];
+ }
+
+ // Get plain text in [cell_begin, cell_end).
+ void getPlainText(unsigned cell_begin, unsigned cell_end,
+ QString &result) const;
+
+ void getAllPlainText(QString &result) const {
+ getPlainText(0, getWidth(), result);
+ }
+
+ // Get text in cells [cell_begin, cell_end), with color and
+ // attribute in ANSI format.
+ void getAnsiText(unsigned cell_begin, unsigned cell_end,
+ QString &result,
+ const char *escape = "\x1b\x1b") const;
+
+ void getAllAnsiText(QString &result, const char* escape = "\x1b\x1b") const {
+ getAnsiText(0, getWidth(), result, escape);
+ }
+
+ void appendWhiteSpace(unsigned count,
+ unsigned char color = NO_COLOR,
+ unsigned char attr = NO_ATTR,
+ UTF16 space = ' ');
+
+ void insertWhiteSpace(unsigned count, unsigned cell_begin,
+ unsigned char color = NO_COLOR,
+ unsigned char attr = NO_ATTR,
+ UTF16 space = ' ');
+
+ void replaceWithWhiteSpace(unsigned count,
+ unsigned cell_begin, unsigned cell_end,
+ unsigned char color = NO_COLOR,
+ unsigned char attr = NO_ATTR,
+ UTF16 space = ' ');
+
+ // insert string at specified cell,
+ void insertText(const UTF16 *str, unsigned count,
+ unsigned cell_begin,
+ unsigned char color, unsigned char attr, int charstate = FQTermTextLine::NORMAL);
+ void replaceText(const UTF16 *str, unsigned count,
+ unsigned cell_begin, unsigned cell_end,
+ unsigned char color, unsigned char attr, int charstate = FQTermTextLine::NORMAL);
+ void deleteText(unsigned cell_begin, unsigned cell_end);
+ void deleteAllText();
+
+ // If cell_begin is a begining of a readable character, return
+ // cell_begin itself, otherwise return the previous cell which starts a
+ // readable character.
+ unsigned getCellBegin(unsigned cell_begin) const;
+
+ // If cell_end is a ending of a readable character, return cell_end
+ // itself, otherwise return the next cell which finishes a
+ // readable character.
+ unsigned getCellEnd(unsigned cell_end) const;
+
+ unsigned getCharBegin(unsigned cell_begin) const;
+ unsigned getCharEnd(unsigned cell_end) const;
+
+ private:
+ unsigned max_cell_count_; // max number of cells allowed.
+
+ std::vector<uint16_t> cells_; // store the index of character in this->chars_ for each cell.
+ std::vector<unsigned char> cell_colors_; // store the color for each cell.
+ std::vector<unsigned char> cell_attrs_; // store the attribute for each cell.
+ std::vector<UTF16> chars_; // store all the character.
+
+ unsigned char stored_color_;
+ unsigned char stored_attr_;
+
+ // range of changed text.
+ unsigned dirty_cell_begin_, dirty_cell_end_;
+
+ // if the given cell isn't a beginning of characters,
+ // i.e is in the middle of a wide character,
+ // break the character into several unicode replacement characters (URC)
+ // to make the given cell be a beginning of character.
+ bool breakCell(unsigned cell_begin);
+
+ // calculate ANSI escape sequence with given color, attribute and escape strings.
+ void getAnsiCtrlSeq(unsigned char color, unsigned char attr,
+ const char *escape, QString &result) const;
+
+ // Two functions for debugging/testing.
+ void verifyTextLine() const;
+ void verifyCellRange(unsigned cell_begin, unsigned cell_end) const;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_TEXTLINE_H
diff --git a/src/terminal/internal/fqterm_decode.cpp b/src/terminal/internal/fqterm_decode.cpp
new file mode 100644
index 0000000..cb7bc9a
--- /dev/null
+++ b/src/terminal/internal/fqterm_decode.cpp
@@ -0,0 +1,1279 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QByteArray>
+
+#include "fqterm.h"
+#include "fqterm_telnet.h"
+#include "fqterm_decode.h"
+#include "fqterm_buffer.h"
+#include "fqwcwidth.h"
+
+namespace FQTerm {
+
+#define MODE_MouseX11 0
+
+/************************************************************************/
+// state for FSM
+// please read ANSI decoding
+StateOption FQTermDecode::VT100StateMachine::normal_state_[] = {
+ {
+ CHAR_CR, &FQTermDecode::cr, normal_state_
+ }, {
+ CHAR_LF, &FQTermDecode::lf, normal_state_
+ }, {
+ CHAR_VT, &FQTermDecode::lf, normal_state_
+ }, {
+ CHAR_ESC, 0, esc_state_
+ }, {
+ CHAR_FF, &FQTermDecode::ff, normal_state_
+ }, {
+ CHAR_TAB, &FQTermDecode::tab, normal_state_
+ }, {
+ CHAR_BS, &FQTermDecode::bs, normal_state_
+ }, {
+ CHAR_BELL, &FQTermDecode::bell, normal_state_
+ }, {
+ CHAR_SO, &FQTermDecode::g1, normal_state_
+ }, {
+ CHAR_SI, &FQTermDecode::g0, normal_state_
+ }, {
+ CHAR_CAN, 0, normal_state_ // should be ignored
+ }, {
+ CHAR_DEL, &FQTermDecode::del, normal_state_
+ }, {
+ CHAR_NUL, 0, normal_state_ // should be ignored
+ }, {
+ CHAR_ENQ, &FQTermDecode::enq, normal_state_
+ }, {
+ CHAR_NORMAL, &FQTermDecode::normalInput, normal_state_
+ }
+};
+
+// state after a ESC_CHAR
+StateOption FQTermDecode::VT100StateMachine::esc_state_[] = {
+ {
+ '7', &FQTermDecode::saveCursor, normal_state_
+ }, {
+ '8', &FQTermDecode::restoreCursor, normal_state_
+ }, {
+ '[', &FQTermDecode::clearParam, bracket_state_
+ }, {
+ ']', &FQTermDecode::clearParam, title_state_
+ }, {
+ '(', 0, select_g0_charset_state_
+ }, {
+ ')', 0, select_g1_charset_state_
+ }, {
+ 'D', &FQTermDecode::moveCursorDown, normal_state_
+ }, {
+ 'E', &FQTermDecode::nextLine, normal_state_
+ }, {
+ 'H', &FQTermDecode::addTabStop, normal_state_
+ }, {
+ 'M', &FQTermDecode::moveCursorUp, normal_state_
+ }, {
+ '>', &FQTermDecode::setNumericKeypad, normal_state_
+ }, {
+ '=', &FQTermDecode::setAppKeypad, normal_state_
+ }, {
+ '<', &FQTermDecode::test, normal_state_
+ }, {
+ '#', 0, sharp_state_
+ }, {
+ CHAR_NORMAL, 0, normal_state_
+ }
+};
+
+// state after ESC [
+StateOption FQTermDecode::VT100StateMachine::bracket_state_[] = {
+ {
+ '0', &FQTermDecode::paramDigit, bracket_state_
+ }, {
+ '1', &FQTermDecode::paramDigit, bracket_state_
+ }, {
+ '2', &FQTermDecode::paramDigit, bracket_state_
+ }, {
+ '3', &FQTermDecode::paramDigit, bracket_state_
+ }, {
+ '4', &FQTermDecode::paramDigit, bracket_state_
+ }, {
+ '5', &FQTermDecode::paramDigit, bracket_state_
+ }, {
+ '6', &FQTermDecode::paramDigit, bracket_state_
+ }, {
+ '7', &FQTermDecode::paramDigit, bracket_state_
+ }, {
+ '8', &FQTermDecode::paramDigit, bracket_state_
+ }, {
+ '9', &FQTermDecode::paramDigit, bracket_state_
+ }, {
+ ';', &FQTermDecode::nextParam, bracket_state_
+ }, {
+ '?', &FQTermDecode::clearParam, private_state_
+ }, {
+ 'A', &FQTermDecode::cursorUp, normal_state_
+ }, {
+ 'B', &FQTermDecode::cursorDown, normal_state_
+ }, {
+ 'C', &FQTermDecode::cursorRight, normal_state_
+ }, {
+ 'D', &FQTermDecode::cursorLeft, normal_state_
+ }, {
+ 'H', &FQTermDecode::cursorPosition, normal_state_
+ }, {
+ 'J', &FQTermDecode::eraseScreen, normal_state_
+ }, {
+ 'K', &FQTermDecode::eraseLine, normal_state_
+ }, {
+ 'L', &FQTermDecode::insertLine, normal_state_
+ }, {
+ 'M', &FQTermDecode::deleteLine, normal_state_
+ }, {
+ 'P', &FQTermDecode::deleteStr, normal_state_
+ }, {
+ 'X', &FQTermDecode::eraseStr, normal_state_
+ }, {
+ 'f', &FQTermDecode::cursorPosition, normal_state_
+ }, {
+ 'g', &FQTermDecode::clearTabStop, normal_state_
+ }, {
+ 'h', &FQTermDecode::setMode, normal_state_
+ }, {
+ 'l', &FQTermDecode::resetMode, normal_state_
+ }, {
+ 'm', &FQTermDecode::setAttr, normal_state_
+ }, {
+ 'q', 0, normal_state_ // ignore LED-related commands.
+ }, {
+ 'r', &FQTermDecode::setMargins, normal_state_
+ }, {
+ 's', &FQTermDecode::saveCursor, normal_state_
+ }, {
+ 'u', &FQTermDecode::restoreCursor, normal_state_
+ }, {
+ '@', &FQTermDecode::insertStr, normal_state_
+ }, {
+ CHAR_CR, &FQTermDecode::cr, bracket_state_
+ }, {
+ CHAR_LF, &FQTermDecode::lf, bracket_state_
+ }, {
+ CHAR_VT, &FQTermDecode::lf, bracket_state_
+ }, {
+ CHAR_FF, &FQTermDecode::ff, bracket_state_
+ }, {
+ CHAR_TAB, &FQTermDecode::tab, bracket_state_
+ }, {
+ CHAR_BS, &FQTermDecode::bs, bracket_state_
+ }, {
+ CHAR_BELL, &FQTermDecode::bell, bracket_state_
+ }, {
+ CHAR_NORMAL, 0, normal_state_
+ }
+};
+
+// state after ESC (
+StateOption FQTermDecode::VT100StateMachine::select_g0_charset_state_[] = {
+ {
+ 'A', &FQTermDecode::selectG0A, normal_state_
+ }, {
+ 'B', &FQTermDecode::selectG0B, normal_state_
+ }, {
+ '0', &FQTermDecode::selectG00, normal_state_
+ }, {
+ '1', &FQTermDecode::selectG01, normal_state_
+ }, {
+ '2', &FQTermDecode::selectG02, normal_state_
+ }, {
+ CHAR_NORMAL, 0, normal_state_
+ }
+};
+
+// state after ESC )
+StateOption FQTermDecode::VT100StateMachine::select_g1_charset_state_[] = {
+ {
+ 'A', &FQTermDecode::selectG1A, normal_state_
+ }, {
+ 'B', &FQTermDecode::selectG1B, normal_state_
+ }, {
+ '0', &FQTermDecode::selectG10, normal_state_
+ }, {
+ '1', &FQTermDecode::selectG11, normal_state_
+ }, {
+ '2', &FQTermDecode::selectG12, normal_state_
+ }, {
+ CHAR_NORMAL, 0, normal_state_
+ }
+};
+
+// state after ESC [ ?
+StateOption FQTermDecode::VT100StateMachine::private_state_[] = {
+ {
+ '0', &FQTermDecode::paramDigit, private_state_
+ }, {
+ '1', &FQTermDecode::paramDigit, private_state_
+ }, {
+ '2', &FQTermDecode::paramDigit, private_state_
+ }, {
+ '3', &FQTermDecode::paramDigit, private_state_
+ }, {
+ '4', &FQTermDecode::paramDigit, private_state_
+ }, {
+ '5', &FQTermDecode::paramDigit, private_state_
+ }, {
+ '6', &FQTermDecode::paramDigit, private_state_
+ }, {
+ '7', &FQTermDecode::paramDigit, private_state_
+ }, {
+ '8', &FQTermDecode::paramDigit, private_state_
+ }, {
+ '9', &FQTermDecode::paramDigit, private_state_
+ }, {
+ ';', &FQTermDecode::nextParam, private_state_
+ }, {
+ 'h', &FQTermDecode::setDecPrivateMode, normal_state_
+ }, {
+ 'l', &FQTermDecode::resetDecPrivateMode, normal_state_
+ }, {
+ 's', &FQTermDecode::saveMode, normal_state_
+ }, {
+ 'r', &FQTermDecode::restoreMode, normal_state_
+ }, {
+ CHAR_NORMAL, 0, normal_state_
+ }
+};
+
+// state after ESC #
+StateOption FQTermDecode::VT100StateMachine::sharp_state_[] = {
+ {
+ '8', &FQTermDecode::fillScreen, normal_state_
+ }, {
+ CHAR_NORMAL, 0, normal_state_
+ }
+};
+
+// state after ESC ]
+// to change the terminal title dynamically.
+// Dynamic titles
+// Many people find it useful to set the title of a terminal to reflect dynamic information,
+// such as the name of the host the user is logged into, the current working directory, etc.
+// This may be done by using XTerm escape sequences. The following sequences are useful in this respect:
+// ESC]0;stringBEL Set icon name and window title to string
+// ESC]1;stringBEL Set icon name to string
+// ESC]2;stringBEL Set window title to string
+// where ESC is the escape character (\033), and BEL is the bell character (\007).
+// Currently we just ignore this.
+StateOption FQTermDecode::VT100StateMachine::title_state_[] = {
+ {
+ '0', &FQTermDecode::paramDigit, title_state_
+ }, {
+ '1', &FQTermDecode::paramDigit, title_state_
+ }, {
+ '2', &FQTermDecode::paramDigit, title_state_
+ }, {
+ '4', &FQTermDecode::paramDigit, title_state_
+ }, {
+ '5', &FQTermDecode::paramDigit, title_state_
+ }, {
+ '6', &FQTermDecode::paramDigit, title_state_
+ }, {
+ ';', &FQTermDecode::clearText, title_text_state_
+ }, {
+ CHAR_NORMAL, 0, normal_state_
+ }
+};
+
+StateOption FQTermDecode::VT100StateMachine::title_text_state_[] = {
+ {
+ CHAR_ESC, 0, esc_state_
+ }, {
+ CHAR_BELL, &FQTermDecode::setTitle, normal_state_
+ }, {
+ CHAR_NORMAL, &FQTermDecode::collectText, title_state_
+ }
+};
+
+const char *FQTermDecode::getStateName(const StateOption *state) {
+ if (state == VT100StateMachine::normal_state_) {
+ return "VT100StateMachine::normal_state_";
+ } else if (state == VT100StateMachine::esc_state_) {
+ return "VT100StateMachine::esc_state_";
+ } else if (state == VT100StateMachine::bracket_state_) {
+ return "VT100StateMachine::bracket_state_";
+ } else if (state == VT100StateMachine::private_state_) {
+ return "VT100StateMachine::private_state_";
+ } else if (state == VT100StateMachine::title_state_) {
+ return "VT100StateMachine::title_state_";
+ } else {
+ return "Unknow";
+ }
+}
+
+
+FQTermDecode::FQTermDecode(FQTermBuffer *buffer, int server_encoding) {
+ leftToDecode_.clear();
+ termBuffer_ = buffer;
+
+ interrupt_decode_ = false;
+
+ current_state_ = VT100StateMachine::normal_state_;
+
+ default_color_ = NO_COLOR;
+ default_attr_ = NO_ATTR;
+
+ current_color_ = default_color_;
+ current_attr_ = default_attr_;
+
+ isBell_ = false;
+
+ termBuffer_->setCurrentAttr(current_color_, current_attr_);
+
+ // TODO_UTF16: please create a encoding enum.
+ server_encoding_ = server_encoding;
+
+ currentMode_[MODE_MouseX11] = savedMode_[MODE_MouseX11] = false;
+ FQ_VERIFY(connect(termBuffer_, SIGNAL(caretChangeRow()), this, SLOT(onCaretChangeRow())));
+}
+
+FQTermDecode::~FQTermDecode() {
+
+}
+
+// precess input string from telnet socket
+//void FQTermDecode::ansiDecode( const QCString &cstr, int length )
+int FQTermDecode::decode(const char *cstr, int length) {
+ inputData_ = cstr;
+ inputLength_ = length; //inputData.length();
+
+ dataIndex_ = 0;
+ isBell_ = false;
+
+ interrupt_decode_ = false;
+
+ int i;
+ StateOption *lastState;
+
+ termBuffer_->startDecode();
+
+ // here we use FSM to ANSI decoding
+ // use switch case is ok too
+ // but i think use function pointer array can make this clear
+ // you can see the defination at the beginning
+ while (dataIndex_ < inputLength_) {
+ // current state always be initialized to point to the deginning of three structures
+ // ( normalState, escState, bracketState )
+ i = 0;
+ while (current_state_[i].byte != CHAR_NORMAL && current_state_[i].byte !=
+ inputData_[dataIndex_]) {
+ i++;
+ }
+
+ // action must be allowed to redirect state change
+ // get current state with input character i ( hehe, current now become last one )
+ lastState = current_state_ + i; // good !!
+
+ bool trace_state = true;
+ if (current_state_ == VT100StateMachine::normal_state_
+ && lastState->nextState == VT100StateMachine::normal_state_) {
+ trace_state = false;
+ }
+
+ if (trace_state) {
+ FQ_TRACE("ansi", 10) << "Current state: " << getStateName(current_state_);
+ FQ_TRACE("ansi", 10) << dumpHexString << std::string("") + inputData_[dataIndex_]
+ << dumpNormalString << " " << inputData_[dataIndex_];
+ }
+
+ if (lastState->action != 0) {
+ (this->*(lastState->action))();
+ } else {
+ if (trace_state) FQ_TRACE("ansi", 10) << "No action";
+ }
+ if (trace_state) FQ_TRACE("ansi", 10) << "Next state: " << getStateName(lastState->nextState);
+
+ // reinit current state
+ current_state_ = lastState->nextState;
+
+ dataIndex_++;
+
+ if (interrupt_decode_) {
+ break;
+ }
+ }
+ termBuffer_->endDecode();
+
+ return dataIndex_;
+}
+
+
+QString FQTermDecode::bbs2unicode(const QByteArray &text) {
+ return encoding2unicode(text, server_encoding_);
+}
+
+///////////////////////////////////
+//helper function to decode utf8//
+//////////////////////////////////
+static int utf8_expected_byte_count(char first_byte)
+{
+ char expected = 0;
+ if (!(first_byte & 0x80))
+ return 0; //1 byte ascii
+ else
+ expected++;
+ if (!(first_byte & 0x40))
+ {
+ return -1; //not a leading byte.
+ }
+ if (!(first_byte & 0x20))
+ return expected;
+ else
+ expected++;
+ if (!(first_byte & 0x10))
+ return expected;
+ else
+ expected++;
+ if (!(first_byte & 0x08))
+ return expected;
+ return -1;
+}
+
+///////////////////////////////////
+//helper function to decode utf8//
+//////////////////////////////////
+static int gdbnbig5_expected_byte_count(char first_byte)
+{
+ char expected = 0;
+ if (!(first_byte & 0x80))
+ return 0; //1 byte ascii
+ else
+ expected++;
+ return expected;
+}
+
+int FQTermDecode::processInput(QByteArray& result)
+{
+ int charstate = FQTermTextLine::NORMAL;
+ int expect_bytes = 0;
+ if (leftToDecode_.size())
+ {
+ switch(server_encoding_)
+ {
+ case FQTERM_ENCODING_GBK:
+ case FQTERM_ENCODING_BIG5:
+ case FQTERM_ENCODING_HKSCS:
+ case FQTERM_ENCODING_UAO:
+ expect_bytes = gdbnbig5_expected_byte_count(leftToDecode_[0]);
+ break;
+ case FQTERM_ENCODING_UTF8:
+ expect_bytes = utf8_expected_byte_count(leftToDecode_[0]);
+ break;
+ }
+ }
+
+ //TODO: error.
+ if (expect_bytes < 0) {
+ expect_bytes = 0;
+ }
+
+
+ int n = 0;
+ int last_char_index = n;
+ while (((dataIndex_ + n) < inputLength_) && (signed(inputData_[dataIndex_ + n]) >= 0x20
+ || signed(inputData_[dataIndex_ + n]) < 0x00)) {
+
+ if (expect_bytes != 0) {
+ expect_bytes--;
+ } else {
+ last_char_index = n;
+ switch(server_encoding_)
+ {
+ case FQTERM_ENCODING_GBK:
+ case FQTERM_ENCODING_BIG5:
+ case FQTERM_ENCODING_HKSCS:
+ case FQTERM_ENCODING_UAO:
+ expect_bytes = gdbnbig5_expected_byte_count(inputData_[dataIndex_ + n]);
+ break;
+ case FQTERM_ENCODING_UTF8:
+ expect_bytes = utf8_expected_byte_count(inputData_[dataIndex_ + n]);
+ break;
+ }
+ //TODO: error.
+ if (expect_bytes < 0) {
+ expect_bytes = 0;
+ }
+
+
+ }
+
+ n++;
+ }
+
+ if (expect_bytes) {
+ if(dataIndex_ + n == inputLength_) {
+ interrupt_decode_ = true;
+ }
+ }
+
+ result.clear();
+ result.reserve(n + 1);
+ if (leftToDecode_.size()) {
+ result += leftToDecode_;
+ switch(server_encoding_)
+ {
+ case FQTERM_ENCODING_GBK:
+ case FQTERM_ENCODING_BIG5:
+ case FQTERM_ENCODING_HKSCS:
+ case FQTERM_ENCODING_UAO:
+ charstate |= FQTermTextLine::SECONDPART;
+ break;
+ case FQTERM_ENCODING_UTF8:
+ break;
+ }
+ leftToDecode_.clear();
+ }
+ int real_n = n;
+ if (expect_bytes) {
+ real_n = last_char_index;
+ leftToDecode_ = QByteArray(inputData_ + dataIndex_ + last_char_index, n - last_char_index);
+ }
+
+ result.push_back(QByteArray(inputData_ + dataIndex_, real_n));
+ if (expect_bytes) {
+ switch(server_encoding_)
+ {
+ case FQTERM_ENCODING_GBK:
+ case FQTERM_ENCODING_BIG5:
+ case FQTERM_ENCODING_HKSCS:
+ case FQTERM_ENCODING_UAO:
+ result.push_back('?'); //make sure the attr is recorded,
+ //since last -1 operation can make cstr to be empty
+ charstate |= FQTermTextLine::FIRSTPART;
+ break;
+ case FQTERM_ENCODING_UTF8:
+ break;
+ }
+ }
+
+ n--;
+ dataIndex_ += n;
+
+ return charstate;
+}
+
+
+// fill letters into char buffer
+// TODO: this function may contain bug, need double-check.
+// 1. input should be ascii-compitable encoding.
+void FQTermDecode::normalInput() {
+
+ FQ_FUNC_TRACE("ansi", 8);
+
+ // TODO_UTF16: check ascii-incompitable encoding.
+ if (signed(inputData_[dataIndex_]) < 0x20 && signed(inputData_[dataIndex_]) >= 0x00) {
+ // not print char
+ return ;
+ }
+
+ QByteArray cstr;
+ int charstate = processInput(cstr);
+
+
+
+ QString str = bbs2unicode(cstr);
+ FQ_TRACE("normal_input", 9) << "hex: " << dumpHexString
+ << str.toLocal8Bit().constData() ;
+ FQ_TRACE("normal_input", 9) << "text: " << str;
+ termBuffer_->writeText(str, charstate);
+
+}
+
+// non-printing characters functions
+void FQTermDecode::cr() {
+ FQ_FUNC_TRACE("ansi", 8);
+ // FIXME: dirty
+ termBuffer_->carriageReturn();
+}
+
+void FQTermDecode::lf() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->lineFeed();
+}
+
+void FQTermDecode::ff() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->eraseEntireTerm();
+
+ termBuffer_->moveCaretTo(0, 0);
+}
+
+void FQTermDecode::tab() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->tab();
+}
+
+void FQTermDecode::bs() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->moveCaretOffset(-1, 0);
+}
+
+void FQTermDecode::bell() {
+ FQ_FUNC_TRACE("ansi", 8);
+ isBell_ = true;
+}
+
+void FQTermDecode::del() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->moveCaretOffset(-1, 0);
+ //termBuffer_->deleteText(1);
+}
+
+void FQTermDecode::g0() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->invokeCharset(true);
+}
+
+void FQTermDecode::g1() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->invokeCharset(false);
+}
+
+void FQTermDecode::enq() {
+ emit enqReceived();
+}
+
+void FQTermDecode::addTabStop() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->addTabStop();
+}
+
+void FQTermDecode::clearTabStop() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ if (param_[0] == 0) {
+ termBuffer_->clearTabStop(false);
+ } else if (param_[0] == 3) {
+ termBuffer_->clearTabStop(true);
+ }
+}
+
+void FQTermDecode::setMargins() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ if (isParamAvailable_) {
+ termBuffer_->setMargins(param_[0] - 1, param_[1] - 1);
+ } else {
+ termBuffer_->setMargins(0, termBuffer_->getNumRows() - 1);
+ }
+}
+
+// parameters functions
+void FQTermDecode::clearParam() {
+ FQ_FUNC_TRACE("ansi", 9);
+ paramIndex_ = 0;
+ memset(param_, 0, sizeof(param_));
+ isParamAvailable_ = false;
+}
+
+// for performance, this grabs all digits
+void FQTermDecode::paramDigit() {
+ FQ_FUNC_TRACE("ansi", 10);
+ isParamAvailable_ = true;
+
+ // make stream into number
+ // ( e.g. this input character is '1' and this param is 4
+ // after the following sentence this param is changed to 41
+ param_[paramIndex_] = param_[paramIndex_] *10+inputData_[dataIndex_] - '0';
+}
+
+void FQTermDecode::nextParam() {
+ FQ_FUNC_TRACE("ansi", 9);
+ paramIndex_++;
+}
+
+void FQTermDecode::saveCursor() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->saveCaret();
+}
+
+void FQTermDecode::restoreCursor() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->restoreCaret();
+}
+
+void FQTermDecode::cursorPosition() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ int x = param_[1];
+ int y = param_[0];
+
+ if (x == 0) {
+ x = 1;
+ }
+ if (y == 0) {
+ y = 1;
+ }
+
+ termBuffer_->changeCaretPosition(x - 1, y - 1);
+}
+
+void FQTermDecode::cursorLeft() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ int n = param_[0];
+
+ if (n < 1) {
+ n = 1;
+ }
+
+ termBuffer_->moveCaretOffset(-n, 0);
+}
+
+void FQTermDecode::cursorRight() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ int n = param_[0];
+
+ if (n < 1) {
+ n = 1;
+ }
+
+ termBuffer_->moveCaretOffset(n, 0);
+}
+
+void FQTermDecode::cursorUp() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ int n = param_[0];
+
+ if (n < 1) {
+ n = 1;
+ }
+
+ termBuffer_->moveCaretOffset(0, -n);
+}
+
+void FQTermDecode::cursorDown() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ int n = param_[0];
+
+ if (n < 1) {
+ n = 1;
+ }
+
+ termBuffer_->moveCaretOffset(0, n);
+}
+
+void FQTermDecode::moveCursorUp() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->scrollTerm(-1);//moveCaretOffset(0, -1, true);
+}
+
+void FQTermDecode::moveCursorDown() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->scrollTerm(1);//moveCaretOffset(0, 1, true);
+}
+
+void FQTermDecode::nextLine() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->carriageReturn();
+ termBuffer_->moveCaretOffset(0, 1, true);
+}
+
+void FQTermDecode::selectG0A() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->SelectVtCharacterSet(FQTermBuffer::UNITED_KINGDOM_SET, true);
+}
+
+void FQTermDecode::selectG0B() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->SelectVtCharacterSet(FQTermBuffer::ASCII_SET, true);
+}
+
+void FQTermDecode::selectG00() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->SelectVtCharacterSet(FQTermBuffer::SPECIAL_GRAPHICS, true);
+}
+
+void FQTermDecode::selectG01() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->SelectVtCharacterSet(
+ FQTermBuffer::ALTERNATE_CHARACTER_ROM_STANDARD_CHARACTER_SET, true);
+}
+
+void FQTermDecode::selectG02() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->SelectVtCharacterSet(
+ FQTermBuffer::ALTERNATE_CHARACTER_ROM_SPECIAL_GRAPHICS, true);
+}
+
+void FQTermDecode::selectG1A() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->SelectVtCharacterSet(FQTermBuffer::UNITED_KINGDOM_SET, false);
+}
+
+void FQTermDecode::selectG1B() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->SelectVtCharacterSet(FQTermBuffer::ASCII_SET, false);
+}
+
+void FQTermDecode::selectG10() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->SelectVtCharacterSet(FQTermBuffer::SPECIAL_GRAPHICS, false);
+}
+
+void FQTermDecode::selectG11() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->SelectVtCharacterSet(
+ FQTermBuffer::ALTERNATE_CHARACTER_ROM_STANDARD_CHARACTER_SET, false);
+}
+
+void FQTermDecode::selectG12() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->SelectVtCharacterSet(
+ FQTermBuffer::ALTERNATE_CHARACTER_ROM_SPECIAL_GRAPHICS, false);
+}
+
+// erase functions
+void FQTermDecode::eraseStr() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ int n = param_[0];
+
+ if (n < 1) {
+ n = 1;
+ }
+
+ termBuffer_->eraseText(n);
+}
+
+// insert functions
+void FQTermDecode::insertStr() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ int n = param_[0];
+
+ if (n < 1) {
+ n = 1;
+ }
+
+ termBuffer_->insertSpaces(n);
+}
+
+// delete functions
+void FQTermDecode::deleteStr() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ int n = param_[0];
+
+ if (n < 1) {
+ n = 1;
+ }
+
+ termBuffer_->deleteText(n);
+}
+
+void FQTermDecode::eraseLine() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ switch (param_[0]) {
+ case 0:
+ termBuffer_->eraseToLineEnd();
+ break;
+ case 1:
+ termBuffer_->eraseToLineBegin();
+ break;
+ case 2:
+ termBuffer_->eraseEntireLine();
+ break;
+ default:
+ break;
+ }
+}
+
+void FQTermDecode::insertLine() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ int n = param_[0];
+
+ if (n < 1) {
+ n = 1;
+ }
+
+ termBuffer_->insertLines(n);
+}
+
+void FQTermDecode::deleteLine() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ int n = param_[0];
+
+ if (n < 1) {
+ n = 1;
+ }
+
+ termBuffer_->deleteLines(n);
+}
+
+void FQTermDecode::eraseScreen() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ switch (param_[0]) {
+ case 0:
+ termBuffer_->eraseToTermEnd();
+ break;
+ case 1:
+ termBuffer_->eraseToTermBegin();
+ break;
+ case 2:
+ termBuffer_->eraseEntireTerm();
+ break;
+ case 3:
+ break;
+ }
+}
+
+void FQTermDecode::setAttr() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ // get all attributes of character
+ if (!paramIndex_ && param_[0] == 0) {
+ current_color_ = default_color_;
+ current_attr_ = default_attr_;
+
+ termBuffer_->setCurrentAttr(current_color_, current_attr_);
+ return ;
+ }
+
+ unsigned char cp = current_color_;
+ unsigned char ea = current_attr_;
+ for (int n = 0; n <= paramIndex_; n++) {
+ if (param_[n] / 10 == 4) {
+ // background color
+ cp = cp &~BGMASK;
+ cp += SETBG(param_[n] % 10);
+ } else if (param_[n] / 10 == 3) {
+ // front color
+ cp = cp &~FGMASK;
+ cp += SETFG(param_[n] % 10);
+ } else {
+ switch (param_[n]) {
+ case 0:
+ // attr off
+ cp = default_color_; //NO_COLOR;
+ ea = default_attr_; //NO_ATTR;
+ break;
+ case 1:
+ // bright
+ ea = SETBRIGHT(ea);
+ break;
+ case 2:
+ // dim
+ ea = SETDIM(ea);
+ break;
+ case 4:
+ // underline
+ ea = SETUNDERLINE(ea);
+ break;
+ case 5:
+ // blink
+ ea = SETBLINK(ea);
+ break;
+ case 7:
+ // reverse
+ ea = SETREVERSE(ea);
+ break;
+ case 8:
+ // invisible
+ ea = SETINVISIBLE(ea);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ current_color_ = cp;
+ current_attr_ = ea;
+
+ termBuffer_->setCurrentAttr(current_color_, current_attr_);
+}
+
+void FQTermDecode::setMode() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ for (int i = 0; i <= paramIndex_; i++) {
+ int n = param_[i];
+ switch (n) {
+ case 4:
+ termBuffer_->setMode(FQTermBuffer::INSERT_MODE);
+ break;
+ case 20:
+ termBuffer_->setMode(FQTermBuffer::NEWLINE_MODE);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void FQTermDecode::resetMode() {
+ //TODO: more modes here.
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ for (int i = 0; i <= paramIndex_; i++) {
+ int n = param_[i];
+ switch (n) {
+ case 4:
+ termBuffer_->resetMode(FQTermBuffer::INSERT_MODE);
+ break;
+ case 20:
+ termBuffer_->resetMode(FQTermBuffer::NEWLINE_MODE);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void FQTermDecode::setDecPrivateMode() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ for (int i = 0; i <= paramIndex_; i++) {
+ int n = param_[i];
+ switch (n) {
+ case 1:
+ termBuffer_->setMode(FQTermBuffer::CURSOR_MODE);
+ break;
+ case 2:
+ termBuffer_->setMode(FQTermBuffer::ANSI_MODE);
+ break;
+ case 3:
+ termBuffer_->setTermSize(132, 24);
+ break;
+ case 4:
+ // smooth scrolling mode
+ // nothing to do.
+ break;
+ case 5:
+ termBuffer_->setMode(FQTermBuffer::LIGHTBG_MODE);
+ break;
+ case 6:
+ termBuffer_->setMode(FQTermBuffer::ORIGIN_MODE);
+ break;
+ case 7:
+ termBuffer_->setMode(FQTermBuffer::AUTOWRAP_MODE);
+ break;
+ case 8:
+ termBuffer_->setMode(FQTermBuffer::AUTOREPEAT_MODE);
+ break;
+ case 9:
+ // Interlace mode
+ // nothing to do.
+ break;
+ case 1000:
+ case 1001:
+ emit mouseMode(true);
+ currentMode_[MODE_MouseX11] = true;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void FQTermDecode::resetDecPrivateMode() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ for (int i = 0; i <= paramIndex_; i++) {
+ int n = param_[i];
+ switch (n) {
+ case 1:
+ termBuffer_->resetMode(FQTermBuffer::CURSOR_MODE);
+ break;
+ case 2:
+ termBuffer_->resetMode(FQTermBuffer::ANSI_MODE);
+ break;
+ case 3:
+ termBuffer_->setTermSize(80, 24);
+ break;
+ case 4:
+ // jump scrolling mode
+ // nothing to do.
+ break;
+ case 5:
+ termBuffer_->resetMode(FQTermBuffer::LIGHTBG_MODE);
+ break;
+ case 6:
+ termBuffer_->resetMode(FQTermBuffer::ORIGIN_MODE);
+ break;
+ case 7:
+ termBuffer_->resetMode(FQTermBuffer::AUTOWRAP_MODE);
+ break;
+ case 8:
+ termBuffer_->resetMode(FQTermBuffer::AUTOREPEAT_MODE);
+ break;
+ case 9:
+ // Interlace mode
+ // nothing to do.
+ break;
+ case 1000:
+ case 1001:
+ currentMode_[MODE_MouseX11] = false;
+ emit mouseMode(false);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void FQTermDecode::setNumericKeypad() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->setMode(FQTermBuffer::NUMERIC_MODE);
+}
+
+void FQTermDecode::setAppKeypad() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->resetMode(FQTermBuffer::NUMERIC_MODE);
+}
+
+void FQTermDecode::saveMode() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ for (int i = 0; i <= paramIndex_; i++) {
+ int n = param_[i];
+ switch (n) {
+ case 1000:
+ case 1001:
+ savedMode_[MODE_MouseX11] = currentMode_[MODE_MouseX11];
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void FQTermDecode::restoreMode() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ for (int i = 0; i <= paramIndex_; i++) {
+ int n = param_[i];
+ switch (n) {
+ case 1000:
+ case 1001:
+ currentMode_[MODE_MouseX11] = savedMode_[MODE_MouseX11];
+ emit mouseMode(currentMode_[MODE_MouseX11]);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void FQTermDecode::fillScreen() {
+ FQ_FUNC_TRACE("ansi", 8);
+
+ termBuffer_->fillScreenWith('E');
+}
+
+void FQTermDecode::test() {
+ FQ_FUNC_TRACE("ansi", 8);
+}
+
+void FQTermDecode::logParam() const {
+ if (isParamAvailable_) {
+ for (int i = 8; i <= paramIndex_; ++i) {
+ FQ_TRACE("ansi", 8) << "Parameter[" << i << "] = " << param_[i];
+ }
+ } else {
+ FQ_TRACE("ansi", 8) << "No parameter.";
+ }
+}
+
+void FQTermDecode::onCaretChangeRow() {
+ leftToDecode_.clear();
+}
+
+void FQTermDecode::setTitle() {
+ if (!isParamAvailable_) {
+ return;
+ }
+ switch(param_[0])
+ {
+ case 0:
+ //icon and text
+ break;
+ case 1:
+ //icon
+ break;
+ case 2:
+ //text
+ emit onTitleSet(bbs2unicode(textParam_));
+ break;
+ case 46:
+ //log file
+ break;
+ case 50:
+ //font
+ break;
+ default:
+ break;
+ }
+}
+
+void FQTermDecode::collectText() {
+ FQ_FUNC_TRACE("ansi", 10);
+ if (textParam_.length() < 4096)
+ textParam_ += inputData_[dataIndex_];
+}
+
+void FQTermDecode::clearText() {
+ FQ_FUNC_TRACE("ansi", 10);
+ textParam_.clear();
+}
+
+
+
+
+} // namespace FQTerm
+
+#include "fqterm_decode.moc"
diff --git a/src/terminal/internal/fqterm_decode.h b/src/terminal/internal/fqterm_decode.h
new file mode 100644
index 0000000..5f3f46d
--- /dev/null
+++ b/src/terminal/internal/fqterm_decode.h
@@ -0,0 +1,194 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_DECODE_H
+#define FQTERM_DECODE_H
+
+#include <QObject>
+#include "fqterm_text_line.h"
+
+namespace FQTerm {
+
+class FQTermDecode;
+class FQTermBuffer;
+class FQTermTelnet;
+
+// this for FSM
+typedef void(FQTermDecode:: *StateFunc)();
+
+struct StateOption {
+ int byte; // char value to look for; -1==end/default
+ StateFunc action;
+ StateOption *nextState;
+};
+
+class FQTermDecode: public QObject {
+ Q_OBJECT;
+ public:
+ FQTermDecode(FQTermBuffer *, int server_encoding);
+ ~FQTermDecode();
+
+
+ // translate data from telnet socket to our own buffer
+ // return how many bytes are processed.
+ int decode(const char *cstr, int length);
+
+ bool bellReceive() {
+ return isBell_;
+ }
+
+ void setServerEncoding(int encoding) {
+ server_encoding_ = encoding;
+ }
+
+
+ //signals:
+ // void decodeFinished();
+ signals:
+ void mouseMode(bool);
+ void enqReceived();
+ void onTitleSet(const QString&);
+ public slots:
+ void onCaretChangeRow();
+ private:
+ // escape sequence actions
+ // you'd better see FSM structure array in FQTermDecode.cpp
+
+ void setAttr();
+ void setMargins();
+
+ // char screen functions
+ void deleteStr();
+ void deleteLine();
+ void insertStr();
+ void insertLine();
+ void eraseStr();
+ void eraseLine();
+ void eraseScreen();
+
+ // cursor functions
+ void saveCursor();
+ void restoreCursor();
+ void cursorPosition();
+
+ // Move cursor, stop at boundary.
+ void cursorLeft();
+ void cursorDown();
+ void cursorRight();
+ void cursorUp();
+
+ // Move cursor, scroll at boundary.
+ void moveCursorUp();
+ void moveCursorDown();
+ void nextLine();
+
+ void selectG0A();
+ void selectG0B();
+ void selectG00();
+ void selectG01();
+ void selectG02();
+
+ void selectG1A();
+ void selectG1B();
+ void selectG10();
+ void selectG11();
+ void selectG12();
+
+ // other escape sequence actions
+ void normalInput();
+
+ //title settings
+ void setTitle();
+ void collectText();
+ void clearText();
+
+ // action parameters
+ void clearParam();
+ void paramDigit();
+ void nextParam();
+
+ // non-printing characters
+ void cr(), lf(), ff(), bell(), tab(), bs(), del(), g0(), g1(), enq();
+
+ void addTabStop();
+ void clearTabStop();
+
+ void setMode();
+ void resetMode();
+ void setDecPrivateMode();
+ void resetDecPrivateMode();
+ void setNumericKeypad();
+ void setAppKeypad();
+
+ void saveMode();
+ void restoreMode();
+
+ // video alignment test - fill screen with E's.
+ void fillScreen();
+
+ void test();
+
+ private:
+
+ bool isBell_;
+ // short currentAttr_, defaultAttr_;
+ unsigned char current_color_, default_color_;
+ unsigned char current_attr_, default_attr_;
+
+ // ********** ansi decoder states ****************
+ StateOption *current_state_;
+
+ struct VT100StateMachine {
+ static StateOption normal_state_[], esc_state_[], bracket_state_[];
+ static StateOption private_state_[], sharp_state_[];
+ static StateOption title_state_[], title_text_state_[];
+ static StateOption select_g0_charset_state_[], select_g1_charset_state_[];
+ };
+
+ static const char *getStateName(const StateOption *state);
+
+ void logParam() const;
+
+
+ bool interrupt_decode_;
+
+ // ********** decoder *****************
+ const char *inputData_;
+ int inputLength_, dataIndex_;
+
+ int paramIndex_, param_[30];
+ bool isParamAvailable_;
+
+ QByteArray textParam_;
+
+ bool savedMode_[30];
+ bool currentMode_[30];
+
+ FQTermBuffer *termBuffer_;
+ int server_encoding_;
+
+ QString bbs2unicode(const QByteArray &text);
+ int processInput(QByteArray& result);
+ QByteArray leftToDecode_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_DECODE_H
diff --git a/src/terminal/internal/fqterm_telnet.cpp b/src/terminal/internal/fqterm_telnet.cpp
new file mode 100644
index 0000000..2446b8a
--- /dev/null
+++ b/src/terminal/internal/fqterm_telnet.cpp
@@ -0,0 +1,1041 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <QAbstractSocket>
+
+#include "fqterm.h"
+#include "fqterm_telnet.h"
+#include "fqterm_socket.h"
+
+#ifndef _NO_SSH_COMPILED
+#include "fqterm_ssh_socket.h"
+#endif
+
+/* TELNET Command Codes: */
+/* Hints: These NVT control characters are sent from client to server, So
+ the client side will not receive these commands */
+#define TCSB (u_char)250 /* Start Subnegotiation */
+#define TCSE (u_char)240 /* End Of Subnegotiation */
+#define TCNOP (u_char)241 /* No Operation */
+#define TCDM (u_char)242 /* Data Mark (for Sync) */
+#define TCBRK (u_char)243 /* NVT Character BRK */
+#define TCIP (u_char)244 /* Interrupt Process */
+#define TCAO (u_char)245 /* Abort Output */
+#define TCAYT (u_char)246 /* "Are You There?" Function */
+#define TCEC (u_char)247 /* Erase Character */
+#define TCEL (u_char)248 /* Erase Line */
+#define TCGA (u_char)249 /* "Go Ahead" Function */
+#define TCWILL (u_char)251 /* Desire/Confirm Will Do Option*/
+#define TCWONT (u_char)252 /* Refusal To Do Option */
+#define TCDO (u_char)253 /* Request To Do Option */
+#define TCDONT (u_char)254 /* Request NOT To Do Option */
+#define TCIAC (u_char)255 /* Interpret As Command Escape */
+
+/* Telnet Option Codes: */
+#define TOTXBINARY (u_char) 0 /* TRANSMIT-BINARY option */
+#define TOECHO (u_char) 1 /* ECHO Option */
+#define TONOGA (u_char) 3 /* Suppress Go-Ahead Option */
+#define TOTERMTYPE (u_char) 24 /* Terminal-Type Option */
+#define TONAWS (u_char) 31 /* Window Size */
+
+/* Network Virtual Printer Special Characters: */
+/* In normal situations, these characters will to translated into local
+ control characters , then pass to upper layer term. But in our situation,
+ we can pass them to term directly */
+
+#define VPLF '\n' /* Line Feed */
+#define VPCR '\r' /* Carriage Return */
+#define VPBEL '\a' /* Bell (attention signal) */
+#define VPBS '\b' /* Back Space */
+#define VPHT '\t' /* Horizontal Tab */
+#define VPVT '\v' /* Vertical Tab */
+#define VPFF '\f' /* Form Feed */
+
+/* Keyboard Command Characters: */
+
+/* Option Subnegotiation Constants: */
+#define TT_IS 0 /* TERMINAL_TYPE option "IS" command */
+#define TT_SEND 1 /* TERMINAL_TYPE option "SEND" command */
+
+/* Telnet Socket-Input FSM States: */
+#define TSDATA 0 /* normal data processing */
+#define TSIAC 1 /* have seen IAC */
+#define TSWOPT 2 /* have seen IAC-{WILL/WONT} */
+#define TSDOPT 3 /* have seen IAC-{DO/DONT} */
+#define TSSUBNEG 4 /* have seen IAC-SB */
+#define TSSUBIAC 5 /* have seen IAC-SB-...-IAC */
+// if any state added here, please update NTSTATES (currently 6).
+
+// Telnet Option Subnegotiation FSM States:
+#define SS_START 0 // initial state
+#define SS_TERMTYPE 1 // TERMINAL_TYPE option subnegotiation
+#define SS_END 2 // state after all legal input
+// if any state added here, please update NSSTATES (currently 3).
+
+#define FSINVALID 0xff // an invalid state number
+#define TCANY (NCHRS+1) // match any character
+
+#define TINVALID 0xff // an invalid transition index
+
+namespace FQTerm {
+
+struct fsm_trans FQTermTelnet::ttstab[] = {
+ /* State Input Next State Action */
+ /* ------ ------ ----------- ------- */
+ {
+ TSDATA, TCIAC, TSIAC, &FQTermTelnet::no_op
+ }, {
+ TSDATA, TCANY, TSDATA, &FQTermTelnet::ttputc
+ }, {
+ TSIAC, TCIAC, TSDATA, &FQTermTelnet::ttputc
+ }, {
+ TSIAC, TCSB, TSSUBNEG, &FQTermTelnet::no_op
+ }, {/* Telnet Commands */
+ TSIAC, TCNOP, TSDATA, &FQTermTelnet::no_op
+ }, {
+ TSIAC, TCDM, TSDATA, &FQTermTelnet::tcdm
+ }, { /* Option Negotiation */
+ TSIAC, TCWILL, TSWOPT, &FQTermTelnet::recopt
+ }, {
+ TSIAC, TCWONT, TSWOPT, &FQTermTelnet::recopt
+ }, {
+ TSIAC, TCDO, TSDOPT, &FQTermTelnet::recopt
+ }, {
+ TSIAC, TCDONT, TSDOPT, &FQTermTelnet::recopt
+ }, {
+ TSIAC, TCANY, TSDATA, &FQTermTelnet::no_op
+ }, { /* Option Subnegotion */
+ TSSUBNEG, TCIAC, TSSUBIAC, &FQTermTelnet::no_op
+ }, {
+ TSSUBNEG, TCANY, TSSUBNEG, &FQTermTelnet::subopt
+ }, {
+ TSSUBIAC, TCSE, TSDATA, &FQTermTelnet::subend
+ }, {
+ TSSUBIAC, TCANY, TSSUBNEG, &FQTermTelnet::subopt
+ }, {
+ TSWOPT, TOECHO, TSDATA, &FQTermTelnet::do_echo
+ }, {
+ TSWOPT, TONOGA, TSDATA, &FQTermTelnet::do_noga
+ }, {
+ TSWOPT, TOTXBINARY, TSDATA, &FQTermTelnet::do_txbinary
+ }, {
+ TSWOPT, TCANY, TSDATA, &FQTermTelnet::do_notsup
+ },{
+ TSDOPT, TONAWS, TSDATA, &FQTermTelnet::will_naws
+ }, {
+ TSDOPT, TOTERMTYPE, TSDATA, &FQTermTelnet::will_termtype
+ }, {
+ TSDOPT, TOTXBINARY, TSDATA, &FQTermTelnet::will_txbinary
+ }, {
+ TSDOPT, TCANY, TSDATA, &FQTermTelnet::will_notsup
+ }, {
+ FSINVALID, TCANY, FSINVALID, &FQTermTelnet::tnabort
+ },
+};
+
+
+struct fsm_trans FQTermTelnet::substab[] = {
+ /* State Input Next State Action */
+ /* ---------------------------------------------------- */
+ {
+ SS_START, TOTERMTYPE, SS_TERMTYPE, &FQTermTelnet::no_op
+ }, {
+ SS_START, TCANY, SS_END, &FQTermTelnet::no_op
+ }, {
+ SS_TERMTYPE, TT_SEND, SS_END, &FQTermTelnet::subtermtype
+ }, {
+ SS_TERMTYPE, TCANY, SS_END, &FQTermTelnet::no_op
+ }, {
+ SS_END, TCANY, SS_END, &FQTermTelnet::no_op
+ }, {
+ FSINVALID, TCANY, FSINVALID, &FQTermTelnet::tnabort
+ },
+};
+
+
+
+/*------------------------------------------------------------------------
+ * Constructor
+ *------------------------------------------------------------------------
+ */
+FQTermTelnet::FQTermTelnet(const QString &strTermType, int rows, int columns,
+ int protocolType, int hostType, const char *sshuser, const char *sshpasswd)
+ : from_socket(),
+ to_ansi(),
+ from_ansi(),
+ to_socket(),
+ hostType_(hostType),
+ protocolType_(protocolType) {
+ term = new char[21];
+ memset(term, 0, sizeof(term));
+ // TODO: clean up, need???
+#ifdef WIN32
+ _snprintf(term, sizeof(term), "%s", strTermType.toLatin1().constData());
+#else
+ strncpy(term,strTermType.toLatin1(),20);
+#endif
+
+ wx = columns;
+ wy = rows;
+ wsize = 0;
+ done_naws = 0;
+ synching = 0;
+ doecho = 0;
+ sndbinary = 0;
+ rcvbinary = 0;
+ noga = 0;
+ termtype = 0;
+ naws = 0;
+ server_sent_do_naws = 0;
+ raw_size = 0;
+
+#ifndef _NO_SSH_COMPILED
+ if (protocolType == 1 || protocolType == 2) {
+ socket = new FQTermSSHSocket(columns, rows, strTermType, sshuser, sshpasswd);
+ FQ_VERIFY(connect(socket, SIGNAL(sshAuthOK()),
+ this, SIGNAL(onSSHAuthOK())));
+ } else if (protocolType == 3) {
+ socket = new FQTermLocalSocket("");
+ } else {
+ socket = new FQTermTelnetSocket();
+ }
+#else
+ socket = new FQTermTelnetSocket();
+#endif
+
+ // connect signal and slots
+ FQ_VERIFY(connect(socket, SIGNAL(connected()), this, SLOT(connected())));
+ FQ_VERIFY(connect(socket, SIGNAL(readyRead()), this, SLOT(socketReadyRead())));
+ FQ_VERIFY(connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(showError(QAbstractSocket::SocketError))));
+ FQ_VERIFY(connect(socket, SIGNAL(hostFound()), this, SLOT(hostFound())));
+ FQ_VERIFY(connect(socket, SIGNAL(delayedCloseFinished()),
+ this, SLOT(delayCloseFinished())));
+ FQ_VERIFY(connect(socket, SIGNAL(connectionClosed()), this, SLOT(closed())));
+ FQ_VERIFY(connect(socket, SIGNAL(socketState(int)), this, SIGNAL(TelnetState(int))));
+
+ FQ_VERIFY(connect(socket, SIGNAL(requestUserPwd(QString *, QString *, bool *)),
+ this, SIGNAL(requestUserPwd(QString *, QString *, bool *))));
+
+ FQ_VERIFY(connect(socket, SIGNAL(errorMessage(QString)), this, SIGNAL(errorMessage(QString))));
+
+ // Init telnet, mainly the FSMs
+ init_telnet();
+}
+
+/*------------------------------------------------------------------------
+ * destructor
+ *------------------------------------------------------------------------
+ */
+FQTermTelnet::~FQTermTelnet() {
+ // delete objects
+ delete [] term;
+ delete socket;
+}
+
+
+
+/*------------------------------------------------------------------------
+ * init_telnet
+ *------------------------------------------------------------------------
+ */
+void FQTermTelnet::init_telnet() {
+ fsmbuild(); /* setup FSMs */
+}
+
+
+/*------------------------------------------------------------------------
+ * fsmbuild - build the Finite State Machine data structures
+ *------------------------------------------------------------------------
+ */
+void FQTermTelnet::fsmbuild() {
+ fsminit(ttfsm, ttstab, NTSTATES);
+ ttstate = TSDATA;
+
+ fsminit(subfsm, substab, NSSTATES);
+ substate = SS_START;
+
+}
+
+/*------------------------------------------------------------------------
+ * fsminit - Finite State Machine initializer
+ *------------------------------------------------------------------------
+ */
+void FQTermTelnet::fsminit(u_char fsm[][NCHRS], struct fsm_trans ttab[], int
+ nstates) {
+ struct fsm_trans *pt;
+ int sn, ti, cn;
+
+ for (cn = 0; cn < NCHRS; ++cn) {
+ for (ti = 0; ti < nstates; ++ti) {
+ fsm[ti][cn] = TINVALID;
+ }
+ }
+
+ for (ti = 0; ttab[ti].ft_state != FSINVALID; ++ti) {
+ pt = &ttab[ti];
+ sn = pt->ft_state;
+ if (pt->ft_char == TCANY) {
+ for (cn = 0; cn < NCHRS; ++cn) {
+ if (fsm[sn][cn] == TINVALID) {
+ fsm[sn][cn] = ti;
+ }
+ }
+ } else {
+ fsm[sn][pt->ft_char] = ti;
+ }
+ }
+
+ /* set all uninitialized indices to an invalid transition */
+ for (cn = 0; cn < NCHRS; ++cn) {
+ for (ti = 0; ti < nstates; ++ti) {
+ if (fsm[ti][cn] == TINVALID) {
+ fsm[ti][cn] = ti;
+ }
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------
+ * connect to host
+ *------------------------------------------------------------------------
+ */
+void FQTermTelnet::connectHost(const QString &hostname, quint16 portnumber) {
+ done_naws = 0;
+ synching = 0;
+ doecho = 0;
+ sndbinary = 0;
+ rcvbinary = 0;
+ noga = 0;
+ termtype = 0;
+ naws = 0;
+
+ socket->connectToHost(hostname, portnumber);
+ // host name resolving
+ emit TelnetState(TSRESOLVING);
+}
+
+void FQTermTelnet::windowSizeChanged(int x, int y) {
+ wx = x;
+ wy = y;
+ if (bConnected) {
+ if (hostType_ == 1 && (protocolType_ == 1 || protocolType_ == 2)) {
+ //This is a *nix host, with ssh connection.
+ socket->setTermSize(x, y);
+ return;
+ }
+ naws = 0;
+
+ QByteArray cmd(10, 0);
+ cmd[0] = (char)TCIAC;
+ cmd[1] = (char)TCSB;
+ cmd[2] = (char)TONAWS;
+ cmd[3] = (char)(short(wx) >> 8);
+ cmd[4] = (char)(short(wx) & 0xff);
+ cmd[5] = (char)(short(wy) >> 8);
+ cmd[6] = (char)(short(wy) & 0xff);
+ cmd[7] = (char)TCIAC;
+ cmd[8] = (char)TCSE;
+ socket->writeBlock(cmd);
+
+ }
+}
+
+/*------------------------------------------------------------------------
+ * set proxy
+ *-----------------------------------------------------------------------
+ */
+void FQTermTelnet::setProxy(int nProxyType, bool bAuth, const QString
+ &strProxyHost, quint16 uProxyPort,
+ const QString &strProxyUsr,
+ const QString &strProxyPwd) {
+ socket->setProxy(nProxyType, bAuth, strProxyHost,
+ uProxyPort, strProxyUsr, strProxyPwd);
+}
+
+/*------------------------------------------------------------------------
+ * close connection
+ *-----------------------------------------------------------------------
+ */
+
+void FQTermTelnet::close() {
+ socket->close();
+}
+
+/*------------------------------------------------------------------------
+ * SLOT connected
+ *------------------------------------------------------------------------
+ */
+void FQTermTelnet::connected() {
+ bConnected = true;
+ emit TelnetState(TSHOSTCONNECTED);
+}
+
+/*------------------------------------------------------------------------
+ * SLOT closed
+ *------------------------------------------------------------------------
+ */
+
+void FQTermTelnet::closed() {
+ bConnected = false;
+ emit TelnetState(TSCLOSED);
+}
+
+/*------------------------------------------------------------------------
+ * SLOT delayCloseFinished
+ *------------------------------------------------------------------------
+ */
+
+void FQTermTelnet::delayCloseFinished() {
+ bConnected = false;
+ emit TelnetState(TSCLOSEFINISH);
+}
+
+/*------------------------------------------------------------------------
+ * SLOT hostFound
+ *------------------------------------------------------------------------
+ */
+void FQTermTelnet::hostFound() {
+ emit TelnetState(TSHOSTFOUND);
+}
+
+/*------------------------------------------------------------------------
+ * SLOT error
+ *------------------------------------------------------------------------
+ */
+void FQTermTelnet::showError(QAbstractSocket::SocketError index) {
+
+ switch (index) {
+ case QAbstractSocket::ConnectionRefusedError: emit TelnetState(TSREFUSED);
+ break;
+ case QAbstractSocket::HostNotFoundError: emit TelnetState(TSHOSTNOTFOUND);
+ break;
+ //FIXME: am I right
+ case QAbstractSocket::SocketAccessError: emit TelnetState(TSREADERROR);
+ break;
+ case QAbstractSocket::RemoteHostClosedError: emit TelnetState(TSCLOSED);
+ break;
+ default:
+ emit TelnetState(TSERROR);
+ ;
+ break;
+ }
+
+}
+
+/*------------------------------------------------------------------------
+ * SLOOT socketReadyRead -
+ * when socket has data to upload, it send out readyRead() signal, it
+ * invokes this SLOT to read data in, do telnet decode job, and send out
+ * readyRead() SIGNAL to upper layer
+ *------------------------------------------------------------------------
+ */
+void FQTermTelnet::socketReadyRead() {
+ int nbytes, nread;
+ // TODO_UTF16: check this function.
+
+ // get the data size
+ nbytes = socket->bytesAvailable();
+ if (nbytes <= 0) {
+ return ;
+ }
+
+ raw_size = nbytes;
+
+ //resize input buffer
+ from_socket.resize(0);
+
+ //read data from socket to from_socket
+ from_socket = socket->readBlock(nbytes);
+ nread = from_socket.size();
+ //do some checks
+ if (nread <= 0) {
+ FQ_TRACE("telnet", 8) << "Failed to read socket: " << nread << " <= 0.";
+ return ;
+ }
+ if (nread > nbytes) {
+ FQ_TRACE("telnet", 0) << "Overflow when reading socket: "
+ << " nread = " << nread
+ << " > nbytes = " << nbytes;
+ return ;
+ }
+
+ //resize output buffer
+ to_ansi.resize(2 *nread);
+ to_socket.resize(4 *nread);
+
+ rsize = 0;
+ wsize = 0;
+
+ // do telnet decode job...
+ struct fsm_trans *pt;
+ int i, ti;
+
+ u_char c;
+ for (i = 0; i < nread; ++i) {
+ c = (u_char)(from_socket[i]);
+ ti = ttfsm[ttstate][c];
+ pt = &ttstab[ti];
+ (this->*(pt->ft_action))((int)c);
+ ttstate = pt->ft_next;
+ }
+
+ // flush the to_socket buffer, it contain response to server
+ if (wsize > 0) {
+ socket->writeBlock(to_socket.left(wsize));
+ socket->flush();
+ }
+
+ /* send SIGNAL readyRead() with the size of data available*/
+ if (rsize > 0 || raw_size > 0) {
+ emit readyRead(rsize, raw_size);
+ }
+
+}
+
+int FQTermTelnet::raw_len() {
+ return raw_size;
+}
+
+/*------------------------------------------------------------------------
+ * actions
+ *------------------------------------------------------------------------
+ */
+int FQTermTelnet::read_raw(char *data, uint maxlen) {
+ //do some checks
+ if (data == 0) {
+ FQ_TRACE("telnet", 0) << "NULL pointer.";
+ return -1;
+ }
+ if ((long)maxlen < raw_size) {
+ /* we need all data be read out in one read */
+ FQ_TRACE("telnet", 0) << "The upper layer's buffer is too small.";
+ return -1;
+ }
+
+ //do it, memcpy( destination, source, size)
+ memcpy(data, from_socket.data(), raw_size);
+ return raw_size;
+}
+
+
+/*------------------------------------------------------------------------
+ * actions
+ *------------------------------------------------------------------------
+ */
+int FQTermTelnet::read(char *data, uint maxlen) {
+ //do some checks
+ if (data == 0) {
+ FQ_TRACE("telent", 0) << "NULL pointer.";
+ return -1;
+ }
+ if (maxlen < rsize) {
+ /* we need all data be read out in one read */
+ FQ_TRACE("telnet", 0) << "The upper layer's buffer is too small.";
+ return -1;
+ }
+
+ //do it, memcpy( destination, source, size)
+ memcpy(data, to_ansi.data(), rsize);
+
+ FQ_TRACE("telnet", 8) << "read " << rsize << " bytes:\n"
+ << dumpHexString << std::string(data, rsize);
+
+ return rsize;
+}
+
+/*------------------------------------------------------------------------
+ * actions
+ *------------------------------------------------------------------------
+ */
+
+
+/*------------------------------------------------------------------------
+ * writeBlock
+ * write data from data-> to socket, the length of data is len
+ *------------------------------------------------------------------------
+ */
+int FQTermTelnet::write(const char *data, uint len) {
+ // TODO: accept data, (This seems can be removed????)
+ from_ansi.resize(len);
+ memcpy(from_ansi.data(), data, len);
+
+ // resize output buffer
+ to_socket.resize(2 *len);
+ wsize = 0;
+
+ // process keyboard input
+ // because we use GUI, there is no need to support a "command mode"
+ // So the keyboard-input FSM isnt' necessary.
+
+ uint i;
+
+ u_char c; // TODO: for gcc's happy :)
+ for (i = 0; i < len; ++i) {
+ c = (u_char)(from_ansi[i]);
+ soputc((int)c);
+ }
+
+ FQ_TRACE("telnet", 2) << "write " << len << " bytes:\n"
+ << dumpHexString << std::string(data, len);
+
+ //flush socket
+ socket->writeBlock(to_socket.left(wsize));
+ socket->flush();
+
+ emit TelnetState(TSWRITED);
+ return 0;
+}
+
+
+/*------------------------------------------------------------------------
+ * Trans functions
+ * All trans functions use from_socket, to_ansi, to_socket buffers, and
+ * rsize, wsize .
+ *------------------------------------------------------------------------
+ */
+
+/*------------------------------------------------------------------------
+ * tcdm - handle the telnet "DATA MARK" command (marks end of SYNCH)
+ *------------------------------------------------------------------------
+ */
+int FQTermTelnet::tcdm(int) {
+ if (synching > 0) {
+ synching--;
+ }
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * rcvurg - receive urgent data input (indicates a telnet SYNCH)
+ *------------------------------------------------------------------------
+ */
+/*
+ int FQTermTelnet::rcvurg(int sig)
+ {
+ synching++;
+ }
+*/
+
+/*------------------------------------------------------------------------
+ * recopt - record option type
+ *------------------------------------------------------------------------
+ */
+
+int FQTermTelnet::recopt(int c) {
+ option_cmd = c;
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * no_op - do nothing
+ *------------------------------------------------------------------------
+ */
+
+int FQTermTelnet::no_op(int) {
+ return 0;
+}
+
+
+/*------------------------------------------------------------------------
+ * do_echo - handle TELNET WILL/WON'T ECHO option
+ *------------------------------------------------------------------------
+ */
+int FQTermTelnet::do_echo(int c) {
+ if (doecho) {
+ if (option_cmd == TCWILL) {
+ return 0;
+ }
+ /* already doing ECHO */
+ } else if (option_cmd == TCWONT) {
+ return 0;
+ }
+ /* already NOT doing ECHO */
+
+ doecho = !doecho;
+
+ putc_down(TCIAC);
+ if (doecho) {
+ putc_down(TCDO);
+ } else {
+ putc_down(TCDONT);
+ }
+ putc_down((char)c);
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * putc_down - put a character in to_socket buffer.
+ * wsize represent the number of bytes in to_socket buffer, and the buffer
+ * is addressed from 0, NOT 1.
+ *------------------------------------------------------------------------
+ */
+void FQTermTelnet::putc_down(u_char c) {
+ // check overflow
+ if ((long)(wsize + 1) > to_socket.size()) {
+ FQ_TRACE("telnet", 0) << "Buffer to_socket overflow.";
+ return ;
+ }
+ // put it in the buffer
+ //to_socket->replace(wsize, 1, (const char *)&c);
+ to_socket[wsize] = c;
+
+ wsize++;
+ return ;
+}
+
+/*------------------------------------------------------------------------
+ * do_notsup - handle an unsupported telnet "will/won't" option
+ *------------------------------------------------------------------------
+ */
+
+int FQTermTelnet::do_notsup(int c) {
+ putc_down(TCIAC);
+ putc_down(TCDONT);
+ putc_down((char)c);
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * do_noga - don't do telnet Go-Ahead's
+ *------------------------------------------------------------------------
+ */
+
+int FQTermTelnet::do_noga(int c) {
+ if (noga) {
+ if (option_cmd == TCWILL) {
+ return 0;
+ }
+ } else if (option_cmd == TCWONT) {
+ return 0;
+ }
+
+ noga = !noga;
+
+ putc_down(TCIAC);
+ if (noga) {
+ putc_down(TCDO);
+ } else {
+ putc_down(TCDONT);
+ }
+ putc_down((char)c);
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * do_txbinary - handle telnet "will/won't" TRANSMIT-BINARY option
+ *------------------------------------------------------------------------
+ */
+
+int FQTermTelnet::do_txbinary(int c) {
+ if (rcvbinary) {
+ if (option_cmd == TCWILL) {
+ return 0;
+ }
+ } else if (option_cmd == TCWONT) {
+ return 0;
+ }
+
+ rcvbinary = !rcvbinary;
+
+ putc_down(TCIAC);
+ if (rcvbinary) {
+ putc_down(TCDO);
+ } else {
+ putc_down(TCDONT);
+ }
+ putc_down((char)c);
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * will_notsup - handle an unsupported telnet "do/don't" option
+ *------------------------------------------------------------------------
+ */
+
+int FQTermTelnet::will_notsup(int c) {
+ putc_down(TCIAC);
+ putc_down(TCWONT);
+ putc_down((char)c);
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * will_txbinary - handle telnet "do/don't" TRANSMIT-BINARY option
+ *------------------------------------------------------------------------
+ */
+
+int FQTermTelnet::will_txbinary(int c) {
+ if (sndbinary) {
+ if (option_cmd == TCDO) {
+ return 0;
+ }
+ } else if (option_cmd == TCDONT) {
+ return 0;
+ }
+
+ sndbinary = !sndbinary;
+
+ putc_down(TCIAC);
+ if (sndbinary) {
+ putc_down(TCWILL);
+ } else {
+ putc_down(TCWONT);
+ }
+ putc_down((char)c);
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * will_termtype - handle telnet "do/don't" TERMINAL-TYPE option
+ *------------------------------------------------------------------------
+ */
+int FQTermTelnet::will_termtype(int c) {
+ if (termtype) {
+ if (option_cmd == TCDO) {
+ return 0;
+ }
+ } else if (option_cmd == TCDONT) {
+ return 0;
+ }
+
+ termtype = !termtype;
+
+ putc_down(TCIAC);
+
+ if (termtype) {
+ putc_down(TCWILL);
+ } else {
+ putc_down(TCWONT);
+ }
+
+ putc_down((char)c);
+
+ // TODO: Do NOT use this assume! some foolish BBS not response the request
+ /* The client expects that once the remote application receives
+ terminal type information it will send control sequences for
+ the terminal, which cannot be sent using the NVT encoding, So
+ change the transfer mode to binary in both directions */
+ /* set up binary data path; send WILL, DO */
+ /* if (termtype) {
+ option_cmd = TCWILL;
+ do_txbinary(TOTXBINARY);
+ option_cmd = TCDO;
+ will_txbinary(TOTXBINARY);
+ }
+ */
+ return 0;
+}
+
+int FQTermTelnet::will_naws(int c) {
+ if (naws) {
+ if (option_cmd == TCDO)
+ return 0;
+ } else if (option_cmd == TCDONT)
+ return 0;
+
+
+ naws = !naws;
+
+ putc_down(TCIAC);
+ if (naws)
+ putc_down(TCWILL);
+ else
+ putc_down(TCWONT);
+ putc_down((char)c);
+
+ putc_down(TCIAC);
+ putc_down(TCSB);
+ putc_down(TONAWS);
+ putc_down((char)(short(wx) >> 8));
+ putc_down((char)(short(wx)&0xff));
+ putc_down((char)(short(wy) >> 8));
+ putc_down((char)(short(wy)&0xff));
+ putc_down(((char)TCIAC));
+ putc_down((char)TCSE);
+
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * subopt - do option subnegotiation FSM transitions
+ *------------------------------------------------------------------------
+ */
+int FQTermTelnet::subopt(int c) {
+ struct fsm_trans *pt;
+ int ti;
+
+ ti = subfsm[substate][c];
+ pt = &substab[ti];
+ (this->*(pt->ft_action))(c);
+ substate = pt->ft_next;
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * subtermtype - do terminal type option subnegotation
+ *------------------------------------------------------------------------
+ */
+
+int FQTermTelnet::subtermtype(int) {
+ char *i;
+ /* have received IAC.SB.TERMTYPE.SEND */
+
+ putc_down(TCIAC);
+ putc_down(TCSB);
+ putc_down(TOTERMTYPE);
+ putc_down(TT_IS);
+
+ //write term type string
+ //fputs(term, sfp);
+ for (i = term; (*i) != '\000'; i++) {
+ putc_down(*i);
+ }
+
+ putc_down(TCIAC);
+ putc_down(TCSE);
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * subend - end of an option subnegotiation; reset FSM
+ *------------------------------------------------------------------------
+ */
+
+int FQTermTelnet::subend(int) {
+ substate = SS_START;
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * soputc - move a character from the keyboard to the socket
+ * convert an character into the NVT encoding and send it
+ * through the socket to the server.
+ *------------------------------------------------------------------------
+ */
+
+int FQTermTelnet::soputc(int c) {
+ if (sndbinary) {
+ if (c == TCIAC) {
+ putc_down(TCIAC);
+ }
+ /* byte-stuff IAC */
+ putc_down(c);
+ return 0;
+ }
+
+ //c &= 0x7f; /* 7-bit ASCII only ???*/
+ // Convert local special characters to NVT characters
+ /* TODO: // BBS don't need control signals
+ if (c == t_intrc || c == t_quitc) { // Interrupt
+ putc_down(TCIAC);
+ putc_down(TCIP);
+ } else if (c == sg_erase) { // Erase Char
+ putc_down(TCIAC);
+ putc_down(TCEC);
+ } else if (c == sg_kill) { // Erase Line
+ putc_down(TCIAC);
+ putc_down(TCEL);
+ } else if (c == t_flushc) { // Abort Output
+ putc_down(TCIAC);
+ putc_down(TCAO);
+ } else */
+ putc_down((char)c);
+
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * xputc - putc to upper layer with optional file scripting
+ *------------------------------------------------------------------------
+ */
+int FQTermTelnet::xputc_up(char ch) {
+ if ((long)(rsize + 1) > to_ansi.size()) {
+ FQ_TRACE("telnet", 0) << "Buffer to_ansi overflow.";
+ return - 1;
+ }
+ //to_ansi->replace(wsize, 1, &ch);
+ to_ansi[rsize] = u_char(ch);
+ rsize++;
+
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * xfputs - fputs with optional file scripting
+ *------------------------------------------------------------------------
+ */
+int FQTermTelnet::xputs_up(char *str) {
+ /*if (scrfp)
+ fputs(str, scrfp);*/
+
+ char *i;
+ for (i = str; (*i) != '\000'; i++) {
+ xputc_up(*i);
+ }
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * ttputc - print a single character on a Network Virtual Terminal
+ *------------------------------------------------------------------------
+ */
+int FQTermTelnet::ttputc(int c) {
+ if (rcvbinary) {
+ xputc_up((char)c); /* print uninterpretted */
+ return 0;
+ }
+ /* no data, if in SYNCH */
+ /*
+ if (synching)
+ return 0;
+ */
+ /* TODO: FQTermTelnet doesnot interpret NVT code, provide datas to upper
+ layer directly. So, <cr><lf> will not be replaced with <lf>
+ */
+ xputc_up((char)c);
+
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * invalid state reached, aborted
+ *------------------------------------------------------------------------
+ */
+int FQTermTelnet::tnabort(int) {
+ FQ_VERIFY(false); // "invalid state reached, aborted";
+ // exit(-1);
+ return -1;
+}
+
+bool FQTermTelnet::readyForInput()
+{
+ return socket->readyForInput();
+}
+
+
+
+} // namespace FQTerm
+
+#include "fqterm_telnet.moc"
diff --git a/src/terminal/internal/fqterm_telnet.h b/src/terminal/internal/fqterm_telnet.h
new file mode 100644
index 0000000..33e8c6e
--- /dev/null
+++ b/src/terminal/internal/fqterm_telnet.h
@@ -0,0 +1,195 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_TELNET_H
+#define FQTERM_TELNET_H
+
+#include <QAbstractSocket>
+#include <QByteArray>
+
+namespace FQTerm {
+
+#ifndef u_char
+#define u_char uchar
+#endif
+
+#define NTSTATES 6 // # of Telnet Socket-Input FSM States
+#define NSSTATES 3 // # of Telnet Option Subnegotiation FSM States
+#define NCHRS 256 // # of valid characters
+
+// decleration
+class FQTermTelnet;
+// actionFunc is a pointer, point to a FQTermTelnet's func
+typedef int(FQTermTelnet:: *ptrActionFunc)(int c);
+
+//fsm struct
+struct fsm_trans {
+ u_char ft_state; // current state
+ short ft_char; // input character
+ u_char ft_next; // next state
+ ptrActionFunc ft_action; // action to take
+};
+
+
+/*------------------------------------------------------------------------------
+ * FQTermTelnet class definition
+ *-------------------------------------------------------------------------------
+ */
+class FQTermSocket;
+
+// Telnet connection, a wrapper of socket.
+// It will translate raw NVT data from low level socket to ansi data,
+// and then upper level application can read it.
+// It also can send ascii data (0~127).
+class FQTermTelnet: public QObject {
+ Q_OBJECT;
+ public:
+ FQTermTelnet(const QString &termtype, int rows, int numColumns, int protocolType, int hostType, const
+ char *sshuser = NULL, const char *sshpasswd = NULL);
+ ~FQTermTelnet();
+
+ void setProxy(int nProxyType, //0-no proxy; 1-wingate; 2-sock4; 3-socks5
+ bool bAuth, // if authentation needed
+ const QString &strProxyHost, quint16 uProxyPort, const QString &strProxyUsr,
+ const QString &strProxyPwd);
+ void connectHost(const QString &hostname, quint16 portnumber);
+
+ // Read ansi data.
+ int read(char *data, uint maxlen);
+
+ // Write data raw data
+ int write(const char *data, uint len);
+
+ void close(); // User close the connection
+
+ int raw_len();
+ int read_raw(char *data, uint maxlen);
+
+ bool readyForInput();
+
+
+ signals:
+ void readyRead(int, int); // There are datas to be read out
+ void TelnetState(int); // The state telnet, defined as TSXXXX in fqterm.h
+ void requestUserPwd(QString *user, QString *pwd, bool *isOK);
+ void errorMessage(QString);
+
+ public slots:
+ void windowSizeChanged(int, int);
+
+ private slots:
+ // Retrieve data from socket, translate NVT data to ansi data,
+ // then notify data ready.
+ void socketReadyRead();
+
+ void connected();
+ void showError(QAbstractSocket::SocketError);
+ void hostFound();
+ void delayCloseFinished();
+ void closed();
+ protected:
+ //init structure fsm
+ void init_telnet();
+ void fsmbuild();
+ void fsminit(u_char fsm[][NCHRS], struct fsm_trans ttab[], int nstates);
+
+ //actions
+ int tcdm(int);
+ int recopt(int);
+ int no_op(int);
+ int do_echo(int);
+ int do_notsup(int);
+ int do_noga(int);
+ int do_txbinary(int);
+ int will_notsup(int);
+ int will_txbinary(int);
+ int will_termtype(int);
+ int will_naws(int);
+ int subopt(int);
+ int subtermtype(int);
+ int subend(int);
+ int soputc(int);
+ int ttputc(int);
+ int tnabort(int);
+
+ //utility functions
+ int xputc_up(char);
+ int xputs_up(char*);
+ void putc_down(u_char);
+
+signals:
+
+ void onSSHAuthOK();
+
+ private:
+ // Boolean Flags
+ char synching, doecho, sndbinary, rcvbinary;
+ char noga;
+ char naws;
+ char server_sent_do_naws;
+ u_char option_cmd; // has value WILL, WONT, DO, or DONT
+
+ char termtype; // non-zero if received "DO TERMTYPE"
+ char *term; // terminal name
+
+ /* // TODO: BBS don't need control signals
+ // Special keys - Terminal control characters
+ // need work...
+ static const char t_flushc=FQTERM_CTRL('S'); // Abort Output i.e:(^S)
+ static const char t_intrc=FQTERM_CTRL('C'); // Interrupt i.e:(^C)
+ static const char t_quitc=FQTERM_CTRL('\\'); // Quit i.e:(^\)
+ static const char sg_erase=FQTERM_CTRL('?'); // Erase a character i.e:(^?)
+ static const char sg_kill=FQTERM_CTRL('U'); // Kill a line i.e:(^U)
+ */
+
+ // FSM stuffs
+ static struct fsm_trans ttstab[];
+ int ttstate;
+ u_char ttfsm[NTSTATES][NCHRS];
+
+ static struct fsm_trans substab[];
+ int substate;
+ u_char subfsm[NSSTATES][NCHRS];
+
+ // socket stuffs
+ FQTermSocket *socket;
+
+ //Pointers to internal buffers
+ //
+ // |-->from_socket-->process-->to_ansi-->|
+ // socket<---> <---> ansi decode
+ // |<---to_socket<--process<--from_ansi--|
+ //
+ QByteArray from_socket, to_ansi, from_ansi, to_socket;
+ uint rsize; // size of to_ansi buffer
+ uint wsize; // size of to_socket buffer
+
+ // for test
+ int wx, wy;
+ int done_naws;
+ bool bConnected;
+ int raw_size;
+ int hostType_;
+ int protocolType_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_TELNET_H
diff --git a/src/terminal/internal/fqterm_zmodem.cpp b/src/terminal/internal/fqterm_zmodem.cpp
new file mode 100644
index 0000000..afb99c9
--- /dev/null
+++ b/src/terminal/internal/fqterm_zmodem.cpp
@@ -0,0 +1,3056 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QApplication>
+#include <QString>
+#include <QFileDialog>
+#include <QFileInfo>
+
+#include "fqterm.h"
+#include "fqterm_config.h"
+#include "fqterm_param.h"
+#include "fqterm_path.h"
+#include "fqterm_telnet.h"
+#include "fqterm_zmodem.h"
+#include "fqterm_filedialog.h"
+
+#ifdef FQTERM_ZMODEM_DEBUG
+#include <sys/time.h>
+#endif
+
+namespace FQTerm {
+
+static const uchar zeros[4] = {
+ 0, 0, 0, 0
+};
+
+static const char hexChars[] = "0123456789abcdef";
+
+static const uchar AckStr[1] = {
+ ACK
+};
+static const uchar NakStr[1] = {
+ NAK
+};
+static const uchar CanStr[2] = {
+ CAN, CAN
+};
+static const uchar eotstr[1] = {
+ EOT
+};
+
+
+/*
+ * Crc calculation stuff
+ */
+
+/* crctab calculated by Mark G. Mendel, Network Systems Corporation */
+unsigned short crctab[256] = {
+ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129,
+ 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273,
+ 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a,
+ 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6,
+ 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf,
+ 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695,
+ 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
+ 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc,
+ 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4,
+ 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf,
+ 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5,
+ 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a,
+ 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32,
+ 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59,
+ 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
+ 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 0x83b9,
+ 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290,
+ 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8,
+ 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481,
+ 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f,
+ 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676,
+ 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a,
+ 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
+ 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75,
+ 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f,
+ 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64,
+ 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c,
+ 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93,
+ 0x3eb2, 0x0ed1, 0x1ef0
+};
+
+/*
+ * updcrc macro derived from article Copyright (C) 1986 Stephen Satchell.
+ * NOTE: First argument must be in range 0 to 255.
+ * Second argument is referenced twice.
+ *
+ * Programmers may incorporate any or all code into their programs,
+ * giving proper credit within the source. Publication of the
+ * source routines is permitted so long as proper credit is given
+ * to Stephen Satchell, Satchell Evaluations and Chuck Forsberg,
+ * Omen Technology.
+ */
+
+#define updcrc(cp, crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ cp)
+
+/*
+ * Copyright (C) 1986 Gary S. Brown. You may use this program, or
+ * code or tables extracted from it, as desired without restriction.
+ */
+
+/* First, the polynomial itself and its table of feedback terms. The */
+/* polynomial is */
+/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
+/* Note that we take it "backwards" and put the highest-order term in */
+/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */
+/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */
+/* the MSB being 1. */
+
+/* Note that the usual hardware shift register implementation, which */
+/* is what we're using (we're merely optimizing it by doing eight-bit */
+/* chunks at a time) shifts bits into the lowest-order term. In our */
+/* implementation, that means shifting towards the right. Why do we */
+/* do it this way? Because the calculated CRC must be transmitted in */
+/* order from highest-order term to lowest-order term. UARTs transmit */
+/* characters in order from LSB to MSB. By storing the CRC this way, */
+/* we hand it to the UART in the order low-byte to high-byte; the UART */
+/* sends each low-bit to hight-bit; and the result is transmission bit */
+/* by bit from highest- to lowest-order term without requiring any bit */
+/* shuffling on our part. Reception works similarly. */
+
+/* The feedback terms table consists of 256, 32-bit entries. Notes: */
+/* */
+/* The table can be generated at runtime if desired; code to do so */
+/* is shown later. It might not be obvious, but the feedback */
+/* terms simply represent the results of eight shift/xor opera- */
+/* tions for all combinations of data and CRC register values. */
+/* */
+/* The values must be right-shifted by eight bits by the "updcrc" */
+/* logic; the shift must be unsigned (bring in zeroes). On some */
+/* hardware you could probably optimize the shift in assembler by */
+/* using byte-swap instructions. */
+
+unsigned long cr3tab[] = {
+ /* CRC polynomial 0xedb88320 */
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
+ 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
+ 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
+ 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
+ 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
+ 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
+ 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
+ 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
+ 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
+ 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
+ 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
+ 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
+ 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
+ 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
+ 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
+ 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
+ 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
+ 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+ };
+
+#define UPDC32(b, c) (cr3tab[((int)c ^ b) & 0xff] ^ ((c >> 8) & 0x00FFFFFF))
+
+#define updcrc(cp, crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ cp)
+
+
+
+#if 1
+StateTable FQTermZmodem::RStartOps[] = {
+ {ZSINIT, &FQTermZmodem::GotSinit, 0, 1, RSinitWait},
+ /* SINIT, wait for attn str */
+ {ZFILE, &FQTermZmodem::GotFile, 0, 0, RFileName},
+ /* FILE, wait for filename */
+ {ZRQINIT, &FQTermZmodem::SendRinit, 0, 1, RStart},
+ /* sender confused, resend */
+ {ZFIN, &FQTermZmodem::GotFin, 1, 0, RFinish},
+ /* sender shutting down */
+ {ZNAK, &FQTermZmodem::SendRinit, 1, 0, RStart},
+ /* RINIT was bad, resend */
+ {ZFREECNT, &FQTermZmodem::GotFreecnt, 0, 0, RStart},
+ /* sender wants free space */
+ {ZCOMMAND, &FQTermZmodem::GotCommand, 0, 0, CommandData},
+ /* sender wants command */
+ {ZSTDERR, &FQTermZmodem::GotStderr, 0, 0, StderrData},
+ /* sender wants to send msg */
+ {ZRINIT, &FQTermZmodem::ZmodemTInit, 1, 1, TStart},
+ {99, &FQTermZmodem::ZPF, 0, 0, RStart}
+ /* anything else is an error */
+};
+
+StateTable FQTermZmodem::RSinitWaitOps[] = {
+ /* waiting for data */
+ {
+ 99, &FQTermZmodem::ZPF, 0, 0, RSinitWait
+ },
+};
+
+StateTable FQTermZmodem::RFileNameOps[] = {
+ /* waiting for file name */
+ {
+ 99, &FQTermZmodem::ZPF, 0, 0, RFileName
+ },
+};
+
+StateTable FQTermZmodem::RCrcOps[] = {
+ /* waiting for CRC */
+ {
+ ZCRC, &FQTermZmodem::GotFileCrc, 0, 0, RFile
+ }, { /* sender sent it */
+ ZNAK, &FQTermZmodem::ResendCrcReq, 0, 0, RCrc
+ }, { /* ZCRC was bad, resend */
+ ZRQINIT, &FQTermZmodem::SendRinit, 1, 1, RStart
+ }, { /* sender confused, restart */
+ ZFIN, &FQTermZmodem::GotFin, 1, 1, RFinish
+ }, { /* sender signing off */
+ 99, &FQTermZmodem::ZPF, 0, 0, RCrc
+ },
+};
+
+
+StateTable FQTermZmodem::RFileOps[] = {
+ /* waiting for ZDATA */
+ {
+ ZDATA, &FQTermZmodem::GotData, 0, 0, RData
+ }, { /* got it */
+ ZNAK, &FQTermZmodem::ResendRpos, 0, 0, RFile
+ }, { /* ZRPOS was bad, resend */
+ ZEOF, &FQTermZmodem::GotEof, 0, 0, RStart
+ }, { /* end of file */
+ ZRQINIT, &FQTermZmodem::SendRinit, 1, 1, RStart
+ }, { /* sender confused, restart */
+ ZFILE, &FQTermZmodem::ResendRpos, 0, 0, RFile
+ }, { /* ZRPOS was bad, resend */
+ ZFIN, &FQTermZmodem::GotFin, 1, 1, RFinish
+ }, { /* sender signing off */
+ 99, &FQTermZmodem::ZPF, 0, 0, RFile
+ },
+};
+
+/* waiting for data, but a packet could possibly arrive due
+ * to error recovery or something
+ */
+StateTable FQTermZmodem::RDataOps[] = {
+ {
+ ZRQINIT, &FQTermZmodem::SendRinit, 1, 1, RStart
+ }, { /* sender confused, restart */
+ ZFILE, &FQTermZmodem::GotFile, 0, 1, RFileName
+ }, { /* start a new file (??) */
+ ZNAK, &FQTermZmodem::ResendRpos, 1, 1, RFile
+ }, { /* ZRPOS was bad, resend */
+ ZFIN, &FQTermZmodem::GotFin, 1, 1, RFinish
+ }, { /* sender signing off */
+ ZDATA, &FQTermZmodem::GotData, 0, 1, RData
+ }, { /* file data follows */
+ ZEOF, &FQTermZmodem::GotEof, 1, 1, RStart
+ }, { /* end of file */
+ 99, &FQTermZmodem::ZPF, 0, 0, RData
+ },
+};
+
+/* here if we've sent ZFERR or ZABORT. Waiting for ZFIN */
+
+StateTable FQTermZmodem::RFinishOps[] = {
+
+ {
+ ZRQINIT, &FQTermZmodem::SendRinit, 1, 1, RStart
+ } , { /* sender confused, restart */
+ ZFILE, &FQTermZmodem::GotFile, 1, 1, RFileName
+ }, { /* start a new file */
+ ZNAK, &FQTermZmodem::GotFin, 1, 1, RFinish
+ }, { /* resend ZFIN */
+ ZFIN, &FQTermZmodem::GotFin, 1, 1, RFinish
+ }, { /* sender signing off */
+ 99, &FQTermZmodem::ZPF, 0, 0, RFinish
+ },
+};
+
+
+/* sent ZRQINIT, waiting for response */
+StateTable FQTermZmodem::TStartOps[] = {
+ {
+ ZRINIT, &FQTermZmodem::GotRinit, 1, 1, TStart
+ }, {
+ ZCHALLENGE, &FQTermZmodem::AnswerChallenge, 1, 0, TStart
+ }, {
+ ZABORT, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ ZFERR, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ ZNAK, &FQTermZmodem::Ignore, 0, 0, TStart
+ }, {
+ ZCOMMAND, &FQTermZmodem::GotCommand, 0, 0, CommandData
+ }, {
+ ZSTDERR, &FQTermZmodem::GotStderr, 0, 0, StderrData
+ }, {
+ 99, &FQTermZmodem::ZPF, 0, 0, TStart
+ },
+};
+
+/* sent ZSINIT, waiting for response */
+StateTable FQTermZmodem::TInitOps[] = {
+ {
+ ZACK, &FQTermZmodem::RetDone, 1, 0, TInit
+ }, {
+ ZNAK, &FQTermZmodem::SendZSInit, 1, 0, TInit
+ }, {
+ ZRINIT, &FQTermZmodem::GotRinit, 1, 1, TInit
+ }, { /* redundant, but who cares */
+ ZCHALLENGE, &FQTermZmodem::AnswerChallenge, 1, 0, TInit
+ }, {
+ ZABORT, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ ZFERR, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ ZCOMMAND, &FQTermZmodem::GotCommand, 0, 0, CommandData
+ }, {
+ ZSTDERR, &FQTermZmodem::GotStderr, 0, 0, StderrData
+ }, {
+ 99, &FQTermZmodem::ZPF, 0, 0, TInit
+ },
+};
+
+/* sent ZFILE, waiting for response */
+StateTable FQTermZmodem::FileWaitOps[] = {
+ {
+ ZRPOS, &FQTermZmodem::SendFileData, 1, 1, Sending
+ }, {
+ ZSKIP, &FQTermZmodem::SkipFile, 1, 0, TStart
+ }, {
+ ZCRC, &FQTermZmodem::SendFileCrc, 1, 0, FileWait
+ }, {
+ ZNAK, &FQTermZmodem::sendFilename, 1, 0, FileWait
+ }, {
+ ZRINIT, &FQTermZmodem::sendFilename, 1, 1, FileWait
+ }, { /* rcvr confused, retry file */
+ ZABORT, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ ZFERR, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ ZCHALLENGE, &FQTermZmodem::AnswerChallenge, 1, 0, FileWait
+ }, {
+ ZCOMMAND, &FQTermZmodem::GotCommand, 0, 0, CommandData
+ }, {
+ ZSTDERR, &FQTermZmodem::GotStderr, 0, 0, StderrData
+ }, {
+ ZACK, &FQTermZmodem::SendFileData, 1, 0, Sending
+ }, { // receiver always sends ZACK back
+ 99, &FQTermZmodem::ZPF, 0, 0, FileWait
+ },
+};
+
+/* sent file CRC, waiting for response */
+StateTable FQTermZmodem::CrcWaitOps[] = {
+ {
+ ZRPOS, &FQTermZmodem::SendFileData, 1, 0, Sending
+ }, {
+ ZSKIP, &FQTermZmodem::SkipFile, 1, 0, FileWait
+ }, {
+ ZNAK, &FQTermZmodem::SendFileCrc, 1, 0, CrcWait
+ }, {
+ ZRINIT, &FQTermZmodem::sendFilename, 1, 1, FileWait
+ }, { /* rcvr confused, retry file */
+ ZABORT, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ ZFERR, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ ZCRC, &FQTermZmodem::SendFileCrc, 0, 0, CrcWait
+ }, {
+ ZCHALLENGE, &FQTermZmodem::AnswerChallenge, 0, 0, CrcWait
+ }, {
+ ZCOMMAND, &FQTermZmodem::GotCommand, 0, 0, CommandData
+ }, {
+ ZSTDERR, &FQTermZmodem::GotStderr, 0, 0, StderrData
+ }, {
+ 99, &FQTermZmodem::ZPF, 0, 0, CrcWait
+ },
+};
+
+/* sending data, interruptable */
+StateTable FQTermZmodem::SendingOps[] = {
+ {
+ ZACK, &FQTermZmodem::GotSendAck, 0, 0, Sending
+ }, {
+ ZRPOS, &FQTermZmodem::GotSendPos, 1, 1, Sending
+ }, {
+ ZSKIP, &FQTermZmodem::SkipFile, 1, 1, FileWait
+ }, {
+ ZNAK, &FQTermZmodem::GotSendNak, 1, 1, Sending
+ }, {
+ ZRINIT, &FQTermZmodem::sendFilename, 1, 1, FileWait
+ },{ /* rcvr confused, retry file */
+ ZABORT, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ ZFERR, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ 99, &FQTermZmodem::ZPF, 0, 0, SendWait
+ },
+};
+
+/* sent data, need to send EOF */
+StateTable FQTermZmodem::SendDoneOps[] = {
+ {
+ ZACK, &FQTermZmodem::GotSendDoneAck, 0, 0, SendWait
+ }, {
+ ZRPOS, &FQTermZmodem::GotSendPos, 1, 1, Sending
+ }, {
+ ZSKIP, &FQTermZmodem::SkipFile, 1, 1, FileWait
+ }, {
+ ZNAK, &FQTermZmodem::GotSendNak, 1, 1, Sending
+ }, {
+ ZRINIT, &FQTermZmodem::sendFilename, 1, 1, FileWait
+ }, { /* rcvr confused, retry file */
+ ZABORT, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ ZFERR, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ 99, &FQTermZmodem::ZPF, 0, 0, SendWait
+ },
+};
+
+/* sending data, waiting for ACK */
+StateTable FQTermZmodem::SendWaitOps[] = {
+ {
+ ZACK, &FQTermZmodem::GotSendWaitAck, 0, 0, Sending
+ }, {
+ ZRPOS, &FQTermZmodem::GotSendPos, 0, 0, SendWait
+ }, {
+ ZSKIP, &FQTermZmodem::SkipFile, 1, 1, FileWait
+ }, {
+ ZNAK, &FQTermZmodem::GotSendNak, 0, 0, Sending
+ }, {
+ ZRINIT, &FQTermZmodem::sendFilename, 1, 1, FileWait
+ }, { /* rcvr confused, retry file */
+ ZABORT, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ ZFERR, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ 99, &FQTermZmodem::ZPF, 0, 0, SendWait
+ },
+};
+
+/* sent ZEOF, waiting for new RINIT */
+StateTable FQTermZmodem::SendEofOps[] = {
+ {
+ ZRINIT, &FQTermZmodem::SkipFile, 1, 0, TFinish
+ }, { /* successful completion */
+ ZACK, &FQTermZmodem::Ignore, 0, 0, SendEof
+ }, { /* probably ACK from last packet */
+ ZRPOS, &FQTermZmodem::GotSendPos, 1, 1, SendWait
+ }, {
+ ZSKIP, &FQTermZmodem::SkipFile, 1, 1, TStart
+ }, {
+ ZNAK, &FQTermZmodem::ResendEof, 1, 0, SendEof
+ }, {
+ ZRINIT, &FQTermZmodem::sendFilename, 1, 1, FileWait
+ }, { /* rcvr confused, retry file */
+ ZABORT, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ ZFERR, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ 99, &FQTermZmodem::ZPF, 0, 0, SendEof
+ },
+};
+
+StateTable FQTermZmodem::TFinishOps[] = {
+ {
+ ZFIN, &FQTermZmodem::OverAndOut, 1, 1, Done
+ }, {
+ ZNAK, &FQTermZmodem::ZmodemTFinish, 1, 1, TFinish
+ }, {
+ ZRINIT, &FQTermZmodem::ZmodemTFinish, 1, 1, TFinish
+ }, {
+ ZABORT, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ ZFERR, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ 99, &FQTermZmodem::ZPF, 0, 0, TFinish
+ },
+};
+
+StateTable FQTermZmodem::CommandDataOps[] = {
+ {
+ 99, &FQTermZmodem::ZPF, 0, 0, CommandData
+ },
+};
+
+StateTable FQTermZmodem::CommandWaitOps[] = {
+ {
+ 99, &FQTermZmodem::ZPF, 0, 0, CommandWait
+ },
+};
+
+StateTable FQTermZmodem::StderrDataOps[] = {
+ {
+ 99, &FQTermZmodem::ZPF, 0, 0, StderrData
+ },
+};
+
+StateTable FQTermZmodem::DoneOps[] = {
+ {
+ 99, &FQTermZmodem::ZPF, 0, 0, Done
+ },
+};
+
+StateTable *FQTermZmodem::tables[] = {
+ FQTermZmodem::RStartOps, FQTermZmodem::RSinitWaitOps, FQTermZmodem::RFileNameOps,
+ FQTermZmodem::RCrcOps, FQTermZmodem::RFileOps, FQTermZmodem::RDataOps,
+ FQTermZmodem::RDataOps, /* RDataErr is the same as RData */
+ FQTermZmodem::RFinishOps,
+
+ FQTermZmodem::TStartOps, FQTermZmodem::TInitOps, FQTermZmodem::FileWaitOps,
+ FQTermZmodem::CrcWaitOps, FQTermZmodem::SendingOps, FQTermZmodem::SendWaitOps,
+ FQTermZmodem::SendDoneOps, FQTermZmodem::SendEofOps, FQTermZmodem::TFinishOps,
+
+ FQTermZmodem::CommandDataOps, FQTermZmodem::CommandWaitOps,
+ FQTermZmodem::StderrDataOps, FQTermZmodem::DoneOps,
+};
+
+const char *FQTermZmodem::hdrnames[] = {
+ "ZRQINIT", "ZRINIT", "ZSINIT", "ZACK", "ZFILE", "ZSKIP", "ZNAK", "ZABORT",
+ "ZFIN", "ZRPOS", "ZDATA", "ZEOF", "ZFERR", "ZCRC", "ZCHALLENGE", "ZCOMPL",
+ "ZCAN", "ZFREECNT", "ZCOMMAND", "ZSTDERR",
+};
+
+#endif
+
+FQTermZmodem::FQTermZmodem(FQTermConfig *config, FQTermTelnet *netinterface, int type, int serverEncoding) {
+
+ //now set network interface Telnet
+
+ connectionType = type;
+
+ serverEncodingID = serverEncoding;
+
+ switch (connectionType) {
+ case 0:
+ case 1:
+ case 2:
+ telnet_ = netinterface;
+ break;
+ default:
+ FQ_TRACE("zmodem", 0) << "connection type unknown! Expect segmentation fault!";
+ telnet_ = netinterface;
+ break;
+ }
+
+ config_ = config;
+
+ sending = false;
+
+ transferstate = notransfer;
+
+ zmodemTimer = new QTimer(this);
+ FQ_VERIFY(connect(zmodemTimer, SIGNAL(timeout()), this, SLOT(ZmodemTimeout())));
+
+#ifdef FQTERM_ZMODEM_DEBUG
+ zmodemlogfile = fopen("zmodem.log", "w+");
+ fprintf(zmodemlogfile, "%s", "\n================================\n");
+ fclose(zmodemlogfile);
+#endif
+
+
+ //init struct INFO
+ info.zrinitflags = CANFDX | CANOVIO | CANBRK | CANFC32;
+ info.zsinitflags = 0;
+ info.attn = NULL;
+ info.bufsize = 0; /* full streaming */
+ info.buffer = NULL;
+
+ zerrno = 0;
+ lastPullByte = 0;
+
+ ZmodemReset(&info);
+ // other init function not complete
+
+}
+
+FQTermZmodem::~FQTermZmodem(){}
+
+int FQTermZmodem::ZmodemTInit(ZModem *info) {
+ int err;
+ int i;
+
+ info->state = TStart;
+ info->Protocol = ZMODEM;
+ info->crc32 = 0;
+ info->packetCount = 0;
+ info->errCount = 0;
+ info->escCtrl = info->escHibit = info->atSign = info->escape = 0;
+ info->InputState = Idle;
+ info->canCount = info->chrCount = 0;
+ info->windowCount = 0;
+ info->filename = NULL;
+ info->bufsize = 0;
+ info->interrupt = 0;
+ info->waitflag = 0;
+
+ // if( info->packetsize <= 0 )
+ info->packetsize = 8096;
+ info->windowsize = 0;
+ //we won't be receiving much data, pick a reasonable buffer
+ // size (largest packet will do)
+ //
+
+ i = info->packetsize *2;
+
+ if (info->buffer != NULL) {
+ free(info->buffer);
+ info->buffer = NULL;
+ }
+ //since in the constructor function buffer is malloc
+
+ if (i < 1024) {
+ i = 1024;
+ }
+ info->buffer = (uchar*)malloc(i);
+
+ ZIFlush(info);
+
+// FQTermConfig *config = new FQTermConfig(getPath(USER_CONFIG) + "fqterm.cfg");
+// QString strPrevSave = config->getItemValue("global", "previous");
+
+// if (strPrevSave.isEmpty()) {
+// strFileList = QFileDialog::getOpenFileNames(0, "Choose the files",
+// getPath(USER_CONFIG), "All files(*)");
+// } else {
+// strFileList = QFileDialog::getOpenFileNames(0, "Choose the files",
+// strPrevSave, "All files(*)");
+// }
+ FQTermFileDialog fileDialog(config_);
+ strFileList = fileDialog.getOpenNames("Choose a file to upload", "");
+ if (strFileList.count() != 0) {
+ QStringList::Iterator itFile = strFileList.begin();
+ QFileInfo fi(*itFile);
+ }
+
+ this->transferstate = transferstop;
+
+ // optional: send "rz\r" to remote end
+ if (DoInitRZ) {
+ if ((err = ZXmitStr((uchar*)"rz\r", 3, info))) {
+ return err;
+ }
+ }
+
+ if ((err = ZXmitHdr(ZRQINIT, ZHEX, zeros, info))) {
+ // nudge receiver
+ return err;
+ }
+
+ info->timeout = 60;
+
+ zmodemlog("ZmodemTInit[%s]: sent ZRQINIT\n", sname(info));
+
+ return 0;
+}
+
+
+int FQTermZmodem::ZmodemTFile(char *file, char *rfile, uint f0, uint f1, uint f2,
+ uint f3, int filesRem, int bytesRem, ZModem *info) {
+ if (file == NULL || (info->file = fopen(file, "rb")) == NULL) {
+ return ZmErrCantOpen;
+ }
+
+ info->fileEof = 0;
+ info->filename = file;
+ if (rfile != NULL) {
+ info->rfilename = rfile;
+ } else {
+ info->rfilename = strdup("noname");
+ }
+ info->filesRem = filesRem;
+ info->bytesRem = bytesRem;
+ info->fileFlags[3] = f0;
+ info->fileFlags[2] = f1;
+ info->fileFlags[1] = f2;
+ info->fileFlags[0] = f3;
+ info->offset = info->lastOffset = 0;
+ info->len = info->date = info->fileType = info->mode = 0;
+ if (info->filename != NULL) {
+ struct stat buf;
+ if (stat(info->filename, &buf) == 0) {
+ info->len = buf.st_size;
+ info->date = buf.st_mtime;
+ info->fileType = 0;
+ info->mode = (buf.st_mode &0777) | 0100000;
+ }
+ }
+
+ if (info->Protocol == XMODEM) {
+ return YSendData(info);
+ }
+
+ if (info->Protocol == YMODEM) {
+ return YSendFilename(info);
+ }
+
+ info->state = FileWait;
+ ZStatus(FileBegin, info->bytesRem, info->rfilename);
+ zmodemlog("ZmodemTFile[%s]: send ZFILE(%s)\n", sname(info), info->rfilename);
+ return sendFilename(info);
+}
+
+
+int FQTermZmodem::ZmodemTFinish(ZModem *info) {
+ int i;
+ if (info->Protocol == XMODEM) {
+ return ZmDone;
+ }
+
+ if (info->Protocol == YMODEM) {
+ return YSendFin(info);
+ }
+
+ info->state = TFinish;
+ if (info->buffer != NULL) {
+ free(info->buffer);
+ info->buffer = NULL;
+ }
+ zmodemlog("ZmodemTFinish[%s]: send ZFIN\n", sname(info));
+ i = ZXmitHdr(ZFIN, ZHEX, zeros, info);
+
+ return i;
+}
+
+
+
+int FQTermZmodem::ZmodemAbort(ZModem *info) {
+ uchar canistr[] = {
+ CAN, CAN, CAN, CAN, CAN, CAN, CAN, CAN, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0
+ };
+ info->state = Done;
+ ZIFlush(info);
+ ZOFlush(info);
+
+ transferstate = transferstop; // transfer complete
+ ZmodemReset(info); //Tranfer complete, zmodem return to receive state
+
+ zmodemlog("ZmodemAbort[%s]: send CAN\n", sname(info));
+ return ZXmitStr(canistr, sizeof(canistr), info);
+}
+
+
+int FQTermZmodem::ZmodemRInit(ZModem *info) {
+ info->packetCount = 0;
+ info->offset = 0;
+ info->errCount = 0;
+ info->escCtrl = info->escHibit = info->atSign = info->escape = 0;
+ info->InputState = Idle;
+ info->canCount = info->chrCount = 0;
+ info->filename = NULL;
+ info->interrupt = 0;
+ info->waitflag = 0;
+ info->attn = NULL;
+ info->file = NULL;
+
+ if (info->buffer != NULL) {
+ free(info->buffer);
+ info->buffer = NULL;
+ }
+
+ info->buffer = (uchar*)malloc(1024);
+
+ info->state = RStart;
+ info->timeoutCount = 0;
+
+ ZIFlush(info);
+
+ /* Don't send ZRINIT right away, there might be a ZRQINIT in
+ * the input buffer. Instead, set timeout to zero and return.
+ * This will allow ZmodemRcv() to check the input stream first.
+ * If nothing found, a ZRINIT will be sent immediately.
+ */
+ info->timeout = 0;
+
+ zmodemlog("ZmodemRInit[%s]: flush input, new state = RStart\n", sname(info));
+
+ return 0;
+}
+
+int FQTermZmodem::ZmodemRcv(uchar *str, int len, ZModem *info,
+ int &consumed_bytes) {
+ register uchar c;
+ int err;
+
+ zmodemlog("zmodemRcv called");
+
+ info->rcvlen = len;
+
+ while (--info->rcvlen >= 0) {
+ c = *str++;
+
+ if (c == CAN) {
+ if (++info->canCount >= 5) {
+ ZStatus(RmtCancel, 0, NULL);
+ consumed_bytes = len - info->rcvlen - 1;
+ return ZmErrCancel;
+ }
+ } else {
+ info->canCount = 0;
+ }
+
+ if (info->InputState == Ysend) {
+ if ((err = YsendChar(c, info))) {
+ consumed_bytes = len - info->rcvlen - 1;
+ return err;
+ }
+ } else if (info->InputState == Yrcv) {
+ if ((err = YrcvChar(c, info))) {
+ consumed_bytes = len - info->rcvlen - 1;
+ return err;
+ }
+ } else if (c != XON && c != XOFF) {
+ /* now look at what we have */
+ switch (info->InputState) {
+ case Idle:
+ if ((err = IdleChar(c, info))) {
+ consumed_bytes = len - info->rcvlen - 1;
+ return err;
+ }
+ break;
+ case Inhdr:
+ if ((err = HdrChar(c, info))) {
+ consumed_bytes = len - info->rcvlen - 1;
+ return err;
+ }
+ break;
+ case Indata:
+ if ((err = DataChar(c, info))) {
+ consumed_bytes = len - info->rcvlen - 1;
+ return err;
+ }
+ break;
+ case Finish:
+ if ((err = FinishChar(c, info))) {
+ consumed_bytes = len - info->rcvlen - 1;
+ return err;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ consumed_bytes = len - info->rcvlen - 1;
+ return 0;
+}
+
+
+
+
+int FQTermZmodem::ZmodemTimeout( /*ZModem *info*/) {
+ /* timed out while waiting for input */
+
+ ++info.timeoutCount;
+
+ zmodemlog("timeout %d [%s]\n", info.timeoutCount, sname(&info));
+
+ switch (info.state) {
+ /* receive */
+ case RStart:
+ /* waiting for INIT frame from other end */
+ if (info.timeoutCount > 4) {
+ return YmodemRInit(&info);
+ }
+
+ case RSinitWait:
+ case RFileName:
+ if (info.timeout > 0) {
+ ZStatus(SndTimeout, info.timeoutCount, NULL);
+ }
+ if (info.timeoutCount > 4) {
+ return ZmErrRcvTo;
+ }
+ info.state = RStart;
+ return SendRinit(&info);
+
+ case RCrc:
+ case RFile:
+ case RData:
+ ZStatus(SndTimeout, info.timeoutCount, NULL);
+ if (info.timeoutCount > 2) {
+ info.timeoutCount = 0;
+ info.state = RStart;
+ return SendRinit(&info);
+ }
+ return info.state == RCrc ? ResendCrcReq(&info): ResendRpos(&info);
+
+ case RFinish:
+ ZStatus(SndTimeout, info.timeoutCount, NULL);
+ return ZmDone;
+
+ case YRStart:
+ case YRDataWait:
+ case YRData:
+ case YREOF:
+ return YrcvTimeout(&info);
+
+ /* transmit */
+ case TStart:
+ /* waiting for INIT frame from other end */
+ case TInit:
+ /* sent INIT, waiting for ZACK */
+ case FileWait:
+ /* sent file header, waiting for ZRPOS */
+ case CrcWait:
+ /* sent file crc, waiting for ZRPOS */
+ case SendWait:
+ /* waiting for ZACK */
+ case SendEof:
+ /* sent EOF, waiting for ZACK */
+ case TFinish:
+ /* sent ZFIN, waiting for ZFIN */
+ case YTStart:
+ case YTFile:
+ case YTDataWait:
+ case YTData:
+ case YTEOF:
+ case YTFin:
+ ZStatus(RcvTimeout, 0, NULL);
+ return ZmErrRcvTo;
+
+ case Sending:
+ /* sending data subpackets, ready for int */
+ return SendMoreFileData(&info);
+
+ /* general */
+ case CommandData:
+ /* waiting for command data */
+ case StderrData:
+ /* waiting for stderr data */
+ return ZmErrSndTo;
+ case CommandWait:
+ /* waiting for command to execute */
+ return ZmErrCmdTo;
+ case Done:
+ return ZmDone;
+ default:
+ return 0;
+ }
+}
+
+
+
+int FQTermZmodem::ZmodemAttention(ZModem *info) {
+ /* attention received from remote end */
+ if (info->state == Sending) {
+ ZOFlush(info);
+ info->interrupt = 1;
+ }
+ return 0;
+}
+
+int FQTermZmodem::YmodemTInit(ZModem *info) {
+ info->state = YTStart;
+ info->Protocol = YMODEM;
+ info->errCount = 0;
+ info->InputState = Ysend;
+ info->canCount = info->chrCount = 0;
+ info->windowCount = 0;
+ info->filename = NULL;
+
+ if (info->packetsize != 1024) {
+ info->packetsize = 128;
+ }
+
+ info->buffer = (uchar*)malloc(1024);
+
+ ZIFlush(info);
+ ZFlowControl(0, info);
+
+ info->timeout = 60;
+
+ return 0;
+}
+
+
+int FQTermZmodem::XmodemTInit(ZModem *info) {
+ (void)YmodemTInit(info);
+ info->Protocol = XMODEM;
+ return 0;
+}
+
+
+int FQTermZmodem::YmodemRInit(ZModem *info) {
+ info->errCount = 0;
+ info->InputState = Yrcv;
+ info->canCount = info->chrCount = 0;
+ info->noiseCount = 0;
+ info->filename = NULL;
+ info->file = NULL;
+
+ if (info->buffer == NULL) {
+ info->buffer = (uchar*)malloc(1024);
+ }
+
+ info->state = YRStart;
+ info->packetCount = -1;
+ info->timeoutCount = 0;
+ info->timeout = 10;
+ info->offset = 0;
+
+ ZIFlush(info);
+
+ return ZXmitStr((uchar*)"C", 1, info);
+}
+
+
+int FQTermZmodem::XmodemRInit(ZModem *info) {
+#if 0
+ int err;
+
+ state = Start;
+ protocol = prot;
+ ymodem = prot == Ymodem || prot == YmodemG;
+
+ if (ymodem) {
+ strcpy(xmDefPath, file);
+ } else {
+ strcpy(xmFilename, file);
+ }
+
+ eotCount = errorCount = errorCount2 = 0;
+
+ if (err = XmodemRStart()) {
+ return err;
+ }
+
+ state = Init;
+ packetId = ymodem ? 255 : 0;
+ packetCount = 0;
+
+ pktHdrLen = protocol == Xmodem ? 3 : 4;
+#endif
+ return 0;
+}
+
+
+ulong FQTermZmodem::FileCrc(char *name) {
+ ulong crc;
+ FILE *ifile = fopen(name, "rb");
+ int i;
+
+ if (ifile == NULL)
+ /* shouldn't happen, since we did access(2) */ {
+ return 0;
+ }
+
+ crc = 0xffffffff;
+
+ while ((i = fgetc(ifile)) != EOF) {
+ crc = UPDC32(i, crc);
+ }
+
+ fclose(ifile);
+ return ~crc;
+}
+
+
+
+const char *FQTermZmodem::sname(ZModem *info) {
+ return sname2(info->state);
+}
+
+const char *FQTermZmodem::sname2(ZMState state) {
+ const char *names[] = {
+ "RStart", "RSinitWait", "RFileName", "RCrc", "RFile", "RData", "RDataErr",
+ "RFinish", "TStart", "TInit", "FileWait", "CrcWait", "Sending", "SendWait",
+ "SendDone", "SendEof", "TFinish", "CommandData", "CommandWait", "StderrData",
+ "Done", "YTStart", "YTFile", "YTDataWait", "YTData", "YTEOF", "YTFin",
+ "YRStart", "YRDataWait", "YRData", "YREOF"
+ };
+
+ return names[(int)state];
+
+}
+
+
+int FQTermZmodem::ZXmitChr(uchar c, ZModem *info) {
+ // to be completed
+ return 0;
+}
+
+int FQTermZmodem::ZXmitStr(const uchar *str, int len, ZModem *info) {
+ //to be completed
+ telnet_->write((const char*)str, (uint)len);
+ return 0;
+}
+
+void FQTermZmodem::ZIFlush(ZModem *info) {
+ //to be completed
+}
+
+void FQTermZmodem::ZOFlush(ZModem *info) {
+ //to be completed
+}
+
+int FQTermZmodem::ZAttn(ZModem *info) {
+ //to be completed
+ return 0;
+}
+
+void FQTermZmodem::ZStatus(int type, int value, const char *status) {
+ emit ZmodemState(type, value, status);
+ switch (type) {
+ case RcvByteCount:
+ FQ_TRACE("zmodem", 5) << value << " bytes received.";
+ break;
+ case SndByteCount:
+ FQ_TRACE("zmodem", 5) << value << " bytes sent.";
+ break;
+ case RcvTimeout:
+ /* receiver did not respond, aborting */
+ FQ_TRACE("zmodem", 0) << "Zmodem time out!";
+ break;
+ case SndTimeout:
+ /* value is # of consecutive send timeouts */
+ FQ_TRACE("zmodem", 0) << "Zmodem time out after trying "
+ << value << " times";
+ break;
+ case RmtCancel:
+ /* remote end has cancelled */
+ FQ_TRACE("zmodem", 1) << "Zmodem canceled by remote peer";
+ break;
+ case ProtocolErr:
+ /* protocol error has occurred, val=hdr */
+ FQ_TRACE("zmodem", 0) << "Unhandled header " << value
+ << " at state " << status;
+ break;
+ case RemoteMessage:
+ /* message from remote end */
+ FQ_TRACE("zmodem", 0) << "Message from remote peer: " << status;
+ break;
+ case DataErr:
+ /* data error, val=error count */
+ FQ_TRACE("zmodem", 0) << "Data errors " << value;
+ break;
+ case FileErr:
+ /* error writing file, val=errno */
+ FQ_TRACE("zmodem", 0) << "Falied to write file.";
+ break;
+ case FileBegin:
+ /* file transfer begins, str=name */
+ FQ_TRACE("zmodem", 0) << "Starting file: " << status;
+ break;
+ case FileEnd:
+ /* file transfer ends, str=name */
+ FQ_TRACE("zmodem", 0) << "Finishing file: " << status;
+ break;
+ case FileSkip:
+ /* file being skipped, str=name */
+ FQ_TRACE("zmodem", 0) << "Skipping file: " << status;
+ break;
+ }
+}
+
+FILE *FQTermZmodem::ZOpenFile(char *name, ulong crc, ZModem *info) {
+ //to be complete
+ FILE *rval;
+ int apnd = 0;
+ QString strText;
+ strText = encoding2unicode(name, serverEncodingID);
+ QString str = FQTermPref::getInstance()->zmodemDir_ + strText;
+
+ QString zpath = QFileInfo(FQTermPref::getInstance()->zmodemDir_).absoluteFilePath();
+ QString path = QFileInfo(str).absoluteFilePath();
+
+ lastDownloadedFilename_ = path;
+
+ if (path.startsWith(zpath)) {
+ // Ensure that file is only saved under zmodemDir_.
+ // TODO: lazy, should use bbs2unicode
+ rval = fopen(str.toLocal8Bit(), apnd ? "ab" : "wb");
+ } else {
+ rval = NULL;
+ }
+
+ if (rval == NULL) {
+ perror(name);
+ }
+
+ return rval;
+}
+
+int FQTermZmodem::ZXmitHdr(int type, int format, const uchar data[4], ZModem *info) {
+ if (format == ZBIN && info->crc32) {
+ format = ZBIN32;
+ }
+
+ switch (format) {
+ case ZHEX:
+ return ZXmitHdrHex(type, data, info);
+
+ case ZBIN:
+ return ZXmitHdrBin(type, data, info);
+
+ case ZBIN32:
+ return ZXmitHdrBin32(type, data, info);
+
+ default:
+ return 0;
+ }
+}
+
+
+int FQTermZmodem::ZXmitHdrHex(int type, const uchar data[4], ZModem *info) {
+ uchar buffer[128];
+ uchar *ptr = buffer;
+ uint crc;
+ int i;
+
+ zmodemlog("sending %s: %2.2x %2.2x %2.2x %2.2x = %lx\n", hdrnames[type],
+ data[0], data[1], data[2], data[3], ZDec4(data));
+
+ *ptr++ = ZPAD;
+ *ptr++ = ZPAD;
+ *ptr++ = ZDLE;
+ *ptr++ = ZHEX;
+
+ ptr = putHex(ptr, type);
+ crc = updcrc(type, 0);
+ for (i = 4; --i >= 0; ++data) {
+ ptr = putHex(ptr, *data);
+ crc = updcrc(*data, crc);
+ }
+ crc = updcrc(0, crc);
+ crc = updcrc(0, crc);
+ ptr = putHex(ptr, (crc >> 8) &0xff);
+ ptr = putHex(ptr, crc &0xff);
+ *ptr++ = '\r';
+ *ptr++ = '\n';
+ if (type != ZACK && type != ZFIN) {
+ *ptr++ = XON;
+ }
+
+ return ZXmitStr(buffer, ptr - buffer, info);
+}
+
+
+int FQTermZmodem::ZXmitHdrBin(int type, const uchar data[4], ZModem *info) {
+ uchar buffer[128];
+ uchar *ptr = buffer;
+ uint crc;
+ int len;
+
+ zmodemlog("sending %s: %2.2x %2.2x %2.2x %2.2x = %lx\n", hdrnames[type],
+ data[0], data[1], data[2], data[3], ZDec4(data));
+
+ *ptr++ = ZPAD;
+ *ptr++ = ZDLE;
+ *ptr++ = ZBIN;
+
+ ptr = putZdle(ptr, type, info);
+ crc = updcrc(type, 0);
+ for (len = 4; --len >= 0; ++data) {
+ ptr = putZdle(ptr, *data, info);
+ crc = updcrc(*data, crc);
+ }
+ crc = updcrc(0, crc);
+ crc = updcrc(0, crc);
+ ptr = putZdle(ptr, (crc >> 8) &0xff, info);
+ ptr = putZdle(ptr, crc &0xff, info);
+
+ len = ptr - buffer;
+ return ZXmitStr(buffer, len, info);
+}
+
+int FQTermZmodem::ZXmitHdrBin32(int type, const uchar data[4], ZModem *info) {
+ uchar buffer[128];
+ uchar *ptr = buffer;
+ ulong crc;
+ int len;
+
+ zmodemlog("sending %s: %2.2x %2.2x %2.2x %2.2x = %lx\n", hdrnames[type],
+ data[0], data[1], data[2], data[3], ZDec4(data));
+
+ *ptr++ = ZPAD;
+ *ptr++ = ZDLE;
+ *ptr++ = ZBIN32;
+ ptr = putZdle(ptr, type, info);
+ crc = UPDC32(type, 0xffffffffL);
+ for (len = 4; --len >= 0; ++data) {
+ ptr = putZdle(ptr, *data, info);
+ crc = UPDC32(*data, crc);
+ }
+ crc = ~crc;
+ for (len = 4; --len >= 0; crc >>= 8) {
+ ptr = putZdle(ptr, crc &0xff, info);
+ }
+
+ len = ptr - buffer;
+ return ZXmitStr(buffer, len, info);
+}
+
+
+uchar *FQTermZmodem::putZdle(uchar *ptr, uchar c, ZModem *info) {
+ uchar c2 = c &0177;
+
+ if (c == ZDLE || c2 == 020 || c2 == 021 || c2 == 023 || c2 == 0177 || (c2 ==
+ 015 && connectionType == 0 /*&& info->atSign*/) ||
+#ifdef COMMENT
+ c2 == 035 || (c2 == '~' && info->lastCR) ||
+#endif /* COMMENT */
+ c2 == 035 || (c2 < 040 && info->escCtrl)) {
+ *ptr++ = ZDLE;
+ if (c == 0177) {
+ *ptr = ZRUB0;
+ } else if (c == 0377) {
+ *ptr = ZRUB1;
+ } else {
+ *ptr = c ^ 0100;
+ }
+ } else {
+ *ptr = c;
+ }
+
+ info->atSign = c2 == '@';
+ info->lastCR = c2 == '\r';
+
+ return ++ptr;
+}
+
+
+uchar *FQTermZmodem::ZEnc4(ulong n) {
+ static uchar buf[4];
+ buf[0] = n &0xff;
+ n >>= 8;
+ buf[1] = n &0xff;
+ n >>= 8;
+ buf[2] = n &0xff;
+ n >>= 8;
+ buf[3] = n &0xff;
+ return buf;
+}
+
+ulong FQTermZmodem::ZDec4(const uchar buf[4]) {
+ return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
+}
+
+
+
+
+int FQTermZmodem::YrcvChar(char c, register ZModem *info) {
+ int err;
+
+ if (info->canCount >= 2) {
+ ZStatus(RmtCancel, 0, NULL);
+ return ZmErrCancel;
+ }
+
+ switch (info->state) {
+ case YREOF:
+ if (c == EOT) {
+ ZCloseFile(info);
+ info->file = NULL;
+ ZStatus(FileEnd, 0, info->filename);
+ if (info->filename != NULL) {
+ free(info->filename);
+ }
+ if ((err = acceptPacket(info)) != 0) {
+ return err;
+ }
+ info->packetCount = -1;
+ info->offset = 0;
+ info->state = YRStart;
+ return ZXmitStr((uchar*)"C", 1, info);
+ }
+ /* else, drop through */
+
+ case YRStart:
+ case YRDataWait:
+ switch (c) {
+ case SOH:
+ case STX:
+ info->pktLen = c == SOH ? (128+4): (1024+4);
+ info->state = YRData;
+ info->chrCount = 0;
+ info->timeout = 1;
+ info->noiseCount = 0;
+ info->crc = 0;
+ break;
+
+ case EOT:
+ /* ignore first EOT to protect against false eot */
+ info->state = YREOF;
+ return rejectPacket(info);
+
+ default:
+ if (++info->noiseCount > 135) {
+ return ZXmitStr(NakStr, 1, info);
+ }
+ break;
+ }
+ break;
+
+ case YRData:
+ info->buffer[info->chrCount++] = c;
+ if (info->chrCount >= info->pktLen) {
+ return ProcessPacket(info);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+int FQTermZmodem::YrcvTimeout(ZModem *info) {
+ switch (info->state) {
+ case YRStart:
+ if (info->timeoutCount >= 10) {
+ (void)ZXmitStr(CanStr, 2, info);
+ return ZmErrInitTo;
+ }
+ return ZXmitStr((uchar*)"C", 1, info);
+
+ case YRDataWait:
+ case YREOF:
+ case YRData:
+ if (info->timeoutCount >= 10) {
+ (void)ZXmitStr(CanStr, 2, info);
+ return ZmErrRcvTo;
+ }
+ return ZXmitStr(NakStr, 1, info);
+ default:
+ return 0;
+ }
+}
+
+
+void FQTermZmodem::ZIdleStr(uchar *buffer, int len, ZModem *info) {
+ //to be completed
+}
+
+
+int FQTermZmodem::FinishChar(char c, register ZModem *info) {
+ if (c == 'O') {
+ if (++info->chrCount >= 2) {
+ return ZmDone;
+ }
+ } else {
+ info->chrCount = 0;
+ }
+ return 0;
+}
+
+
+
+int FQTermZmodem::DataChar(uchar c, register ZModem *info) {
+ if (c == ZDLE) {
+ info->escape = 1;
+ return 0;
+ }
+
+ if (info->escape) {
+ info->escape = 0;
+ switch (c) {
+ case ZCRCE:
+ case ZCRCG:
+ case ZCRCQ:
+ case ZCRCW:
+ info->PacketType = c;
+ info->crcCount = (info->DataType == ZBIN32) ? 4 : 2;
+ if (info->DataType == ZBIN) {
+ info->crc = updcrc(c, info->crc);
+ } else {
+ info->crc = UPDC32(c, info->crc);
+ }
+ return 0;
+ case ZRUB0:
+ c = 0177;
+ break;
+ case ZRUB1:
+ c = 0377;
+ break;
+ default:
+ c ^= 0100;
+ break;
+ }
+ }
+ if (connectionType == 0) {
+ if (lastPullByte == 0x0d && c == 0x00) {
+ lastPullByte = 0;
+ return 0;
+ } else if (lastPullByte == 0xff && c == 0xff) {
+ lastPullByte = 0;
+ return 0;
+ }
+ }
+ lastPullByte = c;
+
+ switch (info->DataType) {
+ /* TODO: are hex data packets ever used? */
+ case ZBIN:
+ info->crc = updcrc(c, info->crc);
+ if (info->crcCount == 0) {
+ info->buffer[info->chrCount++] = c;
+ } else if (--info->crcCount == 0) {
+ return ZDataReceived(info, (info->crc &0xffff) == 0);
+ }
+ break;
+
+
+ case ZBIN32:
+ info->crc = UPDC32(c, info->crc);
+ if (info->crcCount == 0) {
+ info->buffer[info->chrCount++] = c;
+ } else if (--info->crcCount == 0) {
+ return ZDataReceived(info, info->crc == 0xdebb20e3);
+ }
+ break;
+ }
+ return 0;
+}
+
+
+int FQTermZmodem::HdrChar(uchar c, register ZModem *info) {
+ int i;
+ int crc = 0;
+
+ if (c == ZDLE) {
+ info->escape = 1;
+ return 0;
+ }
+
+ if (info->escape) {
+ info->escape = 0;
+ switch (c) {
+ case ZRUB0:
+ c = 0177;
+ break;
+ case ZRUB1:
+ c = 0377;
+ break;
+ default:
+ c ^= 0100;
+ break;
+ }
+ }
+
+ if (info->chrCount == 0) {
+ /* waiting for format */
+ switch (c) {
+ case ZHEX:
+ case ZBIN:
+ case ZBIN32:
+ info->DataType = c;
+ info->chrCount = 1;
+ info->crc = (info->DataType != ZBIN32) ? 0 : 0xffffffffL;
+ memset(info->hdrData, 0, sizeof(info->hdrData));
+ break;
+ default:
+ info->InputState = Idle;
+ info->chrCount = 0;
+ return ZXmitHdrHex(ZNAK, zeros, info);
+ }
+ return 0;
+ }
+
+
+ switch (info->DataType) {
+ /* hex header is 14 hex digits, cr, lf. Optional xon is ignored */
+ case ZHEX:
+ if (info->chrCount <= 14 && !isxdigit(c)) {
+ info->InputState = Idle;
+ info->chrCount = 0;
+ return ZXmitHdrHex(ZNAK, zeros, info);
+ }
+
+ if (info->chrCount <= 14) {
+ i = (info->chrCount - 1) / 2;
+ info->hdrData[i] = rcvHex(info->hdrData[i], c);
+ }
+
+ if (info->chrCount == 16) {
+ crc = 0;
+ for (i = 0; i < 7; ++i) {
+ crc = updcrc(info->hdrData[i], crc);
+ }
+ info->InputState = Idle;
+ info->chrCount = 0;
+ if ((crc &0xffff) != 0) {
+ return ZXmitHdrHex(ZNAK, zeros, info);
+ } else {
+ return ZProtocol(info);
+ }
+ }
+ else {
+ ++info->chrCount;
+ }
+ break;
+
+
+ case ZBIN:
+ /* binary header is type, 4 bytes data, 2 bytes CRC */
+ info->hdrData[info->chrCount - 1] = c;
+ info->crc = updcrc(c, info->crc);
+ if (++info->chrCount > 7) {
+ info->InputState = Idle;
+ info->chrCount = 0;
+ if ((crc &0xffff) != 0) {
+ return ZXmitHdrHex(ZNAK, zeros, info);
+ } else {
+ return ZProtocol(info);
+ }
+ }
+ break;
+
+
+ case ZBIN32:
+ /* binary32 header is type, 4 bytes data, 4 bytes CRC */
+ info->hdrData[info->chrCount - 1] = c;
+ info->crc = UPDC32(c, info->crc);
+ if (++info->chrCount > 9) {
+ info->InputState = Idle;
+ info->chrCount = 0;
+ if (info->crc != 0xdebb20e3)
+ /* see note below */ {
+ return ZXmitHdrHex(ZNAK, zeros, info);
+ } else {
+ return ZProtocol(info);
+ }
+ }
+ break;
+ }
+ return 0;
+}
+
+
+
+
+int FQTermZmodem::IdleChar(uchar c, register ZModem *info) {
+ if (info->chrCount == 0) {
+ if (c == ZPAD) {
+ ++info->chrCount;
+ } else if (info->state == Sending && ++info->noiseCount > MaxNoise) {
+ info->waitflag = 1;
+ } else if (info->state == TStart && (c == 'C' || c == 'G' || c == NAK)) {
+ /* switch to ymodem */
+ info->state = YTStart;
+ info->InputState = Ysend;
+ info->Protocol = YMODEM;
+ return YsendChar(c, info);
+ } else {
+ ZIdleStr(&c, 1, info);
+ }
+ }
+
+ else {
+ switch (c) {
+ case ZPAD:
+ ++info->chrCount;
+ break;
+ case ZDLE:
+ info->InputState = Inhdr;
+ info->chrCount = 0;
+ break;
+ default:
+ while (--info->chrCount >= 0) {
+ ZIdleStr((uchar*)"*", 1, info);
+ }
+ info->chrCount = 0;
+ break;
+ }
+ }
+ return 0;
+}
+
+
+
+int FQTermZmodem::YsendChar(char c, ZModem *info) {
+ int err;
+
+ if (info->canCount >= 2) {
+ ZStatus(RmtCancel, 0, NULL);
+ return ZmErrCancel;
+ }
+
+ switch (info->state) {
+ case YTStart:
+ /* wait for 'G', 'C' or NAK */
+ switch (c) {
+ case 'G':
+ /* streaming YModem */
+ case 'C':
+ /* CRC YModem */
+ case NAK:
+ /* checksum YModem */
+ info->PacketType = c;
+ return ZmDone;
+ default:
+ return 0;
+ }
+
+ case YTFile:
+ /* sent filename, waiting for ACK or NAK */
+ switch (c) {
+ case NAK:
+ /* resend */
+ case 'C':
+ case 'G':
+ ZStatus(DataErr, ++info->errCount, NULL);
+ return YSendFilename(info);
+ case ACK:
+ info->state = YTDataWait;
+ default:
+ return 0;
+ }
+
+ case YTDataWait:
+ /* sent filename, waiting for G,C or NAK */
+ switch (c) {
+ case NAK:
+ case 'C':
+ case 'G':
+ info->chrCount = 0;
+ if (info->PacketType == 'G') {
+ /* send it all at once */
+ while (info->state == YTData) {
+ if ((err = YSendData(info))) {
+ return err;
+ }
+ }
+ return 0;
+ } else {
+ return YSendData(info);
+ }
+ break;
+ default:
+ return 0;
+ }
+
+ case YTData:
+ /* sent data, waiting for ACK or NAK */
+ switch (c) {
+ case 'C':
+ case 'G':
+ /* protocol failure, resend filename */
+ if (info->Protocol == YMODEM) {
+ ZStatus(DataErr, ++info->errCount, NULL);
+ info->state = YTFile;
+ rewind(info->file);
+ return YSendFilename(info);
+ }
+ /* else XModem, treat it like a NAK */
+ case NAK:
+ ZStatus(DataErr, ++info->errCount, NULL);
+ return YXmitData(info->buffer + info->bufp, info->ylen, info);
+ case ACK:
+ info->offset += info->ylen;
+ info->bufp += info->ylen;
+ info->chrCount -= info->ylen;
+ ZStatus(SndByteCount, info->offset, NULL);
+ return YSendData(info);
+ default:
+ return 0;
+ }
+
+ case YTEOF:
+ /* sent EOF, waiting for ACK or NAK */
+ switch (c) {
+ case NAK:
+ return ZXmitStr(eotstr, 1, info);
+ case ACK:
+ info->state = info->Protocol == YMODEM ? YTStart : Done;
+ return ZmDone;
+ default:
+ return 0;
+ }
+
+ case YTFin:
+ /* sent Fin, waiting for ACK or NAK */
+ switch (c) {
+ case NAK:
+ return YSendFin(info);
+ case ACK:
+ return ZmDone;
+ default:
+ return 0;
+ }
+ default:
+ return 0;
+ }
+}
+
+
+
+int FQTermZmodem::ZProtocol(register ZModem *info) {
+ register StateTable *table;
+
+ zmodemlog("received %s: %2.2x %2.2x %2.2x %2.2x = %lx\n",
+ hdrnames[info->hdrData[0]], info->hdrData[1], info->hdrData[2],
+ info->hdrData[3], info->hdrData[4], ZDec4(info->hdrData + 1));
+
+ /* Flags are sent in F3 F2 F1 F0 order. Data is sent in P0 P1 P2 P3 */
+
+ info->timeoutCount = 0;
+ info->noiseCount = 0;
+
+ // zmodemTimer->start(info->timeout*1000);
+
+ table = tables[(int)info->state];
+ while (table->type != 99 && table->type != info->hdrData[0]) {
+ ++table;
+ }
+
+ zmodemlog(" state %s => %s, iflush=%d, oflush=%d, call %x\n", sname(info),
+ sname2(table->newstate), table->IFlush, table->OFlush, table->func);
+
+ info->state = table->newstate;
+
+ if (table->IFlush) {
+ info->rcvlen = 0;
+ ZIFlush(info);
+ }
+ if (table->OFlush) {
+ ZOFlush(info);
+ }
+ return (this->*(table->func))(info);
+}
+
+
+int FQTermZmodem::ZDataReceived(register ZModem *info, int crcGood) {
+ switch (info->state) {
+ case RSinitWait:
+ return GotSinitData(info, crcGood);
+ case RFileName:
+ return GotFileName(info, crcGood);
+ case RData:
+ return GotFileData(info, crcGood);
+ case CommandData:
+ return GotCommandData(info, crcGood);
+ case StderrData:
+ return GotStderrData(info, crcGood);
+ default:
+ return ZPF(info);
+ }
+}
+
+
+int FQTermZmodem::ZPF(ZModem *info) {
+ info->waitflag = 1; /* pause any in-progress transmission */
+ ZStatus(ProtocolErr, info->hdrData[0], sname(info));
+ return 0;
+}
+
+
+int FQTermZmodem::Ignore(ZModem *info) {
+ return 0;
+}
+
+
+int FQTermZmodem::AnswerChallenge(register ZModem *info) {
+ return ZXmitHdrHex(ZACK, info->hdrData + 1, info);
+}
+
+
+int FQTermZmodem::GotAbort(register ZModem *info) {
+ ZStatus(RmtCancel, 0, NULL);
+ return ZXmitHdrHex(ZFIN, zeros, info);
+}
+
+
+int FQTermZmodem::GotCancel(ZModem *info) {
+ return ZmErrCancel;
+}
+
+
+int FQTermZmodem::GotCommand(ZModem *info) {
+ uchar rbuf[4];
+ /* TODO: add command capability */
+
+
+ /// EPERM not defined????????
+
+ rbuf[0] = EPERM;
+ rbuf[1] = rbuf[2] = rbuf[3] = 0;
+ return ZXmitHdrHex(ZCOMPL, rbuf, info);
+}
+
+int FQTermZmodem::GotStderr(register ZModem *info) {
+ info->InputState = Indata;
+ info->chrCount = 0;
+ return 0;
+}
+
+
+int FQTermZmodem::RetDone(ZModem *info) {
+
+
+ return ZmDone;
+}
+
+
+int FQTermZmodem::GotCommandData(register ZModem *info, int crcGood) {
+ /* TODO */
+ return 0;
+}
+
+
+int FQTermZmodem::GotStderrData(register ZModem *info, int crcGood) {
+ info->buffer[info->chrCount] = '\0';
+ ZStatus(RemoteMessage, info->chrCount, (char*)info->buffer);
+ return 0;
+}
+
+
+int FQTermZmodem::GotFileName(ZModem *info, int crcGood) {
+ info->InputState = Idle;
+ info->chrCount = 0;
+
+ if (!crcGood) {
+ zmodemlog("GotFileName[%s]: bad crc, send ZNAK\n", sname(info));
+ info->state = RStart;
+ return ZXmitHdrHex(ZNAK, zeros, info);
+ }
+
+ parseFileName(info, (char*)info->buffer);
+
+ if ((info->f1 &ZMMASK) == ZMCRC) {
+ info->state = RCrc;
+ return ZXmitHdrHex(ZCRC, zeros, info);
+ }
+
+ zmodemlog("GotFileName[%s]: good crc, call requestFile\n", sname(info));
+ info->state = RFile;
+ return requestFile(info, 0);
+}
+
+
+int FQTermZmodem::ResendCrcReq(ZModem *info) {
+ zmodemlog("ResendCrcReq[%s]: send ZCRC\n", sname(info));
+ return ZXmitHdrHex(ZCRC, zeros, info);
+}
+
+
+int FQTermZmodem::GotSinitData(ZModem *info, int crcGood) {
+ info->InputState = Idle;
+ info->chrCount = 0;
+ info->state = RStart;
+
+ zmodemlog("GotSinitData[%s]: crcGood=%d\n", sname(info), crcGood);
+
+ if (!crcGood) {
+ return ZXmitHdrHex(ZNAK, zeros, info);
+ }
+
+ if (info->attn != NULL) {
+ free(info->attn);
+ }
+ info->attn = NULL;
+ if (info->buffer[0] != '\0') {
+ info->attn = strdup((char*)info->buffer);
+ }
+ return ZXmitHdrHex(ZACK, ZEnc4(SerialNo), info);
+}
+
+
+int FQTermZmodem::ResendRpos(ZModem *info) {
+ zmodemlog("ResendRpos[%s]: send ZRPOS(%ld)\n", sname(info), info->offset);
+ return ZXmitHdrHex(ZRPOS, ZEnc4(info->offset), info);
+}
+
+
+int FQTermZmodem::GotFileData(ZModem *info, int crcGood) {
+ /* OK, now what? Fushing the buffers and executing the
+ * attn sequence has likely chopped off the input stream
+ * mid-packet. Now we switch to idle mode and treat all
+ * incoming stuff like noise until we get a new valid
+ * packet.
+ */
+
+ if (!crcGood) {
+ /* oh bugger, an error. */
+ zmodemlog("GotFileData[%s]: bad crc, send ZRPOS(%ld), new state = RFile\n",
+ sname(info), info->offset);
+ ZStatus(DataErr, ++info->errCount, NULL);
+ if (info->errCount > MaxErrs) {
+ ZmodemAbort(info);
+ return ZmDataErr;
+ } else {
+ info->state = RFile;
+ info->InputState = Idle;
+ info->chrCount = 0;
+ return fileError(info, ZRPOS, info->offset);
+ }
+ }
+
+ if (ZWriteFile(info->buffer, info->chrCount, info->file, info)) {
+ /* RED ALERT! Could not write the file. */
+ ZStatus(FileErr, zerrno, NULL);
+ info->state = RFinish;
+ info->InputState = Idle;
+ info->chrCount = 0;
+ return fileError(info, ZFERR, zerrno);
+ }
+
+ zmodemlog("GotFileData[%s]: %ld.%d,", sname(info), info->offset,
+ info->chrCount);
+ info->offset += info->chrCount;
+ ZStatus(RcvByteCount, info->offset, NULL);
+
+ /* if this was the last data subpacket, leave data mode */
+ if (info->PacketType == ZCRCE || info->PacketType == ZCRCW) {
+ zmodemlog(" ZCRCE|ZCRCW, new state RFile");
+ info->state = RFile;
+ info->InputState = Idle;
+ info->chrCount = 0;
+ } else {
+ zmodemlog(" call dataSetup");
+ (void)dataSetup(info);
+ }
+
+ if (info->PacketType == ZCRCQ || info->PacketType == ZCRCW) {
+ zmodemlog(", send ZACK\n");
+ return ZXmitHdrHex(ZACK, ZEnc4(info->offset), info);
+ } else {
+ zmodemlog("\n");
+ }
+
+ return 0;
+}
+
+int FQTermZmodem::SendRinit(ZModem *info) {
+ uchar dbuf[4];
+
+
+
+#ifdef COMMENT
+ if (info->timeoutCount >= 5)
+ /* TODO: switch to Ymodem */
+#endif /* COMMENT */
+ {
+ transferstate = transferstart;
+ }
+ //transfer would be active, it must be set to false when transfer complete or abort
+ zmodemlog("SendRinit[%s]: send ZRINIT\n", sname(info));
+
+ info->timeout = ResponseTime;
+ dbuf[0] = info->bufsize &0xff;
+ dbuf[1] = (info->bufsize >> 8) &0xff;
+ dbuf[2] = 0;
+ dbuf[3] = info->zrinitflags;
+ return ZXmitHdrHex(ZRINIT, dbuf, info);
+}
+
+
+int FQTermZmodem::SendMoreFileData(ZModem *info) {
+ int type;
+ int qfull = 0;
+ int err;
+ int len; /* max # chars to send this packet */
+ long pending; /* # of characters sent but not acknowledged */
+
+ /* ZCRCE: CRC next, frame ends, header follows
+ * ZCRCG: CRC next, frame continues nonstop
+ * ZCRCQ: CRC next, send ZACK, frame continues nonstop
+ * ZCRCW: CRC next, send ZACK, frame ends, header follows
+ */
+
+ if (info->interrupt) {
+ /* Bugger, receiver sent an interrupt. Enter a wait state
+ * and see what they want. Next header *should* be ZRPOS.
+ */
+ info->state = SendWait;
+ info->timeout = 60;
+ return 0;
+ }
+
+ /* Find out how many bytes we can transfer in the next packet */
+
+ len = info->packetsize;
+
+ pending = info->offset - info->lastOffset;
+
+ if (info->windowsize != 0 && info->windowsize - pending <= len) {
+ len = info->windowsize - pending;
+ qfull = 1;
+ }
+ if (info->bufsize != 0 && info->bufsize - pending <= len) {
+ len = info->bufsize - pending;
+ qfull = 1;
+ }
+
+ if (len == 0) {
+ /* window still full, keep waiting */
+ info->state = SendWait;
+ info->timeout = 60;
+ return 0;
+ }
+
+
+ /* OK, we can safely transmit 'len' bytes of data. Start reading
+ * file until buffer is full.
+ */
+
+ len -= 10; /* Pre-deduct 10 bytes for trailing CRC */
+
+
+ /* find out what kind of packet to send */
+ if (info->waitflag) {
+ type = ZCRCW;
+ info->waitflag = 0;
+ }
+#ifdef COMMENT
+ else if (info->fileEof) {
+ type = ZCRCE;
+ }
+#endif /* COMMENT */
+ else if (qfull) {
+ type = ZCRCW;
+ } else {
+ switch (info->Streaming) {
+ case Full:
+ case Segmented:
+ type = ZCRCG;
+ break;
+
+ case StrWindow:
+ if ((info->windowCount += len) < info->windowsize / 4) {
+ type = ZCRCG;
+ } else {
+ type = ZCRCQ;
+ info->windowCount = 0;
+ }
+ break;
+
+ default:
+ case SlidingWindow:
+ type = ZCRCQ;
+ break;
+ }
+ }
+
+ {
+ int crc32 = info->crc32;
+ int c = 0, c2, atSign = 0;
+ ulong crc;
+ uchar *ptr = info->buffer;
+
+ crc = crc32 ? 0xffffffff : 0;
+
+ /* read characters from file and put into buffer until buffer is
+ * full or file is exhausted
+ */
+
+
+ while (len > 0 && (c = getc(info->file)) != EOF) {
+ if (!crc32) {
+ crc = updcrc(c, crc);
+ } else {
+ crc = UPDC32(c, crc);
+ }
+
+ /* zmodem protocol requires that CAN(ZDLE), DLE, XON, XOFF and
+ * a CR following '@' be escaped. In addition, I escape '^]'
+ * to protect telnet, "<CR>~." to protect rlogin, and ESC for good
+ * measure.
+ */
+ c2 = c &0177;
+ if (c == ZDLE || c2 == 020 || c2 == 021 || c2 == 023 || c2 == 0177 || c2 ==
+ '\r' || c2 == '\n' || c2 == 033 || c2 == 035 || (c2 < 040 && info->escCtrl)) {
+ *ptr++ = ZDLE;
+ if (c == 0177) {
+ *ptr = ZRUB0;
+ } else if (c == 0377) {
+ *ptr = ZRUB1;
+ } else {
+ *ptr = c ^ 0100;
+ }
+ len -= 2;
+ } else {
+ *ptr = c;
+ --len;
+ }
+ ++ptr;
+
+ atSign = c2 == '@';
+ ++info->offset;
+ }
+
+ /* if we've reached file end, a ZEOF header will follow. If
+ * there's room in the outgoing buffer for it, end the packet
+ * with ZCRCE and append the ZEOF header. If there isn't room,
+ * we'll have to do a ZCRCW
+ */
+ if ((info->fileEof = (c == EOF))) {
+ if (qfull || (info->bufsize != 0 && len < 24)) {
+ type = ZCRCW;
+ } else {
+ type = ZCRCE;
+ }
+ }
+
+ *ptr++ = ZDLE;
+ if (!crc32) {
+ crc = updcrc(type, crc);
+ } else {
+ crc = UPDC32(type, crc);
+ }
+ *ptr++ = type;
+
+ if (!crc32) {
+ crc = updcrc(0, crc);
+ crc = updcrc(0, crc);
+ ptr = putZdle(ptr, (crc >> 8) &0xff, info);
+ ptr = putZdle(ptr, crc &0xff, info);
+ } else {
+ crc = ~crc;
+ for (len = 4; --len >= 0; crc >>= 8) {
+ ptr = putZdle(ptr, crc &0xff, info);
+ }
+ }
+
+ len = ptr - info->buffer;
+ }
+
+ ZStatus(SndByteCount, info->offset, NULL);
+
+ if ((err = ZXmitStr(info->buffer, len, info))) {
+ return err;
+ }
+
+#ifdef COMMENT
+ if ((err = ZXmitData(ZBIN, len, uchar(type), info->buffer, info))) {
+ return err;
+ }
+#endif /* COMMENT */
+
+ /* finally, do we want to wait after this packet? */
+
+ switch (type) {
+ case ZCRCE:
+ info->state = SendEof;
+ info->timeout = 60;
+ return ZXmitHdrHex(ZEOF, ZEnc4(info->offset), info);
+ case ZCRCW:
+ info->state = info->fileEof ? SendDone : SendWait;
+ info->timeout = 60;
+ break;
+ default:
+ info->state = Sending;
+ info->timeout = 0;
+ break;
+ }
+
+
+#ifdef COMMENT
+ if (info->fileEof) {
+ /* Yes, file is done, send EOF and wait */
+ info->state = SendEof;
+ info->timeout = 60;
+ return ZXmitHdrHex(ZEOF, ZEnc4(info->offset), info);
+ } else if (type == ZCRCW) {
+ info->state = SendWait;
+ info->timeout = 60;
+ } else {
+ info->state = Sending;
+ info->timeout = 0;
+ }
+#endif /* COMMENT */
+ return 0;
+}
+
+
+uint FQTermZmodem::rcvHex(uint i, char c) {
+ if (c <= '9') {
+ c -= '0';
+ } else if (c <= 'F') {
+ c -= 'A' - 10;
+ } else {
+ c -= 'a' - 10;
+ }
+ return (i << 4) + c;
+}
+
+
+int FQTermZmodem::dataSetup(register ZModem *info) {
+ info->InputState = Indata;
+ info->chrCount = 0;
+ info->crcCount = 0;
+ info->crc = (info->DataType != ZBIN32) ? 0 : 0xffffffffL;
+ return 0;
+}
+
+int FQTermZmodem::ZWriteFile(uchar *buffer, int len, FILE *file, ZModem*) {
+ return (int)fwrite(buffer, 1, len, file) == len ? 0 : ZmErrSys;
+}
+
+int FQTermZmodem::ZCloseFile(ZModem *info) {
+ //to be completed
+ fclose(info->file);
+ return 0;
+}
+
+void FQTermZmodem::ZFlowControl(int onoff, ZModem *info) {
+ //to be completed
+}
+
+int FQTermZmodem::GotSinit(ZModem *info) {
+ zmodemlog("GotSinit[%s]: call dataSetup\n", sname(info));
+
+ info->zsinitflags = info->hdrData[4];
+ info->escCtrl = info->zsinitflags &TESCCTL;
+ info->escHibit = info->zsinitflags &TESC8;
+ ZFlowControl(1, info);
+ return dataSetup(info);
+}
+
+int FQTermZmodem::GotFile(ZModem *info) {
+ zmodemlog("GotFile[%s]: call dataSetup\n", sname(info));
+
+ info->errCount = 0;
+ info->f0 = info->hdrData[4];
+ info->f1 = info->hdrData[3];
+ info->f2 = info->hdrData[2];
+ info->f3 = info->hdrData[1];
+ return dataSetup(info);
+}
+
+int FQTermZmodem::GotFin(ZModem *info) {
+ int i;
+ zmodemlog("GotFin[%s]: send ZFIN\n", sname(info));
+ info->InputState = Finish;
+ info->chrCount = 0;
+ if (info->filename != NULL) {
+ free(info->filename);
+ }
+ i = ZXmitHdrHex(ZFIN, zeros, info);
+ ZmodemReset(info);
+ transferstate = transferstop; // transfer complete
+ return i;
+}
+
+
+int FQTermZmodem::GotData(ZModem *info) {
+ int err;
+
+ zmodemlog("GotData[%s]:\n", sname(info));
+
+ if (ZDec4(info->hdrData + 1) != info->offset) {
+ if (info->attn != NULL && (err = ZAttn(info)) != 0) {
+ return err;
+ }
+ zmodemlog(" bad, send ZRPOS(%ld)\n", info->offset);
+ return ZXmitHdrHex(ZRPOS, ZEnc4(info->offset), info);
+ }
+
+ /* Let's do it! */
+ zmodemlog(" call dataSetup\n");
+ return dataSetup(info);
+}
+
+int FQTermZmodem::GotEof(ZModem *info) {
+ zmodemlog("GotEof[%s]: offset=%ld\n", sname(info), info->offset);
+ if (ZDec4(info->hdrData + 1) != info->offset) {
+ zmodemlog("zdec4(info->hdrdata+1)=%ld\n", ZDec4(info->hdrData + 1));
+ zmodemlog(" bad length, state = RFile\n");
+ info->state = RFile;
+ return 0; /* it was probably spurious */
+ }
+
+ /* TODO: if we can't close the file, send a ZFERR */
+
+ ZCloseFile(info);
+ info->file = NULL;
+ ZStatus(FileEnd, 0, info->filename);
+ if (info->filename != NULL) {
+ free(info->filename);
+ info->filename = NULL;
+ }
+ return SendRinit(info);
+}
+
+int FQTermZmodem::GotFreecnt(ZModem *info) {
+ /* TODO: how do we find free space on system? */
+ return ZXmitHdrHex(ZACK, ZEnc4(0xffffffff), info);
+}
+
+
+int FQTermZmodem::GotFileCrc(ZModem *info) {
+ zmodemlog("GotFileCrc[%s]: call requestFile\n", sname(info));
+ return requestFile(info, ZDec4(info->hdrData + 1));
+}
+
+int FQTermZmodem::requestFile(ZModem *info, ulong crc) {
+ info->file = ZOpenFile((char*)info->buffer, crc, info);
+
+ if (info->file == NULL) {
+ zmodemlog("requestFile[%s]: send ZSKIP\n", sname(info));
+
+ info->state = RStart;
+ ZStatus(FileSkip, 0, info->filename);
+ return ZXmitHdrHex(ZSKIP, zeros, info);
+ } else {
+ zmodemlog("requestFile[%s]: send ZRPOS(%ld)\n", sname(info), info->offset);
+ info->offset = info->f0 == ZCRESUM ? ftell(info->file): 0;
+ info->state = RFile;
+ ZStatus(FileBegin, info->len, info->filename);
+ return ZXmitHdrHex(ZRPOS, ZEnc4(info->offset), info);
+ }
+}
+
+void FQTermZmodem::parseFileName(ZModem *info, char *fileinfo) {
+ char *ptr;
+ int serial = 0;
+
+ info->len = info->mode = info->filesRem = info->bytesRem = info->fileType = 0;
+ ptr = fileinfo + strlen(fileinfo) + 1;
+ if (info->filename != NULL) {
+ free(info->filename);
+ }
+ info->filename = strdup(fileinfo);
+ sscanf(ptr, "%d %lo %o %o %d %d %d", &info->len, &info->date, &info->mode,
+ &serial, &info->filesRem, &info->bytesRem, &info->fileType);
+}
+
+
+
+int FQTermZmodem::fileError(ZModem *info, int type, int data) {
+ int err;
+
+ info->InputState = Idle;
+ info->chrCount = 0;
+
+ if (info->attn != NULL && (err = ZAttn(info)) != 0) {
+ return err;
+ }
+ return ZXmitHdrHex(type, ZEnc4(data), info);
+}
+
+
+int FQTermZmodem::ProcessPacket(ZModem *info) {
+ int idx = (uchar)info->buffer[0];
+ int idxc = (uchar)info->buffer[1];
+ int crc0, crc1;
+ int err;
+
+ info->state = YRDataWait;
+
+ if (idxc != 255-idx) {
+ ZStatus(DataErr, ++info->errCount, NULL);
+ return rejectPacket(info);
+ }
+
+ if (idx == (info->packetCount % 256))
+ /* quietly ignore dup */ {
+ return acceptPacket(info);
+ }
+
+ if (idx != (info->packetCount + 1) % 256) {
+ /* out of sequence */
+ (void)ZXmitStr(CanStr, 2, info);
+ return ZmErrSequence;
+ }
+
+ crc0 = (uchar)info->buffer[info->pktLen - 2] << 8
+ | (uchar)info->buffer[info->pktLen - 1];
+ crc1 = calcCrc(info->buffer + 2, info->pktLen - 4);
+ if (crc0 != crc1) {
+ ZStatus(DataErr, ++info->errCount, NULL);
+ return rejectPacket(info);
+ }
+
+ ++info->packetCount;
+
+ if (info->packetCount == 0) {
+ /* packet 0 is filename */
+ if (info->buffer[2] == '\0') {
+ /* null filename is FIN */
+ (void)acceptPacket(info);
+ return ZmDone;
+ }
+
+ parseFileName(info, (char*)info->buffer + 2);
+ info->file = ZOpenFile(info->filename, 0, info);
+ if (info->file == NULL) {
+ (void)ZXmitStr(CanStr, 2, info);
+ return ZmErrCantOpen;
+ }
+ if ((err = acceptPacket(info)) != 0) {
+ return err;
+ }
+ return ZXmitStr((uchar*)"C", 1, info);
+ }
+
+
+ if (ZWriteFile(info->buffer + 2, info->pktLen - 4, info->file, info)) {
+ ZStatus(FileErr, zerrno, NULL);
+ (void)ZXmitStr(CanStr, 2, info);
+ return ZmErrSys;
+ }
+ info->offset += info->pktLen - 4;
+ ZStatus(RcvByteCount, info->offset, NULL);
+
+ (void)acceptPacket(info);
+ return 0;
+}
+
+int FQTermZmodem::rejectPacket(ZModem *info) {
+ info->timeout = 10;
+ return ZXmitStr(NakStr, 1, info);
+}
+
+
+int FQTermZmodem::acceptPacket(ZModem *info) {
+ info->state = YRDataWait;
+ info->timeout = 10;
+ return ZXmitStr(AckStr, 1, info);
+}
+
+
+int FQTermZmodem::calcCrc(uchar *str, int len) {
+ int crc = 0;
+ while (--len >= 0) {
+ crc = updcrc(*str++, crc);
+ }
+ crc = updcrc(0, crc);
+ crc = updcrc(0, crc);
+ return crc &0xffff;
+}
+
+
+char *FQTermZmodem::strdup(const char *str) {
+ char *rval;
+ int len = strlen(str) + 1;
+ rval = (char*)malloc(len);
+ strcpy(rval, str);
+ return rval;
+}
+
+
+int FQTermZmodem::ZXmitData(int format, int len, uchar term, uchar *data, ZModem
+ *info) {
+ uchar *ptr = info->buffer;
+ uint crc;
+
+ if (format == ZBIN && info->crc32) {
+ format = ZBIN32;
+ }
+
+ zmodemlog("ZXmiteData: fmt=%c, len=%d, term=%c\n", format, len, term);
+
+ crc = (format == ZBIN) ? 0 : 0xffffffff;
+
+ while (--len >= 0) {
+ if (format == ZBIN) {
+ crc = updcrc(*data, crc);
+ } else {
+ crc = UPDC32(*data, crc);
+ }
+ ptr = putZdle(ptr, *data++, info);
+ }
+
+ *ptr++ = ZDLE;
+ if (format == ZBIN) {
+ crc = updcrc(term, crc);
+ } else {
+ crc = UPDC32(term, crc);
+ }
+ *ptr++ = term;
+ if (format == ZBIN) {
+ crc = updcrc(0, crc);
+ crc = updcrc(0, crc);
+ ptr = putZdle(ptr, (crc >> 8) &0xff, info);
+ ptr = putZdle(ptr, crc &0xff, info);
+ } else {
+ crc = ~crc;
+ for (len = 4; --len >= 0; crc >>= 8) {
+ ptr = putZdle(ptr, crc &0xff, info);
+ }
+ }
+
+ return ZXmitStr(info->buffer, ptr - info->buffer, info);
+}
+
+
+
+int FQTermZmodem::YXmitData(uchar *buffer, int len, ZModem *info) {
+ uchar hdr[3];
+ uchar trail[2];
+ ulong crc = 0;
+ int i, err;
+
+ hdr[0] = len == 1024 ? STX : SOH;
+ hdr[1] = info->packetCount;
+ hdr[2] = ~hdr[1];
+ if ((err = ZXmitStr(hdr, 3, info)) || (err = ZXmitStr(buffer, len, info))) {
+ return err;
+ }
+
+ if (info->PacketType == NAK) {
+ /* checksum */
+ for (i = 0; i < len; ++i) {
+ crc += buffer[i];
+ }
+ trail[0] = crc % 256;
+ return ZXmitStr(trail, 1, info);
+ } else {
+ for (i = 0; i < len; ++i) {
+ crc = updcrc(buffer[i], crc);
+ }
+ crc = updcrc(0, crc);
+ crc = updcrc(0, crc);
+ trail[0] = crc / 256;
+ trail[1] = crc % 256;
+ return ZXmitStr(trail, 2, info);
+ }
+}
+
+
+int FQTermZmodem::YSendFilename(ZModem *info) {
+ int i, len;
+ uchar obuf[1024];
+ uchar *ptr = obuf;
+
+ info->state = info->PacketType != 'G' ? YTFile : YTDataWait;
+ info->packetCount = 0;
+ info->offset = 0;
+
+ i = strlen(info->rfilename);
+ memcpy(ptr, info->rfilename, i + 1);
+ ptr += i + 1;
+ sprintf((char*)ptr, "%d %lo %o 0", info->len, info->date, info->mode);
+ ptr += strlen((char*)ptr);
+ *ptr++ = '\0';
+ /* pad out to 128 bytes or 1024 bytes */
+ i = ptr - obuf;
+ len = i > 128 ? 1024 : 128;
+ for (; i < len; ++i) {
+ *ptr++ = '\0';
+ }
+
+ return YXmitData(obuf, len, info);
+}
+
+int FQTermZmodem::YSendData(ZModem *info) {
+ int i;
+
+ /* are there characters still in the read buffer? */
+
+ if (info->chrCount <= 0) {
+ info->bufp = 0;
+ info->chrCount = fread(info->buffer, 1, info->packetsize, info->file);
+ info->fileEof = feof(info->file);
+ }
+
+ if (info->chrCount <= 0) {
+ fclose(info->file);
+ info->state = YTEOF;
+ return ZXmitStr(eotstr, 1, info);
+ }
+
+ /* pad out to 128 bytes if needed */
+ if (info->chrCount < 128) {
+ i = 128-info->chrCount;
+ memset(info->buffer + info->bufp + info->chrCount, 0x1a, i);
+ info->chrCount = 128;
+ }
+
+ info->ylen = info->chrCount >= 1024 ? 1024 : 128;
+ ++info->packetCount;
+
+ info->state = YTData;
+
+ return YXmitData(info->buffer + info->bufp, info->ylen, info);
+}
+
+
+int FQTermZmodem::YSendFin(ZModem *info) {
+ uchar obuf[128];
+
+ info->state = YTFin;
+ info->packetCount = 0;
+
+ memset(obuf, 0, 128);
+
+ return YXmitData(obuf, 128, info);
+}
+
+int FQTermZmodem::sendFilename(ZModem *info) {
+ int err;
+ int i;
+ uchar obuf[2048];
+ uchar *ptr = obuf;
+
+ info->state = FileWait;
+
+ if ((err = ZXmitHdr(ZFILE, ZBIN, info->fileFlags, info))) {
+ return err;
+ }
+
+ i = strlen(info->rfilename);
+ memcpy(ptr, info->rfilename, i + 1);
+ ptr += i + 1;
+ sprintf((char*)ptr, "%d %lo %o 0 %d %d 0", info->len, info->date, info->mode,
+ info->filesRem, info->bytesRem);
+ ptr += strlen((char*)ptr);
+ *ptr++ = '\0';
+
+ return ZXmitData(ZBIN, ptr - obuf, ZCRCW, obuf, info);
+}
+
+int FQTermZmodem::GotRinit(ZModem *info) {
+ if (strFileList.count() == 0) {
+ return ZmodemTFinish(info);
+ }
+
+
+ info->bufsize = info->hdrData[1] + info->hdrData[2] *256;
+ info->zrinitflags = info->hdrData[4] + info->hdrData[3] *256;
+ info->crc32 = info->zrinitflags &CANFC32;
+ info->escCtrl = info->zrinitflags &ESCCTL;
+ info->escHibit = info->zrinitflags &ESC8;
+
+ /* Full streaming: If receiver can overlap I/O, and if
+ * the sender can sample the reverse channel without hanging,
+ * and the receiver has not specified a buffer size, then we
+ * can simply blast away with ZCRCG packets. If the receiver
+ * detects an error, it sends an attn sequence and a new ZRPOS
+ * header to restart the file where the error occurred.
+ *
+ * [note that zmodem8.doc does not define how much noise is
+ * required to trigger a ZCRCW packet. We arbitrarily choose
+ * 64 bytes]
+ *
+ * If 'windowsize' is nonzero, and the receiver can do full
+ * duplex, ZCRCQ packets are sent instead of ZCRCG, to keep track
+ * of the number of characters in the queue. If the queue fills
+ * up, we pause and wait for a ZACK.
+ *
+ *
+ * Full Streaming with Reverse Interrupt: If sender cannot
+ * sample the input stream, then we define an Attn sequence
+ * that will be used to interrupt transmission.
+ *
+ *
+ * Full Streaming with Sliding Window: If sender cannot
+ * sample input stream or respond to Attn signal, we send
+ * several ZCRCQ packets until we're sure the receiver must
+ * have sent back at least one ZACK. Then we stop sending and
+ * read that ZACK. Then we send one more packet and so on.
+ *
+ *
+ * Segmented Streaming: If receiver cannot overlap I/O or can't do
+ * full duplex and has specified a maximum receive buffer size,
+ * whenever the buffer size is reached, we send a ZCRCW packet.
+ *
+ * TODO: what if receiver can't overlap, but hasn't set a buffer
+ * size?
+ *
+ * ZCRCE: CRC next, frame ends, header follows
+ * ZCRCG: CRC next, frame continues nonstop
+ * ZCRCQ: CRC next, send ZACK, frame continues nonstop
+ * ZCRCW: CRC next, send ZACK, frame ends, header follows
+ */
+
+ transferstate = transferstart;
+
+ ZFlowControl(1, info);
+
+ if ((info->zrinitflags &(CANFDX | CANOVIO)) == (CANFDX | CANOVIO) &&
+ (SendSample || SendAttn) && info->bufsize == 0) {
+ if (info->windowsize == 0) {
+ info->Streaming = Full;
+ } else {
+ info->Streaming = StrWindow;
+ }
+ }
+
+ else if ((info->zrinitflags &(CANFDX | CANOVIO)) == (CANFDX | CANOVIO) &&
+ info->bufsize == 0) {
+ info->Streaming = SlidingWindow;
+ }
+
+ else {
+ info->Streaming = Segmented;
+ }
+ // get filenames to transfer
+ zmodemlog("GotRinit[%s]\n", sname(info));
+
+ if (AlwaysSinit || info->zsinitflags != 0 || info->attn != NULL) {
+ SendZSInit(info);
+ }
+
+
+ itFile = strFileList.begin();
+ QFileInfo fi(*itFile);
+ FQ_TRACE("zmodem", 0) << "Number of files to be transfered: "
+ << strFileList.count();
+ char *filename = strdup(fi.absoluteFilePath().toLatin1());
+ char *rfilename = strdup(fi.fileName().toLatin1());
+ ZmodemTFile(filename, rfilename, 0, 0, 0, 0, strFileList.count(), fi.size(),
+ info);
+ strFileList.erase(itFile);
+ return ZmDone;
+}
+
+
+int FQTermZmodem::SendZSInit(ZModem *info) {
+ char tmp = '\0';
+ int err;
+ //char *at = (info->attn != NULL) ? info->attn : "" ;
+ char *at;
+ if (info->attn != NULL) {
+ at = info->attn;
+ } else {
+ at = &tmp;
+ }
+ uchar fbuf[4];
+
+ /* TODO: zmodem8.doc states: "If the ZSINIT header specifies
+ * ESCCTL or ESC8, a HEX header is used, and the receiver
+ * activates the specified ESC modes before reading the following
+ * data subpacket." What does that mean?
+ */
+
+ zmodemlog("SendZSInit[%s]\n", sname(info));
+
+ info->state = TInit;
+ fbuf[0] = fbuf[1] = fbuf[2] = 0;
+ fbuf[3] = info->zsinitflags;
+ if ((err = ZXmitHdr(ZSINIT, ZBIN, fbuf, info)) || (err = ZXmitData(ZBIN,
+ strlen(at) + 1, ZCRCW, (uchar*)at, info))) {
+ return err;
+ }
+ return 0;
+}
+
+
+int FQTermZmodem::SendFileCrc(ZModem *info) {
+ ulong crc;
+
+ crc = FileCrc(info->filename);
+
+ zmodemlog("SendFileCrc[%s]: %lx\n", sname(info), crc);
+
+ return ZXmitHdrHex(ZCRC, ZEnc4(crc), info);
+}
+
+int FQTermZmodem::GotSendAck(ZModem *info) {
+ ulong offset;
+
+ offset = ZDec4(info->hdrData + 1);
+
+ if (offset > info->lastOffset) {
+ info->lastOffset = offset;
+ }
+
+ zmodemlog("GotSendAck[%s]: %lx\n", sname(info), info->offset);
+
+ return 0; /* DONT send more data, that will happen
+ * later anyway */
+}
+
+int FQTermZmodem::GotSendDoneAck(ZModem *info) {
+ ulong offset;
+
+ offset = ZDec4(info->hdrData + 1);
+
+ if (offset > info->lastOffset) {
+ info->lastOffset = offset;
+ }
+
+ zmodemlog("GotSendDoneAck[%s]: %ld\n", sname(info), info->offset);
+
+ info->state = SendEof;
+ info->timeout = 60;
+ return ZXmitHdrHex(ZEOF, ZEnc4(info->offset), info);
+}
+
+int FQTermZmodem::GotSendNak(ZModem *info) {
+ info->offset = info->zrposOffset;
+
+ fseek(info->file, info->offset, 0);
+
+ /* TODO: what if fseek fails? Send EOF? */
+
+ zmodemlog("GotSendNak[%s]: %ld\n", sname(info), info->offset);
+
+ return SendMoreFileData(info);
+}
+
+int FQTermZmodem::GotSendWaitAck(ZModem *info) {
+
+ ulong offset;
+ int err;
+
+ offset = ZDec4(info->hdrData + 1);
+
+ FQ_TRACE("zmodem", 10) << "last = " << info->lastOffset
+ << ", now = " << offset;
+
+ if (offset > info->lastOffset) {
+ info->lastOffset = offset;
+ }
+
+ //receiver return -1 without setting this flag, kingson 00:07 14-07-04
+ info->waitflag = 1;
+
+ zmodemlog("GotSendWaitAck[%s]\n", sname(info), offset);
+
+ if ((err = ZXmitHdr(ZDATA, ZBIN, info->hdrData + 1, info))) {
+ return err;
+ }
+ return SendMoreFileData(info);
+}
+
+int FQTermZmodem::SkipFile(ZModem *info) {
+ zmodemlog("SkipFile[%s]\n", sname(info));
+ ZStatus(FileEnd, 0, info->rfilename);
+ fclose(info->file);
+
+ // stupid SMTH doesnt send further command, kick
+ // lets send files in the list
+ info->state = TStart;
+ return GotRinit(info);
+}
+
+int FQTermZmodem::GotSendPos(ZModem *info) {
+ ZStatus(DataErr, ++info->errCount, NULL);
+ info->waitflag = 1; /* next pkt should wait, to resync */
+ FQ_TRACE("zmodem", 9) << "GotSendPos, offset = " << info->offset;
+ zmodemlog("GotSendPos[%s] %lx\n", sname(info), info->offset);
+ return startFileData(info);
+}
+
+int FQTermZmodem::SendFileData(ZModem *info) {
+ info->waitflag = 0;
+ return startFileData(info);
+}
+
+int FQTermZmodem::ResendEof(ZModem *info) {
+ return ZXmitHdrHex(ZEOF, ZEnc4(info->offset), info);
+}
+
+int FQTermZmodem::OverAndOut(ZModem *info) {
+ zmodemlog("OverAndOut[%s]\n", sname(info));
+
+ ZXmitStr((uchar*)"OO", 2, info);
+
+ transferstate = transferstop; // transfer complete
+
+ ZmodemReset(info); //Tranfer complete, zmodem return to receive state
+
+ return ZmDone;
+}
+
+int FQTermZmodem::startFileData(ZModem *info) {
+ int err;
+
+ info->offset = info->lastOffset = info->zrposOffset = ZDec4(info->hdrData + 1);
+
+ fseek(info->file, info->offset, 0);
+
+ /* TODO: what if fseek fails? Send EOF? */
+
+ zmodemlog("startFileData[%s]: %lx\n", sname(info), info->offset);
+
+ if ((err = ZXmitHdr(ZDATA, ZBIN, ZEnc4(info->offset), info))) {
+ return err;
+ }
+ return SendMoreFileData(info);
+}
+
+uchar *FQTermZmodem::putHex(uchar *ptr, uchar c) {
+ *ptr++ = hexChars[(c >> 4) &0xf];
+ *ptr++ = hexChars[c &0xf];
+ return ptr;
+}
+
+
+int FQTermZmodem::ZmodemReset(ZModem *info) {
+ zmodemlog("\nZmodemReset\n");
+
+ ZmodemRInit(info);
+
+ return 0;
+}
+
+
+void FQTermZmodem::zmodemlog(const char *fmt, ...) {
+ // only for debug
+#ifdef FQTERM_ZMODEM_DEBUG
+ va_list ap;
+ struct timeval tv;
+ struct tm *tm;
+ static int do_ts = 1;
+
+ zmodemlogfile = fopen("zmodem.log", "a");
+
+ if (zmodemlogfile == NULL) {
+ return ;
+ }
+
+ if (do_ts) {
+ gettimeofday(&tv, NULL);
+ tm = localtime(&tv.tv_sec);
+ fprintf(zmodemlogfile, "%2.2d:%2.2d:%2.2d.%2.2ld: ", tm->tm_hour, tm->tm_min,
+ tm->tm_sec, tv.tv_usec / 10000);
+ }
+ do_ts = strchr(fmt, '\n') != NULL;
+
+ va_start(ap, fmt);
+ vfprintf(zmodemlogfile, fmt, ap);
+ va_end(ap);
+
+ fclose(zmodemlogfile);
+#endif
+
+}
+
+void FQTermZmodem::zmodemCancel() {
+ ZmodemAbort(&info);
+}
+
+} // namespace FQTerm
+
+#include "fqterm_zmodem.moc"
+
diff --git a/src/terminal/internal/fqterm_zmodem.h b/src/terminal/internal/fqterm_zmodem.h
new file mode 100644
index 0000000..bd1f4f4
--- /dev/null
+++ b/src/terminal/internal/fqterm_zmodem.h
@@ -0,0 +1,623 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_ZMODEM_H
+#define FQTERM_ZMODEM_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
+#include <time.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <QByteArray>
+#include <QObject>
+#include <QTimer>
+#include <QFile>
+#include <QStringList>
+
+namespace FQTerm {
+
+/* PARAMETERS
+ *
+ * The following #defines control the behavior of the Zmodem
+ * package. Note that these may be replaced with variables
+ * if you like. For example, "#define DoInitRZ" may be replaced
+ * with "extern int DoInitRz" to use a global variable, or with
+ * "#define DoInitRZ (info->doInitRz)" to use a variable you
+ * add to the ZModem structure.
+ *
+ * It is assumed that the compiler is good enough to optimize
+ * "if( 0 )" and "if( 1 )" cases. If not, you may wish to modify
+ * the source code to use #ifdef instead.
+ */
+
+#define DoInitRZ 1 /* send initial "rz\r" when transmitting */
+#define AllowCommand 0 /* allow remote end to execute commands */
+#define SendSample 1 /* sender can sample reverse channel */
+#define SendAttn 1 /* sender can be interrupted with Attn signal */
+#define ResponseTime 10 /* reasonable response time for sender to
+ * respond to requests from receiver */
+#define SerialNo 1 /* receiver serial # */
+#define MaxNoise 64 /* max "noise" characters before transmission
+ * pauses */
+#define MaxErrs 30 /* Max receive errors before cancel */
+#define AlwaysSinit 1 /* always send ZSINIT header, even if not
+ * needed, this makes protocol more robust */
+
+#define SendOnly 0 /* compiles smaller version for send only */
+#define RcvOnly 0 /* compiles smaller version for receive only */
+
+enum enum_InputState {
+ Idle, Padding, Inhdr, Indata, Finish, Ysend, Yrcv
+};
+enum enum_Protocol {
+ XMODEM, YMODEM, ZMODEM
+};
+enum enum_Streaming {
+ Full, StrWindow, SlidingWindow, Segmented
+};
+enum enum_transferstate {
+ notransfer, transferstart, transferstop
+};
+
+
+/* Internal State */
+
+typedef enum zmstate {
+ /* receive */
+ RStart, /* sent RINIT, waiting for ZFILE or SINIT */
+ RSinitWait, /* got SINIT, waiting for data */
+ RFileName, /* got ZFILE, waiting for filename & info */
+ RCrc, /* got filename, want crc too */
+ RFile, /* got filename, ready to read */
+ RData, /* reading data */
+ RDataErr, /* encountered error, ignoring input */
+ RFinish, /* sent ZFIN, waiting for 'OO' */
+
+ /* transmit */
+ TStart, /* waiting for INIT frame from other end */
+ TInit, /* received INIT, sent INIT, waiting for ZACK */
+ FileWait, /* sent file header, waiting for ZRPOS */
+ CrcWait, /* sent file crc, waiting for ZRPOS */
+ Sending, /* sending data subpackets, ready for int */
+ SendWait, /* waiting for ZACK */
+ SendDone, /* file finished, need to send EOF */
+ SendEof, /* sent EOF, waiting for ZACK */
+ TFinish, /* sent ZFIN, waiting for ZFIN */
+
+ /* general */
+ CommandData, /* waiting for command data */
+ CommandWait, /* waiting for command to execute */
+ StderrData, /* waiting for stderr data */
+ Done,
+
+ /* x/ymodem transmit */
+ YTStart, /* waiting for 'G', 'C' or NAK */
+ YTFile, /* sent filename, waiting for ACK */
+ YTDataWait, /* ready to send data, waiting for 'C' */
+ YTData, /* sent data, waiting for ACK */
+ YTEOF, /* sent eof, waiting for ACK */
+ YTFin, /* sent null filename, waiting for ACK */
+
+ /* x/ymodem receive */
+ YRStart, /* sent 'C', waiting for filename */
+ YRDataWait, /* received filename, waiting for data */
+ YRData, /* receiving filename or data */
+ YREOF /* received first EOT, waiting for 2nd */
+
+} ZMState;
+
+
+
+
+typedef struct {
+ int ifd; /* input fd, for use by caller's routines */
+ int ofd; /* output fd, for use by caller's routines */
+ FILE *file; /* file being transfered */
+ int zrinitflags; /* receiver capabilities, see below */
+ int zsinitflags; /* sender capabilities, see below */
+ char *attn; /* attention string, see below */
+ int timeout; /* timeout value, in seconds */
+ int bufsize; /* receive buffer size, bytes */
+ int packetsize; /* preferred transmit packet size */
+ int windowsize; /* max window size */
+
+ /* file attributes: read-only */
+
+ int filesRem, bytesRem;
+ uchar f0, f1, f2, f3; /* file flags */
+ int len, mode, fileType; /* file flags */
+ ulong date; /* file date */
+
+ /* From here down, internal to Zmodem package */
+
+ ZMState state; /* protocol internal state */
+ char *filename; /* filename */
+ char *rfilename; /* remote filename */
+ int crc32; /* use 32-bit crc */
+ int pktLen; /* length of this packet */
+ int DataType; /* input data type */
+ int PacketType; /* type of this packet */
+ int rcvlen;
+ int chrCount; /* chars received in current header/buffer */
+ int crcCount; /* crc characters remaining at end of buffer */
+ int canCount; /* how many CAN chars received? */
+ int noiseCount; /* how many noise chars received? */
+ int errorFlush; /* ignore incoming data because of error */
+ uchar *buffer; /* data buffer */
+ ulong offset; /* file offset */
+ ulong lastOffset; /* last acknowledged offset */
+ ulong zrposOffset; /* last offset specified w/zrpos */
+ int ylen, bufp; /* len,location of last Ymodem packet */
+ int fileEof; /* file eof reached */
+ int packetCount; /* # packets received */
+ int errCount; /* how many data errors? */
+ int timeoutCount; /* how many times timed out? */
+ int windowCount; /* how much data sent in current window */
+ int atSign; /* last char was '@' */
+ int lastCR; /* last char was CR */
+ int escCtrl; /* other end requests ctrl chars be escaped */
+ int escHibit; /* other end requests hi bit be escaped */
+ int escape; /* next character is escaped */
+ int interrupt; /* received attention signal */
+ int waitflag; /* next send should wait */
+ /* parser state */
+ // enum enum_InputState {Idle, Padding, Inhdr, Indata, Finish, Ysend, Yrcv} InputState ;
+ enum_InputState InputState;
+ // enum enum_Protocol {XMODEM, YMODEM, ZMODEM} Protocol ;
+ enum_Protocol Protocol;
+ uchar hdrData[9]; /* header type and data */
+ uchar fileFlags[4]; /* file xfer flags */
+ ulong crc; /* crc of incoming header/data */
+ // enum enum_Streaming {Full, StrWindow, SlidingWindow, Segmented} Streaming ;
+ enum_Streaming Streaming;
+} ZModem;
+
+
+
+/* ZRINIT flags. Describe receiver capabilities */
+
+#define CANFDX 1 /* Rx is Full duplex */
+#define CANOVIO 2 /* Rx can overlap I/O */
+#define CANBRK 4 /* Rx can send a break */
+#define CANCRY 010 /* Rx can decrypt */
+#define CANLZW 020 /* Rx can uncompress */
+#define CANFC32 040 /* Rx can use 32-bit crc */
+#define ESCCTL 0100 /* Rx needs control chars escaped */
+#define ESC8 0200 /* Rx needs 8th bit escaped. */
+
+/* ZSINIT flags. Describe sender capabilities */
+
+#define TESCCTL 0100 /* Tx needs control chars escaped */
+#define TESC8 0200 /* Tx needs 8th bit escaped. */
+
+
+/* ZFILE transfer flags */
+
+/* F0 */
+#define ZCBIN 1 /* binary transfer */
+#define ZCNL 2 /* convert NL to local eol convention */
+#define ZCRESUM 3 /* resume interrupted file xfer, or append to a
+ growing file. */
+
+/* F1 */
+#define ZMNEWL 1 /* transfer if source newer or longer */
+#define ZMCRC 2 /* transfer if different CRC or length */
+#define ZMAPND 3 /* append to existing file, if any */
+#define ZMCLOB 4 /* replace existing file */
+#define ZMNEW 5 /* transfer if source is newer */
+#define ZMDIFF 6 /* transfer if dates or lengths different */
+#define ZMPROT 7 /* protect: transfer only if dest doesn't exist */
+#define ZMCHNG 8 /* change filename if destination exists */
+#define ZMMASK 037 /* mask for above. */
+#define ZMSKNOLOC 0200 /* skip if not present at Rx end */
+
+/* F2 */
+#define ZTLZW 1 /* lzw compression */
+#define ZTRLE 3 /* run-length encoding */
+
+/* F3 */
+#define ZCANVHDR 1 /* variable headers ok */
+#define ZRWOVR 4 /* byte position for receive window override/256 */
+#define ZXSPARS 64 /* encoding for sparse file ops. */
+
+
+
+/* ATTN string special characters. All other characters sent verbose */
+
+#define ATTNBRK '\335' /* send break signal */
+#define ATTNPSE '\336' /* pause for one second */
+
+/* error code definitions [O] means link still open */
+
+#define ZmDone -1 /* done */
+#define ZmErrInt -2 /* internal error */
+#define ZmErrSys -3 /* system error, see errno */
+#define ZmErrNotOpen -4 /* communication channel not open */
+#define ZmErrCantOpen -5 /* can't open file, see errno [O] */
+#define ZmFileTooLong -6 /* remote filename too long [O] */
+#define ZmFileCantWrite -7 /* could not write file, see errno */
+#define ZmDataErr -8 /* too many data errors */
+#define ZmErrInitTo -10 /* transmitter failed to respond to init req. */
+#define ZmErrSequence -11 /* packet received out of sequence */
+#define ZmErrCancel -12 /* cancelled by remote end */
+#define ZmErrRcvTo -13 /* remote receiver timed out during transfer */
+#define ZmErrSndTo -14 /* remote sender timed out during transfer */
+#define ZmErrCmdTo -15 /* remote command timed out */
+
+
+
+/* ZModem character definitions */
+
+#define ZDLE 030 /* zmodem escape is CAN */
+#define ZPAD '*' /* pad */
+#define ZBIN 'A' /* introduces 16-bit crc binary header */
+#define ZHEX 'B' /* introduces 16-bit crc hex header */
+#define ZBIN32 'C' /* introduces 32-bit crc binary header */
+#define ZBINR32 'D' /* introduces RLE packed binary frame w/32-bit crc */
+#define ZVBIN 'a' /* alternate ZBIN */
+#define ZVHEX 'b' /* alternate ZHEX */
+#define ZVBIN32 'c' /* alternate ZBIN32 */
+#define ZVBINR32 'd' /* alternate ZBINR32 */
+#define ZRESC 0177 /* RLE flag/escape character */
+
+
+
+/* ZModem header type codes */
+
+#define ZRQINIT 0 /* request receive init */
+#define ZRINIT 1 /* receive init */
+#define ZSINIT 2 /* send init sequence, define Attn */
+#define ZACK 3 /* ACK */
+#define ZFILE 4 /* file name, from sender */
+#define ZSKIP 5 /* skip file command, from receiver */
+#define ZNAK 6 /* last packet was garbled */
+#define ZABORT 7 /* abort */
+#define ZFIN 8 /* finish session */
+#define ZRPOS 9 /* resume file from this position, from receiver */
+#define ZDATA 10 /* data packets to follow, from sender */
+#define ZEOF 11 /* end of file, from sender */
+#define ZFERR 12 /* fatal i/o error, from receiver */
+#define ZCRC 13 /* request for file crc, from receiver */
+#define ZCHALLENGE 14 /* "send this number back to me", from receiver */
+#define ZCOMPL 15 /* request is complete */
+#define ZCAN 16 /* other end cancelled with CAN-CAN-CAN-CAN-CAN */
+#define ZFREECNT 17 /* request for free bytes on filesystem */
+#define ZCOMMAND 18 /* command, from sending program */
+#define ZSTDERR 19 /* output this message to stderr */
+
+
+/* ZDLE escape sequences */
+
+
+#define ZCRCE 'h' /* CRC next, frame ends, header follows */
+#define ZCRCG 'i' /* CRC next, frame continues nonstop */
+#define ZCRCQ 'j' /* CRC next, send ZACK, frame continues nonstop */
+#define ZCRCW 'k' /* CRC next, send ZACK, frame ends */
+#define ZRUB0 'l' /* translate to 0177 */
+#define ZRUB1 'm' /* translate to 0377 */
+
+
+/* ascii definitions */
+
+#define SOH 1 /* ^A */
+#define STX 2 /* ^B */
+#define EOT 4 /* ^D */
+#define ACK 6 /* ^F */
+#define DLE 16 /* ^P */
+#define XON 17 /* ^Q */
+#define XOFF 19 /* ^S */
+#define NAK 21 /* ^U */
+#define SYN 22 /* ^V */
+#define CAN 24 /* ^X */
+
+
+/* state table entry. There is one row of the table per
+ * possible state. Each row is a row of all reasonable
+ * inputs for this state. The entries are sorted so that
+ * the most common inputs occur first, to reduce search time
+ * Unexpected input is reported and ignored, as it might be
+ * caused by echo or something.
+ *
+ * Extra ZRINIT headers are the receiver trying to resync.
+ */
+class FQTermConfig;
+
+class FQTermZmodem;
+
+class FQTermTelnet;
+
+class FQTermFileDialog;
+
+typedef int(FQTermZmodem:: *ActionFunc)(ZModem*);
+
+typedef struct {
+ int type; /* frame type */
+ // int (*func)(ZModem *) ; /* transition function */
+ ActionFunc func;
+ int IFlush; /* flag: flush input first */
+ int OFlush; /* flag: flush output first */
+ ZMState newstate; /* new state. May be overridden by func */
+} StateTable;
+
+//class FQTermTelnet;
+
+class FQTermZmodem: public QObject {
+ Q_OBJECT;
+ public:
+ FQTermZmodem(FQTermConfig *config, FQTermTelnet *netinterface, int type, int serverEncoding);
+ ~FQTermZmodem();
+
+ /* zmodem-supplied functions: */
+ int ZmodemTInit(ZModem *info);
+ int ZmodemTFile(char *file, char *rmtname, uint f0, uint f1, uint f2, uint f3,
+ int filesRem, int bytesRem, ZModem *info);
+ int ZmodemTFinish(ZModem *info);
+ int ZmodemAbort(ZModem *info);
+ int ZmodemRInit(ZModem *info);
+ int ZmodemRcv(uchar *str, int len, ZModem *info, int &consumed_bytes);
+ int ZmodemAttention(ZModem *info);
+
+ int ZmodemReset(ZModem *info);
+
+ int YmodemTInit(ZModem *info);
+ int XmodemTInit(ZModem *info);
+ int YmodemRInit(ZModem *info);
+ int XmodemRInit(ZModem *info);
+
+ ulong FileCrc(char *name);
+ const char *sname(ZModem*);
+ const char *sname2(ZMState);
+
+ /* caller-supplied functions: */
+ int ZXmitChr(uchar c, ZModem *info);
+ int ZXmitStr(const uchar *str, int len, ZModem *info);
+ void ZIFlush(ZModem *info);
+ void ZOFlush(ZModem *info);
+ int ZAttn(ZModem *info);
+ void ZStatus(int type, int value, const char *status);
+ FILE *ZOpenFile(char *name, ulong crc, ZModem *info);
+
+ int ZWriteFile(uchar *buffer, int len, FILE *, ZModem*);
+ int ZCloseFile(ZModem *info);
+ void ZFlowControl(int onoff, ZModem *info);
+
+ /* end caller-supplied functions */
+
+ int ZXmitHdr(int type, int format, const uchar data[4], ZModem *info);
+ int ZXmitHdrHex(int type, const uchar data[4], ZModem *info);
+ int ZXmitHdrBin(int type, const uchar data[4], ZModem *info);
+ int ZXmitHdrBin32(int type, const uchar data[4], ZModem *info);
+ uchar *putZdle(uchar *ptr, uchar c, ZModem *info);
+ uchar *putHex(uchar *ptr, uchar c);
+
+ uchar *ZEnc4(ulong n);
+ ulong ZDec4(const uchar buf[4]);
+
+ int YrcvChar(char c, register ZModem *info);
+ int YrcvTimeout(register ZModem *info);
+ void ZIdleStr(uchar *buffer, int len, ZModem *info);
+
+ /* LEXICAL BOX: handle characters received from remote end.
+ * These may be header, data or noise.
+ *
+ * This section is a finite state machine for parsing headers
+ * and reading input data. The info->chrCount field is effectively
+ * the state variable.
+ */
+
+ int FinishChar(char c, register ZModem *info);
+ int DataChar(uchar c, register ZModem *info);
+ int HdrChar(uchar c, register ZModem *info);
+ int IdleChar(uchar c, register ZModem *info);
+
+ int YsendChar(char c, ZModem *info);
+
+ int ZPF(ZModem *info);
+ int Ignore(ZModem *info);
+ int AnswerChallenge(register ZModem *info);
+ int GotAbort(register ZModem *info);
+ int GotCancel(ZModem *info);
+ int GotCommand(ZModem *info);
+ int GotStderr(register ZModem *info);
+ int RetDone(ZModem *info);
+ int GotCommandData(register ZModem *info, int crcGood);
+ int GotStderrData(register ZModem *info, int crcGood);
+
+ int GotFileName(ZModem *info, int crcGood);
+ int ResendCrcReq(ZModem *info);
+ int GotSinitData(ZModem *info, int crcGood);
+ int ResendRpos(ZModem *info);
+ int GotFileData(ZModem *info, int crcGood);
+ int SendRinit(ZModem *info);
+
+ int GotSinit(ZModem *info);
+ int GotFile(ZModem *info);
+ int GotFin(ZModem *info);
+ int GotData(ZModem *info);
+ int GotEof(ZModem *info);
+ int GotFreecnt(ZModem *info);
+ int GotFileCrc(ZModem *info);
+
+ int GotRinit(ZModem*);
+ int SendZSInit(ZModem*);
+ int SendFileCrc(ZModem*);
+ int GotSendAck(ZModem*);
+ int GotSendDoneAck(ZModem*);
+ int GotSendNak(ZModem*);
+ int GotSendWaitAck(ZModem*);
+ int SkipFile(ZModem*);
+ int GotSendPos(ZModem*);
+
+ int requestFile(ZModem *info, ulong crc);
+ void parseFileName(ZModem *info, char *fileinfo);
+ int fileError(ZModem *info, int type, int data);
+
+ int ProcessPacket(ZModem *info);
+ int rejectPacket(ZModem *info);
+ int acceptPacket(ZModem *info);
+
+ int calcCrc(uchar *str, int len);
+
+ char *strdup(const char *str);
+
+ int SendMoreFileData(ZModem *info);
+
+ uint rcvHex(uint i, char c);
+
+ int ZDataReceived(register ZModem *info, int crcGood);
+ int dataSetup(register ZModem *info);
+ int ZProtocol(register ZModem *info);
+
+ int ZXmitData(int, int, uchar, uchar *data, ZModem*);
+ int YXmitData(uchar *, int, ZModem*);
+
+ int YSendFilename(ZModem*);
+ int YSendData(ZModem*);
+ int YSendFin(ZModem*);
+
+ int sendFilename(ZModem*);
+ int SendFileData(ZModem*);
+ int ResendEof(ZModem*);
+
+ int OverAndOut(ZModem*);
+
+ int startFileData(ZModem *info);
+
+ void zmodemlog(const char *fmt, ...);
+
+ // interface function
+ // all not completed
+ void transferTimeOut(void*);
+ void upload(char*);
+ void uploadNext(char*);
+ void transferFinish();
+ void xferCancel();
+
+ /* data received from remote, pass it to Zmodem funcs */
+ void transferSendData(char *, int);
+ void TransferCancel();
+
+#if 1
+ static StateTable RStartOps[];
+ static StateTable RSinitWaitOps[];
+ static StateTable RFileNameOps[];
+ static StateTable RCrcOps[];
+ static StateTable RFileOps[];
+ static StateTable RDataOps[];
+ static StateTable RFinishOps[];
+
+
+ static StateTable TStartOps[];
+ static StateTable TInitOps[];
+ static StateTable FileWaitOps[];
+ static StateTable CrcWaitOps[];
+ static StateTable SendingOps[];
+ static StateTable SendDoneOps[];
+ static StateTable SendWaitOps[];
+ static StateTable SendEofOps[];
+ static StateTable TFinishOps[];
+
+ static StateTable CommandDataOps[];
+ static StateTable CommandWaitOps[];
+ static StateTable StderrDataOps[];
+ static StateTable DoneOps[];
+
+ static StateTable *tables[];
+ static const char *hdrnames[];
+#endif
+
+#if 0
+ StateTable RStartOps[];
+ StateTable RSinitWaitOps[];
+ StateTable RFileNameOps[];
+ StateTable RCrcOps[];
+ StateTable RFileOps[];
+ StateTable RDataOps[];
+ StateTable RFinishOps[];
+
+
+ StateTable TStartOps[];
+ StateTable TInitOps[];
+ StateTable FileWaitOps[];
+ StateTable CrcWaitOps[];
+ StateTable SendingOps[];
+ StateTable SendDoneOps[];
+ StateTable SendWaitOps[];
+ StateTable SendEofOps[];
+ StateTable TFinishOps[];
+
+ StateTable CommandDataOps[];
+ StateTable CommandWaitOps[];
+ StateTable StderrDataOps[];
+ StateTable DoneOps[];
+
+ StateTable *tables[];
+ char *hdrnames[];
+#endif
+ FQTermTelnet *telnet_;
+ FQTermConfig *config_;
+ // Dialog
+ // QDialog *zmodemDialog, uploadListDialog;
+
+ bool sending;
+
+ enum_transferstate transferstate;
+
+ ZModem info;
+
+ // connection type, e.g. telnet or ssh , 0=telnet, 1=ssh
+
+ int connectionType;
+
+ // Timer
+ QTimer *zmodemTimer;
+
+ //log file
+ FILE *zmodemlogfile;
+
+ int zerrno;
+ uchar lastPullByte;
+
+ QStringList strFileList;
+ QStringList::Iterator itFile;
+
+ int serverEncodingID;
+
+ QString lastDownloadedFilename_;
+
+ // end Member
+ signals:
+ void ZmodemState(int, int, const char *);
+
+ public slots:
+ void zmodemCancel();
+ int ZmodemTimeout();
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_ZMODEM_H
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
new file mode 100644
index 0000000..09af483
--- /dev/null
+++ b/src/ui/CMakeLists.txt
@@ -0,0 +1,122 @@
+set(fqterm_ui_SRCS
+ aboutdialog.h
+ addrdialog.h
+ articledialog.h
+ keydialog.h
+ msgdialog.h
+ prefdialog.h
+ quickdialog.h
+ schemadialog.h
+ soundconf.h
+ sshlogindialog.h
+ zmodemdialog.h
+ aboutdialog.cpp
+ addrdialog.cpp
+ articledialog.cpp
+ keydialog.cpp
+ msgdialog.cpp
+ prefdialog.cpp
+ quickdialog.cpp
+ schemadialog.cpp
+ soundconf.cpp
+ sshlogindialog.cpp
+ zmodemdialog.cpp
+ osdmessage.h
+ osdmessage.cpp
+ overlayWidget.h
+ overlayWidget.cpp
+ pictureflow.h
+ pictureflow.cpp
+ popupMessage.h
+ popupMessage.cpp
+ popwidget.h
+ popwidget.cpp
+ progressBar.h
+ progressBar.cpp
+ fqterm_time_label.h
+ fqterm_time_label.cpp
+ fqterm_tool_button.h
+ fqterm_tool_button.cpp
+ imageviewer.h
+ imageviewer.cpp
+ shortcutdialog.h
+ shortcutdialog.cpp
+ statusBar.h
+ statusBar.cpp
+ fqterm_canvas.h
+ fqterm_canvas.cpp
+ sitemanager.h
+ sitemanager.cpp
+ iplookup.h
+ iplookup.cpp
+ defineescape.h
+ defineescape.cpp
+)
+
+set(fqterm_ui_gen_HS
+ ui_aboutdialog.h
+ ui_addrdialog.h
+ ui_articledialog.h
+ ui_keydialog.h
+ ui_msgdialog.h
+ ui_prefdialog.h
+ ui_quickdialog.h
+ ui_schemadialog.h
+ ui_sitemanager.h
+ ui_soundconf.h
+ ui_sshlogin.h
+ ui_zmodemdialog.h
+ ui_iplookup.h
+ ui_defineescape.h
+)
+
+set(fqterm_ui_UIS
+ aboutdialog.ui
+ addrdialog.ui
+ articledialog.ui
+ keydialog.ui
+ msgdialog.ui
+ prefdialog.ui
+ quickdialog.ui
+ schemadialog.ui
+ sitemanager.ui
+ soundconf.ui
+ sshlogin.ui
+ zmodemdialog.ui
+ iplookup.ui
+ defineescape.ui
+)
+
+qt4_wrap_ui(fqterm_ui_UIS_H
+ ${fqterm_ui_UIS}
+)
+
+qt4_automoc(
+ ${fqterm_ui_SRCS}
+ ${fqterm_ui_gen_HS}
+)
+
+qt4_create_translation(fqterm_ui_qm_file
+ ${fqterm_ui_UIS}
+ ${fqterm_ui_SRCS}
+ ${CMAKE_SOURCE_DIR}/res/dict/ui_zh_CN.ts
+)
+
+include_directories(
+ ${QT_INCLUDE_DIR}
+ ${QT_QTCORE_INCLUDE_DIR}
+ ${QT_QTGUI_INCLUDE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../common
+ ${CMAKE_CURRENT_SOURCE_DIR}/../utilities
+ ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+add_library(fqterm_ui
+ ${fqterm_ui_SRCS}
+ ${fqterm_ui_gen_HS}
+)
+
+add_dependencies(fqterm_ui
+ fqterm_common
+ fqterm_utilities
+)
diff --git a/src/ui/aboutdialog.cpp b/src/ui/aboutdialog.cpp
new file mode 100644
index 0000000..5c56dcc
--- /dev/null
+++ b/src/ui/aboutdialog.cpp
@@ -0,0 +1,71 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QPixmap>
+#include <QFile>
+#include <QTextBrowser>
+#include <QTextStream>
+#include <QtGlobal>
+
+#include "fqterm.h"
+#include "fqterm_path.h"
+#include "aboutdialog.h"
+
+namespace FQTerm {
+
+/*
+ * Constructs a aboutDialog which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'.
+ *
+ * The dialog will by default be modeless, unless you set 'modal' to
+ * TRUE to construct a modal dialog.
+ */
+aboutDialog::aboutDialog(QWidget *parent, Qt::WFlags fl)
+ : QDialog(parent, fl) {
+ ui_.setupUi(this);
+
+ QFile file(getPath(RESOURCE) + "credits");
+ if (file.open(QIODevice::ReadOnly)) {
+ QTextStream stream(&file);
+ QString line;
+ while (!stream.atEnd()) {
+ // line of text excluding '\n'
+ line += stream.readLine() + "\n";
+ }
+ ui_.TextBrowser->setPlainText(line);
+ file.close();
+ }
+ QString aboutText = "FQTerm " + QString(FQTERM_VERSION_STRING) + QString("\nSVN revision ") + QString(FQTERM_SVN_REVISION) + QString("\n Built with Qt") + QT_VERSION_STR + QString("\n Running with Qt ") + qVersion();
+ if (QString(FQTERM_VERSION_STRING).startsWith("0.9.8")) {
+ aboutText += "\n>>2012 - End of the world edition<<";
+ }
+ ui_.TextLabel->setText(aboutText);
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+aboutDialog::~aboutDialog() {
+ // no need to delete child widgets, Qt does it all for us
+}
+
+} // namespace FQTerm
+
+#include "aboutdialog.moc"
diff --git a/src/ui/aboutdialog.h b/src/ui/aboutdialog.h
new file mode 100644
index 0000000..cf40c4b
--- /dev/null
+++ b/src/ui/aboutdialog.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_ABOUT_DIALOG_H
+#define FQTERM_ABOUT_DIALOG_H
+
+#include "ui_aboutdialog.h"
+
+namespace FQTerm {
+
+class aboutDialog: public QDialog {
+ Q_OBJECT;
+ public:
+ aboutDialog(QWidget *parent = 0, Qt::WFlags fl = 0);
+ ~aboutDialog();
+ private:
+ Ui::aboutDialog ui_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_ABOUT_DIALOG_H
diff --git a/src/ui/aboutdialog.ui b/src/ui/aboutdialog.ui
new file mode 100644
index 0000000..5770cd8
--- /dev/null
+++ b/src/ui/aboutdialog.ui
@@ -0,0 +1,175 @@
+<ui version="4.0" >
+ <class>aboutDialog</class>
+ <widget class="QDialog" name="aboutDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>290</height>
+ </rect>
+ </property>
+ <property name="mouseTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="windowTitle" >
+ <string>About FQTerm</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="pixmapLabel" >
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="scaledContents" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLabel" name="TextLabel" >
+ <property name="frameShape" >
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="text" >
+ <string>FQTerm</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="3" >
+ <widget class="QTabWidget" name="mainTabWidget" >
+ <property name="currentIndex" >
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab1" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>376</width>
+ <height>194</height>
+ </rect>
+ </property>
+ <attribute name="title" >
+ <string>About</string>
+ </attribute>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;style type="text/css">
+p, li { white-space: pre-wrap; }
+&lt;/style>&lt;/head>&lt;body>
+&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">&lt;br />FQTerm&lt;br />&lt;br />&lt;br />&lt;a href="http://code.google.com/p/fqterm">&lt;span style=" text-decoration: underline; color:#0000ff;">http://code.google.com/p/fqterm&lt;/span>&lt;/a>&lt;/p>&lt;/body>&lt;/html></string>
+ </property>
+ <property name="textFormat" >
+ <enum>Qt::RichText</enum>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ <property name="openExternalLinks" >
+ <bool>true</bool>
+ </property>
+ <property name="textInteractionFlags" >
+ <set>Qt::TextBrowserInteraction</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab2" >
+ <property name="geometry" >
+ <rect>
+ <x>77</x>
+ <y>97</y>
+ <width>944</width>
+ <height>522</height>
+ </rect>
+ </property>
+ <attribute name="title" >
+ <string>Authors</string>
+ </attribute>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="TextLabel1" >
+ <property name="text" >
+ <string>fqterm@gmail.com
+
+devilphoenix@newsmth</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab3" >
+ <property name="geometry" >
+ <rect>
+ <x>100</x>
+ <y>120</y>
+ <width>944</width>
+ <height>522</height>
+ </rect>
+ </property>
+ <attribute name="title" >
+ <string>Credits</string>
+ </attribute>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QTextBrowser" name="TextBrowser" >
+ <property name="html" >
+ <string>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;style type="text/css">
+p, li { white-space: pre-wrap; }
+&lt;/style>&lt;/head>&lt;body style=" font-family:'SimSun'; font-size:9pt; font-weight:400; font-style:normal;">
+&lt;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;">&lt;/p>&lt;/body>&lt;/html></string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item row="2" column="2" >
+ <widget class="QPushButton" name="closeButton" >
+ <property name="text" >
+ <string>Close</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <tabstops>
+ <tabstop>closeButton</tabstop>
+ <tabstop>mainTabWidget</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>closeButton</sender>
+ <signal>clicked()</signal>
+ <receiver>aboutDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>339</x>
+ <y>261</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>211</x>
+ <y>249</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/ui/addrdialog.cpp b/src/ui/addrdialog.cpp
new file mode 100644
index 0000000..79e62a8
--- /dev/null
+++ b/src/ui/addrdialog.cpp
@@ -0,0 +1,396 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QPixmap>
+#include <QMessageBox>
+#include <QColorDialog>
+#include <QFontDialog>
+#include <QPainter>
+#include <QFileDialog>
+#include <QPalette>
+#include <QMenu>
+
+#include "fqterm_config.h"
+#include "fqterm_param.h"
+#include "fqterm_path.h"
+#include "fqterm_trace.h"
+
+#include "addrdialog.h"
+#include "schemadialog.h"
+
+namespace FQTerm {
+
+const int addrDialog::ports[3] = {23, 22, 22};
+
+/*
+ * Constructs a addrDialog which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'.
+ *
+ * The dialog will by default be modeless, unless you set 'modal' to
+ * TRUE to construct a modal dialog.
+ */
+addrDialog::addrDialog(QWidget *parent_, const FQTermParam& parameter, int buttons, Qt::WFlags fl)
+ : QDialog(parent_, fl),
+ menuButtonGroup_(this),
+ param_(parameter) {
+ ui_.setupUi(this);
+ menuButtonGroup_.addButton(ui_.radioButton1, 0);
+ menuButtonGroup_.addButton(ui_.radioButton2, 1);
+ menuButtonGroup_.addButton(ui_.radioButton3, 2);
+ if (!(buttons & SAVE))
+ ui_.savePushButton->setVisible(false);
+ if (!(buttons & APPLY))
+ ui_.applyPushButton->setVisible(false);
+ QMenu *fontMenu = new QMenu(this);
+ for (int i = 0; i < 2; ++i) {
+ QAction *act = fontMenu->addAction(FQTermParam::getLanguageName(bool(i)) + " Font", this, SLOT(onFont()));
+ act->setData(i);
+ }
+ ui_.fontToolButton->setMenu(fontMenu);
+ setUIFromParam();
+ connector();
+}
+
+void addrDialog::setParamFromUI() {
+ param_.name_ = ui_.nameLineEdit->text();
+ param_.hostAddress_ = ui_.addrLineEdit->text();
+ param_.port_ = ui_.portLineEdit->text().toUShort();
+ param_.hostType_ = ui_.hostTypeComboBox->currentIndex();
+ param_.preLoginCommand_ = ui_.preloginLineEdit->text();
+ param_.userName_ = ui_.userLineEdit->text();
+ param_.password_ = ui_.passwdLineEdit->text();
+ param_.postLoginCommand_ = ui_.postloginLineEdit->text();
+ param_.serverEncodingID_ = ui_.bbscodeComboBox->currentIndex();
+ param_.isFontAutoFit_ = ui_.fontAdjustComboBox->currentIndex();
+ param_.isAlwaysHighlight_ = ui_.highlightCheckBox->isChecked();
+ param_.isAnsiColor_ = ui_.ansicolorCheckBox->isChecked();
+ param_.backgroundColor_ = ui_.fontPreviewer->palette().color(QPalette::Background);
+ param_.foregroundColor_ = ui_.fontPreviewer->palette().color(QPalette::Foreground);
+ param_.schemaFileName_ = ui_.schemaComboBox->currentText().isEmpty() || ui_.schemaComboBox->currentIndex() >= schemaDialog::getSchemaList().count()
+ ? "" : schemaDialog::getSchemaList()[ui_.schemaComboBox->currentIndex()].absoluteFilePath();
+ param_.virtualTermType_ = ui_.termtypeLineEdit->text();
+ param_.keyboardType_ = ui_.keytypeComboBox->currentIndex();
+ param_.backspaceType_ = ui_.backspace8->isChecked()?0:1;
+ param_.numColumns_ = ui_.columnLineEdit->text().toInt();
+ param_.numRows_ = ui_.rowLineEdit->text().toInt();
+ param_.numScrollLines_ = ui_.scrollLineEdit->text().toInt();
+ param_.cursorType_ = ui_.cursorTypeComboBox->currentIndex();
+ param_.escapeString_ = ui_.escapeLineEdit->text();
+ param_.proxyType_ = ui_.proxytypeComboBox->currentIndex();
+ param_.proxyHostName_ = ui_.proxyaddrLineEdit->text();
+ param_.proxyPort_ = ui_.proxyportLineEdit->text().toUShort();
+ param_.isAuthentation_ = ui_.authentationGroup->isChecked();
+ param_.proxyUserName_ = ui_.proxyuserLineEdit->text();
+ param_.proxyPassword_ = ui_.proxypasswdLineEdit->text();
+ param_.protocolType_ = ui_.protocolComboBox->currentIndex();
+ if (param_.port_ != ports[param_.protocolType_]) {
+ ui_.portCheckBox->setChecked(true);
+ }
+ switch(param_.protocolType_)
+ {
+ case 0:
+ param_.isAutoLogin_ = ui_.telnetAutoLoginGroup->isChecked();
+ break;
+ case 1:
+ case 2:
+ param_.isAutoLogin_ = ui_.sshAutoLoginGroup->isChecked();
+ case 100:
+ break;
+ }
+ param_.sshUserName_ = ui_.sshuserLineEdit->text();
+ param_.sshPassword_ = ui_.sshpasswdLineEdit->text();
+ param_.maxIdleSeconds_ = ui_.idletimeLineEdit->text().toInt();
+ param_.replyKeyCombination_ = ui_.replykeyLineEdit->text();
+ if (param_.replyKeyCombination_.isNull()) {
+ FQ_TRACE("addrdialog", 0) << "Key combination for reply is NULL.";
+ }
+ param_.antiIdleMessage_ = ui_.antiLineEdit->text();
+ param_.isAntiIdle_ = ui_.antiIdleGroupBox->isChecked();
+ param_.isAutoReply_ = ui_.replyCheckBox->isChecked();
+ param_.autoReplyMessage_ = ui_.replyLineEdit->text();
+ param_.isAutoReconnect_ = ui_.reconnectCheckBox->isChecked();
+ param_.reconnectInterval_ = ui_.reconnectLineEdit->text().toInt();
+ param_.retryTimes_ = ui_.retryLineEdit->text().toInt();
+ param_.isAutoCloseWin_ = ui_.autoCloseWinCheckBox->isChecked();
+ param_.isAutoLoadScript_ = ui_.scriptCheckBox->isChecked();
+ param_.enableZmodem_ = ui_.zmodemCheck->isChecked();
+ param_.isBeep_ = ui_.beepCheck->isChecked();
+ param_.isBuzz_ = ui_.buzzCheck->isChecked();
+ param_.isSupportMouse_ = ui_.mouseCheck->isChecked();
+ param_.autoLoadedScriptFileName_ = ui_.scriptLineEdit->text();
+ param_.menuType_ = menuButtonGroup_.checkedId();
+ param_.menuColor_ = ui_.menuLabel->palette().color(QPalette::Background);
+ param_.alignMode_ = ui_.alignComboBox->currentIndex();
+ param_.charSpacing_ = ui_.charSpacingSpinBox->value();
+ param_.lineSpacing_ = ui_.lineSpacingSpinBox->value();
+}
+
+void addrDialog::setUIFromParam() {
+
+ updateSchemaList(param_.schemaFileName_);
+ QString strTmp;
+ ui_.nameLineEdit->setText(param_.name_);
+ ui_.addrLineEdit->setText(param_.hostAddress_);
+ ui_.hostTypeComboBox->setCurrentIndex(param_.hostType_);
+// ui_.autoLoginCheckBox->setChecked(param_.isAutoLogin_);
+ ui_.preloginLineEdit->setText(param_.preLoginCommand_);
+ ui_.userLineEdit->setText(param_.userName_);
+ ui_.passwdLineEdit->setText(param_.password_);
+ ui_.postloginLineEdit->setText(param_.postLoginCommand_);
+ ui_.bbscodeComboBox->setCurrentIndex(param_.serverEncodingID_);
+ ui_.fontAdjustComboBox->setCurrentIndex(param_.isFontAutoFit_);
+ ui_.highlightCheckBox->setChecked(param_.isAlwaysHighlight_);
+ ui_.ansicolorCheckBox->setChecked(param_.isAnsiColor_);
+ ui_.termtypeLineEdit->setText(param_.virtualTermType_);
+ ui_.keytypeComboBox->setCurrentIndex(param_.keyboardType_);
+ ui_.backspace8->setChecked(param_.backspaceType_ == 0);
+ ui_.backspace127->setChecked(param_.backspaceType_ == 1);
+ strTmp.setNum(param_.numColumns_);
+ ui_.columnLineEdit->setText(strTmp);
+ strTmp.setNum(param_.numRows_);
+ ui_.rowLineEdit->setText(strTmp);
+ strTmp.setNum(param_.numScrollLines_);
+ ui_.scrollLineEdit->setText(strTmp);
+ ui_.cursorTypeComboBox->setCurrentIndex(param_.cursorType_);
+ ui_.escapeLineEdit->setText(param_.escapeString_);
+ ui_.proxytypeComboBox->setCurrentIndex(param_.proxyType_);
+ ui_.proxyaddrLineEdit->setText(param_.proxyHostName_);
+ strTmp.setNum(param_.proxyPort_);
+ ui_.proxyportLineEdit->setText(strTmp);
+ ui_.authentationGroup->setChecked(param_.isAuthentation_);
+ ui_.proxyuserLineEdit->setText(param_.proxyUserName_);
+ ui_.proxypasswdLineEdit->setText(param_.proxyPassword_);
+ ui_.protocolComboBox->setCurrentIndex(param_.protocolType_);
+ onProtocol(param_.protocolType_);
+ strTmp.setNum(param_.port_);
+ ui_.portLineEdit->setText(strTmp);
+ ui_.portCheckBox->setChecked(param_.port_ != ports[param_.protocolType_]);
+ ui_.sshuserLineEdit->setText(param_.sshUserName_);
+ ui_.sshpasswdLineEdit->setText(param_.sshPassword_);
+ strTmp.setNum(param_.maxIdleSeconds_);
+ ui_.idletimeLineEdit->setText(strTmp);
+ ui_.replykeyLineEdit->setText(param_.replyKeyCombination_);
+ ui_.antiLineEdit->setText(param_.antiIdleMessage_);
+ ui_.antiIdleGroupBox->setChecked(param_.isAntiIdle_);
+ ui_.replyCheckBox->setChecked(param_.isAutoReply_);
+ ui_.replyLineEdit->setEnabled(param_.isAutoReply_);
+ ui_.replyLineEdit->setText(param_.autoReplyMessage_);
+ ui_.reconnectCheckBox->setChecked(param_.isAutoReconnect_);
+ ui_.reconnectLineEdit->setEnabled(param_.isAutoReconnect_);
+ ui_.retryLineEdit->setEnabled(param_.isAutoReconnect_);
+ ui_.alignComboBox->setCurrentIndex(param_.alignMode_);
+ ui_.charSpacingSpinBox->setValue(param_.charSpacing_);
+ ui_.lineSpacingSpinBox->setValue(param_.lineSpacing_);
+ strTmp.setNum(param_.reconnectInterval_);
+ ui_.reconnectLineEdit->setText(strTmp);
+ strTmp.setNum(param_.retryTimes_);
+ ui_.retryLineEdit->setText(strTmp);
+ ui_.autoCloseWinCheckBox->setChecked(param_.isAutoCloseWin_);
+ ui_.scriptCheckBox->setChecked(param_.isAutoLoadScript_);
+ ui_.scriptLineEdit->setText(param_.autoLoadedScriptFileName_);
+ ui_.zmodemCheck->setChecked(param_.enableZmodem_);
+ ui_.beepCheck->setChecked(param_.isBeep_);
+ ui_.buzzCheck->setChecked(param_.isBuzz_);
+ ui_.mouseCheck->setChecked(param_.isSupportMouse_);
+ //ui.menuGroup->setButton(param_.m_nMenuType);
+ QRadioButton *rbMenu = qobject_cast < QRadioButton * > (menuButtonGroup_.button
+ (param_.menuType_));
+ rbMenu->setChecked(true);
+ previewFont();
+ previewMenu();
+}
+
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+addrDialog::~addrDialog() {
+}
+
+
+void addrDialog::onOK() {
+ setParamFromUI();
+ done(1);
+}
+
+void addrDialog::onSave() {
+ setParamFromUI();
+ done(2);
+}
+void addrDialog::onCancel() {
+ done(0);
+}
+
+
+
+void addrDialog::onFgcolor() {
+ QColor color = QColorDialog::getColor(param_.foregroundColor_);
+ if (color.isValid() == TRUE) {
+ param_.foregroundColor_ = color;
+ previewFont();
+ }
+}
+
+void addrDialog::onBgcolor() {
+ QColor color = QColorDialog::getColor(param_.backgroundColor_);
+ if (color.isValid() == TRUE) {
+ param_.backgroundColor_ = color;
+ previewFont();
+ }
+}
+
+
+
+void addrDialog::onProtocol(int n) {
+ ui_.portCheckBox->setChecked(false);
+ ui_.portLineEdit->setText(QString("%1").arg(ports[n]));
+ switch(n)
+ {
+ case 0: //telnet
+ ui_.telnetAutoLoginGroup->setEnabled(true);
+ ui_.telnetAutoLoginGroup->setChecked(param_.isAutoLogin_);
+ ui_.sshAutoLoginGroup->setEnabled(false);
+ ui_.sshAutoLoginGroup->setChecked(false);
+ break;
+ case 1:
+#if defined(_NO_SSH_COMPILED)
+ QMessageBox::warning(this, "sorry",
+ "SSH support is not compiled, check your OpenSSL and try to recompile FQTerm");
+ ui_.protocolComboBox->setCurrentItem(0);
+#else
+ ui_.telnetAutoLoginGroup->setEnabled(false);
+ ui_.telnetAutoLoginGroup->setChecked(false);
+ ui_.sshAutoLoginGroup->setEnabled(true);
+ ui_.sshAutoLoginGroup->setChecked(param_.isAutoLogin_);
+#endif
+ break;
+ case 2:
+#if defined(_NO_SSH_COMPILED)
+ QMessageBox::warning(this, "sorry",
+ "SSH support is not compiled, check your OpenSSL and try to recompile FQTerm");
+ ui_.protocolComboBox->setCurrentItem(0);
+#else
+ ui_.telnetAutoLoginGroup->setEnabled(false);
+ ui_.telnetAutoLoginGroup->setChecked(false);
+ ui_.sshAutoLoginGroup->setEnabled(true);
+ ui_.sshAutoLoginGroup->setChecked(param_.isAutoLogin_);
+#endif
+ break;
+ }
+}
+
+void addrDialog::onChooseScript() {
+ QString path = getPath(RESOURCE) + "script";
+
+ QString strFile = QFileDialog::getOpenFileName(this, "choose a script file",
+ path, "JavaScript/Python File (*.js *.py)");
+
+ if (strFile.isNull()) {
+ return ;
+ }
+
+ ui_.scriptLineEdit->setText(strFile);
+}
+
+void addrDialog::onMenuColor() {
+ QColor color = QColorDialog::getColor(param_.menuColor_);
+ if (color.isValid() == TRUE) {
+ param_.menuColor_ = color;
+ previewMenu();
+ }
+}
+
+void addrDialog::previewFont() {
+ //issue 98 preview both en and zh
+
+ QPalette palette;
+ palette.setColor(QPalette::Window, param_.backgroundColor_);
+ palette.setColor(QPalette::WindowText, param_.foregroundColor_);
+ ui_.fontPreviewer->setPalette(palette);
+ QString sample("<html><body style=\" font-family:'" + param_.englishFontName_
+ + "'; font-size:" + QString().setNum(param_.englishFontSize_)
+ + "pt;\"><BR>AaBbCc</body></html>");
+ sample += QString("<html><body style=\" font-family:'"
+ + param_.otherFontName_ + "'; font-size:"
+ + QString().setNum(param_.otherFontSize_) + "pt;\">"
+ + param_.otherFontName_ + "<BR></body></html>");
+ ui_.fontPreviewer->setText(sample);
+}
+
+
+void addrDialog::connector() {
+ FQ_VERIFY(connect(ui_.applyPushButton, SIGNAL(clicked()), this, SLOT(onOK())));
+ FQ_VERIFY(connect(ui_.savePushButton, SIGNAL(clicked()), this, SLOT(onSave())));
+ FQ_VERIFY(connect(ui_.closePushButton, SIGNAL(clicked()), this, SLOT(onCancel())));
+
+
+ FQ_VERIFY(connect(ui_.fgcolorPushButton, SIGNAL(clicked()), this, SLOT(onFgcolor())));
+ FQ_VERIFY(connect(ui_.bgcolorPushButton, SIGNAL(clicked()), this, SLOT(onBgcolor())));
+
+ FQ_VERIFY(connect(ui_.protocolComboBox, SIGNAL(activated(int)), this, SLOT(onProtocol(int))));
+
+ FQ_VERIFY(connect(ui_.scriptPushButton, SIGNAL(clicked()), this, SLOT(onChooseScript())));
+
+ FQ_VERIFY(connect(ui_.menuColorButton, SIGNAL(clicked()), this, SLOT(onMenuColor())));
+}
+
+void addrDialog::previewMenu() {
+ QPalette palette;
+ palette.setColor(QPalette::Window, param_.menuColor_);
+ ui_.menuLabel->setPalette(palette);
+}
+
+void addrDialog::onFont() {
+ bool isEnglish = ((QAction*)(sender()))->data().toBool();
+ bool ok;
+ QString& fontName = isEnglish?param_.englishFontName_:param_.otherFontName_;
+ int& fontSize = isEnglish?param_.englishFontSize_:param_.otherFontSize_;
+ QFont now(fontName, fontSize);
+
+ QFont font = QFontDialog::getFont(&ok, now, this, tr("Font Selector")
+#ifdef __APPLE__
+ , QFontDialog::DontUseNativeDialog
+#endif
+ );
+ if (ok == true) {
+ fontName = font.family();
+ fontSize = font.pointSize();
+ previewFont();
+ }
+}
+
+void addrDialog::updateSchemaList(const QString& currentSchema) {
+ ui_.schemaComboBox->clear();
+ QFileInfoList lstFile = schemaDialog::getSchemaList();
+ foreach(QFileInfo fi, lstFile) {
+ FQTermConfig *pConf = new FQTermConfig(fi.absoluteFilePath());
+ ui_.schemaComboBox->addItem(pConf->getItemValue("schema", "title"));
+ delete pConf;
+ }
+ ui_.schemaComboBox->addItem("");
+ int schemaIdx = lstFile.indexOf(currentSchema);
+ if (schemaIdx < 0)
+ schemaIdx = ui_.schemaComboBox->count() - 1;
+ ui_.schemaComboBox->setCurrentIndex(schemaIdx);
+}
+
+} // namespace FQTerm
+
+#include "addrdialog.moc"
diff --git a/src/ui/addrdialog.h b/src/ui/addrdialog.h
new file mode 100644
index 0000000..8405a0a
--- /dev/null
+++ b/src/ui/addrdialog.h
@@ -0,0 +1,87 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_ADDR_DIALOG_H
+#define FQTERM_ADDR_DIALOG_H
+
+#include <QButtonGroup>
+
+#include "fqterm_param.h"
+#include "ui_addrdialog.h"
+
+namespace FQTerm {
+
+class FQTermConfig;
+
+class addrDialog: public QDialog {
+ Q_OBJECT;
+ public:
+ enum BUTTONS{SAVE = 0x01, APPLY = 0x02};
+ addrDialog(QWidget *parent_ = 0, const FQTermParam& param = FQTermParam(), int buttons = SAVE | APPLY, Qt::WFlags fl = 0);
+ ~addrDialog();
+ void setParam(const FQTermParam& param) {
+ param_ = param;
+ }
+ FQTermParam param() {
+ return param_;
+ }
+
+ enum Tabs{General, Display, Terminal, Keyboard, Proxy, Misc, Mouse};
+ void setCurrentTabIndex(Tabs tab) {
+ ui_.tabWidget->setCurrentIndex(tab);
+ }
+
+ static const int ports[3]; // telnet, ssh1, ssh2
+
+ protected slots:
+ void onOK();
+ void onSave();
+ void onCancel();
+ void onFgcolor();
+ void onBgcolor();
+ void onProtocol(int);
+ void onChooseScript();
+ void onMenuColor();
+ void onFont();
+
+ protected:
+ void connector();
+ bool isChanged();
+ void previewFont();
+ void previewMenu();
+ void setUIFromParam();
+ void setParamFromUI();
+
+ QButtonGroup menuButtonGroup_;
+
+ private:
+
+ FQTermParam param_;
+ Ui::addrDialog ui_;
+
+ void updateSchemaList(const QString& currentFile);
+};
+
+
+
+
+} // namespace FQTerm
+
+#endif // FQTERM_ADDR_DIALOG_H
diff --git a/src/ui/addrdialog.ui b/src/ui/addrdialog.ui
new file mode 100644
index 0000000..e5dc40b
--- /dev/null
+++ b/src/ui/addrdialog.ui
@@ -0,0 +1,1211 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>addrDialog</class>
+ <widget class="QDialog" name="addrDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>493</width>
+ <height>383</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Site Setting</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_4">
+ <item row="1" column="0">
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="1">
+ <widget class="QPushButton" name="applyPushButton">
+ <property name="text">
+ <string>Apply (&amp;Temporarily)</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QPushButton" name="closePushButton">
+ <property name="text">
+ <string>&amp;Cancel</string>
+ </property>
+ <property name="shortcut">
+ <string/>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QPushButton" name="savePushButton">
+ <property name="text">
+ <string>&amp;Apply (Save)</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" colspan="4">
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="Widget2">
+ <attribute name="title">
+ <string>General</string>
+ </attribute>
+ <layout class="QGridLayout">
+ <item row="0" column="0">
+ <layout class="QGridLayout" name="_2">
+ <item row="0" column="0">
+ <widget class="QLabel" name="TextLabel1">
+ <property name="text">
+ <string>Name</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="3">
+ <widget class="QLineEdit" name="nameLineEdit"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="TextLabel2">
+ <property name="text">
+ <string>Address</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" colspan="3">
+ <widget class="QLineEdit" name="addrLineEdit"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="TextLabel1_3">
+ <property name="text">
+ <string>Protocol</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QComboBox" name="protocolComboBox">
+ <item>
+ <property name="text">
+ <string>Telnet</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>SSH1</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>SSH2</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="2" column="3">
+ <widget class="QLineEdit" name="portLineEdit">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="TextLabel3_6">
+ <property name="text">
+ <string>Type</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QComboBox" name="hostTypeComboBox">
+ <item>
+ <property name="text">
+ <string>BBS</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>*NIX</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="4" column="0" colspan="4">
+ <widget class="QGroupBox" name="telnetAutoLoginGroup">
+ <property name="title">
+ <string>Telnet Auto Login</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="TextLabel1_2">
+ <property name="text">
+ <string>Prelogin</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="preloginLineEdit"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="TextLabel4">
+ <property name="text">
+ <string>User</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="userLineEdit"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="TextLabel5">
+ <property name="text">
+ <string>Password</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="passwdLineEdit">
+ <property name="echoMode">
+ <enum>QLineEdit::Password</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="TextLabel11">
+ <property name="text">
+ <string>Postlogin</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLineEdit" name="postloginLineEdit"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QCheckBox" name="portCheckBox">
+ <property name="text">
+ <string>Port</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="4">
+ <widget class="QGroupBox" name="sshAutoLoginGroup">
+ <property name="title">
+ <string>SSH Auto Login</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="TextLabel2_3">
+ <property name="text">
+ <string>User</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="sshuserLineEdit"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="TextLabel3_3">
+ <property name="text">
+ <string>Password</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="sshpasswdLineEdit">
+ <property name="echoMode">
+ <enum>QLineEdit::Password</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab1">
+ <attribute name="title">
+ <string>Display</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="0">
+ <widget class="QLabel" name="TextLabel6">
+ <property name="text">
+ <string>BBS Encoding</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="bbscodeComboBox">
+ <item>
+ <property name="text">
+ <string>GBK</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>BIG5</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>UTF8</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>BIG5-HKSCS</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>BIG5-UAO</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QCheckBox" name="highlightCheckBox">
+ <property name="text">
+ <string>Always Hightlight</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" rowspan="4" colspan="4">
+ <widget class="QLabel" name="fontPreviewer">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>TextLabel3</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::RichText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Align Mode</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="4">
+ <widget class="QSpinBox" name="lineSpacingSpinBox"/>
+ </item>
+ <item row="0" column="3">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Line Spacing</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="4">
+ <widget class="QSpinBox" name="charSpacingSpinBox"/>
+ </item>
+ <item row="1" column="3">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Char Spacing</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QCheckBox" name="ansicolorCheckBox">
+ <property name="text">
+ <string>ANSI Color</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="4">
+ <widget class="QComboBox" name="alignComboBox">
+ <item>
+ <property name="text">
+ <string>Align Mid</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Align Bottom</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Align Top</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="7" column="4">
+ <widget class="QComboBox" name="schemaComboBox"/>
+ </item>
+ <item row="6" column="4">
+ <widget class="QPushButton" name="bgcolorPushButton">
+ <property name="text">
+ <string>Background</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="4">
+ <widget class="QPushButton" name="fgcolorPushButton">
+ <property name="text">
+ <string>Text Color</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="4">
+ <widget class="QToolButton" name="fontToolButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Font</string>
+ </property>
+ <property name="popupMode">
+ <enum>QToolButton::InstantPopup</enum>
+ </property>
+ <property name="toolButtonStyle">
+ <enum>Qt::ToolButtonTextOnly</enum>
+ </property>
+ <property name="arrowType">
+ <enum>Qt::DownArrow</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QComboBox" name="fontAdjustComboBox">
+ <property name="currentIndex">
+ <number>1</number>
+ </property>
+ <item>
+ <property name="text">
+ <string>Keep Font; Adjust Row/Column.</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Keep Row/Column; Adjust Font.</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Keep Font; Keep Row/Column.</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab2">
+ <attribute name="title">
+ <string>Terminal</string>
+ </attribute>
+ <layout class="QGridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="TextLabel1_5">
+ <property name="text">
+ <string>Term Type</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="termtypeLineEdit"/>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="TextLabel2_5">
+ <property name="text">
+ <string>Key Type</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="QComboBox" name="keytypeComboBox">
+ <item>
+ <property name="text">
+ <string>VT100</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>XTERM</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>BBS</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="TextLabel3_4">
+ <property name="text">
+ <string>Columns</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="columnLineEdit"/>
+ </item>
+ <item row="1" column="2">
+ <widget class="QLabel" name="TextLabel5_3">
+ <property name="text">
+ <string>Scroll Lines</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QLineEdit" name="scrollLineEdit"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="TextLabel4_3">
+ <property name="text">
+ <string>Rows</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="rowLineEdit"/>
+ </item>
+ <item row="2" column="2">
+ <widget class="QLabel" name="TextLabel6_3">
+ <property name="text">
+ <string>Cursor Type</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3">
+ <widget class="QComboBox" name="cursorTypeComboBox">
+ <item>
+ <property name="text">
+ <string>Block</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Underline</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>I Type</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="2">
+ <widget class="QLabel" name="TextLabel1_4">
+ <property name="text">
+ <string>Escape string (i.e. *[ )</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2" colspan="2">
+ <widget class="QLineEdit" name="escapeLineEdit"/>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab7">
+ <attribute name="title">
+ <string>Keyboard</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QGroupBox" name="BackSpace">
+ <property name="title">
+ <string>BackSpace Setting</string>
+ </property>
+ <layout class="QGridLayout" name="_3">
+ <item row="0" column="0">
+ <widget class="QRadioButton" name="backspace8">
+ <property name="text">
+ <string>Send backspace as ^H</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QRadioButton" name="backspace127">
+ <property name="text">
+ <string>Send backspace as ^? (127)</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="spacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab3">
+ <attribute name="title">
+ <string>Proxy</string>
+ </attribute>
+ <layout class="QGridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="TextLabel2_2">
+ <property name="text">
+ <string>Type</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="proxytypeComboBox">
+ <item>
+ <property name="text">
+ <string>None</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Wingate</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>SOCKS4</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>SOCKS5</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>HTTP</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="TextLabel3_2">
+ <property name="text">
+ <string>Address</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="proxyaddrLineEdit"/>
+ </item>
+ <item row="1" column="2">
+ <widget class="QLabel" name="TextLabel4_2">
+ <property name="text">
+ <string>Port</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QLineEdit" name="proxyportLineEdit"/>
+ </item>
+ <item row="2" column="0" colspan="4">
+ <widget class="QGroupBox" name="authentationGroup">
+ <property name="title">
+ <string>Authentation</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="TextLabel5_2">
+ <property name="text">
+ <string>User</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="proxyuserLineEdit"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="TextLabel5_4">
+ <property name="text">
+ <string>Password</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="proxypasswdLineEdit"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="Widget3">
+ <attribute name="title">
+ <string>Misc</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0" colspan="5">
+ <widget class="QGroupBox" name="antiIdleGroupBox">
+ <property name="title">
+ <string>Anti-idle</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="antiLineEdit"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="TextLabel8">
+ <property name="text">
+ <string>Max Idle Time</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="idletimeLineEdit"/>
+ </item>
+ <item row="1" column="2">
+ <widget class="QLabel" name="TextLabel9">
+ <property name="text">
+ <string>s</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Anti-idle String</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QLabel" name="textLabel1_2">
+ <property name="text">
+ <string>Key to reply message</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QLineEdit" name="replykeyLineEdit"/>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <widget class="QCheckBox" name="replyCheckBox">
+ <property name="text">
+ <string>Autoreply Message</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2" colspan="3">
+ <widget class="QLineEdit" name="replyLineEdit">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="3">
+ <widget class="QCheckBox" name="reconnectCheckBox">
+ <property name="text">
+ <string>When disconnected, reconnect every</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="3">
+ <widget class="QLineEdit" name="reconnectLineEdit">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="4">
+ <widget class="QLabel" name="textLabel2">
+ <property name="text">
+ <string>s</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="textLabel4">
+ <property name="text">
+ <string>For Maximum</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1" colspan="2">
+ <widget class="QLineEdit" name="retryLineEdit">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="3" colspan="2">
+ <widget class="QLabel" name="textLabel5">
+ <property name="text">
+ <string>Times (-1 means infinite)</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0" colspan="2">
+ <widget class="QCheckBox" name="scriptCheckBox">
+ <property name="text">
+ <string>Load Control Script</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0" colspan="3">
+ <widget class="QLineEdit" name="scriptLineEdit">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="3" colspan="2">
+ <widget class="QPushButton" name="scriptPushButton">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="0">
+ <widget class="QCheckBox" name="zmodemCheck">
+ <property name="text">
+ <string>Enable Zmodem</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="3">
+ <widget class="QCheckBox" name="buzzCheck">
+ <property name="text">
+ <string>Enable Buzz</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="2">
+ <widget class="QCheckBox" name="beepCheck">
+ <property name="text">
+ <string>Enable Beep</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0" colspan="3">
+ <widget class="QCheckBox" name="autoCloseWinCheckBox">
+ <property name="text">
+ <string>When disconnected, close window automatically</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab4">
+ <attribute name="title">
+ <string>Mouse</string>
+ </attribute>
+ <layout class="QGridLayout">
+ <item row="0" column="0">
+ <widget class="QGroupBox" name="menuGroup">
+ <property name="title">
+ <string>Menu Type</string>
+ </property>
+ <layout class="QGridLayout">
+ <item row="0" column="0">
+ <widget class="QRadioButton" name="radioButton1">
+ <property name="text">
+ <string>Underline</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QRadioButton" name="radioButton2">
+ <property name="text">
+ <string>Reverse</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QRadioButton" name="radioButton3">
+ <property name="text">
+ <string>Custom Color</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QLabel" name="menuLabel">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Menu Color</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QPushButton" name="menuColorButton">
+ <property name="text">
+ <string>Color...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="0">
+ <widget class="QCheckBox" name="mouseCheck">
+ <property name="text">
+ <string>Enable Mouse Support</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <tabstops>
+ <tabstop>tabWidget</tabstop>
+ <tabstop>nameLineEdit</tabstop>
+ <tabstop>addrLineEdit</tabstop>
+ <tabstop>portLineEdit</tabstop>
+ <tabstop>hostTypeComboBox</tabstop>
+ <tabstop>preloginLineEdit</tabstop>
+ <tabstop>userLineEdit</tabstop>
+ <tabstop>passwdLineEdit</tabstop>
+ <tabstop>postloginLineEdit</tabstop>
+ <tabstop>bbscodeComboBox</tabstop>
+ <tabstop>highlightCheckBox</tabstop>
+ <tabstop>termtypeLineEdit</tabstop>
+ <tabstop>keytypeComboBox</tabstop>
+ <tabstop>columnLineEdit</tabstop>
+ <tabstop>scrollLineEdit</tabstop>
+ <tabstop>rowLineEdit</tabstop>
+ <tabstop>cursorTypeComboBox</tabstop>
+ <tabstop>escapeLineEdit</tabstop>
+ <tabstop>idletimeLineEdit</tabstop>
+ <tabstop>replykeyLineEdit</tabstop>
+ <tabstop>replyCheckBox</tabstop>
+ <tabstop>replyLineEdit</tabstop>
+ <tabstop>reconnectCheckBox</tabstop>
+ <tabstop>reconnectLineEdit</tabstop>
+ <tabstop>retryLineEdit</tabstop>
+ <tabstop>autoCloseWinCheckBox</tabstop>
+ <tabstop>scriptCheckBox</tabstop>
+ <tabstop>scriptLineEdit</tabstop>
+ <tabstop>scriptPushButton</tabstop>
+ <tabstop>radioButton1</tabstop>
+ <tabstop>radioButton2</tabstop>
+ <tabstop>radioButton3</tabstop>
+ <tabstop>menuColorButton</tabstop>
+ <tabstop>applyPushButton</tabstop>
+ <tabstop>closePushButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>radioButton2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>menuColorButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>260</x>
+ <y>79</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>392</x>
+ <y>110</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>menuColorButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>53</x>
+ <y>79</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>392</x>
+ <y>110</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>menuColorButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>392</x>
+ <y>79</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>392</x>
+ <y>110</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>replyCheckBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>replyLineEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>23</x>
+ <y>158</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>168</x>
+ <y>156</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>reconnectCheckBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>reconnectLineEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>23</x>
+ <y>184</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>295</x>
+ <y>182</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>reconnectCheckBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>retryLineEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>23</x>
+ <y>184</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>147</x>
+ <y>213</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>scriptCheckBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>scriptLineEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>26</x>
+ <y>236</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>26</x>
+ <y>261</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>scriptCheckBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>scriptPushButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>26</x>
+ <y>236</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>289</x>
+ <y>260</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>portCheckBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>portLineEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>187</x>
+ <y>108</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>209</x>
+ <y>108</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>antiIdleGroupBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>antiLineEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>89</x>
+ <y>42</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>145</x>
+ <y>67</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>antiIdleGroupBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>idletimeLineEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>114</x>
+ <y>40</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>270</x>
+ <y>110</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>beepCheck</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>buzzCheck</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>223</x>
+ <y>301</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>298</x>
+ <y>299</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/ui/articledialog.cpp b/src/ui/articledialog.cpp
new file mode 100644
index 0000000..43ba617
--- /dev/null
+++ b/src/ui/articledialog.cpp
@@ -0,0 +1,105 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "articledialog.h"
+#include <QFileDialog>
+#include <QMessageBox>
+#include "fqterm_trace.h"
+#include "fqterm_path.h"
+#include "fqterm_config.h"
+#include "fqterm_filedialog.h"
+
+/*
+ * Constructs a articleDialog as a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'.
+ *
+ * The dialog will by default be modeless, unless you set 'modal' to
+ * TRUE to construct a modal dialog.
+ */
+
+namespace FQTerm {
+
+articleDialog::articleDialog(FQTermConfig *config, QWidget *parent, Qt::WFlags fl)
+ : QDialog(parent, fl) {
+ ui_.setupUi(this);
+ connectSlots();
+
+ config_ = config;
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+articleDialog::~articleDialog() {
+ // no need to delete child widgets, Qt does it all for us
+}
+
+
+void articleDialog::connectSlots() {
+ FQ_VERIFY(connect(ui_.selectButton, SIGNAL(clicked()), this, SLOT(onSelect())));
+ FQ_VERIFY(connect(ui_.copyButton, SIGNAL(clicked()), this, SLOT(onCopy())));
+ FQ_VERIFY(connect(ui_.saveButton, SIGNAL(clicked()), this, SLOT(onSave())));
+ FQ_VERIFY(connect(ui_.closeButton, SIGNAL(clicked()), this, SLOT(onClose())));
+}
+
+void articleDialog::onSelect() {
+ ui_.textBrowser->selectAll();
+}
+
+void articleDialog::onCopy() {
+ ui_.textBrowser->copy();
+ // QString strText = textBrowser->selectedText();
+ //
+ // QClipboard *clipboard = QApplication::clipboard();
+ //
+ // #if (QT_VERSION>=0x030100)
+ // clipboard->setText(strText, QClipboard::Selection );
+ // clipboard->setText(strText, QClipboard::Clipboard );
+ // #else
+ // clipboard->setText(strText);
+ // #endif
+}
+
+void articleDialog::onSave() {
+
+ QString filename;
+ FQTermFileDialog fileDialog(config_);
+ filename = fileDialog.getSaveName(NULL, "");
+
+ if (!filename.isNull()) {
+ QFile f(filename);
+ if ((f.open(QIODevice::WriteOnly))) {
+ f.write(articleText_.toLocal8Bit());
+ f.close();
+ } else {
+ QMessageBox mb("Access file error:", filename, QMessageBox::Warning, 0, 0, 0,
+ this, 0);
+ mb.exec();
+ }
+ }
+}
+
+void articleDialog::onClose() {
+ done(0);
+}
+
+} // namespace FQTerm
+
+#include "articledialog.moc"
diff --git a/src/ui/articledialog.h b/src/ui/articledialog.h
new file mode 100644
index 0000000..0e40cbf
--- /dev/null
+++ b/src/ui/articledialog.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_ARTICLEDIALOG_H
+#define FQTERM_ARTICLEDIALOG_H
+
+#include "ui_articledialog.h"
+
+namespace FQTerm {
+
+class FQTermConfig;
+class FQTermFileDialog;
+
+class articleDialog: public QDialog {
+ Q_OBJECT;
+public:
+ articleDialog(FQTermConfig *, QWidget *parent_ = 0, Qt::WFlags fl = 0);
+ ~articleDialog();
+
+ QString articleText_;
+ Ui::articleDialog ui_;
+protected:
+ void connectSlots();
+protected slots:
+ void onClose();
+ void onSave();
+ void onSelect();
+ void onCopy();
+private:
+ FQTermConfig * config_;
+};
+
+} // name space FQTerm
+
+#endif // FQTERM_ARTICLEDIALOG_H
diff --git a/src/ui/articledialog.ui b/src/ui/articledialog.ui
new file mode 100644
index 0000000..436671f
--- /dev/null
+++ b/src/ui/articledialog.ui
@@ -0,0 +1,132 @@
+<ui version="4.0" >
+ <class>articleDialog</class>
+ <widget class="QDialog" name="articleDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>542</width>
+ <height>487</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Article Viewer</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" colspan="8" >
+ <widget class="QTextBrowser" name="textBrowser" />
+ </item>
+ <item row="1" column="4" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>50</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="0" colspan="6" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>410</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="6" colspan="2" >
+ <widget class="QPushButton" name="closeButton" >
+ <property name="text" >
+ <string>Close</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QPushButton" name="selectButton" >
+ <property name="text" >
+ <string>Select All</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>60</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="7" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>60</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="5" colspan="2" >
+ <widget class="QPushButton" name="saveButton" >
+ <property name="text" >
+ <string>Save...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3" >
+ <widget class="QPushButton" name="copyButton" >
+ <property name="text" >
+ <string>Copy</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/ui/defineescape.cpp b/src/ui/defineescape.cpp
new file mode 100644
index 0000000..e9dd655
--- /dev/null
+++ b/src/ui/defineescape.cpp
@@ -0,0 +1,51 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+
+#include "defineescape.h"
+#include "fqterm.h"
+
+namespace FQTerm {
+
+DefineEscapeDialog::~DefineEscapeDialog()
+{
+}
+
+DefineEscapeDialog::DefineEscapeDialog(QString& strEsc, QWidget *parent_ /*= 0*/, Qt::WFlags fl /*= 0*/)
+: QDialog(parent_, fl), strEsc_(strEsc)
+{
+ ui_.setupUi(this);
+ ui_.edtEscape->setText(strEsc_);
+ FQ_VERIFY(connect(ui_.btnOK, SIGNAL(clicked()), this, SLOT(onOK())));
+ FQ_VERIFY(connect(ui_.btnCancel, SIGNAL(clicked()), this, SLOT(onCancel())));
+}
+
+void DefineEscapeDialog::onOK()
+{
+ strEsc_ = ui_.edtEscape->text();
+ done(1);
+}
+
+void DefineEscapeDialog::onCancel()
+{
+ done(0);
+}
+} //namespace FQTerm
+
+#include "defineescape.moc"
diff --git a/src/ui/defineescape.h b/src/ui/defineescape.h
new file mode 100644
index 0000000..0083603
--- /dev/null
+++ b/src/ui/defineescape.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+
+#ifndef __FQTERM_DEFINEESCAPE__
+#define __FQTERM_DEFINEESCAPE__
+
+#include <QDialog>
+#include "ui_defineescape.h"
+namespace FQTerm {
+
+class DefineEscapeDialog : public QDialog {
+ Q_OBJECT;
+public:
+ DefineEscapeDialog(QString& strEsc, QWidget *parent_ = 0, Qt::WFlags fl = 0);
+ ~DefineEscapeDialog();
+
+protected slots:
+ void onOK();
+ void onCancel();
+private:
+ QString& strEsc_;
+ Ui::dlgDefineEscape ui_;
+};
+
+} //namespace FQTerm
+
+#endif //__FQTERM_DEFINEESCAPE__ \ No newline at end of file
diff --git a/src/ui/defineescape.ui b/src/ui/defineescape.ui
new file mode 100644
index 0000000..6549610
--- /dev/null
+++ b/src/ui/defineescape.ui
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>dlgDefineEscape</class>
+ <widget class="QDialog" name="dlgDefineEscape">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>213</width>
+ <height>121</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Define Escape</string>
+ </property>
+ <widget class="QLabel" name="lblEscape">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>10</y>
+ <width>81</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Escape String *[</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" name="edtEscape">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>40</y>
+ <width>171</width>
+ <height>20</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QWidget" name="">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>76</y>
+ <width>171</width>
+ <height>31</height>
+ </rect>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="btnOK">
+ <property name="text">
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnCancel">
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/ui/fqterm_canvas.cpp b/src/ui/fqterm_canvas.cpp
new file mode 100644
index 0000000..f17ee58
--- /dev/null
+++ b/src/ui/fqterm_canvas.cpp
@@ -0,0 +1,537 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QCloseEvent>
+#include <QKeyEvent>
+#include <QResizeEvent>
+#include <QMouseEvent>
+#include <QMenu>
+#include <QMenuBar>
+#include <QFileDialog>
+#include <QMessageBox>
+#include <QLabel>
+#include <QMatrix>
+#include <QToolBar>
+#include <QActionGroup>
+#include <QToolButton>
+#include <QDesktopServices>
+#include <QDir>
+#include <QUrl>
+#include <QImageReader>
+#include <QMovie>
+
+#include "fqterm_canvas.h"
+#include "fqterm.h"
+#include "fqterm_config.h"
+#include "fqterm_path.h"
+#include "fqterm_filedialog.h"
+
+namespace FQTerm {
+
+FQTermCanvas::FQTermCanvas(FQTermConfig * config, QWidget *parent, Qt::WFlags f)
+ : QScrollArea(parent),
+ adjustMode_(Fit),
+ aspectRatioMode_(Qt::KeepAspectRatio){
+ // TODO: dirty trick
+
+ if (f == 0) {
+ isEmbedded = true;
+ } else {
+ isEmbedded = false;
+ }
+
+ config_ = config;
+
+ menu_ = new QMenu(parent);
+ menu_->addAction(tr("zoom 1:1"), this, SLOT(oriSize()), tr("Ctrl+Z"));
+ menu_->addAction(tr("adjust size"), this, SLOT(autoAdjust()), tr("Ctrl+X"));
+ menu_->addSeparator();
+ QAction* zoomInAction = menu_->addAction(tr("zoom in"), this,
+ SLOT(zoomIn()), tr("Ctrl+="));
+ QAction* zoomOutAction = menu_->addAction(tr("zoom out"), this,
+ SLOT(zoomOut()), tr("Ctrl+-"));
+ if (!isEmbedded) {
+ menu_->addAction(tr("fullscreen"), this, SLOT(fullScreen()), tr("Ctrl+F"));
+ }
+ menu_->addSeparator();
+ menu_->addAction(tr("rotate CW 90"), this, SLOT(cwRotate()),
+ tr("Ctrl+]"));
+ menu_->addAction(tr("rotate CCW 90"), this, SLOT(ccwRotate()),
+ tr("Ctrl+["));
+ menu_->addSeparator();
+ gifPlayAction_ = menu_->addAction(tr("play gif"), this,
+ SLOT(playGIF()), tr("Ctrl+/"));
+ menu_->addSeparator();
+ menu_->addAction(tr("save as"), this, SLOT(saveImage()), tr("Ctrl+S"));
+ menu_->addAction(tr("copy to"), this, SLOT(copyImage()), tr("Ctrl+C"));
+ menu_->addAction(tr("silent copy"), this, SLOT(silentCopy()),
+ tr("Shift+S"));
+
+ if (!isEmbedded) {
+ menu_->addAction(tr("delete"), this, SLOT(deleteImage()), tr("Ctrl+D"));
+
+ menu_->addSeparator();
+ menu_->addAction(tr("exit"), this, SLOT(close()), tr("Ctrl+Q"));
+ }
+
+ toolBar_ = new QToolBar(this);
+
+ toolBar_->addAction(QIcon(getPath(RESOURCE) + "pic/ViewerButtons/open.png"),
+ tr("Open Dir"), this, SLOT(openDir()));
+
+ zoomInAction->setIcon(
+ QIcon(getPath(RESOURCE) + "pic/ViewerButtons/zoomin.png"));
+ zoomOutAction->setIcon(
+ QIcon(getPath(RESOURCE) + "pic/ViewerButtons/zoomout.png"));
+
+ toolBar_->addAction(zoomInAction);
+ toolBar_->addAction(zoomOutAction);
+
+ QActionGroup* gifGroup = new QActionGroup(this);
+ gifPlayAction_->setIcon(
+ QIcon(getPath(RESOURCE) + "pic/ViewerButtons/play_gif.png"));
+ toolBar_->addAction(gifPlayAction_);
+
+ QActionGroup* showSettingGroup = new QActionGroup(this);
+ QMenu* showSettingMenu = new QMenu(this);
+
+ QAction* showSettingFitAction =
+ showSettingMenu->addAction(tr("show Fit"), this, SLOT(SetAdjustMode()));
+ showSettingFitAction->setCheckable(true);
+ showSettingFitAction->setData(Fit);
+ showSettingGroup->addAction(showSettingFitAction);
+
+ QAction* showSettingMaxFitAction =
+ showSettingMenu->addAction(tr("show MaxFit"),
+ this, SLOT(SetAdjustMode()));
+ showSettingMaxFitAction->setCheckable(true);
+ showSettingMaxFitAction->setData(MaxFit);
+ showSettingGroup->addAction(showSettingMaxFitAction);
+
+ QAction* showSettingOriginAction =
+ showSettingMenu->addAction(tr("show Origin"),
+ this, SLOT(SetAdjustMode()));
+ showSettingOriginAction->setCheckable(true);
+ showSettingOriginAction->setData(Origin);
+ showSettingGroup->addAction(showSettingOriginAction);
+
+ QAction* showSettingStrechAction =
+ showSettingMenu->addAction(tr("show Stretch"),
+ this, SLOT(SetAdjustMode()));
+ showSettingStrechAction->setCheckable(true);
+ showSettingStrechAction->setData(Stretch);
+ showSettingGroup->addAction(showSettingStrechAction);
+
+ QToolButton* showSettingButton = new QToolButton(this);
+ QAction* dummyAction = new QAction(
+ QIcon(getPath(RESOURCE) + "pic/ViewerButtons/adjustsize.png"),
+ tr("Adjust Mode"), showSettingButton);
+ showSettingButton->setDefaultAction(dummyAction);
+ showSettingButton->setMenu(showSettingMenu);
+ showSettingButton->setPopupMode(QToolButton::InstantPopup);
+
+ showSettingFitAction->setChecked(true);
+
+ toolBar_->addWidget(showSettingButton);
+
+
+
+#if QT_VERSION >= 0x040200
+ setAlignment(Qt::AlignCenter);
+#endif
+ label_ = new QLabel(viewport());
+ label_->setScaledContents(true);
+ label_->setAlignment(Qt::AlignCenter);
+ label_->setText(tr("No Preview Available"));
+ setWidget(label_);
+ // resize(200, 100);
+}
+
+FQTermCanvas::~FQTermCanvas() {
+ //delete label;
+ //delete m_pMenu;
+}
+
+void FQTermCanvas::oriSize() {
+ useAdjustMode_ = false;
+ imageSize_ = image_.size();
+ adjustSize(size());
+}
+
+void FQTermCanvas::zoomIn() {
+ useAdjustMode_ = false;
+ resizeImage(0.05f);
+}
+
+void FQTermCanvas::zoomOut() {
+ useAdjustMode_ = false;
+ resizeImage(-0.05f);
+}
+
+void FQTermCanvas::autoAdjust() {
+ useAdjustMode_ = true;
+ adjustSize(size());
+}
+
+void FQTermCanvas::cwRotate() {
+ rotateImage(90);
+}
+
+void FQTermCanvas::ccwRotate() {
+ rotateImage(-90);
+}
+
+void FQTermCanvas::fullScreen() {
+ if (!isFullScreen()) {
+ showFullScreen();
+ } else {
+ showNormal();
+ }
+}
+
+void FQTermCanvas::loadImage(const QString& name, bool performAdjust) {
+ if (label_->movie()) {
+ label_->movie()->stop();
+ label_->setMovie(NULL);
+ }
+
+ gifPlayAction_->setEnabled(name.endsWith("gif"));
+
+
+ bool res = image_.load(name);
+ if (!res) {
+ QList<QByteArray> formats = QImageReader::supportedImageFormats();
+ for (QList<QByteArray>::iterator it = formats.begin();
+ !res && it != formats.end();
+ ++it) {
+ res = image_.load(name, it->data());
+ }
+ }
+ if (!image_.isNull()) {
+ fileName_ = QFileInfo(name).absoluteFilePath();
+ setWindowTitle(QFileInfo(name).fileName());
+
+ useAdjustMode_ = true;
+
+ if (!isEmbedded) {
+ QSize szView(image_.size());
+ szView.scale(640, 480, aspectRatioMode_);
+
+ if (szView.width() < image_.width()) {
+ imageSize_ = szView;
+ label_->resize(imageSize_);
+ label_->clear();
+ label_->setAlignment(Qt::AlignCenter);
+ label_->setPixmap(scaleImage(imageSize_));
+
+ if (!isEmbedded) {
+ resize(szView *1.1);
+ }
+ } else {
+ imageSize_ = image_.size();
+ label_->resize(imageSize_);
+ label_->setPixmap(QPixmap::fromImage(image_));
+ if (!isEmbedded) {
+ resize(imageSize_ + QSize(5, 5));
+ }
+ }
+ }
+ if (isEmbedded) {
+ label_->hide();
+ if (performAdjust) autoAdjust();
+ else label_->setPixmap(QPixmap::fromImage(image_));
+
+ label_->show();
+ }
+
+ } else {
+ FQ_TRACE("canvas", 1) << "Can't load the image: " << name;
+ }
+}
+
+void FQTermCanvas::playGIF() {
+ if (fileName_.endsWith("gif")) {
+ gifPlayer_.setFileName(fileName_);
+ if (gifPlayer_.isValid()) {
+ label_->setMovie(&gifPlayer_);
+ gifPlayer_.stop();
+ gifPlayer_.start();
+ return;
+ }
+ }
+}
+
+void FQTermCanvas::resizeImage(float ratio) {
+ QSize szImg = imageSize_;
+ szImg *= (1+ratio);
+ //we dont need so big
+ if (szImg.width() > 10000 || szImg.height() > 10000 ||
+ szImg.width() < 1 || szImg.height() < 1) {
+ return ;
+ }
+ imageSize_ = szImg;
+
+ if (!isFullScreen() && !isEmbedded) {
+ resize(imageSize_ *1.1);
+ } else {
+ adjustSize(size());
+ }
+}
+
+void FQTermCanvas::rotateImage(float ang) {
+ QMatrix wm;
+
+ wm.rotate(ang);
+
+ image_ = image_.transformed(wm, Qt::SmoothTransformation);
+
+ imageSize_ = image_.size();
+
+ adjustSize(size());
+}
+
+void FQTermCanvas::copyImage() {
+ QFileInfo fi(fileName_);
+// QString strSave =
+// QFileDialog::getSaveFileName(
+// this,tr("Choose a filename to save under"),
+// QDir::currentPath() + fi.fileName());
+ FQTermFileDialog fileDialog(config_);
+ QString strSave = fileDialog.getSaveName(fi.fileName(), "");
+ if (strSave.isEmpty()) {
+ return ;
+ }
+ QFile file(fileName_);
+ if (file.open(QIODevice::ReadOnly)) {
+ QFile save(strSave);
+ if (save.open(QIODevice::WriteOnly)) {
+ QByteArray ba = file.readAll();
+ QDataStream ds(&save);
+ ds.writeRawData(ba, ba.size());
+ save.close();
+ }
+ file.close();
+ }
+}
+
+void FQTermCanvas::silentCopy() {
+ // save it to $savefiledialog
+ QString strPath = config_->getItemValue("global", "savefiledialog");
+
+ QFileInfo fi(fileName_);
+ QString strSave = strPath + "/" + fi.fileName();
+
+ fi.setFile(strSave);
+
+ // add (%d) if exist
+ int i = 1;
+ while (fi.exists()) {
+ strSave = QString("%1/%2(%3).%4").arg(fi.dir().path()).arg
+ (fi.completeBaseName()).arg(i).arg(fi.suffix());
+ fi.setFile(strSave);
+ }
+
+ // copy it
+ QFile file(fileName_);
+ if (file.open(QIODevice::ReadOnly)) {
+ QFile save(strSave);
+ if (save.open(QIODevice::WriteOnly)) {
+ QByteArray ba = file.readAll();
+ QDataStream ds(&save);
+ ds.writeRawData(ba, ba.size());
+ save.close();
+ }
+ file.close();
+ }
+}
+
+QPixmap FQTermCanvas::scaleImage(const QSize &sz) {
+ return QPixmap::fromImage(
+ image_.scaled(sz, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
+}
+
+void FQTermCanvas::moveImage(float dx, float dy) {
+ scrollContentsBy(int(widget()->width()*dx), int(widget()->height() *dy));
+}
+
+void FQTermCanvas::saveImage() {
+
+ QFileInfo fi(fileName_);
+ FQTermFileDialog fileDialog(config_);
+ QString strSave = fileDialog.getSaveName(fi.fileName(), "");
+ if (strSave.isEmpty()) {
+ return ;
+ }
+ QString fmt = fi.suffix().toUpper();
+ if (!image_.save(strSave, fmt.toLatin1())) {
+ QMessageBox::warning(this, tr("Failed to save file"),
+ tr("Cant save file, maybe format not supported"));
+ }
+}
+
+void FQTermCanvas::deleteImage() {
+ QFile::remove(fileName_);
+ close();
+}
+
+void FQTermCanvas::closeEvent(QCloseEvent *ce) {
+ if (!isEmbedded) {
+ delete this;
+ }
+}
+
+void FQTermCanvas::viewportResizeEvent(QResizeEvent *re) {
+ adjustSize(re->size());
+}
+
+void FQTermCanvas::mousePressEvent(QMouseEvent *me) {
+ /* remove this to avoid click by mistake
+ if(me->button()&LeftButton)
+ {
+ close();
+ return;
+ }
+ */
+ if (me->button() &Qt::RightButton) {
+ menu_->popup(me->globalPos());
+ }
+}
+
+void FQTermCanvas::keyPressEvent(QKeyEvent *ke) {
+ switch (ke->key()) {
+ case Qt::Key_Escape:
+ if (!isEmbedded) {
+ if (isFullScreen()) {
+ showNormal();
+ } else {
+ close();
+ }
+ }
+
+ break;
+ case Qt::Key_D:
+ if (!isEmbedded){
+ deleteImage();
+ }
+ break;
+ case Qt::Key_Q:
+ if (!isEmbedded){
+ close();
+ }
+ break;
+ }
+}
+
+void FQTermCanvas::adjustSize(QSize szView) {
+ szView -= QSize(2 * frameWidth(), 2 * frameWidth());
+ if (label_->pixmap() == NULL && image_.isNull()) {
+ label_->resize(szView);
+ return ;
+ }
+
+ QSize szImg = imageSize_;
+
+ if (useAdjustMode_) {
+ szImg = image_.size();
+ switch(adjustMode_)
+ {
+ case MaxFit:
+ szImg.scale(szView, aspectRatioMode_);
+ break;
+ case Fit:
+ if (szImg.width() > szView.width() || szImg.height() > szView.height() ||
+ szImg.width() < image_.width()) {
+ szImg.scale(szView, aspectRatioMode_);
+ }
+ szImg = szImg.boundedTo(image_.size());
+ if (szImg.width() < 1 || szImg.height() < 1) {
+ return;
+ }
+ break;
+ case Origin:
+ break;
+ case Stretch:
+ szImg = szView;
+ break;
+ }
+ }
+
+ imageSize_ = szImg;
+ label_->resize(imageSize_);
+ label_->setPixmap(scaleImage(imageSize_));
+}
+
+void FQTermCanvas::resizeEvent(QResizeEvent * event) {
+ if (useAdjustMode_){
+ autoAdjust();
+ }
+ else adjustSize(size());
+ QScrollArea::resizeEvent(event);
+}
+
+QMenu* FQTermCanvas::menu() {
+ return menu_;
+}
+
+
+QToolBar* FQTermCanvas::ToolBar() {
+ return toolBar_;
+}
+
+void FQTermCanvas::SetAdjustMode(AdjustMode am) {
+ adjustMode_ = am;
+ if (adjustMode_ == Stretch) {
+ aspectRatioMode_ = Qt::IgnoreAspectRatio;
+ }
+ else {
+ aspectRatioMode_ = Qt::KeepAspectRatio;
+ }
+ autoAdjust();
+}
+
+void FQTermCanvas::SetAdjustMode() {
+ SetAdjustMode(AdjustMode((((QAction*)sender())->data()).toInt()));
+}
+
+void FQTermCanvas::openDir() {
+ QString poolPath = config_->getItemValue("preference", "pool");
+ if (poolPath.isEmpty()) {
+ poolPath = getPath(USER_CONFIG) + "pool/";
+ }
+#ifdef WIN32
+ QString path = "file:///" + poolPath;
+#else
+ QString path = "file://" + poolPath;
+#endif
+ QDesktopServices::openUrl(path);
+}
+
+void FQTermCanvas::updateImage(const QString& filename)
+{
+ if (QFileInfo(filename).absoluteFilePath().toLower() == fileName_) {
+ loadImage(fileName_);
+ }
+
+}
+
+
+} // namespace FQTerm
+
+#include "fqterm_canvas.moc"
diff --git a/src/ui/fqterm_canvas.h b/src/ui/fqterm_canvas.h
new file mode 100644
index 0000000..be15879
--- /dev/null
+++ b/src/ui/fqterm_canvas.h
@@ -0,0 +1,105 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_CANVAS_H
+#define FQTERM_CANVAS_H
+
+#include <QScrollArea>
+#include <QImage>
+#include <QMovie>
+
+class QAction;
+class QLabel;
+class QMenu;
+class QCloseEvent;
+class QMouseEvent;
+class QKeyEvent;
+class QResizeEvent;
+class QToolBar;
+class QImage;
+
+namespace FQTerm {
+
+class FQTermConfig;
+class ExifExtractor;
+class FQTermFileDialog;
+
+class FQTermCanvas: public QScrollArea {
+ Q_OBJECT;
+ public:
+ FQTermCanvas(FQTermConfig *, QWidget *parent_ = NULL, Qt::WFlags f = Qt::Window);
+ ~FQTermCanvas();
+
+ enum AdjustMode{Origin, Fit, Stretch, MaxFit};
+
+ void updateImage(const QString& filename);
+ void loadImage(const QString&, bool = true);
+ QMenu* menu();
+ QToolBar* ToolBar();
+ public slots:
+ void oriSize();
+ void zoomIn();
+ void zoomOut();
+ void autoAdjust();
+ void fullScreen();
+ void saveImage();
+ void copyImage();
+ void silentCopy();
+ void cwRotate();
+ void ccwRotate();
+ void deleteImage();
+ void SetAdjustMode(AdjustMode am);
+ void openDir();
+ void playGIF();
+ protected slots:
+ void SetAdjustMode();
+ protected:
+ void resizeEvent (QResizeEvent * event);
+ void moveImage(float, float);
+ void resizeImage(float);
+ void rotateImage(float);
+
+ void closeEvent(QCloseEvent*);
+ void mousePressEvent(QMouseEvent*);
+ void keyPressEvent(QKeyEvent *ke);
+ void viewportResizeEvent(QResizeEvent *re);
+ void adjustSize(QSize);
+ QPixmap scaleImage(const QSize &);
+ protected:
+ QLabel *label_;
+ bool useAdjustMode_;
+ QSize imageSize_;
+ QString fileName_;
+ QImage image_;
+ QMovie gifPlayer_;
+ QMenu *menu_;
+ QToolBar *toolBar_;
+ FQTermConfig * config_;
+ QAction* gifPlayAction_;
+
+ AdjustMode adjustMode_;
+ Qt::AspectRatioMode aspectRatioMode_;
+ // TODO: Very dirty trick, I hate it
+ bool isEmbedded;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_CANVAS_H
diff --git a/src/ui/fqterm_time_label.cpp b/src/ui/fqterm_time_label.cpp
new file mode 100644
index 0000000..1d05b0e
--- /dev/null
+++ b/src/ui/fqterm_time_label.cpp
@@ -0,0 +1,50 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_time_label.h"
+
+#include <QLabel>
+#include <QTimerEvent>
+#include <QDateTime>
+
+namespace FQTerm {
+
+//constructor
+FQTermTimeLabel::FQTermTimeLabel(QWidget *parent, const char *name, Qt::WFlags f)
+ : QLabel(parent, f) {
+ setAlignment(Qt::AlignHCenter);
+ currentTime_ = new QTime();
+ currentTime_->start();
+ startTimer(1000);
+}
+
+//destructor
+FQTermTimeLabel::~FQTermTimeLabel() {
+ delete currentTime_;
+}
+
+//timer to display the current time
+void FQTermTimeLabel::timerEvent(QTimerEvent*) {
+ setText(currentTime_->currentTime().toString());
+}
+
+} // namespace FQTerm
+
+#include "fqterm_time_label.moc"
diff --git a/src/ui/fqterm_time_label.h b/src/ui/fqterm_time_label.h
new file mode 100644
index 0000000..ac510b6
--- /dev/null
+++ b/src/ui/fqterm_time_label.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_TIME_LABEL_H
+#define FQTERM_TIME_LABEL_H
+
+#include <QTimerEvent>
+#include <QLabel>
+
+class QTime;
+
+namespace FQTerm {
+
+class FQTermTimeLabel: public QLabel {
+ Q_OBJECT;
+ public:
+ FQTermTimeLabel(QWidget *parent, const char *name = 0, Qt::WFlags f = 0);
+ ~FQTermTimeLabel();
+
+ protected:
+ QTime *currentTime_;
+ void timerEvent(QTimerEvent*);
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_TIME_LABEL_H
diff --git a/src/ui/fqterm_tool_button.cpp b/src/ui/fqterm_tool_button.cpp
new file mode 100644
index 0000000..4680e6f
--- /dev/null
+++ b/src/ui/fqterm_tool_button.cpp
@@ -0,0 +1,41 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_tool_button.h"
+#include "fqterm_trace.h"
+
+namespace FQTerm {
+
+FQTermToolButton::FQTermToolButton(QWidget *parent_, int id, QString name)
+ : QToolButton(parent_) {
+ setObjectName(name);
+ this->id_ = id;
+ FQ_VERIFY(connect(this, SIGNAL(clicked()), this, SLOT(slotClicked())));
+}
+
+FQTermToolButton::~FQTermToolButton(){}
+
+void FQTermToolButton::slotClicked() {
+ emit(buttonClicked(id_));
+}
+
+} // namespace FQTerm
+
+#include "fqterm_tool_button.moc"
diff --git a/src/ui/fqterm_tool_button.h b/src/ui/fqterm_tool_button.h
new file mode 100644
index 0000000..56f5626
--- /dev/null
+++ b/src/ui/fqterm_tool_button.h
@@ -0,0 +1,46 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_TOOL_BUTTON_H
+#define FQTERM_TOOL_BUTTON_H
+
+#include <QToolButton>
+
+namespace FQTerm {
+
+class FQTermToolButton: public QToolButton {
+ Q_OBJECT;
+ public:
+ FQTermToolButton(QWidget *parent_, int id, QString name = "");
+ ~FQTermToolButton();
+
+ signals:
+ void buttonClicked(int);
+
+ protected slots:
+ void slotClicked();
+
+ protected:
+ int id_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_TOOL_BUTTON_H
diff --git a/src/ui/imageviewer.cpp b/src/ui/imageviewer.cpp
new file mode 100644
index 0000000..296c5a8
--- /dev/null
+++ b/src/ui/imageviewer.cpp
@@ -0,0 +1,1749 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QAction>
+#include <QBuffer>
+#include <QCursor>
+#include <QComboBox>
+#include <QDateTime>
+#include <QDataStream>
+#include <QDir>
+#include <QFile>
+#include <QFileInfo>
+#include <QIcon>
+#include <QKeyEvent>
+#include <QLineEdit>
+#include <QMessageBox>
+#include <QMouseEvent>
+#include <QMenu>
+#include <QMenuBar>
+#include <QPainter>
+#include <QPixmap>
+#include <QPushButton>
+#include <QSizeGrip>
+#include <QString>
+#include <QTextCodec>
+#include <QTimer>
+#include <QToolTip>
+#include <QTransform>
+#include <QTreeView>
+#include <QTextEdit>
+#include <QHeaderView>
+#include <QImageReader>
+
+#include "fqterm_canvas.h"
+#include "fqterm_config.h"
+#include "fqterm_exif_extractor.h"
+#include "fqterm_filedialog.h"
+#include "fqterm_path.h"
+#include "fqterm_trace.h"
+#include "imageviewer.h"
+
+
+namespace FQTerm {
+
+ typedef enum {
+ V_UNKNOWN = -1,
+ V_ORIGINAL = 0,
+ V_SHADOW,
+ V_BESTFIT,
+ V_ZOOMIN,
+ V_ZOOMOUT,
+ V_ROTLEFT,
+ V_ROTRIGHT,
+ V_FULLSCREEN
+ } slideViewModes;
+
+ typedef enum {
+ SORT_UNSORTED = -1,
+ SORT_LIKE,
+ SORT_NEW,
+ SORT_TRASH,
+ SORT_RECOVER,
+ SORT_TITLE
+ } slideSortFlags;
+
+
+ typedef enum {
+ STAT_UNKNOWN = -1,
+ STAT_LIKE,
+ STAT_NEW,
+ STAT_TRASH,
+ STAT_RECOVER,
+ STAT_TITLE,
+ STAT_ALL
+ } slideStatus;
+
+ typedef enum {
+ GEN_UNKNOWN = -1,
+ GEN_CANCEL,
+ GEN_NOCHANGE,
+ GEN_RESHUFFLE,
+ GEN_NOTAG,
+ GEN_INTRASH,
+ GEN_INTRASHES,
+ GEN_TOSAVE,
+ GEN_TOSAVES,
+ GEN_TRASH,
+ GEN_TRASHES,
+ GEN_NOTRASH,
+ GEN_RECOVER,
+ GEN_RECOVERS,
+ GEN_NORECOVER,
+ GEN_SAVE,
+ GEN_SAVES,
+ GEN_DELETE,
+ GEN_DELETES,
+ GEN_SEARCHWRAP,
+ GEN_SEARCHNOMATCH
+ } generalStatus;
+
+ static const char *fqloraTagStatus[] = {
+ "Like",
+ "New",
+ "Trash",
+ "Recover",
+ "Title"
+ };
+
+ static const char *fqloraGeneralStatus[] = {
+ "Canceled.",
+ "No changes for ",
+ "Reshuffled by ",
+ "No tags by ",
+ "item in the trash.",
+ "items in the trash.",
+ "item to save.",
+ "items to save.",
+ "image trashed.",
+ "images trashed.",
+ "Nothing to trash.",
+ "image recovered.",
+ "images recovered.",
+ "Nothing to recover.",
+ "image saved in ",
+ "images saved in ",
+ "image deleted.",
+ "images deleted.",
+ "Search wrapped.",
+ "No matches."
+ };
+
+ static const int toolBarFixedHeight = 40;
+ static const int statusBarFixedHeight = 18;
+ static const QSize sortBoxFixedSize(110, 25);
+
+ static const QString &iconPath(const QString &fileName) {
+
+ static QString p = "";
+
+ if (!fileName.isEmpty()) {
+ p = getPath(RESOURCE) + ICON_SOURCE + fileName;
+ }
+
+ return p;
+ }
+
+ const QString &isPlural(const int num, const int status) {
+
+ static QString m = "";
+
+ if (num == 1) {
+ return (m = fqloraGeneralStatus[status]);
+ } else if (num > 1 && status > GEN_UNKNOWN && status < GEN_DELETES) {
+ return (m = fqloraGeneralStatus[status + 1]);
+ }
+
+ return (m = fqloraGeneralStatus[GEN_UNKNOWN]);
+ }
+
+ // get user's desktop rectangle
+ static const QRect &desktopSize() {
+
+ static QRect size;
+ QDesktopWidget myDesktop;
+ return ((size = myDesktop.screenGeometry(myDesktop.primaryScreen())));
+ }
+
+ // FQTermImageFlow
+ FQTermImageFlow::~FQTermImageFlow() {
+
+ delete statusBar_;
+ delete imageMenu_;
+ delete imageFlow_;
+
+ statusBar_ = NULL;
+ imageMenu_ = NULL;
+ imageFlow_ = NULL;
+ }
+
+ FQTermImageFlow::FQTermImageFlow(FQTermConfig * config, QWidget *parent,
+ Qt::WindowFlags wflag) :
+ FQTermImage(parent, wflag),
+ imageFlow_(new ImageFlow(this)),
+ imageMenu_(new ImageMenu(this)),
+ statusBar_(new QStatusBar(this)),
+ config_(config) {
+
+ setWindowTitle(IMAGE_BROWSER_NAME);
+ setAutoFillBackground(true);
+ setBackgroundRole(QPalette::Midlight);
+ setFixedSize(desktopSize().width() / 1.3, desktopSize().height() / 1.9);
+
+ FQ_VERIFY(connect(this, SIGNAL(isTrashEmpty()), this, SLOT(checkTrashState())));
+
+ // emblem state
+ FQ_VERIFY(connect(imageFlow_, SIGNAL(emblemStatus(const int)), imageMenu_, SLOT(updateEmblems(const int))));
+ FQ_VERIFY(connect(imageMenu_, SIGNAL(toggleFlowStatus(const int)), imageFlow_, SLOT(toggleStatus(const int))));
+
+ // clear state
+ FQ_VERIFY(connect(imageFlow_, SIGNAL(clearStatus(const bool)), imageMenu_, SLOT(updateClear(const bool))));
+ FQ_VERIFY(connect(imageMenu_, SIGNAL(clearImages()), this, SLOT(clearImages())));
+
+ // save state
+ FQ_VERIFY(connect(imageFlow_, SIGNAL(saveStatus(const bool)), imageMenu_, SLOT(updateSave(const bool))));
+ FQ_VERIFY(connect(imageMenu_, SIGNAL(saveImages()), this, SLOT(saveImages())));
+
+ // trash state
+ FQ_VERIFY(connect(this, SIGNAL(trashStatus(const bool)), imageMenu_, SLOT(updateDustbin(const bool))));
+ FQ_VERIFY(connect(imageMenu_, SIGNAL(recoverImages()), this, SLOT(recoverImages())));
+
+ // constructs a tool bar and its tool buttons
+ QAction *closeBrowserAct = new QAction(QIcon(iconPath("window-close.png")), tr("Close"), this);
+ closeBrowserAct->setShortcut(QKeySequence(Qt::Key_Q));
+ FQ_VERIFY(connect(closeBrowserAct, SIGNAL(triggered()), this, SLOT(close())));
+
+ QAction *trashAllAct = new QAction(QIcon(iconPath("trash-empty.png")), tr("Trash All"), this);
+ trashAllAct->setShortcut(QKeySequence(Qt::Key_Delete));
+ FQ_VERIFY(connect(trashAllAct, SIGNAL(triggered()), this, SLOT(trashAllImages())));
+
+ QLabel *sortLabel = new QLabel(this);
+ sortLabel->setMargin(5);
+ sortLabel->setToolTip("Reshuffle images by tags");
+ sortLabel->setPixmap(QPixmap(iconPath("edit-shuffle.png")));
+
+ QComboBox *sortBox = new QComboBox(this);
+ sortBox->setFocusPolicy(Qt::ClickFocus);
+ sortBox->setFont(QFont("Serif", 12));
+ sortBox->setFrame(false);
+ sortBox->setFixedSize(sortBoxFixedSize);
+ sortBox->insertItem(0, QIcon(iconPath("emblem-like-16x16.png")), tr("Like "));
+ sortBox->insertItem(1, QIcon(iconPath("emblem-new-16x16.png")), tr("New "));
+ sortBox->insertItem(2, QIcon(iconPath("emblem-trash-16x16.png")), tr("Trash "));
+ sortBox->insertItem(3, QIcon(iconPath("emblem-recover-16x16.png")), tr("Recover "));
+ sortBox->insertItem(4, QIcon(iconPath("emblem-title-16x16.png")), tr("Title "));
+ FQ_VERIFY(connect(sortBox, SIGNAL(currentIndexChanged(int)), this, SLOT(reshuffleImages(int))));
+
+ QToolBar *toolBar = new QToolBar(this);
+ toolBar->setFixedHeight(toolBarFixedHeight);
+ toolBar->setIconSize(QSize(32, 32));
+ toolBar->addAction(closeBrowserAct);
+ toolBar->addSeparator();
+ toolBar->addWidget(sortLabel);
+ toolBar->addWidget(sortBox);
+ toolBar->addSeparator();
+ toolBar->addAction(trashAllAct);
+
+ // constructs a status bar to show instant messages
+ statusBar_->setSizeGripEnabled(false);
+ statusBar_->setFixedHeight(statusBarFixedHeight);
+ statusBar_->setFont(QFont("Serif", 10, QFont::Bold));
+ FQ_VERIFY(connect(imageFlow_, SIGNAL(statusMessage(const QString &)), this, SLOT(showStatusMessage(const QString &))));
+ FQ_VERIFY(connect(this, SIGNAL(statusMessage(const QString &)), this, SLOT(showStatusMessage(const QString &))));
+ // constructs a horizontal layout
+ QVBoxLayout *vBox = new QVBoxLayout(this);
+ vBox->setMargin(0);
+ vBox->setSpacing(0);
+ vBox->addWidget(toolBar);
+ vBox->addWidget(imageFlow_);
+ vBox->addWidget(imageMenu_);
+ vBox->addWidget(statusBar_);
+ vBox->setEnabled(true);
+ setLayout(vBox);
+ }
+
+ const QString &FQTermImageFlow::poolSource(void) const {
+
+ static QString p = "";
+
+ p = config_->getItemValue("preference", "pool");
+
+ if (p.isEmpty()) {
+ p = getPath(USER_CONFIG) + POOL_SOURCE;
+ }
+
+ return p;
+ }
+
+ const QString &FQTermImageFlow::trashSource(void) const {
+
+ static QString p = "";
+
+ p = poolSource() + TRASH_SOURCE;
+ return p;
+ }
+
+ // these three functions below are kept for
+ // API compatibility.
+ void FQTermImageFlow::adjustItemSize() {
+
+ }
+
+ void FQTermImageFlow::scrollTo(const QString &filePath) {
+
+ }
+
+ void FQTermImageFlow::updateImage(const QString &filePath) {
+
+ }
+
+ // slots and functions
+ void FQTermImageFlow::loadImages(const int status) {
+
+ int i;
+ int itemStatus = (status == STAT_RECOVER) ? status : STAT_UNKNOWN;
+ QString comment;
+ QFileInfoList sourceList = sortedList(poolSource());
+ QFileInfoList targetList = imageFlow_->digest(STAT_ALL);
+
+ for (i = 0; i < sourceList.count(); i++) {
+
+ if (!targetList.contains(sourceList[i])) {
+
+ QImage image;
+
+ if (!image.load(sourceList[i].absoluteFilePath())) {
+ QFileIconProvider iconProvider;
+ image = iconProvider.icon(sourceList[i]).pixmap(desktopSize().height() / 6.0).toImage();
+ } else {
+ image = image.scaled(desktopSize().width() / 6.0, desktopSize().height() / 6.0,
+ Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ }
+
+ /* TODO */
+ /* there should be a more flexible */
+ /* method to deal with items' status */
+ if (status == STAT_ALL) {
+ itemStatus = STAT_NEW;
+ }
+
+ ImageFlowItem newItem(image, sourceList[i], comment,itemStatus);
+ imageFlow_->add(newItem);
+ }
+ }
+ }
+
+ void FQTermImageFlow::reshuffleImages(const int status) {
+
+ // there are images in the pool directory
+ QList<qint64> itemKeys = imageFlow_->sort(status);
+
+ if (imageFlow_->reorder(itemKeys)) {
+ imageFlow_->setCurrentSlide(0);
+ emit statusMessage(tr(fqloraGeneralStatus[GEN_RESHUFFLE]) + tr(fqloraTagStatus[status]));
+ } else {
+ emit statusMessage(tr(fqloraGeneralStatus[GEN_NOCHANGE]) + tr(fqloraTagStatus[status]));
+ }
+ }
+
+ void FQTermImageFlow::saveImages() {
+
+ QFileInfoList toSave = imageFlow_->digest(STAT_LIKE);
+
+ if (!toSave.isEmpty()) {
+
+ QMessageBox box;
+ box.setWindowModality(Qt::NonModal);
+ box.setWindowTitle("Information");
+ box.setIconPixmap(QPixmap(iconPath("emblem-info.png")));
+ box.setTextFormat(Qt::RichText);
+ box.setText(QString("<b>%1</b> ").arg(toSave.count()) + isPlural(toSave.count(), GEN_TOSAVE));
+ QPushButton *cancelButton = box.addButton(QMessageBox::Cancel);
+ QPushButton *saveAllButton = box.addButton(QMessageBox::SaveAll);
+ box.setDefaultButton(cancelButton);
+ box.exec();
+
+ if (box.clickedButton() == saveAllButton) {
+
+ FQTermFileDialog fileDialog(config_);
+ QString savePath =
+ fileDialog.getExistingDirectory(tr("Save your likes under"), "*");
+
+ if (savePath.isEmpty()) {
+ emit statusMessage(tr(fqloraGeneralStatus[GEN_CANCEL]));
+ return;
+ }
+
+ int i;
+ for (i = 0; i < toSave.count(); i++) {
+ QFile::rename(toSave[i].absoluteFilePath(), savePath + toSave[i].fileName());
+ }
+
+ imageFlow_->strip(STAT_LIKE);
+ emit statusMessage(QString("%1 ").arg(i) + isPlural(i, GEN_SAVE) + savePath);
+ } else {
+ emit statusMessage(tr(fqloraGeneralStatus[GEN_CANCEL]));
+ }
+ } else {
+ emit statusMessage(tr(fqloraGeneralStatus[GEN_NOTAG]) + tr(fqloraTagStatus[STAT_LIKE]));
+ }
+ }
+
+ void FQTermImageFlow::checkTrashState() {
+
+ QDir trashPath(trashSource());
+
+ if (trashPath.count() <= 2) {
+ emit trashStatus(false);
+ } else {
+ emit trashStatus(true);
+ }
+ }
+
+ void FQTermImageFlow::clearImages() {
+
+ int i;
+ QString trashPath = trashSource();
+ QDir trashDir(trashPath);
+ QFileInfoList toRemove = imageFlow_->digest(STAT_TRASH);
+
+ if (!trashDir.exists()) {
+ trashDir.mkdir(trashPath);
+ }
+
+ if (!toRemove.isEmpty()) {
+
+ for (i = 0; i < toRemove.count(); i++) {
+ if (QFile::exists(toRemove[i].absoluteFilePath())) {
+ QFile::rename(toRemove[i].absoluteFilePath(), trashPath + toRemove[i].fileName());
+ }
+ }
+
+ imageFlow_->strip(STAT_TRASH);
+ emit statusMessage(QString("%1 ").arg(i) + isPlural(i, GEN_TRASH));
+ emit isTrashEmpty();
+ } else {
+ emit statusMessage(tr(fqloraGeneralStatus[GEN_NOTAG]) + tr(fqloraTagStatus[STAT_TRASH]));
+ }
+ }
+
+ void FQTermImageFlow::trashAllImages() {
+
+ int i;
+ QString trashPath = trashSource();
+ QDir trashDir(trashPath);
+ QFileInfoList toRemove = imageFlow_->digest(STAT_ALL);
+
+ if (!trashDir.exists()) {
+ trashDir.mkdir(trashPath);
+ }
+
+ if (imageFlow_->count() > 0) {
+ for (i = 0; i < imageFlow_->count(); i++) {
+ if (QFile::exists(toRemove[i].absoluteFilePath())) {
+ QFile::rename(toRemove[i].absoluteFilePath(), trashPath + toRemove[i].fileName());
+ }
+ }
+
+ imageFlow_->clear();
+ emit statusMessage(QString("%1 ").arg(i) + isPlural(i, GEN_TRASH));
+ emit isTrashEmpty();
+ } else {
+ emit statusMessage(tr(fqloraGeneralStatus[GEN_NOTAG]) + tr(fqloraTagStatus[STAT_TRASH]));
+ }
+ }
+
+ void FQTermImageFlow::recoverImages() {
+
+ QString trashPath = trashSource();
+ QDir trashDir(trashPath);
+
+ if (!trashDir.exists()) {
+ trashDir.mkdir(trashPath);
+ } else if (trashDir.count() > 2) {
+
+ int action = -1;;
+ QFileInfoList toRecover = sortedList(trashPath);
+
+ if (!toRecover.isEmpty()) {
+
+ QMessageBox box;
+ box.setWindowModality(Qt::NonModal);
+ box.setWindowTitle("Take action");
+ box.setIconPixmap(QPixmap(iconPath("emblem-info.png")));
+ box.setTextFormat(Qt::RichText);
+ box.setText(QString("<b>%1</b> ").arg(toRecover.count()) + isPlural(toRecover.count(), GEN_INTRASH));
+ QPushButton *cancelButton = box.addButton(QMessageBox::Cancel);
+ QPushButton *recoverButton = box.addButton(tr("Recover"), QMessageBox::ApplyRole);
+ recoverButton->setIcon(QIcon(iconPath("button-recover.png")));
+ QPushButton *deleteButton = box.addButton(tr("Delete"), QMessageBox::ApplyRole);
+ deleteButton->setIcon(QIcon(iconPath("button-delete.png")));
+ box.setDefaultButton(cancelButton);
+ box.exec();
+
+ if (box.clickedButton() == cancelButton) {
+ emit statusMessage(tr(fqloraGeneralStatus[GEN_CANCEL]));
+ return;
+ } else if (box.clickedButton() == recoverButton) {
+ action = 1;
+ } else if (box.clickedButton() == deleteButton) {
+ action = 0;
+ }
+
+ int i;
+ QFile imageFile;
+ QString poolPath = poolSource();
+
+ for (i = 0; i < toRecover.count(); i++) {
+ if (action == 1) {
+ QFile::rename(toRecover[i].absoluteFilePath(), poolPath + toRecover[i].fileName());
+ } else if (action == 0) {
+ imageFile.setFileName(toRecover[i].absoluteFilePath());
+ imageFile.remove();
+ }
+ }
+
+ if (action == 1) {
+ loadImages(STAT_RECOVER);
+ emit statusMessage(QString("%1 ").arg(i) + isPlural(i, GEN_RECOVER));
+ } else if (action == 0) {
+ emit statusMessage(QString("%1 ").arg(i) + isPlural(i, GEN_DELETE));
+ }
+ }
+ } else {
+
+ emit statusMessage(tr(fqloraGeneralStatus[GEN_NORECOVER]));
+ }
+
+ emit isTrashEmpty();
+ }
+
+
+ void FQTermImageFlow::showStatusMessage(const QString &message) {
+
+ if (statusBar_) {
+ statusBar_->showMessage(message, 3000);
+ }
+ }
+
+ QFileInfoList FQTermImageFlow::sortedList(const QString &path) {
+
+ QDir sortPath(path);
+
+ if (!sortPath.exists()) {
+ sortPath.mkdir(path);
+ }
+
+ QStringList filters;
+ QList<QByteArray> formats = QImageReader::supportedImageFormats();
+ for (QList<QByteArray>::iterator it = formats.begin();
+ it != formats.end();
+ ++it) {
+ QString filter("*.");
+ filter.append(it->data());
+ filters << filter;
+ }
+ sortPath.setNameFilters(filters);
+
+ return (sortPath.entryInfoList(QDir::Files | QDir::Readable | QDir::NoSymLinks, QDir::Time));
+ }
+
+ // FQTermImageFlow events.
+ void FQTermImageFlow::showEvent(QShowEvent *event) {
+
+ emit isTrashEmpty();
+
+ if (imageFlow_->count() <= 0) {
+ loadImages(STAT_UNKNOWN);
+ move((desktopSize().width() - width()) / 2.0, (desktopSize().height() - height()) / 2.0);
+ } else {
+ // TODO: insert new images
+ loadImages(STAT_ALL);
+ }
+ }
+
+ void FQTermImageFlow::closeEvent(QCloseEvent *event) {
+
+ hide();
+ }
+
+ class ImageMenu::Private {
+ public:
+ int emblemStatus;
+ bool dustbinStatus;
+ bool saveStatus;
+ bool clearStatus;
+
+ QString tipMessage;
+
+ QRect rectLike;
+ QRect rectTrash;
+ QRect rectNew;
+ QRect rectRecover;
+ QRect rectEmblems;
+
+ QRect rectClear;
+ QRect rectSave;
+ QRect rectDustbin;
+
+ QPixmap pixmapLike, pixmapLikeGray;
+ QPixmap pixmapTrash, pixmapTrashGray;
+ QPixmap pixmapNew, pixmapNewGray;
+ QPixmap pixmapRecover, pixmapRecoverGray;
+
+ QPixmap pixmapClear, pixmapClearGray;
+ QPixmap pixmapSave, pixmapSaveGray;
+ QPixmap pixmapDustbin, pixmapDustbinGray;
+ };
+
+ //ImageMenu
+ ImageMenu::ImageMenu(QWidget *parent)
+ : fh(new ImageMenu::Private) {
+
+ setAutoFillBackground(true);
+ setBackgroundRole(QPalette::Shadow);
+ setFocusPolicy(Qt::NoFocus);
+ setMouseTracking(true);
+ setFixedHeight(60);
+
+ fh->emblemStatus = -2;
+ fh->dustbinStatus = false;
+ fh->saveStatus = false;
+ fh->clearStatus = false;
+
+ fh->tipMessage = "";
+
+ fh->rectLike = QRect(50, 14, 32, 32);
+ fh->rectTrash = QRect(100, 14, 32, 32);
+ fh->rectNew = QRect(150, 14, 32, 32);
+ fh->rectRecover = QRect(200, 14, 32, 32);
+ fh->rectEmblems = QRect(50, 14, 232, 32);
+
+ fh->rectClear = QRect(300, 14, 32, 32);
+ fh->rectSave = QRect(350, 14, 32, 32);
+ fh->rectDustbin = QRect(400, 14, 32, 32);
+
+ fh->pixmapLike = QPixmap(iconPath("emblem-like.png"));
+ fh->pixmapLikeGray = QPixmap(iconPath("emblem-like-gray.png"));
+
+ fh->pixmapTrash = QPixmap(iconPath("emblem-trash.png"));
+ fh->pixmapTrashGray = QPixmap(iconPath("emblem-trash-gray.png"));
+
+ fh->pixmapNew = QPixmap(iconPath("emblem-new.png"));
+ fh->pixmapNewGray = QPixmap(iconPath("emblem-new-gray.png"));
+
+ fh->pixmapRecover = QPixmap(iconPath("emblem-recover.png"));
+ fh->pixmapRecoverGray = QPixmap(iconPath("emblem-recover-gray.png"));
+
+ fh->pixmapClear = QPixmap(iconPath("clear-state.png"));
+ fh->pixmapClearGray = QPixmap(iconPath("clear-state-gray.png"));
+
+ fh->pixmapSave = QPixmap(iconPath("save-state.png"));
+ fh->pixmapSaveGray = QPixmap(iconPath("save-state-gray.png"));
+
+ fh->pixmapDustbin = QPixmap(iconPath("trash-state.png"));
+ fh->pixmapDustbinGray = QPixmap(iconPath("trash-state-gray.png"));
+ }
+
+ ImageMenu::~ImageMenu() {
+
+ delete fh;
+ fh = NULL;
+ }
+
+ void ImageMenu::updateEmblems(const int status) {
+
+ if (fh->emblemStatus != status) {
+ update(fh->rectEmblems);
+ }
+
+ fh->emblemStatus = status;
+ }
+
+ void ImageMenu::updateClear(const bool hasOrNot) {
+
+ if (fh->clearStatus != hasOrNot) {
+ update(fh->rectClear);
+ }
+
+ fh->clearStatus = hasOrNot;
+ }
+
+ void ImageMenu::updateSave(const bool hasOrNot) {
+
+ if (fh->saveStatus != hasOrNot) {
+ update(fh->rectSave);
+ }
+
+ fh->saveStatus = hasOrNot;
+ }
+
+ void ImageMenu::updateDustbin(const bool fullOrNot) {
+
+ if (fh->dustbinStatus != fullOrNot) {
+ update(fh->rectDustbin);
+ }
+
+ fh->dustbinStatus = fullOrNot;
+ }
+
+ void ImageMenu::paintEvent(QPaintEvent *event) {
+
+ QPainter p(this);
+
+ p.setRenderHints(QPainter::SmoothPixmapTransform | QPainter::Antialiasing);
+
+ if (fh->emblemStatus == STAT_LIKE) {
+ p.drawPixmap(fh->rectLike, fh->pixmapLike);
+ } else {
+ p.drawPixmap(fh->rectLike, fh->pixmapLikeGray);
+ }
+
+ if (fh->emblemStatus == STAT_TRASH) {
+ p.drawPixmap(fh->rectTrash, fh->pixmapTrash);
+ } else {
+ p.drawPixmap(fh->rectTrash, fh->pixmapTrashGray);
+ }
+
+ if (fh->emblemStatus == STAT_NEW) {
+ p.drawPixmap(fh->rectNew, fh->pixmapNew);
+ } else {
+ p.drawPixmap(fh->rectNew, fh->pixmapNewGray);
+ }
+
+ if (fh->emblemStatus == STAT_RECOVER) {
+ p.drawPixmap(fh->rectRecover, fh->pixmapRecover);
+ } else {
+ p.drawPixmap(fh->rectRecover, fh->pixmapRecoverGray);
+ }
+
+ if (fh->clearStatus == true) {
+ p.drawPixmap(fh->rectClear, fh->pixmapClear);
+ } else {
+ p.drawPixmap(fh->rectClear, fh->pixmapClearGray);
+ }
+
+ if (fh->saveStatus == true) {
+ p.drawPixmap(fh->rectSave, fh->pixmapSave);
+ } else {
+ p.drawPixmap(fh->rectSave, fh->pixmapSaveGray);
+ }
+
+ if (fh->dustbinStatus == true) {
+ p.drawPixmap(fh->rectDustbin, fh->pixmapDustbin);
+ } else {
+ p.drawPixmap(fh->rectDustbin, fh->pixmapDustbinGray);
+ }
+
+ p.end();
+ }
+
+ void ImageMenu::mouseReleaseEvent(QMouseEvent *event) {
+
+ if (event->button() == Qt::LeftButton
+ || event->button() == Qt::RightButton) {
+
+ if (fh->rectLike.contains(event->pos())) {
+ emit toggleFlowStatus(STAT_LIKE);
+ }
+
+ if (fh->rectTrash.contains(event->pos())) {
+ emit toggleFlowStatus(STAT_TRASH);
+ }
+
+ if (fh->rectClear.contains(event->pos())) {
+ emit clearImages();
+ }
+
+ if (fh->rectSave.contains(event->pos())) {
+ emit saveImages();
+ }
+
+ if (fh->rectDustbin.contains(event->pos())) {
+ emit recoverImages();
+ }
+ }
+ }
+
+ // ImageFlow: this subclasses PictureFlow
+ class ImageFlow::Private {
+ public:
+ int emblemStatus;
+ int likeCount;
+ int clearCount;
+
+ QList<QByteArray> itemsTitles;
+ QHash<QByteArray, qint64> itemsTitleKeyPairs;
+ QList<ImageFlowItem> items;
+ };
+
+ ImageFlow::~ImageFlow() {
+
+ delete m;
+ m = NULL;
+ }
+
+ // construct an emptry pictureflow.
+ ImageFlow::ImageFlow(QWidget *parent)
+ : PictureFlow(parent), m(new ImageFlow::Private) {
+
+ // initial setup
+ setFocusPolicy(Qt::StrongFocus);
+ setZoomFactor(120);
+ setSlideCount(0);
+ m->emblemStatus = -1;
+ m->likeCount = 0;
+ m->clearCount = 0;
+ }
+
+ const ImageFlowItem& ImageFlow::operator[](int index) const {
+
+ return (m->items[index]);
+ }
+
+ ImageFlowItem& ImageFlow::operator[](int index) {
+
+ return (m->items[index]);
+ }
+
+ const ImageFlowItem& ImageFlow::at(int index) const {
+
+ return (m->items[index]);
+ }
+
+ void ImageFlow::add(const ImageFlowItem &item) {
+
+ QByteArray title = item.info().fileName().toLocal8Bit();
+
+ m->items.append(item);
+ m->itemsTitles.append(title);
+ m->itemsTitleKeyPairs.insert(title, item.key());
+
+ // set the status pixmap
+ int index = m->items.indexOf(item);
+ m->items[index].setStatus(item.status());
+
+ int count = m->items.count();
+ setSlideCount(count);
+ setSlide(count - 1, item.image());
+ }
+
+ QList<QByteArray>& ImageFlow::itemsTitles() const {
+
+ return (m->itemsTitles);
+ }
+
+ void ImageFlow::clear() {
+
+ m->items.clear();
+ setSlideCount(0);
+ setCurrentSlide(0);
+ PictureFlow::clear();
+ }
+
+ int ImageFlow::count() const {
+
+ return (m->items.count());
+ }
+
+ int ImageFlow::size() const {
+
+ return (m->items.size());
+ }
+
+ QFileInfoList& ImageFlow::digest(const int status) {
+
+ int i;
+ int count = m->items.size();
+ static QFileInfoList result;
+
+ result.clear();
+
+ for (i = 0; i < count; i++) {
+ switch (status) {
+ case STAT_ALL:
+ result.append(m->items[i].info());
+ break;
+ default:
+ if (m->items[i].status() == status) {
+ result.append(m->items[i].info());
+ }
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ void ImageFlow::strip(const int status) {
+
+ int i;
+ int count = m->items.count();
+ QList<int> dirtyIndexes;
+
+ // We cannot delete items in a loop because
+ // items count will change while deleting.
+ // A better method is to use another list
+ // to record 'dirty' items, and by looping this
+ // dirty list, we can correctly delete those
+ // dirty items successfully.
+ for (i = 0; i < count; i++) {
+ if (m->items[i].status() == status) {
+ dirtyIndexes.append(i);
+ }
+ }
+
+ if (!dirtyIndexes.isEmpty()) {
+
+ for (i = 0; i < dirtyIndexes.count(); i++) {
+ // Note: dirtyIndexes[i] - i: the actual
+ // position of the dirty item.
+ m->items.removeAt(dirtyIndexes[i] - i);
+ }
+
+ dirtyIndexes.clear();
+ reorder(sort(STAT_ALL));
+
+ for (i = 0; i < m->items.count(); i++) {
+ setSlide(i, m->items[i].image());
+ }
+
+ setSlideCount(i);
+ setCurrentSlide(0);
+
+ switch(status) {
+ case STAT_LIKE:
+ m->likeCount = 0;
+ emit saveStatus(false);
+ emit emblemStatus(STAT_UNKNOWN);
+ break;
+ case STAT_TRASH:
+ m->clearCount = 0;
+ emit clearStatus(false);
+ emit emblemStatus(STAT_UNKNOWN);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ QList<qint64> ImageFlow::sort(const int status) {
+
+ int i;
+ int count = m->items.count();
+ QList<qint64> itemKeys;
+
+ switch (status) {
+ case STAT_TITLE:
+ qStableSort(m->itemsTitles.begin(), m->itemsTitles.end(), qLess<QByteArray>());
+ for (i = 0; i < m->itemsTitles.count(); i++) {
+ itemKeys.append(m->itemsTitleKeyPairs.value(m->itemsTitles[i]));
+ }
+ break;
+ default:
+ for (i = 0; i < count; i++) {
+ if (m->items[i].status() == status) {
+ itemKeys.prepend(m->items[i].key());
+ } else {
+ itemKeys.append(m->items[i].key());
+ }
+ }
+ break;
+ }
+
+ // this might be unnecessary here.
+ return itemKeys;
+ }
+
+ bool ImageFlow::reorder(const QList<qint64>& itemsKey) {
+
+ int items_count = m->items.size();
+
+ if (itemsKey.size() != items_count) {
+
+ return (false);
+ }
+
+ // Collect Items Key
+ QList<qint64> currentItemsKey;
+ for (int i = 0; i < items_count; i++) {
+
+ currentItemsKey.append(m->items.at(i).key());
+ }
+
+ if (currentItemsKey == itemsKey) {
+ // if identical, we don't sort.
+ return (false);
+ }
+
+ // Swap Items
+ for (int i=0; i < items_count; i++) {
+
+ int index = currentItemsKey.indexOf(itemsKey.at(i));
+ if (i == index) {
+ continue;
+ }
+
+ QImage imgA = m->items[i].image();
+ QImage imgB = m->items[index].image();
+
+ setSlide(index, imgA);
+ setSlide(i, imgB);
+
+ m->items.swap(i, index);
+ currentItemsKey.swap(i, index);
+ }
+
+ update();
+ rehash();
+ return(true);
+ }
+
+ void ImageFlow::rehash(void) {
+
+ int count = m->items.count();
+
+ if (count <= 0) {
+ return;
+ }
+
+ int i;
+
+ m->itemsTitles.clear();
+ m->itemsTitleKeyPairs.clear();
+
+ qint64 k;
+ QByteArray b;
+
+ for (i = 0; i < count; i++) {
+ k = m->items[i].key();
+ b = m->items[i].info().fileName().toLocal8Bit();
+ m->itemsTitles.append(b);
+ m->itemsTitleKeyPairs.insert(b, k);
+ }
+ }
+
+ void ImageFlow::toggleStatus(const int status) {
+
+ int index = currentSlide();
+ int count = m->items.count();
+
+ if (index >= 0 && index < count) {
+
+ setUpdatesEnabled(false);
+ if (m->items[index].status() != status) {
+
+ switch (status) {
+ case STAT_LIKE:
+ m->likeCount++;
+ if (m->items[index].status() == STAT_TRASH) {
+ m->clearCount--;
+ }
+ emit saveStatus(true);
+ break;
+ case STAT_TRASH:
+ m->clearCount++;
+ if (m->items[index].status() == STAT_LIKE) {
+ m->likeCount--;
+ }
+ emit clearStatus(true);
+ break;
+ default:
+ break;
+ }
+
+ m->items[index].setStatus(status);
+ emit statusMessage(tr("Tagged as ") + tr(fqloraTagStatus[status]));
+
+ } else {
+
+ switch (status) {
+ case STAT_LIKE:
+ m->likeCount--;
+ break;
+ case STAT_TRASH:
+ m->clearCount--;
+ break;
+ default:
+ break;
+ }
+
+ m->items[index].setStatus(STAT_UNKNOWN);
+ emit statusMessage("Tag cleared");
+ }
+
+ if (m->likeCount <= 0) {
+ emit saveStatus(false);
+ } else {
+ emit saveStatus(true);
+ }
+
+ if (m->clearCount <= 0) {
+ emit clearStatus(false);
+ } else {
+ emit clearStatus(true);
+ }
+
+ setUpdatesEnabled(true);
+ }
+ }
+
+ void ImageFlow::setCurrentImage(const int index) {
+
+ int count = size();
+
+ if (count > 0 && index > 0 && index < count) {
+
+ setCurrentSlide(index);
+ }
+ }
+
+// events
+ void ImageFlow::paintEvent(QPaintEvent *event) {
+
+ PictureFlow::paintEvent(event);
+
+ if (slideCount() < 1) {
+ return;
+ }
+
+ QPainter p(this);
+
+ // White Pen for File Info
+ p.setPen(Qt::gray);
+
+ int cw = width() / 2;
+ int wh = height();
+
+ ImageFlowItem& item = m->items[currentSlide()];
+
+ // Draw File Name if it's not empty
+ QString title = item.info().fileName();
+ if (!title.isEmpty()) {
+
+ p.setFont(QFont(p.font().family(), p.font().pointSize() + 1, QFont::Bold));
+ p.drawText(cw - (QFontMetrics(p.font()).width(title) / 2), wh - 20, title);
+ }
+
+ p.end();
+
+ if (m->emblemStatus != item.status()) {
+ emit emblemStatus(item.status());
+ }
+
+ m->emblemStatus = item.status();
+ }
+
+ // ImageFlowItem
+ class ImageFlowItem::Private {
+ public:
+ QString filePath;
+ QFileInfo info;
+ QString comment;
+ QImage image;
+ int status;
+ qint64 key;
+
+ };
+
+ ImageFlowItem::~ImageFlowItem() {
+
+ delete m;
+ m = NULL;
+ }
+
+ // constructs an empty item
+ ImageFlowItem::ImageFlowItem(QObject *parent)
+ : QObject(parent), m(new ImageFlowItem::Private) {
+
+ m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment);
+ }
+
+ ImageFlowItem::ImageFlowItem(const ImageFlowItem &item)
+ : QObject(item.parent()), m(new ImageFlowItem::Private) {
+
+ operator=(item);
+ }
+
+ // constructs an item with a given image
+ ImageFlowItem::ImageFlowItem(const QImage &image, QObject *parent)
+ : QObject(parent), m(new ImageFlowItem::Private) {
+
+ m->image = image;
+ m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment);
+ }
+
+ // constructs an image with given image and title
+ ImageFlowItem::ImageFlowItem(const QImage &image, const QFileInfo &info, QObject *parent)
+ : QObject(parent), m(new ImageFlowItem::Private) {
+
+ m->image = image;
+ m->info = info;
+ m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment);
+ }
+
+ // constructs an image with given image, title and comment
+ ImageFlowItem::ImageFlowItem(const QImage &image, const QFileInfo &info, const QString &comment, QObject *parent)
+ : QObject(parent), m(new ImageFlowItem::Private) {
+
+ m->image = image;
+ m->info = info;
+ m->comment = comment;
+ m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment);
+ }
+
+ // constructs an image with given image, title, type, size, time and state
+ ImageFlowItem::ImageFlowItem(const QImage &image, const QFileInfo &info, const QString& comment, const int status, QObject *parent)
+ : QObject(parent), m(new ImageFlowItem::Private) {
+
+ m->image = image;
+ m->info = info;
+ m->comment = comment;
+ m->status = status;
+
+ m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment);
+ }
+
+ // funcs and slots
+ ImageFlowItem& ImageFlowItem::operator=(const ImageFlowItem &item) {
+
+ m->info = item.m->info;
+ m->comment = item.m->comment;
+ m->key = item.m->key;
+
+ if (item.m->filePath.isEmpty()) {
+ m->image = item.m->image;
+ } else {
+ setImage(item.m->filePath, m->key);
+ }
+
+ return (*this);
+ }
+
+ bool ImageFlowItem::operator==(const ImageFlowItem& item) const {
+
+ return (item.m->key == m->key);
+ }
+
+ bool ImageFlowItem::operator!=(const ImageFlowItem& item) const {
+
+ return (item.m->key != m->key);
+ }
+
+ const QString& ImageFlowItem::comment() const {
+
+ return (m->comment);
+ }
+
+ const QImage& ImageFlowItem::image() const {
+
+ return (m->image);
+ }
+
+ int ImageFlowItem::status(void) const {
+
+ return (m->status);
+ }
+
+ const QFileInfo& ImageFlowItem::info(void) const {
+
+ return (m->info);
+ }
+
+ qint64 ImageFlowItem::key() const {
+
+ return (m->key);
+ }
+
+ void ImageFlowItem::setInfo(const QFileInfo& info) {
+
+ m->info = info;
+ m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment);
+ }
+
+ void ImageFlowItem::setComment(const QString &comment) {
+
+ m->comment = comment;
+ m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment);
+ }
+
+ void ImageFlowItem::setImage(const QImage &image) {
+
+ m->image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
+ m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment);
+ }
+
+ void ImageFlowItem::setImage(const QString &filePath, int size) {
+
+ m->filePath = filePath;
+ m->key = size;
+
+ QTimer::singleShot(1000, this, SLOT(loadImage()));
+ }
+
+ void ImageFlowItem::setStatus(const int status) {
+
+ m->status = status;
+ }
+
+ void ImageFlowItem::loadImage() {
+
+ int imageHeight = m->key;
+
+ if (!m->image.load(m->filePath)) {
+ QFileIconProvider iconProvider;
+ m->image = iconProvider.icon(QFileInfo(m->filePath)).pixmap(imageHeight).toImage();
+ } else {
+ m->image = resizeImage(m->image, imageHeight);
+ }
+
+ m->filePath.clear();
+ m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment);
+ }
+
+ QImage ImageFlowItem::resizeImage(const QImage &image, int size) {
+
+ if (size == image.width() && size == image.height()) {
+ return image;
+ }
+
+ double scaleWidth = size / (double)image.width();
+ double scaleHeight = size / (double)image.height();
+ double smaller = qMin(scaleWidth, scaleHeight);
+
+ int w = (int) qRound(smaller * image.width());
+ int h = (int) qRound(smaller * image.height());
+
+ return (image.scaled(w, h, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
+ }
+
+ // original viewer
+ void FQTermImageOrigin::onChange(const QModelIndex & index) {
+
+ if (!model_->isDir(index)) {
+
+ if (!isHidden())
+ canvas_->hide();
+
+ QString exifInfo = QString::fromStdString(exifExtractor_->extractExifInfo(model_->filePath(tree_->currentIndex()).toLocal8Bit().data()));
+ bool resized = false;
+
+ if (exifInfo != "") {
+
+ if (!isExifTableShown_) {
+ adjustLayout(true);
+ isExifTableShown_ = true;
+ resized = true;
+ }
+
+ updateExifInfo();
+ } else {
+
+ if (isExifTableShown_) {
+ adjustLayout(false);
+ isExifTableShown_ = false;
+ resized = true;
+ }
+ }
+
+ QString path = QDir::toNativeSeparators(model_->filePath(index));
+
+ if (path.endsWith(QDir::separator()))
+ path.chop(1);
+
+ canvas_->loadImage(path, !resized);
+
+ // canvas_->autoAdjust();
+ if (!isHidden())
+ canvas_->show();
+ }
+ }
+
+ FQTermImageOrigin::~FQTermImageOrigin() {
+ delete menuBar_;
+ delete canvas_;
+ delete tree_;
+ delete model_;
+ }
+
+ FQTermImageOrigin::FQTermImageOrigin(FQTermConfig * config, QWidget *parent,
+ Qt::WindowFlags wflag) :
+ FQTermImage(parent, wflag),
+ config_(config),
+ isExifTableShown_(false) {
+
+ setWindowTitle(tr("FQTerm Image Viewer"));
+ ItemDelegate* itemDelegate = new ItemDelegate;
+ exifExtractor_ = new ExifExtractor;
+ exifTable_ = new ExifTable(this);
+ exifTable_->setTextFormat(Qt::RichText);
+ exifTable_->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+ canvas_ = new FQTermCanvas(config, this, 0);
+ canvas_->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
+ model_ = new ImageViewerDirModel;
+ tree_ = new QTreeView;
+
+
+ tree_->setModel(model_);
+ tree_->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+ adjustItemSize();
+ tree_->setItemDelegate(itemDelegate);
+ tree_->setColumnWidth(0, 150);
+ tree_->setColumnWidth(1, 0);
+
+ tree_->hideColumn(0);
+
+ tree_->setUniformRowHeights(true);
+ tree_->setWordWrap(true);
+ //tree_->header()->setResizeMode(0, QHeaderView::Fixed);
+ //tree_->header()->setResizeMode(1, QHeaderView::ResizeToContents);
+ //tree_->header()->resizeSection(0, 150);
+ //tree_->header()->resizeSection(1, 1);
+ comboBox_ = new QComboBox(this);
+ comboBox_->addItem(tr("Sort by name"), QDir::Name);
+ comboBox_->addItem(tr("Sort by time"), QDir::Time);
+ comboBox_->addItem(tr("Sort by size"), QDir::Size);
+ comboBox_->addItem(tr("Sort by type"), QDir::Type);
+
+ FQ_VERIFY(connect(comboBox_, SIGNAL(currentIndexChanged(int)), this, SLOT(sortFileList(int))));
+
+ comboBox_->setCurrentIndex(1);
+
+ layout_ = new QGridLayout;
+ menuBar_ = new QMenuBar(this);
+ menuBar_->addMenu(canvas_->menu());
+ menuBar_->resize(1,1);
+
+ canvas_->ToolBar()->addAction(
+ QIcon(getPath(RESOURCE) + ICON_SOURCE + "prev.png"), tr("Previous"),
+ this, SLOT(previous()));
+ canvas_->ToolBar()->addAction(
+ QIcon(getPath(RESOURCE) + ICON_SOURCE + "next.png"), tr("Next"),
+ this, SLOT(next()));
+
+ layout_->addWidget(tree_, 0, 0, 12, 1);
+ layout_->addWidget(comboBox_, 12, 0, 1, 1);
+ layout_->addWidget(canvas_, 0, 1, 12, 10);
+ // layout_->addWidget(exifTable_, 10, 1, 2, 10);
+ layout_->addWidget(canvas_->ToolBar(), 12, 1, 1, 10, Qt::AlignHCenter);
+ layout_->setColumnMinimumWidth(0, tree_->columnWidth(0) + 150);
+ setLayout(layout_);
+
+ /*
+ FQ_VERIFY(connect(tree_, SIGNAL(clicked(const QModelIndex &)),
+ this, SLOT(onChange(const QModelIndex &))));
+ */
+ FQ_VERIFY(connect(tree_, SIGNAL(activated(const QModelIndex &)),
+ this, SLOT(onChange(const QModelIndex &))));
+ FQ_VERIFY(connect(tree_->selectionModel(),
+ SIGNAL(selectionChanged(const QItemSelection&,
+ const QItemSelection&)),
+ this, SLOT(selectionChanged(const QItemSelection&,
+ const QItemSelection&))));
+ FQ_VERIFY(connect(exifTable_, SIGNAL(showExifDetails()),
+ this, SLOT(showFullExifInfo())));
+ }
+
+ void FQTermImageOrigin::scrollTo(const QString& filename) {
+
+ QString path = QFileInfo(filename).absolutePath();
+ model_->refresh();
+ tree_->setRootIndex(model_->index(path));
+ canvas_->loadImage(filename);
+
+ if (canvas_->isHidden() && !isHidden()) {
+ canvas_->show();
+ }
+
+ const QModelIndex& index = model_->index(filename);
+ tree_->scrollTo(index);
+ tree_->setCurrentIndex(index);
+ }
+
+ void FQTermImageOrigin::updateImage(const QString& filename) {
+
+ static int i = 0;
+ if (++i == 10) {
+ model_->refresh(model_->index(filename));
+ i = 0;
+ }
+ canvas_->updateImage(filename);
+ }
+
+ void FQTermImageOrigin::previous() {
+
+ const QModelIndex& index = tree_->indexAbove(tree_->currentIndex());
+ if (index.isValid()) {
+ tree_->setCurrentIndex(index);
+ canvas_->loadImage(QDir::toNativeSeparators(model_->filePath(index)));
+ }
+ }
+
+ void FQTermImageOrigin::next() {
+
+ const QModelIndex& index = tree_->indexBelow(tree_->currentIndex());
+ if (index.isValid()) {
+ tree_->setCurrentIndex(index);
+ canvas_->loadImage(QDir::toNativeSeparators(model_->filePath(index)));
+ }
+ }
+
+ void FQTermImageOrigin::adjustItemSize() {
+
+ QFontMetrics fm(font());
+ ItemDelegate::size_.setWidth(qMax(128, fm.width("WWWWWWWW.WWW")));
+ ItemDelegate::size_.setHeight(fm.height() + 150);
+ }
+
+ void FQTermImageOrigin::selectionChanged(const QItemSelection & selected,
+ const QItemSelection & deselected) {
+
+ onChange(tree_->selectionModel()->currentIndex());
+ }
+
+ void FQTermImageOrigin::sortFileList(int index) {
+
+ model_->setSorting(QDir::SortFlag(comboBox_->itemData(index).toInt()));
+ QString poolPath = config_->getItemValue("preference", "pool");
+
+ if (poolPath.isEmpty()) {
+ poolPath = getPath(USER_CONFIG) + "pool/";
+ }
+
+ tree_->setRootIndex(model_->index(poolPath));
+ }
+
+ void FQTermImageOrigin::showFullExifInfo() {
+
+ QString exifInfo = QString::fromStdString(exifExtractor_->extractExifInfo(model_->filePath(tree_->currentIndex()).toLocal8Bit().data()));
+ QString comment;
+
+ if ((*exifExtractor_)["UserComment"].length() > 8) {
+
+ QString commentEncoding = QString::fromStdString((*exifExtractor_)["UserComment"].substr(0, 8));
+
+ if (commentEncoding.startsWith("UNICODE")) {
+ //UTF-16
+ QTextCodec* c = QTextCodec::codecForName("UTF-16");
+ comment = c->toUnicode((*exifExtractor_)["UserComment"].substr(8).c_str());
+ } else if (commentEncoding.startsWith("JIS")) {
+ //JIS X 0208
+ QTextCodec* c = QTextCodec::codecForName("JIS X 0208");
+ comment = c->toUnicode((*exifExtractor_)["UserComment"].substr(8).c_str());
+ } else {
+ comment = QString::fromStdString((*exifExtractor_)["UserComment"].substr(8));
+ }
+ }
+
+
+ QTextEdit* info = new QTextEdit;
+ info->setText(exifInfo + tr("Comment : ") + comment + "\n");
+ info->setWindowFlags(Qt::Dialog);
+ info->setAttribute(Qt::WA_DeleteOnClose);
+ info->setAttribute(Qt::WA_ShowModal);
+ // info->setLineWrapMode(QTextEdit::NoWrap);
+ info->setReadOnly(true);
+ QFontMetrics fm(font());
+ info->resize(fm.width("Orientation : 1st row - 1st col : top - left side "), fm.height() * 20);
+ info->show();
+ }
+
+ void FQTermImageOrigin::adjustLayout(bool withExifTable) {
+
+ if (withExifTable) {
+
+ layout_->addWidget(canvas_, 0, 1, 11, 10);
+ layout_->addWidget(exifTable_, 11, 1, 1, 10, Qt::AlignHCenter);
+ if (!isHidden() && exifTable_->isHidden()) {
+ exifTable_->show();
+ }
+
+ layout_->addWidget(canvas_->ToolBar(), 12, 1, 1, 10, Qt::AlignHCenter);
+ } else {
+ layout_->addWidget(canvas_, 0, 1, 12, 10);
+ layout_->removeWidget(exifTable_);
+ exifTable_->hide();
+ layout_->addWidget(canvas_->ToolBar(), 12, 1, 1, 10, Qt::AlignHCenter);
+ }
+ }
+
+ void FQTermImageOrigin::updateExifInfo() {
+
+ exifTable_->clear();
+
+ QString exifInfoToShow = "<table border=\"1\"><tr><td>"
+ + tr("Model") + " : " + QString::fromStdString((*exifExtractor_)["Model"]) + "</td><td>"
+ + QString::fromStdString((*exifExtractor_)["DateTime"]) + "</td><td>"
+ + QString::fromStdString((*exifExtractor_)["Flash"]) + "</td>"
+ + "</tr><tr><td>"
+ + tr("ExposureTime") + " : " + QString::fromStdString((*exifExtractor_)["ExposureTime"]) + "</td><td>"
+ + tr("FNumber") + " : " + QString::fromStdString((*exifExtractor_)["FNumber"]) + "</td><td>"
+ + tr("ISO") + " : " + QString::fromStdString((*exifExtractor_)["ISOSpeedRatings"]) + "</td>"
+ + "</tr><tr><td>"
+ + tr("FocalLength") + " : " + QString::fromStdString((*exifExtractor_)["FocalLength"]) + "</td><td>"
+ + tr("MeteringMode") + " : " + QString::fromStdString((*exifExtractor_)["MeteringMode"]) + "</td><td>"
+ + tr("ExposureBias") + " : " + QString::fromStdString((*exifExtractor_)["ExposureBiasValue"]) + "</td></tr></tabel>";
+
+ exifTable_->setText(exifInfoToShow);
+ if (!isHidden() && exifTable_->isHidden()) {
+ exifTable_->show();
+ }
+ }
+
+ void FQTermImageOrigin::closeEvent( QCloseEvent *clse ) {
+
+ hide();
+ clse->ignore();
+ return ;
+ }
+
+ ImageViewerDirModel::ImageViewerDirModel(QObject *parent /*= 0*/)
+ : QDirModel(parent) {
+
+ //insertColumn(1);
+ QStringList nameFilterList;
+ QList<QByteArray> formats = QImageReader::supportedImageFormats();
+ for (QList<QByteArray>::iterator it = formats.begin();
+ it != formats.end();
+ ++it) {
+ QString filter("*.");
+ filter.append(it->data());
+ nameFilterList << filter;
+ }
+ setNameFilters(nameFilterList);
+ setFilter(QDir::Files);
+ }
+
+ int ImageViewerDirModel::columnCount(const QModelIndex &/*parent*/) const {
+
+ return 2;
+ }
+
+ QVariant ImageViewerDirModel::headerData(
+ int section, Qt::Orientation orientation, int role) const {
+ //if (section == 0) return QVariant();
+ if (role == Qt::DisplayRole) {
+ // if (section == 1) {
+ return QString(tr("Image Preview"));
+ //}
+ }
+ return QDirModel::headerData(section, orientation, role);
+ }
+
+ QVariant ImageViewerDirModel::data(const QModelIndex &index, int role) const {
+ //if (index.column() == 0) return QVariant();
+ if (role == Qt::DecorationRole) {
+ if (isDir(index)) {
+ return QVariant();
+ }
+
+ QString path = QDir::toNativeSeparators(filePath(index));
+ if (path.endsWith(QDir::separator()))
+ path.chop(1);
+
+ QPixmap pixmap;
+ bool res = pixmap.load(path);
+ if (!res) {
+ QList<QByteArray> formats = QImageReader::supportedImageFormats();
+ for (QList<QByteArray>::iterator it = formats.begin();
+ !res && it != formats.end();
+ ++it) {
+ res = pixmap.load(path, it->data());
+ }
+ }
+
+ if (pixmap.height() > 128 || pixmap.width() > 128) {
+ return pixmap.scaled(128, 128,
+ Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ }
+
+ return pixmap;
+ } else if (role == Qt::DisplayRole) {
+ return fileName(index);
+ }/*
+ else if (role == Qt::TextAlignmentRole) {
+ return Qt::Qt::AlignBottom;
+ }*/
+ return QVariant();
+ }
+
+ QSize ItemDelegate::size_;
+
+ void ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & option,
+ const QModelIndex & index ) const {
+ //if (index.column() == 0) return;
+ QStyleOptionViewItemV3 opt = setOptions(index, option);
+
+ // prepare
+ painter->save();
+
+ // get the data and the rectangles
+ const QPixmap& pixmap
+ = qvariant_cast<QPixmap>(index.data(Qt::DecorationRole));
+ QRect decorationRect = QRect(opt.rect.topLeft(), pixmap.size());
+ decorationRect.moveTo(decorationRect.left(), decorationRect.top() + 10);
+ const QString& text = index.data(Qt::DisplayRole).toString();
+ QFontMetrics fm(painter->font());
+ QRect displayRect = QRect(decorationRect.bottomLeft(),
+ QSize(fm.width(text),fm.height()));
+
+ QRect checkRect;
+ Qt::CheckState checkState = Qt::Unchecked;
+ QVariant value = index.data(Qt::CheckStateRole);
+
+ if (value.isValid()) {
+ checkState = static_cast<Qt::CheckState>(value.toInt());
+ checkRect = check(opt, opt.rect, value);
+ }
+
+ // do the layout
+
+ // doLayout(opt, &checkRect, &decorationRect, &displayRect, false);
+
+ // draw the item
+
+ drawBackground(painter, opt, index);
+ painter->drawPixmap(decorationRect, pixmap);
+ painter->drawText(displayRect, text);
+
+ drawFocus(painter, opt, displayRect);
+
+ // done
+ painter->restore();
+ }
+
+ void ExifTable::mouseReleaseEvent(QMouseEvent *pEvent) {
+
+ if (pEvent->button() == Qt::LeftButton) {
+ emit(showExifDetails());
+ }
+ }
+
+ ExifTable::ExifTable(QWidget *parent) : QLabel(parent) {
+
+ }
+
+ FQTermImage::FQTermImage( QWidget * parent, Qt::WindowFlags f ) : QWidget(parent, f) {
+ }
+
+} // namespace FQTerm
+
+#include "imageviewer.moc"
diff --git a/src/ui/imageviewer.h b/src/ui/imageviewer.h
new file mode 100644
index 0000000..ba98559
--- /dev/null
+++ b/src/ui/imageviewer.h
@@ -0,0 +1,336 @@
+
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef IMAGE_VIERWER_H
+#define IMAGE_VIERWER_H
+
+#include <QDesktopWidget>
+#include <QDirModel>
+#include <QLabel>
+#include <QPainter>
+#include <QPixmapCache>
+#include <QScrollArea>
+#include <QStatusBar>
+#include <QToolButton>
+#include <QToolBar>
+#include <QLayout>
+#include <QItemDelegate>
+#include <QItemSelection>
+
+class QString;
+class QPushButton;
+class QVBoxLayout;
+class QHBoxLayout;
+class QMenuBar;
+class QTreeView;
+class QComboBox;
+
+#include "pictureflow.h"
+
+namespace FQTerm {
+
+#define DISP_MARGIN (10.0) // show a margin
+#define PIXMAP_CACHESIZE (5120) // in KBytes
+#define ZOOMIN_FACTOR (1.15)
+#define ZOOMOUT_FACTOR (0.85)
+#define ROTLEFT_DEG (-90.0)
+#define ROTRIGHT_DEG (90.0)
+#define IMG_CHUNK (16384) // in bytes
+
+#define IMAGE_BROWSER_NAME "FQLora [Image Companion for FQTerm]"
+#define ICON_SOURCE "pic/ViewerButtons/"
+#define POOL_SOURCE "pool/"
+#define SHADOW_SOURCE "shadow-cache/"
+#define TRASH_SOURCE ".Trash/"
+
+#define EMBLEM_LIKE "emblem-like.png"
+#define EMBLEM_NEW "emblem-new.png"
+#define EMBLEM_RECOVER "emblem-recover.png"
+#define EMBLEM_TRASH "emblem-trash.png"
+#define EMBLEM_TITLE "emblem-title.png"
+
+ class FQTermConfig;
+ class FQTermFileDialog;
+
+
+ class FQTermImage : public QWidget {
+ Q_OBJECT;
+ public:
+ FQTermImage(QWidget * parent, Qt::WindowFlags f);
+ virtual void adjustItemSize() = 0;
+ virtual void scrollTo(const QString &) = 0;
+ virtual void updateImage(const QString &) = 0;
+ };
+
+ class ImageFlow;
+ class ImageMenu;
+ class ImageFlowItem;
+
+ class FQTermImageFlow: public FQTermImage {
+ Q_OBJECT;
+
+ public:
+ FQTermImageFlow(FQTermConfig *, QWidget *, Qt::WindowFlags);
+ ~FQTermImageFlow();
+
+ /* don't modify the funcs below */
+ /* they are for API compatibiliy */
+ void adjustItemSize();
+ void scrollTo(const QString &);
+ void updateImage(const QString &);
+ /*********************************/
+
+ public slots:
+ void saveImages(void);
+ void clearImages(void);
+ void trashAllImages(void);
+ void recoverImages(void);
+ void showStatusMessage(const QString &message);
+
+ private:
+ ImageFlow *imageFlow_;
+ ImageMenu *imageMenu_;
+ QStatusBar *statusBar_;
+ FQTermConfig *config_;
+
+ QFileInfoList sortedList(const QString &path);
+ const QString& poolSource(void) const;
+ const QString& trashSource(void) const;
+
+ private slots:
+ void loadImages(const int status);
+ void reshuffleImages(const int status);
+ void checkTrashState(void);
+
+ signals:
+ void statusMessage(const QString &message);
+ void isTrashEmpty(void);
+ void trashStatus(const bool fullOrNot);
+ void saveStatus(const bool hasOrNot);
+ void clearStatus(const bool hasOrNot);
+
+ protected:
+ void showEvent(QShowEvent *event);
+ void closeEvent(QCloseEvent *event);
+ };
+
+ class ImageMenu: public QLabel {
+ Q_OBJECT;
+
+ public:
+ ImageMenu(QWidget *parent = 0);
+ ~ImageMenu();
+
+ public slots:
+ void updateEmblems(const int status);
+ void updateDustbin(const bool fullOrNot);
+ void updateSave(const bool hasOrNot);
+ void updateClear(const bool hasOrNot);
+
+ signals:
+ void toggleFlowStatus(const int status);
+ void recoverImages(void);
+ void saveImages(void);
+ void clearImages(void);
+
+ private:
+ class Private;
+ Private *fh;
+
+ protected:
+ void paintEvent(QPaintEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ };
+
+ class ImageFlow: public PictureFlow {
+ Q_OBJECT;
+ Q_PROPERTY(QList<QByteArray> itemsTitles READ itemsTitles);
+
+ public:
+ ImageFlow(QWidget *parent);
+ ~ImageFlow();
+
+ const ImageFlowItem& operator[](int index) const;
+ ImageFlowItem& operator[](int index);
+ const ImageFlowItem& at(int index) const;
+
+ QList<QByteArray>& itemsTitles(void) const;
+
+ QFileInfoList& digest(const int status);
+ void strip(const int status);
+ QList<qint64> sort(const int status);
+ bool reorder(const QList<qint64>& itemsKey);
+
+ public slots:
+ void add(const ImageFlowItem &item);
+ void clear(void);
+ int count(void) const;
+ int size(void) const;
+ void rehash(void);
+ void toggleStatus(const int status);
+ void setCurrentImage(const int index);
+
+ private:
+ class Private;
+ Private *m;
+
+ signals:
+ void statusMessage(const QString &message);
+ void emblemStatus(const int status);
+ void saveStatus(const bool hasOrNot);
+ void clearStatus(const bool hasOrNot);
+ void titlesChanged(QList<QByteArray> &titles);
+
+ protected:
+ void paintEvent(QPaintEvent *event);
+ };
+
+ class ImageFlowItem: public QObject {
+ Q_OBJECT;
+
+ Q_PROPERTY(qint64 key READ key);
+ Q_PROPERTY(int status READ status WRITE setStatus);
+ Q_PROPERTY(QImage image READ image WRITE setImage);
+ Q_PROPERTY(QFileInfo info READ info WRITE setInfo);
+ Q_PROPERTY(QString comment READ comment WRITE setComment);
+
+ public:
+ ImageFlowItem(QObject *parent = 0);
+ ImageFlowItem(const ImageFlowItem &item);
+ ImageFlowItem(const QImage &image, QObject *parent = 0);
+ ImageFlowItem(const QImage &image, const QFileInfo &info, QObject *parent = 0);
+ ImageFlowItem(const QImage &image, const QFileInfo &info, const int state, QObject *parent = 0);
+ ImageFlowItem(const QImage &image, const QFileInfo &info, const QString &comment, QObject *parent = 0);
+ ImageFlowItem(const QImage &image, const QFileInfo &info, const QString& comment, const int status, QObject *parent = 0);
+ ~ImageFlowItem();
+
+ const QFileInfo& info(void) const;
+ const QString& comment(void) const;
+ const QImage& image(void) const;
+ int status(void) const;
+ qint64 key(void) const;
+
+ ImageFlowItem& operator=(const ImageFlowItem &item);
+ bool operator==(const ImageFlowItem &item) const;
+ bool operator!=(const ImageFlowItem &item) const;
+
+ public slots:
+ void setStatus(const int status);
+ void setInfo(const QFileInfo &info);
+ void setComment(const QString &comment);
+ void setImage(const QImage &image);
+ void setImage(const QString &filePath, int size);
+
+ private slots:
+ void loadImage(void);
+
+ private:
+ QImage resizeImage(const QImage &image, int size);
+ class Private;
+ Private *m;
+
+ };
+
+///////////////////////////////////////////////////////
+//////// the origin image viewer //////////////////////
+///////////////////////////////////////////////////////
+
+ class FQTermCanvas;
+ class ExifExtractor;
+
+ class ItemDelegate : public QItemDelegate {
+ public:
+ ItemDelegate() {
+ size_ = QSize(250,200);
+ }
+
+ QSize sizeHint (const QStyleOptionViewItem & option, const QModelIndex & index) const {
+ //if (index.column() == 0) return QSize(1, 1);
+ return size_;
+ }
+
+ void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const;
+ static QSize size_;
+ };
+
+ class ExifTable : public QLabel {
+ Q_OBJECT;
+
+ public:
+ ExifTable(QWidget *parent);
+
+ signals:
+ void showExifDetails();
+
+ protected:
+ void mouseReleaseEvent(QMouseEvent *pEvent);
+ };
+
+ class ImageViewerDirModel : public QDirModel {
+ public:
+ ImageViewerDirModel(QObject *parent = 0);
+
+ int columnCount(const QModelIndex & = QModelIndex()) const;
+ QVariant headerData ( int section, Qt::Orientation orientation, int role) const;
+ QVariant data(const QModelIndex &index, int role) const;
+ };
+
+
+ class FQTermImageOrigin: public FQTermImage {
+ Q_OBJECT;
+
+ public:
+ FQTermImageOrigin(FQTermConfig * config, QWidget *parent, Qt::WindowFlags wflag);
+ ~FQTermImageOrigin();
+ void scrollTo(const QString& filename);
+ void updateImage(const QString& filename);
+
+ public slots:
+ void onChange(const QModelIndex & index);
+ void next();
+ void previous();
+ void adjustItemSize();
+ void selectionChanged(const QItemSelection & selected, const QItemSelection & deselected);
+ void sortFileList(int index);
+ void showFullExifInfo();
+ void adjustLayout(bool withExifTable);
+ void updateExifInfo();
+
+ protected:
+ void closeEvent(QCloseEvent *clse);
+
+ private:
+ FQTermCanvas* canvas_;
+ QTreeView* tree_;
+ ImageViewerDirModel* model_;
+ QMenuBar* menuBar_;
+ QComboBox* comboBox_;
+ FQTermConfig* config_;
+ ExifExtractor* exifExtractor_;
+ ExifTable* exifTable_;
+ QGridLayout* layout_;
+ bool isExifTableShown_;
+ };
+
+
+} // namespace FQTerm
+
+#endif // IMAGE_VIERWER_H
diff --git a/src/ui/iplookup.cpp b/src/ui/iplookup.cpp
new file mode 100644
index 0000000..e84c126
--- /dev/null
+++ b/src/ui/iplookup.cpp
@@ -0,0 +1,56 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+
+#include "iplookup.h"
+#include "fqterm_ip_location.h"
+#include "fqterm.h"
+namespace FQTerm {
+
+
+
+IPLookupDialog::~IPLookupDialog(){
+
+}
+
+IPLookupDialog::IPLookupDialog( QWidget *parent_ /*= 0*/, Qt::WFlags fl /*= 0*/ ) : QDialog(parent_, fl) {
+ ui_.setupUi(this);
+ FQ_VERIFY(connect(ui_.lookupPushButton, SIGNAL(clicked()), this, SLOT(onLookup())));
+ FQ_VERIFY(connect(ui_.finishedPushButton, SIGNAL(clicked()), this, SLOT(onFinished())));
+}
+
+void IPLookupDialog::onLookup() {
+ QString country, city;
+ QString ip = ui_.ipLineEdit->text();
+ FQTermIPLocation *ipLocation = FQTermIPLocation::getInstance();
+ if (ipLocation == NULL) {
+ ui_.addressLineEdit->setText(QApplication::translate("IPLookupDialog", "IP database file does NOT exist", 0, QApplication::UnicodeUTF8));
+ } else if (!ipLocation->getLocation(ip, country, city)) {
+ ui_.addressLineEdit->setText(QApplication::translate("IPLookupDialog", "Invalid IP", 0, QApplication::UnicodeUTF8));
+ } else {
+ ui_.addressLineEdit->setText(country + " " + city);
+ }
+}
+
+void IPLookupDialog::onFinished() {
+ done(0);
+}
+} //namespace FQTerm
+
+#include "iplookup.moc" \ No newline at end of file
diff --git a/src/ui/iplookup.h b/src/ui/iplookup.h
new file mode 100644
index 0000000..4f38a5a
--- /dev/null
+++ b/src/ui/iplookup.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+
+#ifndef __FQTERM_IPLOOKUP__
+#define __FQTERM_IPLOOKUP__
+
+#include <QDialog>
+#include "ui_iplookup.h"
+namespace FQTerm {
+
+class IPLookupDialog : public QDialog {
+ Q_OBJECT;
+public:
+ IPLookupDialog(QWidget *parent_ = 0, Qt::WFlags fl = 0);
+ ~IPLookupDialog();
+
+protected slots:
+ void onLookup();
+ void onFinished();
+private:
+ Ui::IPLookupDialog ui_;
+};
+
+} //namespace FQTerm
+
+#endif //__FQTERM_IPLOOKUP__ \ No newline at end of file
diff --git a/src/ui/iplookup.ui b/src/ui/iplookup.ui
new file mode 100644
index 0000000..507a456
--- /dev/null
+++ b/src/ui/iplookup.ui
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>IPLookupDialog</class>
+ <widget class="QDialog" name="IPLookupDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>319</width>
+ <height>112</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>IP Lookup</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>IP Address</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="ipLineEdit"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Physical Address</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="addressLineEdit">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="lookupPushButton">
+ <property name="text">
+ <string>Lookup</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="finishedPushButton">
+ <property name="text">
+ <string>Finished</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/ui/keydialog.cpp b/src/ui/keydialog.cpp
new file mode 100644
index 0000000..2e3aadb
--- /dev/null
+++ b/src/ui/keydialog.cpp
@@ -0,0 +1,285 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QFileDialog>
+
+#include "fqterm_config.h"
+#include "fqterm_path.h"
+#include "fqterm_trace.h"
+
+#include "keydialog.h"
+
+namespace FQTerm {
+
+/*
+ * Constructs a keyDialog as a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'.
+ *
+ * The dialog will by default be modeless, unless you set 'modal' to
+ * TRUE to construct a modal dialog.
+ */
+keyDialog::keyDialog(FQTermConfig * config, QWidget *parent, Qt::WFlags fl)
+ : QDialog(parent, fl),
+ keyButtonGroup_(this),
+ config_(config) {
+ ui_.setupUi(this);
+
+ keyButtonGroup_.addButton(ui_.radioButton1, 0);
+ keyButtonGroup_.addButton(ui_.radioButton2, 1);
+ keyButtonGroup_.addButton(ui_.radioButton3, 2);
+
+ connectSlots();
+
+ loadName();
+}
+
+keyDialog::~keyDialog() {
+ // no need to delete child widgets, Qt does it all for us
+}
+
+
+void keyDialog::connectSlots() {
+ FQ_VERIFY(connect(ui_.nameListWidget, SIGNAL(currentRowChanged(int)),
+ this, SLOT(onNamechange(int))));
+ FQ_VERIFY(connect(ui_.addButton, SIGNAL(clicked()), this, SLOT(onAdd())));
+ FQ_VERIFY(connect(ui_.deleteButton, SIGNAL(clicked()), this, SLOT(onDelete())));
+ FQ_VERIFY(connect(ui_.updateButton, SIGNAL(clicked()), this, SLOT(onUpdate())));
+ FQ_VERIFY(connect(ui_.closeButton, SIGNAL(clicked()), this, SLOT(onClose())));
+ FQ_VERIFY(connect(ui_.upButton, SIGNAL(clicked()), this, SLOT(onUp())));
+ FQ_VERIFY(connect(ui_.downButton, SIGNAL(clicked()), this, SLOT(onDown())));
+ FQ_VERIFY(connect(ui_.leftButton, SIGNAL(clicked()), this, SLOT(onLeft())));
+ FQ_VERIFY(connect(ui_.rightButton, SIGNAL(clicked()), this, SLOT(onRight())));
+ FQ_VERIFY(connect(ui_.enterButton, SIGNAL(clicked()), this, SLOT(onEnter())));
+// FQ_VERIFY(connect(&keyButtonGroup_, SIGNAL(buttonClicked(int)), this, SLOT(onSelect(int))));
+ FQ_VERIFY(connect(ui_.scriptButton, SIGNAL(clicked()), this, SLOT(onChooseScript())));
+ FQ_VERIFY(connect(ui_.programButton, SIGNAL(clicked()), this, SLOT(onProgram())));
+
+}
+
+void keyDialog::onNamechange(int item) {
+ loadKey(item);
+}
+
+void keyDialog::onAdd() {
+ QString strTmp = config_->getItemValue("key", "num");
+ int num = strTmp.toInt();
+
+ strTmp.setNum(num + 1);
+ config_->setItemValue("key", "num", strTmp);
+
+ QString strValue;
+ switch (keyButtonGroup_.checkedId()) {
+ case 0:
+ strValue = "0" + ui_.keyEdit->text();
+ break;
+ case 1:
+ strValue = "1" + ui_.scriptEdit->text();
+ break;
+ case 2:
+ strValue = "2" + ui_.programEdit->text();
+ break;
+ }
+ strTmp = QString("key%1").arg(num);
+ config_->setItemValue("key", strTmp, strValue);
+
+ strTmp = QString("name%1").arg(num);
+ config_->setItemValue("key", strTmp, ui_.nameEdit->text());
+
+ strTmp = QString("shortcut%1").arg(num);
+ config_->setItemValue("key", strTmp, ui_.shortcutEdit->text());
+
+ ui_.nameListWidget->addItem(ui_.nameEdit->text());
+ ui_.nameListWidget->setCurrentRow(ui_.nameListWidget->count() -1);
+}
+
+void keyDialog::onDelete() {
+ QString strTmp = config_->getItemValue("key", "num");
+ int num = strTmp.toInt();
+ if (num == 0) {
+ return ;
+ }
+ strTmp.setNum(num -1);
+ config_->setItemValue("key", "num", strTmp);
+
+ int index = ui_.nameListWidget->currentRow();
+ QString strItem1, strItem2;
+ for (int i = index; i < num -1; i++) {
+ strItem1 = QString("key%1").arg(i);
+ strItem2 = QString("key%1").arg(i + 1);
+ config_->setItemValue("key", strItem1, config_->getItemValue("key", strItem2));
+ strItem1 = QString("name%1").arg(i);
+ strItem2 = QString("name%1").arg(i + 1);
+ config_->setItemValue("key", strItem1, config_->getItemValue("key", strItem2));
+ }
+
+ ui_.nameListWidget->takeItem(index);
+ ui_.nameListWidget->setCurrentRow(qMin(index, ui_.nameListWidget->count() -1));
+}
+
+void keyDialog::onUpdate() {
+ int index = ui_.nameListWidget->currentRow();
+ if (index < 0) {
+ return ;
+ }
+
+ QString strValue;
+ switch (keyButtonGroup_.checkedId()) {
+ case 0:
+ strValue = "0" + ui_.keyEdit->text();
+ break;
+ case 1:
+ strValue = "1" + ui_.scriptEdit->text();
+ break;
+ case 2:
+ strValue = "2" + ui_.programEdit->text();
+ break;
+ }
+
+ QString strTmp;
+
+ strTmp = QString("key%1").arg(index);
+ config_->setItemValue("key", strTmp, strValue);
+
+ strTmp = QString("name%1").arg(index);
+ config_->setItemValue("key", strTmp, ui_.nameEdit->text());
+
+ strTmp = QString("shortcut%1").arg(index);
+ config_->setItemValue("key", strTmp, ui_.shortcutEdit->text());
+
+ ui_.nameListWidget->item(index)->setText(ui_.nameEdit->text());
+}
+
+void keyDialog::onClose() {
+ config_->save(getPath(USER_CONFIG) + "fqterm.cfg");
+ done(1);
+}
+
+void keyDialog::onUp() {
+ ui_.keyEdit->insert("^[[A");
+}
+
+void keyDialog::onDown() {
+ ui_.keyEdit->insert("^[[B");
+}
+
+void keyDialog::onLeft() {
+ ui_.keyEdit->insert("^[[D");
+}
+
+void keyDialog::onRight() {
+ ui_.keyEdit->insert("^[[C");
+}
+
+void keyDialog::onEnter() {
+ ui_.keyEdit->insert("^M");
+}
+
+// void keyDialog::onSelect(int id)
+// {
+// switch(id)
+// {
+// case 0: // key
+// ui.keyEdit->setEnabled(true);
+// ui.scriptEdit->setEnabled(false);
+// ui.scriptButton->setEnabled(false);
+// ui.programEdit->setEnabled(false);
+// ui.programButton->setEnabled(false);
+// break;
+// case 1: // script
+// ui.keyEdit->setEnabled(false);
+// ui.scriptEdit->setEnabled(true);
+// ui.scriptButton->setEnabled(true);
+// ui.programEdit->setEnabled(false);
+// ui.programButton->setEnabled(false);
+// break;
+// case 2: // program
+// ui.scriptEdit->setEnabled(false);
+// ui.scriptButton->setEnabled(false);
+// ui.keyEdit->setEnabled(false);
+// ui.programEdit->setEnabled(true);
+// ui.programButton->setEnabled(true);
+// break;
+// }
+// }
+void keyDialog::onChooseScript() {
+ QString script = QFileDialog::getOpenFileName(
+ this, "Select a script", QDir::currentPath(), "JavaScript File (*.js)");
+ if (!script.isEmpty()) {
+ ui_.scriptEdit->setText(script);
+ }
+}
+
+void keyDialog::onProgram() {
+ QString program = QFileDialog::getOpenFileName(
+ this, "Select a program", QDir::currentPath(), "*");
+ if (!program.isNull()) {
+ ui_.programEdit->setText(program);
+ }
+}
+
+void keyDialog::loadName() {
+ QString strTmp = config_->getItemValue("key", "num");
+ int num = strTmp.toInt();
+ for (int i = 0; i < num; i++) {
+ strTmp = QString("name%1").arg(i);
+ ui_.nameListWidget->addItem(config_->getItemValue("key", strTmp));
+ }
+ if (num > 0) {
+ ui_.nameListWidget->setCurrentRow(0);
+ } else {
+ ui_.radioButton1->setChecked(true);
+ //onSelect(0);
+ }
+}
+
+void keyDialog::loadKey(int n) {
+ QString strTmp = config_->getItemValue("key", "num");
+ if (n >= strTmp.toInt()) {
+ return ;
+ }
+
+ QString strItem;
+
+ strItem = QString("name%1").arg(n);
+ ui_.nameEdit->setText(config_->getItemValue("key", strItem));
+
+ strItem = QString("key%1").arg(n);
+ strTmp = config_->getItemValue("key", strItem);
+ if (strTmp[0] == '0') {
+ ui_.keyEdit->setText(strTmp.mid(1));
+ ui_.radioButton1->setChecked(true);
+ //onSelect(0);
+ } else if (strTmp[0] == '1') {
+ ui_.scriptEdit->setText(strTmp.mid(1));
+ ui_.radioButton2->setChecked(true);
+ //onSelect(7);
+ } else if (strTmp[0] == '2') {
+ ui_.programEdit->setText(strTmp.mid(1));
+ ui_.radioButton3->setChecked(true);
+ //onSelect(6);
+ }
+ strItem = QString("shortcut%1").arg(n);
+ strTmp = config_->getItemValue("key", strItem);
+ ui_.shortcutEdit->setText(strTmp);
+}
+
+} // namespace FQTerm
+
+#include "keydialog.moc"
diff --git a/src/ui/keydialog.h b/src/ui/keydialog.h
new file mode 100644
index 0000000..fa087c3
--- /dev/null
+++ b/src/ui/keydialog.h
@@ -0,0 +1,63 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_KEY_DIALOG_H
+#define FQTERM_KEY_DIALOG_H
+
+#include "ui_keydialog.h"
+
+namespace FQTerm {
+
+class FQTermConfig;
+
+class keyDialog: public QDialog {
+ Q_OBJECT;
+ public:
+ keyDialog(FQTermConfig *, QWidget *parent_ = 0, Qt::WFlags fl = 0);
+ ~keyDialog();
+
+ protected:
+ void connectSlots();
+ void loadKey(int);
+ void loadName();
+
+ protected slots:
+ void onNamechange(int);
+ void onClose();
+ void onAdd();
+ void onDelete();
+ void onUpdate();
+ void onChooseScript();
+ void onProgram();
+ void onUp();
+ void onDown();
+ void onLeft();
+ void onRight();
+ void onEnter();
+ // void onSelect(int);
+ private:
+ Ui::keyDialog ui_;
+ QButtonGroup keyButtonGroup_;
+ FQTermConfig * config_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_KEY_DIALOG_H
diff --git a/src/ui/keydialog.ui b/src/ui/keydialog.ui
new file mode 100644
index 0000000..34b8124
--- /dev/null
+++ b/src/ui/keydialog.ui
@@ -0,0 +1,665 @@
+<ui version="4.0" >
+ <class>keyDialog</class>
+ <widget class="QDialog" name="keyDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>545</width>
+ <height>463</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Key Setup</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" colspan="10" >
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QPushButton" name="addButton" >
+ <property name="text" >
+ <string>Add</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="deleteButton" >
+ <property name="text" >
+ <string>Delete</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="updateButton" >
+ <property name="text" >
+ <string>Update</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="closeButton" >
+ <property name="text" >
+ <string>Close</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0" colspan="10" >
+ <widget class="QListWidget" name="nameListWidget" />
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="textLabel1" >
+ <property name="text" >
+ <string>Name</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3" colspan="4" >
+ <widget class="QLineEdit" name="nameEdit" />
+ </item>
+ <item row="3" column="0" colspan="2" >
+ <widget class="QLabel" name="shortcutLabel" >
+ <property name="text" >
+ <string>Short Cut</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="3" colspan="4" >
+ <widget class="QLineEdit" name="shortcutEdit" />
+ </item>
+ <item row="4" column="0" colspan="10" >
+ <widget class="QGroupBox" name="groupBox" >
+ <property name="title" >
+ <string>Define</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QRadioButton" name="radioButton1" >
+ <property name="text" >
+ <string>Key</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="8" >
+ <widget class="QLineEdit" name="keyEdit" />
+ </item>
+ <item row="1" column="0" colspan="3" >
+ <widget class="QLabel" name="textLabel3" >
+ <property name="text" >
+ <string>General Keys</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3" >
+ <widget class="QPushButton" name="upButton" >
+ <property name="text" >
+ <string>Up</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="4" >
+ <widget class="QPushButton" name="downButton" >
+ <property name="text" >
+ <string>Down</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="5" >
+ <widget class="QPushButton" name="leftButton" >
+ <property name="text" >
+ <string>Left</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="6" colspan="2" >
+ <widget class="QPushButton" name="rightButton" >
+ <property name="text" >
+ <string>Right</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="8" >
+ <widget class="QPushButton" name="enterButton" >
+ <property name="text" >
+ <string>Enter</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QRadioButton" name="radioButton2" >
+ <property name="text" >
+ <string>Script</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2" colspan="5" >
+ <widget class="QLineEdit" name="scriptEdit" />
+ </item>
+ <item row="2" column="7" colspan="2" >
+ <widget class="QPushButton" name="scriptButton" >
+ <property name="text" >
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="2" >
+ <widget class="QRadioButton" name="radioButton3" >
+ <property name="text" >
+ <string>Program</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2" colspan="5" >
+ <widget class="QLineEdit" name="programEdit" />
+ </item>
+ <item row="3" column="7" colspan="2" >
+ <widget class="QPushButton" name="programButton" >
+ <property name="text" >
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <resources/>
+ <connections>
+ <connection>
+ <sender>radioButton1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>keyEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>69</x>
+ <y>230</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>109</x>
+ <y>230</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>upButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>66</x>
+ <y>230</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>151</x>
+ <y>266</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>downButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>20</x>
+ <y>237</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>234</x>
+ <y>267</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>leftButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>69</x>
+ <y>230</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>299</x>
+ <y>263</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>rightButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>50</x>
+ <y>230</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>359</x>
+ <y>265</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>enterButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>64</x>
+ <y>230</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>417</x>
+ <y>264</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>scriptEdit</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>20</x>
+ <y>246</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>124</x>
+ <y>314</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>scriptButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>41</x>
+ <y>230</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>362</x>
+ <y>293</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>programEdit</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>20</x>
+ <y>245</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>111</x>
+ <y>354</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>programButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>64</x>
+ <y>230</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>409</x>
+ <y>343</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>keyEdit</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>20</x>
+ <y>296</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>101</x>
+ <y>230</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>upButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>85</x>
+ <y>290</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>142</x>
+ <y>284</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>downButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>20</x>
+ <y>307</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>205</x>
+ <y>277</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>leftButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>21</x>
+ <y>290</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>299</x>
+ <y>277</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>rightButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>25</x>
+ <y>290</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>359</x>
+ <y>284</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>enterButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>81</x>
+ <y>290</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>419</x>
+ <y>266</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>scriptEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>76</x>
+ <y>290</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>119</x>
+ <y>290</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>scriptButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>82</x>
+ <y>290</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>341</x>
+ <y>290</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>programEdit</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>20</x>
+ <y>294</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>113</x>
+ <y>354</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>programButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>83</x>
+ <y>305</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>346</x>
+ <y>354</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>keyEdit</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>20</x>
+ <y>339</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>116</x>
+ <y>248</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>upButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>20</x>
+ <y>349</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>173</x>
+ <y>271</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>downButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>96</x>
+ <y>349</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>200</x>
+ <y>284</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>leftButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>20</x>
+ <y>349</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>299</x>
+ <y>270</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>rightButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>20</x>
+ <y>349</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>359</x>
+ <y>275</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>enterButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>90</x>
+ <y>349</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>419</x>
+ <y>277</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>scriptEdit</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>77</x>
+ <y>349</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>269</x>
+ <y>312</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>scriptButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>98</x>
+ <y>333</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>346</x>
+ <y>309</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>programEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>72</x>
+ <y>349</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>128</x>
+ <y>349</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>programButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>73</x>
+ <y>335</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>342</x>
+ <y>335</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/ui/msgdialog.cpp b/src/ui/msgdialog.cpp
new file mode 100644
index 0000000..1db7495
--- /dev/null
+++ b/src/ui/msgdialog.cpp
@@ -0,0 +1,43 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <stdio.h>
+
+#include "msgdialog.h"
+
+msgDialog::msgDialog(QWidget *parent, Qt::WFlags fl)
+ : QDialog(parent, fl) {
+ ui_.setupUi(this);
+ // signals and slots connections
+ //QVERIFY(connect( okButton, SIGNAL( clicked() ), this, SLOT( accept() ) ));
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+msgDialog::~msgDialog() {
+ // no need to delete child widgets, Qt does it all for us
+}
+
+void msgDialog::setMessageText(const QString& message) {
+ ui_.msgBrowser->setPlainText(message);
+}
+
+#include "msgdialog.moc"
diff --git a/src/ui/msgdialog.h b/src/ui/msgdialog.h
new file mode 100644
index 0000000..e3c5185
--- /dev/null
+++ b/src/ui/msgdialog.h
@@ -0,0 +1,35 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_MSGDIALOG_H
+#define FQTERM_MSGDIALOG_H
+
+#include "ui_msgdialog.h"
+
+class msgDialog: public QDialog {
+ Q_OBJECT;
+public:
+ msgDialog(QWidget *parent = 0, Qt::WFlags fl = 0);
+ ~msgDialog();
+ void setMessageText(const QString& message);
+ Ui::msgDialog ui_;
+};
+
+#endif // FQTERM_MSGDIALOG_H
diff --git a/src/ui/msgdialog.ui b/src/ui/msgdialog.ui
new file mode 100644
index 0000000..93ff1c4
--- /dev/null
+++ b/src/ui/msgdialog.ui
@@ -0,0 +1,86 @@
+<ui version="4.0" >
+ <class>msgDialog</class>
+ <widget class="QDialog" name="msgDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>586</width>
+ <height>393</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Messages Viewer</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" colspan="3" >
+ <widget class="QTextBrowser" name="msgBrowser" />
+ </item>
+ <item row="1" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QPushButton" name="okButton" >
+ <property name="text" >
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <resources/>
+ <connections>
+ <connection>
+ <sender>okButton</sender>
+ <signal>clicked()</signal>
+ <receiver>msgDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>311</x>
+ <y>403</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>396</x>
+ <y>403</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/ui/osdmessage.cpp b/src/ui/osdmessage.cpp
new file mode 100644
index 0000000..1b0883f
--- /dev/null
+++ b/src/ui/osdmessage.cpp
@@ -0,0 +1,210 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QPaintEvent>
+#include <QCursor>
+#include <QTimer>
+#include <QApplication>
+#include <QPainter>
+#include <QBitmap>
+#include <QPalette>
+
+#include "fqterm_trace.h"
+#include "fqterm_path.h"
+
+#include "osdmessage.h"
+
+namespace FQTerm {
+
+PageViewMessage::PageViewMessage(QWidget *parent_)
+ : QWidget(parent_),
+ timer_(0),
+ message_() {
+ setFocusPolicy(Qt::NoFocus);
+ //setBackgroundMode( Qt::NoBackground );
+ QPalette palette;
+ palette.setColor(backgroundRole(), qApp->palette().color(QPalette::Active,
+ QPalette::Background));
+ setPalette(palette);
+ // setPaletteBackgroundColor(qApp->palette().color(QPalette::Active, QPalette::Background));
+ setCursor(QCursor(Qt::ArrowCursor));
+ move(10, 10);
+ resize(0, 0);
+ hide();
+}
+
+// give to Caesar what Caesar owns: code taken from Amarok's osd.h/.cpp
+// "redde (reddite, pl.) cesari quae sunt cesaris", just btw. ;)
+void PageViewMessage::display(const QString &message, Icon icon, int durationMs, QPoint pos, PageViewMessage::Alignment ali)
+{
+ displayImpl(message, icon, false, durationMs, pos, ali);
+}
+
+void PageViewMessage::display(const QString &message, QPoint pos, Icon icon)
+{
+ displayImpl(message, icon, false, 4000, pos, TopLeft);
+}
+
+QRect PageViewMessage::displayCheck(const QString &message, Icon icon)
+{
+ return displayImpl(message, icon, true);
+}
+
+QRect PageViewMessage::displayImpl(const QString &message, Icon icon, bool check, int durationMs, QPoint pos, Alignment ali)
+{
+ //FIXME: add a option in fqterm too.
+ /*
+ if ( !KpdfSettings::showOSD() )
+ {
+ hide();
+ return;
+ }
+ */
+ // determine text rectangle
+
+ if (!isHidden() && message == message_) {
+ timer_->setSingleShot(true);
+ timer_->start(durationMs);
+ return QRect(QPoint(0, 0), size());
+ }
+ message_ = message;
+ QRect textRect = fontMetrics().boundingRect(message);
+ textRect.translate(-textRect.left(), -textRect.top());
+ textRect.adjust(0, 0, 2, 2);
+ int width = textRect.width(), height = textRect.height(), textXOffset = 0,
+ shadowOffset = message.isRightToLeft() ? -1: 1;
+
+ // load icon (if set) and update geometry
+ // [FQTerm], we don't have a icon at this time.
+
+ QPixmap symbol;
+ if (icon != None) {
+ switch (icon) {
+ //case Find:
+ //symbol = SmallIcon( "viewmag" );
+ //break;
+ case Error:
+ symbol = QPixmap(getPath(RESOURCE) + "pic/messagebox_critical.png");
+ break;
+ case Warning:
+ symbol = QPixmap(getPath(RESOURCE) + "pic/messagebox_warning.png");
+ break;
+ default:
+ symbol = QPixmap(getPath(RESOURCE) + "pic/messagebox_info.png");
+ break;
+ }
+ textXOffset = 2+symbol.width();
+ width += textXOffset;
+ height = qMax(height, symbol.height());
+ }
+
+ QRect geometry(0, 0, width + 10, height + 8);
+
+ if (check)
+ return geometry;
+
+ // resize pixmap, mask and widget
+ static QPixmap mask;
+ mask = QPixmap(geometry.size());
+ pixmap_ = QPixmap(geometry.size());
+ resize(geometry.size());
+
+ switch(ali)
+ {
+ case TopLeft:
+ move(pos);
+ break;
+ case TopRight:
+ move(pos - geometry.topRight());
+ break;
+ case BottomLeft:
+ move(pos - geometry.bottomLeft());
+ break;
+ case BottomRight:
+ move(pos - geometry.bottomRight());
+ break;
+ }
+
+ // create and set transparency mask
+ QPainter maskPainter(&mask);
+ mask.fill(Qt::black);
+ maskPainter.setBrush(Qt::white);
+ maskPainter.drawRoundRect(geometry, 1600 / geometry.width(), 1600 /
+ geometry.height());
+ setMask(mask.createHeuristicMask());
+
+ // draw background
+ QPainter bufferPainter(&pixmap_);
+ bufferPainter.setPen(Qt::black);
+ bufferPainter.setBrush(palette().brush(QPalette::Window));
+ bufferPainter.drawRoundRect(geometry, 1600 / geometry.width(), 1600 /
+ geometry.height());
+
+ // draw icon if present
+ if (!symbol.isNull()) {
+ bufferPainter.drawPixmap(5, 4, symbol, 0, 0, symbol.width(), symbol.height());
+ }
+
+ // draw shadow and text
+ int yText = geometry.height() - height / 2;
+ bufferPainter.setPen(palette().color(QPalette::Window).dark(115));
+ bufferPainter.drawText(5+textXOffset + shadowOffset, yText + 1, message);
+ bufferPainter.setPen(palette().color(QPalette::WindowText));
+ bufferPainter.drawText(5+textXOffset, yText, message);
+
+ // show widget and schedule a repaint
+ show();
+ update();
+
+ // close the message window after given mS
+ if (durationMs > 0) {
+ if (!timer_) {
+ timer_ = new QTimer(this);
+ timer_->setSingleShot(true);
+ FQ_VERIFY(connect(timer_, SIGNAL(timeout()), SLOT(hide())));
+ }
+ timer_->start(durationMs);
+ } else if (timer_) {
+ timer_->stop();
+ }
+
+ return QRect(QPoint(0, 0), size());
+}
+
+void PageViewMessage::paintEvent(QPaintEvent *e) {
+ QPainter p(this);
+ p.drawPixmap(e->rect().topLeft(), pixmap_, e->rect());
+}
+
+void PageViewMessage::mousePressEvent(QMouseEvent * /*e*/) {
+ if (timer_) {
+ timer_->stop();
+ }
+ hide();
+}
+
+void PageViewMessage::hideEvent( QHideEvent * event ) {
+ emit hideAt(geometry ());
+ QWidget::hideEvent(event);
+}
+
+} // namespace FQTerm
+
+#include "osdmessage.moc"
diff --git a/src/ui/osdmessage.h b/src/ui/osdmessage.h
new file mode 100644
index 0000000..fe29d4d
--- /dev/null
+++ b/src/ui/osdmessage.h
@@ -0,0 +1,69 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_OSD_MESSAGE_H
+#define FQTERM_OSD_MESSAGE_H
+
+#include <QPixmap>
+#include <QWidget>
+#include <QHideEvent>
+
+namespace FQTerm {
+
+/**
+ * A widget that displays messages in the top-left corner.
+ */
+class PageViewMessage: public QWidget {
+ Q_OBJECT;
+ public:
+ PageViewMessage(QWidget *parent_);
+
+ enum Alignment {
+ TopLeft, TopRight, BottomLeft, BottomRight
+ };
+ enum Icon {
+ None, Info, Warning, Error, Find
+ };
+ void display(const QString &message, Icon icon = Info, int durationMs = 4000,
+ QPoint pos = QPoint(10, 10), Alignment ali = TopLeft);
+ void display(const QString &message, QPoint pos, Icon icon = Info);
+ QRect displayCheck(const QString &message, Icon icon = Info);
+ public slots:
+ void showText(const QString &message){
+ display(message);
+ }
+ protected:
+ void paintEvent(QPaintEvent *e);
+ void mousePressEvent(QMouseEvent *e);
+ QRect displayImpl(const QString &message, Icon icon = Info,
+ bool check = false, int durationMs = 4000,
+ QPoint pos = QPoint(10, 10), Alignment ali = TopLeft);
+ void hideEvent(QHideEvent * event);
+ private:
+ QPixmap pixmap_;
+ QTimer *timer_;
+ QString message_;
+signals:
+ void hideAt(const QRect& rect);
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_OSD_MESSAGE_H
diff --git a/src/ui/overlayWidget.cpp b/src/ui/overlayWidget.cpp
new file mode 100644
index 0000000..74f0659
--- /dev/null
+++ b/src/ui/overlayWidget.cpp
@@ -0,0 +1,84 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QPoint>
+#include <QFrame>
+#include <QResizeEvent>
+#include <QEvent>
+
+#include "overlayWidget.h"
+
+namespace FQTerm {
+
+OverlayWidget::OverlayWidget(QWidget *parent, QWidget *anchor)
+ : QFrame(parent->parentWidget()->parentWidget()),
+ anchor_(anchor),
+ parent_(parent) {
+ parent->installEventFilter(this);
+
+ hide();
+}
+
+void OverlayWidget::reposition() {
+ setMaximumSize(parentWidget()->size());
+ adjustSize();
+
+ // p is in the alignWidget's coordinates
+ QPoint p;
+
+ p.setX(anchor_->width() - width());
+ p.setY(-height());
+
+ // Position in the toplevelwidget's coordinates
+ QPoint pTopLevel = anchor_->mapTo(topLevelWidget(), p);
+
+ // Position in the widget's parentWidget coordinates
+ QPoint pParent = parentWidget()->mapFrom(topLevelWidget(), pTopLevel);
+ // keep it on the screen
+ if (pParent.x() < 0) {
+ pParent.rx() = 0;
+ }
+
+ // Move 'this' to that position.
+ move(pParent);
+}
+
+bool OverlayWidget::eventFilter(QObject *o, QEvent *e) {
+ if (e->type() == QEvent::Move || e->type() == QEvent::Resize) {
+ reposition();
+ }
+
+ return QFrame::eventFilter(o, e);
+}
+
+void OverlayWidget::resizeEvent(QResizeEvent *ev) {
+ reposition();
+ QFrame::resizeEvent(ev);
+}
+
+bool OverlayWidget::event(QEvent *e) {
+ if (e->type() == QEvent::ChildAdded) {
+ adjustSize();
+ }
+
+ return QFrame::event(e);
+}
+
+}
diff --git a/src/ui/overlayWidget.h b/src/ui/overlayWidget.h
new file mode 100644
index 0000000..edab3f6
--- /dev/null
+++ b/src/ui/overlayWidget.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERMOVERLAYWIDGET_H
+#define FQTERMOVERLAYWIDGET_H
+
+#include <QFrame>
+#include <QResizeEvent>
+#include <QEvent>
+#include <QHBoxLayout>
+
+namespace FQTerm {
+class OverlayWidget: public QFrame {
+ public:
+ /**
+ * The widget is parented to the toplevelwidget of alignWidget,
+ * this could be an issue if that widget has an autoAdd Layout
+ */
+ OverlayWidget(QWidget *parent, QWidget *anchor);
+ virtual void reposition();
+
+ protected:
+ virtual void resizeEvent(QResizeEvent*);
+ virtual bool eventFilter(QObject *, QEvent*);
+ virtual bool event(QEvent*);
+
+ private:
+ QWidget *anchor_;
+ QWidget *parent_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERMOVERLAYWIDGET_H
diff --git a/src/ui/pictureflow.cpp b/src/ui/pictureflow.cpp
new file mode 100644
index 0000000..cd749f0
--- /dev/null
+++ b/src/ui/pictureflow.cpp
@@ -0,0 +1,1201 @@
+
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+/*
+ PictureFlow - animated image show widget
+ http://pictureflow.googlecode.com
+
+ Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+#include "pictureflow.h"
+
+#include <QBasicTimer>
+#include <QMouseEvent>
+#include <QCache>
+#include <QImage>
+#include <QKeyEvent>
+#include <QPainter>
+#include <QPixmap>
+#include <QTimer>
+#include <QVector>
+#include <QWidget>
+
+// uncomment this to enable bilinear filtering for texture mapping
+// gives much better rendering, at the cost of memory space
+// #define PICTUREFLOW_BILINEAR_FILTER
+
+// for fixed-point arithmetic, we need minimum 32-bit long
+// long long (64-bit) might be useful for multiplication and division
+typedef long PFreal;
+#define PFREAL_SHIFT 10
+#define PFREAL_FACTOR (1 << PFREAL_SHIFT)
+#define PFREAL_ONE (1 << PFREAL_SHIFT)
+#define PFREAL_HALF (PFREAL_ONE >> 1)
+
+inline PFreal fmul(PFreal a, PFreal b)
+{
+ return ((long long)(a))*((long long)(b)) >> PFREAL_SHIFT;
+}
+
+inline PFreal fdiv(PFreal num, PFreal den)
+{
+ long long p = (long long)(num) << (PFREAL_SHIFT*2);
+ long long q = p / (long long)den;
+ long long r = q >> PFREAL_SHIFT;
+
+ return r;
+}
+
+#define IANGLE_MAX 1024
+#define IANGLE_MASK 1023
+
+// warning: regenerate the table if IANGLE_MAX and PFREAL_SHIFT are changed!
+static const PFreal sinTable[IANGLE_MAX] = {
+ 3, 9, 15, 21, 28, 34, 40, 47,
+ 53, 59, 65, 72, 78, 84, 90, 97,
+ 103, 109, 115, 122, 128, 134, 140, 147,
+ 153, 159, 165, 171, 178, 184, 190, 196,
+ 202, 209, 215, 221, 227, 233, 239, 245,
+ 251, 257, 264, 270, 276, 282, 288, 294,
+ 300, 306, 312, 318, 324, 330, 336, 342,
+ 347, 353, 359, 365, 371, 377, 383, 388,
+ 394, 400, 406, 412, 417, 423, 429, 434,
+ 440, 446, 451, 457, 463, 468, 474, 479,
+ 485, 491, 496, 501, 507, 512, 518, 523,
+ 529, 534, 539, 545, 550, 555, 561, 566,
+ 571, 576, 581, 587, 592, 597, 602, 607,
+ 612, 617, 622, 627, 632, 637, 642, 647,
+ 652, 656, 661, 666, 671, 675, 680, 685,
+ 690, 694, 699, 703, 708, 712, 717, 721,
+ 726, 730, 735, 739, 743, 748, 752, 756,
+ 760, 765, 769, 773, 777, 781, 785, 789,
+ 793, 797, 801, 805, 809, 813, 816, 820,
+ 824, 828, 831, 835, 839, 842, 846, 849,
+ 853, 856, 860, 863, 866, 870, 873, 876,
+ 879, 883, 886, 889, 892, 895, 898, 901,
+ 904, 907, 910, 913, 916, 918, 921, 924,
+ 927, 929, 932, 934, 937, 939, 942, 944,
+ 947, 949, 951, 954, 956, 958, 960, 963,
+ 965, 967, 969, 971, 973, 975, 977, 978,
+ 980, 982, 984, 986, 987, 989, 990, 992,
+ 994, 995, 997, 998, 999, 1001, 1002, 1003,
+ 1004, 1006, 1007, 1008, 1009, 1010, 1011, 1012,
+ 1013, 1014, 1015, 1015, 1016, 1017, 1018, 1018,
+ 1019, 1019, 1020, 1020, 1021, 1021, 1022, 1022,
+ 1022, 1023, 1023, 1023, 1023, 1023, 1023, 1023,
+ 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1022,
+ 1022, 1022, 1021, 1021, 1020, 1020, 1019, 1019,
+ 1018, 1018, 1017, 1016, 1015, 1015, 1014, 1013,
+ 1012, 1011, 1010, 1009, 1008, 1007, 1006, 1004,
+ 1003, 1002, 1001, 999, 998, 997, 995, 994,
+ 992, 990, 989, 987, 986, 984, 982, 980,
+ 978, 977, 975, 973, 971, 969, 967, 965,
+ 963, 960, 958, 956, 954, 951, 949, 947,
+ 944, 942, 939, 937, 934, 932, 929, 927,
+ 924, 921, 918, 916, 913, 910, 907, 904,
+ 901, 898, 895, 892, 889, 886, 883, 879,
+ 876, 873, 870, 866, 863, 860, 856, 853,
+ 849, 846, 842, 839, 835, 831, 828, 824,
+ 820, 816, 813, 809, 805, 801, 797, 793,
+ 789, 785, 781, 777, 773, 769, 765, 760,
+ 756, 752, 748, 743, 739, 735, 730, 726,
+ 721, 717, 712, 708, 703, 699, 694, 690,
+ 685, 680, 675, 671, 666, 661, 656, 652,
+ 647, 642, 637, 632, 627, 622, 617, 612,
+ 607, 602, 597, 592, 587, 581, 576, 571,
+ 566, 561, 555, 550, 545, 539, 534, 529,
+ 523, 518, 512, 507, 501, 496, 491, 485,
+ 479, 474, 468, 463, 457, 451, 446, 440,
+ 434, 429, 423, 417, 412, 406, 400, 394,
+ 388, 383, 377, 371, 365, 359, 353, 347,
+ 342, 336, 330, 324, 318, 312, 306, 300,
+ 294, 288, 282, 276, 270, 264, 257, 251,
+ 245, 239, 233, 227, 221, 215, 209, 202,
+ 196, 190, 184, 178, 171, 165, 159, 153,
+ 147, 140, 134, 128, 122, 115, 109, 103,
+ 97, 90, 84, 78, 72, 65, 59, 53,
+ 47, 40, 34, 28, 21, 15, 9, 3,
+ -4, -10, -16, -22, -29, -35, -41, -48,
+ -54, -60, -66, -73, -79, -85, -91, -98,
+ -104, -110, -116, -123, -129, -135, -141, -148,
+ -154, -160, -166, -172, -179, -185, -191, -197,
+ -203, -210, -216, -222, -228, -234, -240, -246,
+ -252, -258, -265, -271, -277, -283, -289, -295,
+ -301, -307, -313, -319, -325, -331, -337, -343,
+ -348, -354, -360, -366, -372, -378, -384, -389,
+ -395, -401, -407, -413, -418, -424, -430, -435,
+ -441, -447, -452, -458, -464, -469, -475, -480,
+ -486, -492, -497, -502, -508, -513, -519, -524,
+ -530, -535, -540, -546, -551, -556, -562, -567,
+ -572, -577, -582, -588, -593, -598, -603, -608,
+ -613, -618, -623, -628, -633, -638, -643, -648,
+ -653, -657, -662, -667, -672, -676, -681, -686,
+ -691, -695, -700, -704, -709, -713, -718, -722,
+ -727, -731, -736, -740, -744, -749, -753, -757,
+ -761, -766, -770, -774, -778, -782, -786, -790,
+ -794, -798, -802, -806, -810, -814, -817, -821,
+ -825, -829, -832, -836, -840, -843, -847, -850,
+ -854, -857, -861, -864, -867, -871, -874, -877,
+ -880, -884, -887, -890, -893, -896, -899, -902,
+ -905, -908, -911, -914, -917, -919, -922, -925,
+ -928, -930, -933, -935, -938, -940, -943, -945,
+ -948, -950, -952, -955, -957, -959, -961, -964,
+ -966, -968, -970, -972, -974, -976, -978, -979,
+ -981, -983, -985, -987, -988, -990, -991, -993,
+ -995, -996, -998, -999, -1000, -1002, -1003, -1004,
+ -1005, -1007, -1008, -1009, -1010, -1011, -1012, -1013,
+ -1014, -1015, -1016, -1016, -1017, -1018, -1019, -1019,
+ -1020, -1020, -1021, -1021, -1022, -1022, -1023, -1023,
+ -1023, -1024, -1024, -1024, -1024, -1024, -1024, -1024,
+ -1024, -1024, -1024, -1024, -1024, -1024, -1024, -1023,
+ -1023, -1023, -1022, -1022, -1021, -1021, -1020, -1020,
+ -1019, -1019, -1018, -1017, -1016, -1016, -1015, -1014,
+ -1013, -1012, -1011, -1010, -1009, -1008, -1007, -1005,
+ -1004, -1003, -1002, -1000, -999, -998, -996, -995,
+ -993, -991, -990, -988, -987, -985, -983, -981,
+ -979, -978, -976, -974, -972, -970, -968, -966,
+ -964, -961, -959, -957, -955, -952, -950, -948,
+ -945, -943, -940, -938, -935, -933, -930, -928,
+ -925, -922, -919, -917, -914, -911, -908, -905,
+ -902, -899, -896, -893, -890, -887, -884, -880,
+ -877, -874, -871, -867, -864, -861, -857, -854,
+ -850, -847, -843, -840, -836, -832, -829, -825,
+ -821, -817, -814, -810, -806, -802, -798, -794,
+ -790, -786, -782, -778, -774, -770, -766, -761,
+ -757, -753, -749, -744, -740, -736, -731, -727,
+ -722, -718, -713, -709, -704, -700, -695, -691,
+ -686, -681, -676, -672, -667, -662, -657, -653,
+ -648, -643, -638, -633, -628, -623, -618, -613,
+ -608, -603, -598, -593, -588, -582, -577, -572,
+ -567, -562, -556, -551, -546, -540, -535, -530,
+ -524, -519, -513, -508, -502, -497, -492, -486,
+ -480, -475, -469, -464, -458, -452, -447, -441,
+ -435, -430, -424, -418, -413, -407, -401, -395,
+ -389, -384, -378, -372, -366, -360, -354, -348,
+ -343, -337, -331, -325, -319, -313, -307, -301,
+ -295, -289, -283, -277, -271, -265, -258, -252,
+ -246, -240, -234, -228, -222, -216, -210, -203,
+ -197, -191, -185, -179, -172, -166, -160, -154,
+ -148, -141, -135, -129, -123, -116, -110, -104,
+ -98, -91, -85, -79, -73, -66, -60, -54,
+ -48, -41, -35, -29, -22, -16, -10, -4
+};
+
+// this is the program the generate the above table
+#if 0
+#include <stdio.h>
+#include <math.h>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+#define PFREAL_ONE 1024
+#define IANGLE_MAX 1024
+
+int main(int, char**)
+{
+ FILE*f = fopen("table.c","wt");
+ fprintf(f,"PFreal sinTable[] = {\n");
+ for(int i = 0; i < 128; ++i)
+ {
+ for(int j = 0; j < 8; ++j)
+ {
+ int iang = j+i*8;
+ double ii = (double)iang + 0.5;
+ double angle = ii * 2 * M_PI / IANGLE_MAX;
+ double sinAngle = sin(angle);
+ fprintf(f,"%6d, ", (int)(floor(PFREAL_ONE*sinAngle)));
+ }
+ fprintf(f,"\n");
+ }
+ fprintf(f,"};\n");
+ fclose(f);
+
+ return 0;
+}
+#endif
+
+inline PFreal fsin(int iangle)
+{
+ while(iangle < 0)
+ iangle += IANGLE_MAX;
+ return sinTable[iangle & IANGLE_MASK];
+}
+
+inline PFreal fcos(int iangle)
+{
+ // quarter phase shift
+ return fsin(iangle + (IANGLE_MAX >> 2));
+}
+
+namespace FQTerm {
+
+struct SlideInfo
+{
+ int slideIndex;
+ int angle;
+ PFreal cx;
+ PFreal cy;
+};
+
+class PictureFlowPrivate
+{
+public:
+ PictureFlowPrivate(PictureFlow* widget);
+
+ int slideCount() const;
+ void setSlideCount(int count);
+
+ QSize slideSize() const;
+ void setSlideSize(QSize size);
+
+ int zoomFactor() const;
+ void setZoomFactor(int z);
+
+ QImage slide(int index) const;
+ void setSlide(int index, const QImage& image);
+
+ int currentSlide() const;
+ void setCurrentSlide(int index);
+
+ void showPrevious();
+ void showNext();
+ void showSlide(int index);
+
+ void resize(int w, int h);
+
+ void render();
+ void startAnimation();
+ void updateAnimation();
+
+ QImage buffer;
+ QBasicTimer animateTimer;
+ QVector<QRect> slidesRect;
+
+private:
+ PictureFlow* widget;
+
+ int slideWidth;
+ int slideHeight;
+ int zoom;
+
+ QVector<QImage> slideImages;
+ int centerIndex;
+
+ SlideInfo centerSlide;
+ QVector<SlideInfo> leftSlides;
+ QVector<SlideInfo> rightSlides;
+
+ QVector<PFreal> rays;
+ int itilt;
+ int spacing;
+ PFreal offsetX;
+ PFreal offsetY;
+
+ QImage blankSurface;
+ QCache<int, QImage> surfaceCache;
+ QTimer triggerTimer;
+
+ int slideFrame;
+ int step;
+ int target;
+ int fade;
+
+ void recalc(int w, int h);
+ QRect renderSlide(const SlideInfo &slide, int alpha=256, int col1=-1, int col=-1);
+ QImage* surface(int slideIndex);
+ void triggerRender();
+ void resetSlides();
+};
+
+PictureFlowPrivate::PictureFlowPrivate(PictureFlow* w)
+{
+ widget = w;
+
+ slideWidth = 200;
+ slideHeight = 200;
+ zoom = 100;
+
+ centerIndex = 0;
+
+ slideFrame = 0;
+ step = 0;
+ target = 0;
+ fade = 256;
+
+ triggerTimer.setSingleShot(true);
+ triggerTimer.setInterval(0);
+ QObject::connect(&triggerTimer, SIGNAL(timeout()), widget, SLOT(render()));
+
+ recalc(200, 200);
+ resetSlides();
+}
+
+int PictureFlowPrivate::slideCount() const
+{
+ return slideImages.count();
+}
+
+void PictureFlowPrivate::setSlideCount(int count)
+{
+ slideImages.resize(count);
+ surfaceCache.clear();
+ resetSlides();
+ triggerRender();
+}
+
+QSize PictureFlowPrivate::slideSize() const
+{
+ return QSize(slideWidth, slideHeight);
+}
+
+void PictureFlowPrivate::setSlideSize(QSize size)
+{
+ slideWidth = size.width();
+ slideHeight = size.height();
+ recalc(buffer.width(), buffer.height());
+ triggerRender();
+}
+
+int PictureFlowPrivate::zoomFactor() const
+{
+ return zoom;
+}
+
+void PictureFlowPrivate::setZoomFactor(int z)
+{
+ if(z <= 0)
+ return;
+
+ zoom = z;
+ recalc(buffer.width(), buffer.height());
+ triggerRender();
+}
+
+QImage PictureFlowPrivate::slide(int index) const
+{
+ return slideImages[index];
+}
+
+void PictureFlowPrivate::setSlide(int index, const QImage& image)
+{
+ if((index >= 0) && (index < slideImages.count()))
+ {
+ slideImages[index] = image;
+ surfaceCache.remove(index);
+ triggerRender();
+ }
+}
+
+int PictureFlowPrivate::currentSlide() const
+{
+ return centerIndex;
+}
+
+void PictureFlowPrivate::setCurrentSlide(int index)
+{
+ step = 0;
+ centerIndex = qBound(index, 0, slideImages.count()-1);
+ target = centerIndex;
+ slideFrame = index << 16;
+ resetSlides();
+ triggerRender();
+}
+
+void PictureFlowPrivate::showPrevious()
+{
+ if(step >= 0)
+ {
+ if(centerIndex > 0)
+ {
+ target = centerIndex - 1;
+ startAnimation();
+ }
+ }
+ else
+ {
+ target = qMax(0, centerIndex - 2);
+ }
+}
+
+void PictureFlowPrivate::showNext()
+{
+ if(step <= 0)
+ {
+ if(centerIndex < slideImages.count()-1)
+ {
+ target = centerIndex + 1;
+ startAnimation();
+ }
+ }
+ else
+ {
+ target = qMin(centerIndex + 2, slideImages.count()-1);
+ }
+}
+
+void PictureFlowPrivate::showSlide(int index)
+{
+ index = qMax(index, 0);
+ index = qMin(slideImages.count()-1, index);
+
+ target = index;
+ startAnimation();
+}
+
+void PictureFlowPrivate::resize(int w, int h)
+{
+ recalc(w, h);
+ resetSlides();
+ triggerRender();
+}
+
+
+// adjust slides so that they are in "steady state" position
+void PictureFlowPrivate::resetSlides()
+{
+ centerSlide.angle = 0;
+ centerSlide.cx = 0;
+ centerSlide.cy = 0;
+ centerSlide.slideIndex = centerIndex;
+
+ leftSlides.clear();
+ leftSlides.resize(6);
+ for(int i = 0; i < leftSlides.count(); ++i)
+ {
+ SlideInfo& si = leftSlides[i];
+ si.angle = itilt;
+ si.cx = -(offsetX + spacing*i*PFREAL_ONE);
+ si.cy = offsetY;
+ si.slideIndex = centerIndex-1-i;
+ }
+
+ rightSlides.clear();
+ rightSlides.resize(6);
+ for(int i = 0; i < rightSlides.count(); ++i)
+ {
+ SlideInfo& si = rightSlides[i];
+ si.angle = -itilt;
+ si.cx = offsetX + spacing*i*PFREAL_ONE;
+ si.cy = offsetY;
+ si.slideIndex = centerIndex+1+i;
+ }
+}
+
+#define BILINEAR_STRETCH_HOR 4
+#define BILINEAR_STRETCH_VER 4
+
+static QImage scaleImage (QImage image, int w, int h) {
+ // I don't have to scale it
+ if (w == image.width() && h == image.height())
+ return(image);
+
+ QImage output(w, h, QImage::Format_ARGB32_Premultiplied);
+ output.fill(0);
+
+ double scaleHeight = w / (double) image.height();
+ double scaleWidth = h / (double) image.width();
+
+ double s = qMin(scaleWidth, scaleHeight);
+
+ int sw = (int) qRound(s * image.width());
+ int sh = (int) qRound(s * image.height());
+
+ // Scale Image
+ QImage imgScaled = image.scaled(sw, sh, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+
+ int _x = (w - sw) / 2;
+ int _y = (h - sh);
+
+ for (int x = 0; x < imgScaled.width(); ++x) {
+ for (int y = 0; y < imgScaled.height(); ++y) {
+ output.setPixel(x + _x, y + _y, imgScaled.pixel(x, y));
+ }
+ }
+
+ return(output);
+}
+
+static QImage prepareSurface(QImage img, int w, int h)
+{
+ img = scaleImage(img, w, h);
+
+ // slightly larger, to accomodate for the reflection
+ int hs = h * 2;
+ int hofs = h / 3;
+
+ // offscreen buffer: black is sweet
+ QImage result(hs, w, QImage::Format_RGB32);
+ result.fill(0);
+
+ // transpose the image, this is to speed-up the rendering
+ // because we process one column at a time
+ // (and much better and faster to work row-wise, i.e in one scanline)
+ for(int x = 0; x < w; x++)
+ for(int y = 0; y < h; y++)
+ result.setPixel(hofs + y, x, img.pixel(x, y));
+
+ // create the reflection
+ int ht = hs - h - hofs;
+ int hte = ht;
+ for(int x = 0; x < w; x++)
+ for(int y = 0; y < ht; y++)
+ {
+ QRgb color = img.pixel(x, img.height()-y-1);
+ int a = qAlpha(color);
+ int r = qRed(color) * a / 256 * (hte - y) / hte * 3/5;
+ int g = qGreen(color) * a / 256 * (hte - y) / hte * 3/5;
+ int b = qBlue(color) * a / 256 * (hte - y) / hte * 3/5;
+ result.setPixel(h+hofs+y, x, qRgb(r, g, b));
+ }
+
+#ifdef PICTUREFLOW_BILINEAR_FILTER
+ int hh = BILINEAR_STRETCH_VER*hs;
+ int ww = BILINEAR_STRETCH_HOR*w;
+ result = scaleImage(result, hh, ww);
+#endif
+
+ return result;
+}
+
+
+// get transformed image for specified slide
+// if it does not exist, create it and place it in the cache
+QImage* PictureFlowPrivate::surface(int slideIndex)
+{
+ if(slideIndex < 0)
+ return 0;
+ if(slideIndex >= slideImages.count())
+ return 0;
+
+ if(surfaceCache.contains(slideIndex))
+ return surfaceCache[slideIndex];
+
+ QImage img = widget->slide(slideIndex);
+ if(img.isNull())
+ {
+ if(blankSurface.isNull())
+ {
+ blankSurface = QImage(slideWidth, slideHeight, QImage::Format_RGB32);
+
+ QPainter painter(&blankSurface);
+ QPoint p1(slideWidth*4/10, 0);
+ QPoint p2(slideWidth*6/10, slideHeight);
+ QLinearGradient linearGrad(p1, p2);
+ linearGrad.setColorAt(0, Qt::black);
+ linearGrad.setColorAt(1, Qt::white);
+ painter.setBrush(linearGrad);
+ painter.fillRect(0, 0, slideWidth, slideHeight, QBrush(linearGrad));
+
+ painter.setPen(QPen(QColor(64,64,64), 4));
+ painter.setBrush(QBrush());
+ painter.drawRect(2, 2, slideWidth-3, slideHeight-3);
+ painter.end();
+ blankSurface = prepareSurface(blankSurface, slideWidth, slideHeight);
+ }
+ return &blankSurface;
+ }
+
+ surfaceCache.insert(slideIndex, new QImage(prepareSurface(img, slideWidth, slideHeight)));
+ return surfaceCache[slideIndex];
+}
+
+
+// Schedules rendering the slides. Call this function to avoid immediate
+// render and thus cause less flicker.
+void PictureFlowPrivate::triggerRender()
+{
+ triggerTimer.start();
+}
+
+// Render the slides. Updates only the offscreen buffer.
+void PictureFlowPrivate::render()
+{
+ buffer.fill(Qt::black);
+
+ int nleft = leftSlides.count();
+ int nright = rightSlides.count();
+
+ QRect r = renderSlide(centerSlide);
+ int c1 = r.left();
+ int c2 = r.right();
+
+ if(step == 0)
+ {
+ slidesRect.clear();
+ slidesRect.resize(11);
+
+ // no animation, boring plain rendering
+ for(int index = 0; index < nleft-1; index++)
+ {
+ int alpha = (index < nleft-2) ? 256 : 128;
+ QRect rs = renderSlide(leftSlides[index], alpha, 0, c1-1);
+ slidesRect[index] = rs;
+ if(!rs.isEmpty())
+ c1 = rs.left();
+ }
+ slidesRect[5] = r;
+ for(int index = 0; index < nright-1; index++)
+ {
+ int alpha = (index < nright-2) ? 256 : 128;
+ QRect rs = renderSlide(rightSlides[index], alpha, c2+1, buffer.width());
+ slidesRect[6 + index] = rs;
+ if(!rs.isEmpty())
+ c2 = rs.right();
+ }
+ }
+ else
+ {
+ // the first and last slide must fade in/fade out
+ for(int index = 0; index < nleft; index++)
+ {
+ int alpha = 256;
+ if(index == nleft-1)
+ alpha = (step > 0) ? 0 : 128-fade/2;
+ if(index == nleft-2)
+ alpha = (step > 0) ? 128-fade/2 : 256-fade/2;
+ if(index == nleft-3)
+ alpha = (step > 0) ? 256-fade/2 : 256;
+ QRect rs = renderSlide(leftSlides[index], alpha, 0, c1-1);
+ if(!rs.isEmpty())
+ c1 = rs.left();
+ }
+ for(int index = 0; index < nright; index++)
+ {
+ int alpha = (index < nright-2) ? 256 : 128;
+ if(index == nright-1)
+ alpha = (step > 0) ? fade/2 : 0;
+ if(index == nright-2)
+ alpha = (step > 0) ? 128+fade/2 : fade/2;
+ if(index == nright-3)
+ alpha = (step > 0) ? 256 : 128+fade/2;
+ QRect rs = renderSlide(rightSlides[index], alpha, c2+1, buffer.width());
+ if(!rs.isEmpty())
+ c2 = rs.right();
+ }
+ }
+}
+
+// Renders a slide to offscreen buffer. Returns a rect of the rendered area.
+// alpha=256 means normal, alpha=0 is fully black, alpha=128 half transparent
+// col1 and col2 limit the column for rendering.
+QRect PictureFlowPrivate::renderSlide(const SlideInfo &slide, int alpha,
+int col1, int col2)
+{
+ QImage* src = surface(slide.slideIndex);
+ if(!src)
+ return QRect();
+
+ QRect rect(0, 0, 0, 0);
+
+#ifdef PICTUREFLOW_BILINEAR_FILTER
+ int sw = src->height() / BILINEAR_STRETCH_HOR;
+ int sh = src->width() / BILINEAR_STRETCH_VER;
+#else
+ int sw = src->height();
+ int sh = src->width();
+#endif
+ int h = buffer.height();
+ int w = buffer.width();
+
+ if(col1 > col2)
+ {
+ int c = col2;
+ col2 = col1;
+ col1 = c;
+ }
+
+ col1 = (col1 >= 0) ? col1 : 0;
+ col2 = (col2 >= 0) ? col2 : w-1;
+ col1 = qMin(col1, w-1);
+ col2 = qMin(col2, w-1);
+
+ int distance = h * 100 / zoom;
+ PFreal sdx = fcos(slide.angle);
+ PFreal sdy = fsin(slide.angle);
+ PFreal xs = slide.cx - slideWidth * sdx/2;
+ PFreal ys = slide.cy - slideWidth * sdy/2;
+ PFreal dist = distance * PFREAL_ONE;
+
+ int xi = qMax((PFreal)0, ((w*PFREAL_ONE/2) + fdiv(xs*h, dist+ys)) >> PFREAL_SHIFT);
+ if(xi >= w)
+ return rect;
+
+ bool flag = false;
+ rect.setLeft(xi);
+
+ for(int x = qMax(xi, col1); x <= col2; x++)
+ {
+ PFreal hity = 0;
+ PFreal fk = rays[x];
+ if(sdy)
+ {
+ fk = fk - fdiv(sdx,sdy);
+ hity = -fdiv((rays[x]*distance - slide.cx + slide.cy*sdx/sdy), fk);
+ }
+
+ dist = distance*PFREAL_ONE + hity;
+ if(dist < 0)
+ continue;
+
+ PFreal hitx = fmul(dist, rays[x]);
+ PFreal hitdist = fdiv(hitx - slide.cx, sdx);
+
+#ifdef PICTUREFLOW_BILINEAR_FILTER
+ int column = sw*BILINEAR_STRETCH_HOR/2 + (hitdist*BILINEAR_STRETCH_HOR >> PFREAL_SHIFT);
+ if(column >= sw*BILINEAR_STRETCH_HOR)
+ break;
+#else
+ int column = sw/2 + (hitdist >> PFREAL_SHIFT);
+ if(column >= sw)
+ break;
+#endif
+ if(column < 0)
+ continue;
+
+ rect.setRight(x);
+ if(!flag)
+ rect.setLeft(x);
+ flag = true;
+
+ int y1 = h/2;
+ int y2 = y1+ 1;
+ QRgb* pixel1 = (QRgb*)(buffer.scanLine(y1)) + x;
+ QRgb* pixel2 = (QRgb*)(buffer.scanLine(y2)) + x;
+ QRgb pixelstep = pixel2 - pixel1;
+
+#ifdef PICTUREFLOW_BILINEAR_FILTER
+ int center = (sh*BILINEAR_STRETCH_VER/2);
+ int dy = dist*BILINEAR_STRETCH_VER / h;
+#else
+ int center = (sh/2);
+ int dy = dist / h;
+#endif
+ int p1 = center*PFREAL_ONE - dy/2;
+ int p2 = center*PFREAL_ONE + dy/2;
+
+ const QRgb *ptr = (const QRgb*)(src->scanLine(column));
+ if(alpha == 256)
+ while((y1 >= 0) && (y2 < h) && (p1 >= 0))
+ {
+ *pixel1 = ptr[p1 >> PFREAL_SHIFT];
+ *pixel2 = ptr[p2 >> PFREAL_SHIFT];
+ p1 -= dy;
+ p2 += dy;
+ y1--;
+ y2++;
+ pixel1 -= pixelstep;
+ pixel2 += pixelstep;
+ }
+ else
+ while((y1 >= 0) && (y2 < h) && (p1 >= 0))
+ {
+ QRgb c1 = ptr[p1 >> PFREAL_SHIFT];
+ QRgb c2 = ptr[p2 >> PFREAL_SHIFT];
+
+ int r1 = qRed(c1) * alpha/256;
+ int g1 = qGreen(c1) * alpha/256;
+ int b1 = qBlue(c1) * alpha/256;
+ int r2 = qRed(c2) * alpha/256;
+ int g2 = qGreen(c2) * alpha/256;
+ int b2 = qBlue(c2) * alpha/256;
+
+ *pixel1 = qRgb(r1, g1, b1);
+ *pixel2 = qRgb(r2, g2, b2);
+ p1 -= dy;
+ p2 += dy;
+ y1--;
+ y2++;
+ pixel1 -= pixelstep;
+ pixel2 += pixelstep;
+ }
+ }
+
+ rect.setTop(0);
+ rect.setBottom(h-1);
+ return rect;
+}
+
+// Updates look-up table and other stuff necessary for the rendering.
+// Call this when the viewport size or slide dimension is changed.
+void PictureFlowPrivate::recalc(int ww, int wh)
+{
+ int w = (ww+1)/2;
+ int h = (wh+1)/2;
+ buffer = QImage(ww, wh, QImage::Format_RGB32);
+ buffer.fill(0);
+
+ rays.resize(w*2);
+
+ for(int i = 0; i < w; ++i)
+ {
+ PFreal gg = (PFREAL_HALF + i * PFREAL_ONE) / (2*h);
+ rays[w-i-1] = -gg;
+ rays[w+i] = gg;
+ }
+
+
+ itilt = 70 * IANGLE_MAX / 360; // approx. 70 degrees tilted
+
+ offsetX = slideWidth/2 * (PFREAL_ONE-fcos(itilt));
+ offsetY = slideWidth/2 * fsin(itilt);
+ offsetX += slideWidth * PFREAL_ONE;
+ offsetY += slideWidth * PFREAL_ONE / 4;
+ spacing = 40;
+
+ surfaceCache.clear();
+ blankSurface = QImage();
+}
+
+void PictureFlowPrivate::startAnimation()
+{
+#if 1
+ if(!animateTimer.isActive())
+ {
+ step = (target < centerSlide.slideIndex) ? -1 : 1;
+ animateTimer.start(30, widget);
+ }
+#else
+ if (animateTimer.isActive())
+ animateTimer.stop();
+
+ step = (target < centerSlide.slideIndex) ? -1 : 1;
+ animateTimer.start(30, widget);
+#endif
+}
+
+// Updates the animation effect. Call this periodically from a timer.
+void PictureFlowPrivate::updateAnimation()
+{
+ if(!animateTimer.isActive())
+ return;
+ if(step == 0)
+ return;
+
+ int speed = 16384;
+
+ // deaccelerate when approaching the target
+ if(true)
+ {
+ const int max = 2 * 65536;
+
+ int fi = slideFrame;
+ fi -= (target << 16);
+ if(fi < 0)
+ fi = -fi;
+ fi = qMin(fi, max);
+
+ int ia = IANGLE_MAX * (fi-max/2) / (max*2);
+ speed = 512 + 16384 * (PFREAL_ONE+fsin(ia))/PFREAL_ONE;
+ }
+
+ slideFrame += speed*step;
+
+ int index = slideFrame >> 16;
+ int pos = slideFrame & 0xffff;
+ int neg = 65536 - pos;
+ int tick = (step < 0) ? neg : pos;
+ PFreal ftick = (tick * PFREAL_ONE) >> 16;
+
+ // the leftmost and rightmost slide must fade away
+ fade = pos / 256;
+
+ if(step < 0)
+ index++;
+ if(centerIndex != index)
+ {
+ centerIndex = index;
+ slideFrame = index << 16;
+ centerSlide.slideIndex = centerIndex;
+ for(int i = 0; i < leftSlides.count(); ++i)
+ leftSlides[i].slideIndex = centerIndex-1-i;
+ for(int i = 0; i < rightSlides.count(); ++i)
+ rightSlides[i].slideIndex = centerIndex+1+i;
+ }
+
+ centerSlide.angle = (step * tick * itilt) >> 16;
+ centerSlide.cx = -step * fmul(offsetX, ftick);
+ centerSlide.cy = fmul(offsetY, ftick);
+
+ if(centerIndex == target)
+ {
+ resetSlides();
+ animateTimer.stop();
+ triggerRender();
+ step = 0;
+ fade = 256;
+ return;
+ }
+
+ for(int i = 0; i < leftSlides.count(); ++i)
+ {
+ SlideInfo& si = leftSlides[i];
+ si.angle = itilt;
+ si.cx = -(offsetX + spacing*i*PFREAL_ONE + step*spacing*ftick);
+ si.cy = offsetY;
+ }
+
+ for(int i = 0; i < rightSlides.count(); ++i)
+ {
+ SlideInfo& si = rightSlides[i];
+ si.angle = -itilt;
+ si.cx = offsetX + spacing*i*PFREAL_ONE - step*spacing*ftick;
+ si.cy = offsetY;
+ }
+
+ if(step > 0)
+ {
+ PFreal ftick = (neg * PFREAL_ONE) >> 16;
+ rightSlides[0].angle = -(neg * itilt) >> 16;
+ rightSlides[0].cx = fmul(offsetX, ftick);
+ rightSlides[0].cy = fmul(offsetY, ftick);
+ }
+ else
+ {
+ PFreal ftick = (pos * PFREAL_ONE) >> 16;
+ leftSlides[0].angle = (pos * itilt) >> 16;
+ leftSlides[0].cx = -fmul(offsetX, ftick);
+ leftSlides[0].cy = fmul(offsetY, ftick);
+ }
+
+ // must change direction ?
+ if(target < index) if(step > 0)
+ step = -1;
+ if(target > index) if(step < 0)
+ step = 1;
+
+ triggerRender();
+}
+
+// -----------------------------------------
+
+PictureFlow::PictureFlow(QWidget* parent): QWidget(parent)
+{
+ d = new PictureFlowPrivate(this);
+
+ setAttribute(Qt::WA_StaticContents, true);
+ setAttribute(Qt::WA_OpaquePaintEvent, true);
+ setAttribute(Qt::WA_NoSystemBackground, true);
+}
+
+PictureFlow::~PictureFlow()
+{
+ delete d;
+}
+
+int PictureFlow::slideCount() const
+{
+ return d->slideCount();
+}
+
+void PictureFlow::setSlideCount(int count)
+{
+ d->setSlideCount(count);
+}
+
+QSize PictureFlow::slideSize() const
+{
+ return d->slideSize();
+}
+
+void PictureFlow::setSlideSize(QSize size)
+{
+ d->setSlideSize(size);
+}
+
+int PictureFlow::zoomFactor() const
+{
+ return d->zoomFactor();
+}
+
+void PictureFlow::setZoomFactor(int z)
+{
+ d->setZoomFactor(z);
+}
+
+QImage PictureFlow::slide(int index) const
+{
+ return d->slide(index);
+}
+
+void PictureFlow::setSlide(int index, const QImage& image)
+{
+ d->setSlide(index, image);
+}
+
+void PictureFlow::setSlide(int index, const QPixmap& pixmap)
+{
+ d->setSlide(index, pixmap.toImage());
+}
+
+int PictureFlow::currentSlide() const
+{
+ return d->currentSlide();
+}
+
+void PictureFlow::setCurrentSlide(int index)
+{
+ d->setCurrentSlide(index);
+}
+
+void PictureFlow::clear()
+{
+ d->setSlideCount(0);
+}
+
+void PictureFlow::render()
+{
+ d->render();
+ update();
+}
+
+void PictureFlow::showPrevious()
+{
+ d->showPrevious();
+}
+
+void PictureFlow::showNext()
+{
+ d->showNext();
+}
+
+void PictureFlow::showSlide(int index)
+{
+ d->showSlide(index);
+}
+
+void PictureFlow::showSlideAt (int x, int y) {
+ if (d->slidesRect[5].contains(x, y))
+ return;
+
+ if (x < d->slidesRect[5].x()) {
+ for (int i=0; i < 5; ++i) {
+ if (d->slidesRect[i].contains(x, y)) {
+ showSlide(d->currentSlide() - (i + 1));
+ return;
+ }
+ }
+ } else {
+ for (int i=6; i < 11; ++i) {
+ if (d->slidesRect[i].contains(x, y)) {
+ showSlide(d->currentSlide() + (i - 5));
+ return;
+ }
+ }
+ }
+}
+
+void PictureFlow::keyPressEvent(QKeyEvent* event)
+{
+
+ switch (event->key()) {
+ case Qt::Key_Left:
+ if(event->modifiers() == Qt::AltModifier) {
+ showSlide(currentSlide() - 5);
+ } else {
+ showPrevious();
+ }
+ event->accept();
+ return;
+ case Qt::Key_Right:
+ if(event->modifiers() == Qt::AltModifier) {
+ showSlide(currentSlide() + 5);
+ } else {
+ showNext();
+ }
+ event->accept();
+ return;
+ case Qt::Key_Up:
+ showSlide(currentSlide() + 10);
+ event->accept();
+ return;
+ case Qt::Key_Down:
+ showSlide(currentSlide() - 10);
+ event->accept();
+ return;
+ default:
+ break;
+ }
+
+ event->ignore();
+}
+
+void PictureFlow::mouseReleaseEvent (QMouseEvent *event) {
+ showSlideAt(event->x(), event->y());
+}
+
+void PictureFlow::mouseMoveEvent (QMouseEvent *event) {
+ showSlideAt(event->x(), event->y());
+}
+
+void PictureFlow::wheelEvent (QWheelEvent *event) {
+ int numDegrees = event->delta() / 8;
+ int numSteps = numDegrees / 15;
+
+ d->showSlide(d->currentSlide() + numSteps);
+ event->accept();
+}
+
+void PictureFlow::paintEvent(QPaintEvent* event)
+{
+ Q_UNUSED(event);
+ QPainter painter(this);
+ painter.setRenderHint(QPainter::Antialiasing, false);
+ painter.drawImage(QPoint(0,0), d->buffer);
+}
+
+void PictureFlow::resizeEvent(QResizeEvent* event)
+{
+ d->resize(width(), height());
+ QWidget::resizeEvent(event);
+}
+
+void PictureFlow::timerEvent(QTimerEvent* event)
+{
+ if(event->timerId() == d->animateTimer.timerId())
+ d->updateAnimation();
+ else
+ QWidget::timerEvent(event);
+}
+
+} // namespace FQTerm
+
+#include "pictureflow.moc"
diff --git a/src/ui/pictureflow.h b/src/ui/pictureflow.h
new file mode 100644
index 0000000..c9cf5aa
--- /dev/null
+++ b/src/ui/pictureflow.h
@@ -0,0 +1,198 @@
+
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+/*
+ PictureFlow - animated image show widget
+ http://pictureflow.googlecode.com
+
+ Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+#ifndef PICTUREFLOW_H
+#define PICTUREFLOW_H
+
+#include <QWidget>
+
+namespace FQTerm {
+
+class PictureFlowPrivate;
+
+/*!
+ Class PictureFlow implements an image show widget with animation effect
+ like Apple's CoverFlow (in iTunes and iPod). Images are arranged in form
+ of slides, one main slide is shown at the center with few slides on
+ the left and right sides of the center slide. When the next or previous
+ slide is brought to the front, the whole slides flow to the right or
+ the right with smooth animation effect; until the new slide is finally
+ placed at the center.
+
+ */
+class PictureFlow : public QWidget
+{
+Q_OBJECT
+
+ Q_PROPERTY(int slideCount READ slideCount WRITE setSlideCount)
+ Q_PROPERTY(int currentSlide READ currentSlide WRITE setCurrentSlide)
+ Q_PROPERTY(QSize slideSize READ slideSize WRITE setSlideSize)
+ Q_PROPERTY(int zoomFactor READ zoomFactor WRITE setZoomFactor)
+
+public:
+ /*!
+ Creates a new PictureFlow widget.
+ */
+ PictureFlow(QWidget* parent = 0);
+
+ /*!
+ Destroys the widget.
+ */
+ ~PictureFlow();
+
+ /*!
+ Returns the total number of slides.
+ */
+ int slideCount() const;
+
+ /*!
+ Sets the total number of slides.
+ */
+ void setSlideCount(int count);
+
+ /*!
+ Returns the dimension of each slide (in pixels).
+ */
+ QSize slideSize() const;
+
+ /*!
+ Sets the dimension of each slide (in pixels).
+ */
+ void setSlideSize(QSize size);
+
+ /*!
+ Sets the zoom factor (in percent).
+ */
+ void setZoomFactor(int zoom);
+
+ /*!
+ Returns the zoom factor (in percent).
+ */
+ int zoomFactor() const;
+
+ /*!
+ Returns QImage of specified slide.
+ This function will be called only whenever necessary, e.g. the 100th slide
+ will not be retrived when only the first few slides are visible.
+ */
+ virtual QImage slide(int index) const;
+
+ /*!
+ Sets an image for specified slide. If the slide already exists,
+ it will be replaced.
+ */
+ virtual void setSlide(int index, const QImage& image);
+
+ /*!
+ Sets a pixmap for specified slide. If the slide already exists,
+ it will be replaced.
+ */
+ virtual void setSlide(int index, const QPixmap& pixmap);
+
+ /*!
+ Returns the index of slide currently shown in the middle of the viewport.
+ */
+ int currentSlide() const;
+
+signals:
+ void slideSelected (int index);
+
+public slots:
+
+ /*!
+ Sets slide to be shown in the middle of the viewport. No animation
+ effect will be produced, unlike using showSlide.
+ */
+ void setCurrentSlide(int index);
+
+ /*!
+ Clears images of all slides.
+ */
+ void clear();
+
+ /*!
+ Rerender the widget. Normally this function will be automatically invoked
+ whenever necessary, e.g. during the transition animation.
+ */
+ void render();
+
+ /*!
+ Shows previous slide using animation effect.
+ */
+ void showPrevious();
+
+ /*!
+ Shows next slide using animation effect.
+ */
+ void showNext();
+
+ /*!
+ Go to specified slide using animation effect.
+ */
+ void showSlide(int index);
+
+
+ /*!
+ Go to slide at specified position using animation effect.
+ */
+ void showSlideAt(int x, int y);
+
+protected:
+ void mouseReleaseEvent (QMouseEvent *event);
+ void mouseMoveEvent (QMouseEvent *event);
+ void wheelEvent (QWheelEvent *event);
+ void paintEvent(QPaintEvent *event);
+ void keyPressEvent(QKeyEvent *event);
+ void resizeEvent(QResizeEvent *event);
+ void timerEvent(QTimerEvent *event);
+
+private:
+ PictureFlowPrivate* d;
+};
+
+} // namespace FQTerm
+
+#endif // PICTUREFLOW_H
diff --git a/src/ui/popupMessage.cpp b/src/ui/popupMessage.cpp
new file mode 100644
index 0000000..6b89b38
--- /dev/null
+++ b/src/ui/popupMessage.cpp
@@ -0,0 +1,316 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QVBoxLayout>
+#include <QPixmap>
+#include <QHBoxLayout>
+#include <QTimerEvent>
+#include <QLabel>
+#include <QMessageBox>
+#include <QTimer>
+#include <QFont>
+#include <QPushButton>
+#include <QPainter>
+
+#include "popupMessage.h"
+#include "fqterm_trace.h"
+
+namespace FQTerm {
+
+PopupMessage::PopupMessage(QWidget *parent_, QWidget *anchor, int timeout)
+ : OverlayWidget(parent_, anchor),
+ anchor_(anchor),
+ parent_(parent_),
+ maskEffect_(Slide),
+ dissolveSize_(0),
+ dissolveDelta_(-1),
+ offset_(0),
+ counter_(0),
+ stage_(1),
+ timeout_(timeout),
+ isCounterShown_(true) {
+ setFrameStyle(QFrame::Panel | QFrame::Raised);
+ setFrameShape(QFrame::StyledPanel);
+ // overrideWindowFlags( Qt::WX11BypassWM );
+
+ QHBoxLayout *hbox;
+ QLabel *label;
+ QLabel *alabel;
+ //KActiveLabel *alabel;
+
+ layout_ = new QVBoxLayout(this); //, 9 /*margin*/, 6 /*spacing*/ );
+ layout_->setMargin(9);
+ layout_->setSpacing(6);
+
+ hbox = new QHBoxLayout; //( layout_, 12 );
+ hbox->setMargin(12);
+
+ layout_->addLayout(hbox);
+
+ hbox->addWidget(countDownFrame_ = new QFrame(this)); //, "counterVisual" ) );
+ countDownFrame_->setObjectName("counterVisual");
+ countDownFrame_->setFixedWidth(fontMetrics().width("X"));
+ countDownFrame_->setFrameStyle(QFrame::Plain | QFrame::Box);
+ QPalette tmp_palette;
+ tmp_palette.setColor(countDownFrame_->foregroundRole(), palette().color
+ (QPalette::Window).dark());
+ countDownFrame_->setPalette(tmp_palette);
+ // m_countdownFrame->setPaletteForegroundColor( paletteBackgroundColor().dark() );
+
+ label = new QLabel(this); //, "image" );
+ label->setObjectName("image");
+ hbox->addWidget(label);
+ label->hide();
+
+ alabel = new QLabel("Details of the tasks: ", this); //, "label");
+ alabel->setObjectName("label");
+ //alabel = new KActiveLabel( this, "label" );
+ //alabel->setTextFormat( Qt::RichText );
+ alabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
+
+ hbox->addWidget(alabel);
+
+ hbox = new QHBoxLayout;
+
+ layout_->addLayout(hbox);
+
+ hbox->addItem(new QSpacerItem(4, 4, QSizePolicy::Expanding,
+ QSizePolicy::Preferred));
+ //FIXME: add icon
+ QPushButton *tmp_button = new QPushButton("Close", this);
+ tmp_button->setObjectName("closeButton");
+ hbox->addWidget(tmp_button); //, "closeButton" ) );
+
+ FQ_VERIFY(connect(findChild < QPushButton * > ("closeButton"), SIGNAL(clicked()),
+ SLOT(close())));
+}
+
+void PopupMessage::addWidget(QWidget *widget) {
+ layout_->addWidget(widget);
+ adjustSize();
+}
+
+void PopupMessage::showCloseButton(const bool show) {
+ findChild < QPushButton * > ("closeButton")->setShown(show);
+ adjustSize();
+}
+
+void PopupMessage::showCounter(const bool show) {
+ isCounterShown_ = show;
+ findChild < QFrame * > ("counterVisual")->setShown(show);
+ adjustSize();
+}
+
+void PopupMessage::setText(const QString &text) {
+ findChild < QLabel * > ("label")->setText(text);
+ adjustSize();
+}
+
+void PopupMessage::setImage(const QString &location_) {
+ findChild < QLabel * > ("image")->setPixmap(QPixmap(location_));
+ adjustSize();
+}
+
+
+////////////////////////////////////////////////////////////////////////
+// Public Slots
+////////////////////////////////////////////////////////////////////////
+
+void PopupMessage::close() { //SLOT
+ stage_ = 3;
+ killTimer(timerId_);
+ timerId_ = startTimer(6);
+}
+
+void PopupMessage::display() { //SLOT
+ dissolveSize_ = 24;
+ dissolveDelta_ = -1;
+
+ if (maskEffect_ == Dissolve) {
+ // necessary to create the mask
+ maskBitmap_ = QBitmap(width(), height());
+ // make the mask empty and hence will not show widget with show() called below
+ dissolveMask();
+ timerId_ = startTimer(1000 / 30);
+ } else {
+ timerId_ = startTimer(6);
+ }
+ show();
+}
+
+////////////////////////////////////////////////////////////////////////
+// Protected
+////////////////////////////////////////////////////////////////////////
+
+void PopupMessage::timerEvent(QTimerEvent*) {
+ switch (maskEffect_) {
+ case Plain:
+ plainMask();
+ break;
+
+ case Slide:
+ slideMask();
+ break;
+
+ case Dissolve:
+ dissolveMask();
+ break;
+ }
+}
+
+void PopupMessage::countDown() {
+ if (!timeout_) {
+ killTimer(timerId_);
+ return ;
+ }
+
+ QFrame * &h = countDownFrame_;
+
+ if (counter_ < h->height() - 3) {
+ QPainter(h).fillRect(2, 2, h->width() - 4, counter_, palette().color
+ (QPalette::Active, QPalette::Highlight));
+ }
+
+ if (!testAttribute(Qt::WA_UnderMouse)) {
+ counter_++;
+ }
+
+ if (counter_ > h->height()) {
+ stage_ = 3;
+ killTimer(timerId_);
+ timerId_ = startTimer(6);
+ } else {
+ killTimer(timerId_);
+ timerId_ = startTimer(timeout_ / h->height());
+ }
+}
+
+void PopupMessage::dissolveMask() {
+ if (stage_ == 1) {
+ //repaint( false );
+ QPainter maskPainter(&maskBitmap_);
+
+ maskBitmap_.fill(Qt::black);
+
+ maskPainter.setBrush(Qt::white);
+ maskPainter.setPen(Qt::white);
+ maskPainter.drawRect(maskBitmap_.rect());
+
+ dissolveSize_ += dissolveDelta_;
+
+ if (dissolveSize_ > 0) {
+ //maskPainter.setCompositionMode( Qt::EraseROP );
+ //FIXME: QRubberBand
+
+ int x, y, s;
+ const int size = 16;
+
+ for (y = 0; y < height() + size; y += size) {
+ x = width();
+ s = dissolveSize_ * x / 128;
+
+ for (; x > size; x -= size, s -= 2) {
+ if (s < 0) {
+ break;
+ }
+
+ maskPainter.drawEllipse(x - s / 2, y - s / 2, s, s);
+ }
+ }
+ } else if (dissolveSize_ < 0) {
+ dissolveDelta_ = 1;
+ killTimer(timerId_);
+
+ if (timeout_) {
+ timerId_ = startTimer(40);
+ stage_ = 2;
+ }
+ }
+
+ setMask(maskBitmap_);
+ } else if (stage_ == 2) {
+ countDown();
+ } else {
+ deleteLater();
+ }
+}
+
+
+void PopupMessage::plainMask() {
+ switch (stage_) {
+ case 1:
+ // Raise
+ killTimer(timerId_);
+ if (timeout_) {
+ timerId_ = startTimer(40);
+ stage_ = 2;
+ }
+
+ break;
+
+ case 2:
+ // Counter
+ countDown();
+ break;
+
+ case 3:
+ // Lower/Remove
+ deleteLater();
+ }
+}
+
+
+void PopupMessage::slideMask() {
+ switch (stage_) {
+ case 1:
+ //raise
+ move(0, parent_->y() - offset_);
+
+ offset_++;
+ if (offset_ > height()) {
+ killTimer(timerId_);
+
+ if (timeout_) {
+ timerId_ = startTimer(40);
+ stage_ = 2;
+ }
+ }
+
+ break;
+
+ case 2:
+ //fill in pause timer bar
+ countDown();
+ break;
+
+ case 3:
+ //lower
+ offset_--;
+ move(0, parent_->y() - offset_);
+
+ if (offset_ < 0) {
+ deleteLater();
+ }
+ }
+}
+
+} // namespace FQTerm
+
+#include "popupMessage.moc"
diff --git a/src/ui/popupMessage.h b/src/ui/popupMessage.h
new file mode 100644
index 0000000..1877b1c
--- /dev/null
+++ b/src/ui/popupMessage.h
@@ -0,0 +1,116 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+//WARNING this is not meant for use outside this unit!
+
+
+#ifndef FQTERM_POPUP_MESSAGE_H
+#define FQTERM_POPUP_MESSAGE_H
+
+#include "overlayWidget.h"
+
+// #include <qbitmap.h>
+// #include <qlayout.h>
+// #include <qpixmap.h>
+//Added by qt3to4:
+#include <QVBoxLayout>
+#include <QTimerEvent>
+#include <QFrame>
+#include <QBitmap>
+#include <QPixmap>
+
+namespace FQTerm {
+/**
+ * @class PopupMessage
+ * @short Widget that animates itself into a position relative to an anchor widget
+ */
+class PopupMessage: public OverlayWidget {
+ Q_OBJECT;
+ public:
+ /**
+ * @param anchor : which widget to tie the popup widget to.
+ * @param timeout : how long to wait before auto closing. A value of 0 means close
+ * only on pressing the closeButton or close() is called.
+ */
+ PopupMessage(QWidget *parent_, QWidget *anchor, int timeout = 5000
+ /*milliseconds*/);
+
+ enum MaskEffect {
+ Plain, Slide, Dissolve
+ };
+
+ void addWidget(QWidget *widget);
+ void showCloseButton(const bool show);
+ void showCounter(const bool show);
+ void setImage(const QString &location_);
+ void setMaskEffect(const MaskEffect type) {
+ maskEffect_ = type;
+ }
+ void setText(const QString &text);
+ void setTimeout(const int time) {
+ timeout_ = time;
+ }
+
+ public slots:
+ void close();
+ void display();
+
+ protected:
+ void timerEvent(QTimerEvent*);
+ void countDown();
+
+ /**
+ * @short Gradually show widget by dissolving from background
+ */
+ void dissolveMask();
+
+ /**
+ * @short instantly display widget
+ */
+ void plainMask();
+
+ /**
+ * @short animation to slide the widget into view
+ */
+ void slideMask();
+
+ private:
+ QVBoxLayout *layout_;
+ QFrame *countDownFrame_;
+ QWidget *anchor_;
+ QWidget *parent_;
+ QBitmap maskBitmap_;
+ MaskEffect maskEffect_;
+
+ int dissolveSize_;
+ int dissolveDelta_;
+
+ int offset_;
+ int counter_;
+ int stage_;
+ int timeout_;
+ int timerId_;
+
+ bool isCounterShown_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_POPUP_MESSAGE_H
diff --git a/src/ui/popwidget.cpp b/src/ui/popwidget.cpp
new file mode 100644
index 0000000..1c702ed
--- /dev/null
+++ b/src/ui/popwidget.cpp
@@ -0,0 +1,177 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "popwidget.h"
+
+#include <QPixmap>
+#include <QApplication>
+#include <QDesktopWidget>
+#include <QTimer>
+#include <QLabel>
+
+#include <QMouseEvent>
+#include <QPalette>
+
+namespace FQTerm {
+
+extern QString pathLib;
+
+popWidget::popWidget(FQTermWindow *win, QWidget *parent_, const char *name,
+ Qt::WFlags f)
+ : QWidget(parent_, f) {
+ // QPixmap pxm(QPixmap(pathLib+"pic/popwidget.png") );
+ // if(!pxm.isNull())
+ // {
+ // resize(pxm.width(), pxm.height());
+ // QPalette palette;
+ // palette.setBrush(backgroundRole(), QBrush(pxm));
+ // setPalette(palette);
+ // //setBackgroundPixmap(pxm);
+ // }
+ // else
+ // {
+ // resize(200, 120);
+ // }
+ //
+ // label_ = new QLabel(this);
+ // label_->setGeometry( QRect( 5, height()/3, width()-10, height()*2/3 ) );
+ // label_->setAlignment( Qt::AlignTop );
+ // label_->setWordWrap(true);
+ // if(!pxm.isNull()){
+ // QPalette palette;
+ // palette.setBrush(label_->backgroundRole(), QBrush(pxm));
+ // label_->setPalette(palette);
+ // // label_->setBackgroundPixmap(pxm);
+ // }
+ // else {
+ // QPalette palette;
+ // palette.setColor(label_->backgroundRole(), QColor(249,250,229));
+ // label_->setPalette(palette);
+ // //label_->setBackgroundColor(QColor(249,250,229));
+ // }
+ // //label_->setBackgroundOrigin( ParentOrigin );
+ // label_->setFont(QFont(qApp->font().family(), 12));
+ //
+ // pTimer = new QTimer(this);
+ // QVERIFY(connect(pTimer, SIGNAL(timeout()), this, SLOT(showTimer())));
+ //
+ // stateID = -1;
+ //
+ // stepID_ = 2;
+ //
+ // intervalID_ = 500/(height()/stepID_);
+ //
+ // setFocusPolicy(Qt::NoFocus);
+ //
+ // termWindow_ = win;
+ //
+ // hide();
+ //
+ // Display *dsp = QX11Info::display();
+ // int screen = DefaultScreen(dsp);
+ // Window root = RootWindow(dsp, screen);
+ //
+ // WId winid = this->winId();
+ //
+ // XEvent ev;
+ // memset(&ev, 0, sizeof(ev));
+ //
+ // ev.xclient.type = ClientMessage;
+ // ev.xclient.termWindow_ = winid;
+ // ev.xclient.message_type = XInternAtom (dsp, "_NET_WM_DESKTOP", False );
+ // ev.xclient.format = 32;
+ // ev.xclient.data.l[0] = -1;
+ // ev.xclient.data.l[1] = 0l;
+ // ev.xclient.data.l[2] = 0l;
+ // ev.xclient.data.l[3] = 0l;
+ // ev.xclient.data.l[4] = 0l;
+ //
+ // XSendEvent(dsp, root, False, SubstructureRedirectMask|SubstructureNotifyMask, &ev);
+ // XSync(dsp, False);
+}
+
+popWidget::~popWidget() {
+ // delete pTimer;
+}
+
+void popWidget::mousePressEvent(QMouseEvent *me) {
+ // QWidgetList list = QApplication::topLevelWidgets();
+ //
+ // //((FQTermFrame *)qApp->mainWidget())->popupFocusIn(termWindow_);
+ //
+ // if(stateID==1)
+ // {
+ // stateID = 2;
+ // pTimer->setInterval(intervalID_);
+ // }
+}
+
+
+void popWidget::popup() {
+ // pTimer->start(intervalID_);
+ // stateID = 0;
+ //
+ // desktopRectangle_ = qApp->desktop()->rect();
+ // position_ = QPoint( desktopRectangle_.width()-width()-5, desktopRectangle_.height()-5 );
+ // move(position_);
+ //
+ // if(!isVisible())
+ // show();
+}
+
+void popWidget::setText(const QString &str) {
+ // label_->setText(str);
+}
+
+void popWidget::showTimer() {
+ // switch(stateID)
+ // {
+ // case 0: // popup
+ // if(position_.y()+height()+5>desktopRectangle_.height())
+ // position_.setY( position_.y() - stepID_ );
+ // else
+ // {
+ // stateID = 1;
+ // pTimer->setInterval(5000);
+ // }
+ // break;
+ // case 1: // wait
+ // stateID = 2;
+ // pTimer->setInterval(intervalID_);
+ // break;
+ // case 2: // hiding
+ // if(position_.y()<desktopRectangle_.height())
+ // position_.setY( position_.y() + stepID_ );
+ // else
+ // {
+ // stateID = -1;
+ // pTimer->stop();
+ // }
+ // break;
+ // default:
+ //
+ // break;
+ // }
+ // move(position_);
+}
+
+} // namespace FQTerm
+
+#include "popwidget.moc"
diff --git a/src/ui/popwidget.h b/src/ui/popwidget.h
new file mode 100644
index 0000000..2a02c7d
--- /dev/null
+++ b/src/ui/popwidget.h
@@ -0,0 +1,70 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_POP_WIDGET_H
+#define FQTERM_POP_WIDGET_H
+
+#include <QWidget>
+//Added by qt3to4:
+#include <QMouseEvent>
+#include <QLabel>
+
+class QTimer;
+class QLabel;
+
+namespace FQTerm {
+
+class FQTermWindow;
+
+class popWidget: public QWidget {
+ Q_OBJECT;
+ public:
+ // #if (QT_VERSION>=310)
+ // popWidget(FQTermWindow * win, QWidget *parent = 0, const char *name=0, WFlags f=WStyle_Splash);
+ // #else
+ popWidget(FQTermWindow *win, QWidget *parent_ = 0, const char *name = 0,
+ Qt::WFlags f = Qt::WindowStaysOnTopHint
+ | Qt::X11BypassWindowManagerHint
+ | Qt::Tool);
+ // #endif
+ ~popWidget();
+
+ void popup();
+ void setText(const QString &);
+
+ public slots:
+ void showTimer();
+
+ protected:
+ QTimer *pTimer;
+ int stateID; // -1 hide, 0 popup, 1 wait, 2 hiding
+ QPoint position_;
+ QRect desktopRectangle_;
+ int stepID_;
+ int intervalID_;
+ QLabel *label_;
+ FQTermWindow *termWindow_;
+
+ void mousePressEvent(QMouseEvent*);
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_POP_WIDGET_H
diff --git a/src/ui/prefdialog.cpp b/src/ui/prefdialog.cpp
new file mode 100644
index 0000000..9f01a08
--- /dev/null
+++ b/src/ui/prefdialog.cpp
@@ -0,0 +1,332 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QCloseEvent>
+#include <QComboBox>
+#include <QFileDialog>
+
+#include "fqterm_config.h"
+#include "fqterm_path.h"
+#include "fqterm_trace.h"
+
+#include "prefdialog.h"
+#include "soundconf.h"
+
+namespace FQTerm {
+
+/*
+ * Constructs a prefDialog which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'.
+ *
+ * The dialog will by default be modeless, unless you set 'modal' to
+ * TRUE to construct a modal dialog.
+ */
+prefDialog::prefDialog(FQTermConfig * config, QWidget *parent, Qt::WFlags fl)
+ : QDialog(parent, fl),
+ soundButtonGroup_(this),
+ verticalSettingButtonGroup_(this),
+ config_(config){
+ ui_.setupUi(this);
+ fileDialog_ = new FQTermFileDialog(config_);
+ soundButtonGroup_.addButton(ui_.noneRadioButton, 0);
+ soundButtonGroup_.addButton(ui_.beepRadioButton, 1);
+ soundButtonGroup_.addButton(ui_.fileRadioButton, 2);
+ verticalSettingButtonGroup_.addButton(ui_.topRadioButton, 0);
+ verticalSettingButtonGroup_.addButton(ui_.middleRadioButton, 1);
+ verticalSettingButtonGroup_.addButton(ui_.bottomRadioButton, 2);
+
+ connectSlots();
+
+ loadSetting();
+
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+prefDialog::~prefDialog() {
+ // no need to delete child widgets, Qt does it all for us
+ delete fileDialog_;
+}
+
+void prefDialog::connectSlots() {
+ FQ_VERIFY(connect(ui_.okPushButton, SIGNAL(clicked()), this, SLOT(onOK())));
+ FQ_VERIFY(connect(ui_.cancelPushButton, SIGNAL(clicked()), this, SLOT(onCancel())));
+ FQ_VERIFY(connect(ui_.selectsoundPushButton, SIGNAL(clicked()), this, SLOT(onSound())));
+ FQ_VERIFY(connect(ui_.choosehttpPushButton, SIGNAL(clicked()), this, SLOT(onHttp())));
+ //FQ_VERIFY(connect(ButtonGroup1 , SIGNAL(clicked(int)), this, SLOT(onBeep(int)) ));
+ FQ_VERIFY(connect(ui_.browsePushButton, SIGNAL(clicked()), this, SLOT(onBrowse())));
+ FQ_VERIFY(connect(ui_.imagePushButton, SIGNAL(clicked()), this, SLOT(onImage())));
+ FQ_VERIFY(connect(ui_.poolPushButton, SIGNAL(clicked()), this, SLOT(onPool())));
+ FQ_VERIFY(connect(ui_.styleSheetPushButton, SIGNAL(clicked()), this, SLOT(onStyleSheet())));
+ FQ_VERIFY(connect(ui_.editorPushButton, SIGNAL(clicked()), this, SLOT(onEditor())));
+}
+
+void prefDialog::loadSetting() {
+
+ QString strTmp;
+
+ strTmp = config_->getItemValue("preference", "displayoffset");
+ ui_.displayOffsetSlider->setSliderPosition(strTmp.toInt());
+
+ strTmp = config_->getItemValue("preference", "xim");
+ ui_.ximComboBox->setCurrentIndex(strTmp.toInt());
+
+ strTmp = config_->getItemValue("preference", "wordwrap");
+ ui_.wordLineEdit3->setText(strTmp);
+
+ strTmp = config_->getItemValue("preference", "smartww");
+ ui_.smartCheckBox->setChecked(strTmp != "0");
+
+ strTmp = config_->getItemValue("preference", "wheel");
+ ui_.wheelCheckBox->setChecked(strTmp != "0");
+
+ strTmp = config_->getItemValue("preference", "url");
+ ui_.urlCheckBox->setChecked(strTmp != "0");
+
+ strTmp = config_->getItemValue("preference", "logmsg");
+ ui_.saveCheckBox->setChecked(strTmp != "0");
+
+ strTmp = config_->getItemValue("preference", "blinktab");
+ ui_.blinkCheckBox->setChecked(strTmp != "0");
+
+ strTmp = config_->getItemValue("preference", "warn");
+ ui_.warnCheckBox->setChecked(strTmp != "0");
+
+ strTmp = config_->getItemValue("preference", "beep");
+ qobject_cast<QRadioButton *>(soundButtonGroup_.button(strTmp.toInt()))->setChecked(true);
+
+ strTmp = config_->getItemValue("preference", "vsetting");
+ qobject_cast<QRadioButton *>(verticalSettingButtonGroup_.button(strTmp.toInt()))->setChecked(true);
+
+ strTmp = config_->getItemValue("preference", "enq");
+ ui_.enqCheckBox->setChecked(strTmp != "0");
+
+ //ButtonGroup1->find(strTmp.toInt()))->setChecked(true);
+
+ // if(strTmp.toInt()!=2)
+ // {
+ // wavefileLineEdit->setEnabled(false);
+ // selectsoundPushButton->setEnabled(false);
+ // }
+
+ strTmp = config_->getItemValue("preference", "wavefile");
+ ui_.wavefileLineEdit->setText(strTmp);
+
+ strTmp = config_->getItemValue("preference", "antialias");
+ ui_.aacheckBox->setChecked(strTmp != "0");
+
+
+ strTmp = config_->getItemValue("preference", "tray");
+ ui_.trayCheckBox->setChecked(strTmp != "0");
+
+ strTmp = config_->getItemValue("preference", "clearpool");
+ ui_.clearCheckBox->setChecked(strTmp == "1");
+
+ strTmp = config_->getItemValue("preference", "pool");
+ if (strTmp.isEmpty()) {
+ strTmp = getPath(USER_CONFIG) + "pool/";
+ }
+ ui_.poolLineEdit->setText(strTmp);
+
+ strTmp = config_->getItemValue("preference", "http");
+ ui_.httpLineEdit->setText(strTmp);
+
+ strTmp = config_->getItemValue("preference", "zmodem");
+ if (strTmp.isEmpty()) {
+ strTmp = getPath(USER_CONFIG) + "zmodem/";
+ }
+ ui_.zmodemLineEdit->setText(strTmp);
+
+ strTmp = config_->getItemValue("preference", "image");
+ ui_.imageLineEdit->setText(strTmp);
+
+ strTmp = config_->getItemValue("preference", "qssfile");
+ ui_.styleSheetLineEdit->setText(strTmp);
+
+ strTmp = config_->getItemValue("preference", "editor");
+ ui_.editorLineEdit->setText(strTmp);
+
+ strTmp = config_->getItemValue("preference", "editorarg");
+ ui_.editorArgLineEdit->setText(strTmp);
+
+ strTmp = config_->getItemValue("preference", "asciienhance");
+ ui_.asciiEnhanceCheckBox->setChecked(strTmp == "1");
+}
+
+void prefDialog::saveSetting() {
+
+ QString strTmp;
+
+ strTmp.setNum(ui_.displayOffsetSlider->sliderPosition());
+ config_->setItemValue("preference", "displayoffset", strTmp);
+
+ strTmp.setNum(ui_.ximComboBox->currentIndex());
+ config_->setItemValue("preference", "xim", strTmp);
+
+
+ config_->setItemValue("preference", "wordwrap", ui_.wordLineEdit3->text());
+
+ strTmp.setNum(ui_.smartCheckBox->isChecked() ? 1 : 0);
+ config_->setItemValue("preference", "smartww", strTmp);
+
+ strTmp.setNum(ui_.wheelCheckBox->isChecked() ? 1 : 0);
+ config_->setItemValue("preference", "wheel", strTmp);
+
+ strTmp.setNum(ui_.urlCheckBox->isChecked() ? 1 : 0);
+ config_->setItemValue("preference", "url", strTmp);
+
+ strTmp.setNum(ui_.saveCheckBox->isChecked() ? 1 : 0);
+ config_->setItemValue("preference", "logmsg", strTmp);
+
+ strTmp.setNum(ui_.blinkCheckBox->isChecked() ? 1 : 0);
+ config_->setItemValue("preference", "blinktab", strTmp);
+
+ strTmp.setNum(ui_.warnCheckBox->isChecked() ? 1 : 0);
+ config_->setItemValue("preference", "warn", strTmp);
+
+ strTmp.setNum(ui_.aacheckBox->isChecked() ? 1 : 0);
+ config_->setItemValue("preference", "antialias", strTmp);
+
+ strTmp.setNum(ui_.trayCheckBox->isChecked() ? 1 : 0);
+ config_->setItemValue("preference", "tray", strTmp);
+
+ strTmp.setNum(ui_.enqCheckBox->isChecked() ? 1 : 0);
+ config_->setItemValue("preference", "enq", strTmp);
+
+ strTmp.setNum(soundButtonGroup_.checkedId());
+ config_->setItemValue("preference", "beep", strTmp);
+
+ strTmp.setNum(verticalSettingButtonGroup_.checkedId());
+ config_->setItemValue("preference", "vsetting", strTmp);
+
+ if (strTmp == "2") {
+ config_->setItemValue("preference", "wavefile", ui_.wavefileLineEdit->text());
+ }
+
+ strTmp.setNum(ui_.clearCheckBox->isChecked() ? 1 : 0);
+ config_->setItemValue("preference", "clearpool", strTmp);
+
+ strTmp.setNum(ui_.asciiEnhanceCheckBox->isChecked() ? 1 : 0);
+ config_->setItemValue("preference", "asciienhance", strTmp);
+
+ strTmp = ui_.poolLineEdit->text();
+ if (strTmp.isEmpty()) {
+ strTmp = getPath(USER_CONFIG) + "pool/";
+ }
+ config_->setItemValue("preference", "pool", strTmp);
+
+ strTmp = ui_.zmodemLineEdit->text();
+ if (strTmp.isEmpty()) {
+ strTmp = getPath(USER_CONFIG) + "zmodem/";
+ }
+ config_->setItemValue("preference", "zmodem", strTmp);
+ config_->setItemValue("preference", "http", ui_.httpLineEdit->text());
+ config_->setItemValue("preference", "image", ui_.imageLineEdit->text());
+
+ config_->setItemValue("preference", "qssfile", ui_.styleSheetLineEdit->text().trimmed());
+
+ config_->setItemValue("preference", "editor", ui_.editorLineEdit->text());
+ config_->setItemValue("preference", "editorarg", ui_.editorArgLineEdit->text());
+
+ config_->save(getPath(USER_CONFIG) + "fqterm.cfg");
+}
+
+void prefDialog::closeEvent(QCloseEvent*) {
+ reject();
+}
+
+void prefDialog::onOK() {
+ saveSetting();
+ done(1);
+}
+
+void prefDialog::onCancel() {
+ done(0);
+}
+
+void prefDialog::onSound() {
+ soundConf soundconf(config_, this);
+ if (soundconf.exec() == 1) {
+ loadSetting();
+ }
+
+}
+
+void prefDialog::onHttp() {
+ QString http = fileDialog_->getOpenName("Choose a WWW browser", "*");
+ if (!http.isEmpty()) {
+ ui_.httpLineEdit->setText(http);
+ }
+
+}
+
+// void prefDialog::onBeep( int id )
+// {
+// if(id==2)
+// {
+// ui.wavefileLineEdit->setEnabled(true);
+// ui.selectsoundPushButton->setEnabled(true);
+// }
+// else if(id==0 || id==1 )
+// {
+// ui.wavefileLineEdit->setEnabled(false);
+// ui.selectsoundPushButton->setEnabled(false);
+// }
+// }
+
+void prefDialog::onBrowse() {
+ QString dir = fileDialog_->getExistingDirectory("Choose a directory", ui_.zmodemLineEdit->text());
+ if (!dir.isEmpty()) {
+ ui_.zmodemLineEdit->setText(dir);
+ }
+}
+
+void prefDialog::onImage() {
+ QString image = fileDialog_->getOpenName("Choose an Image Viewer", "*");
+ if (!image.isEmpty()) {
+ ui_.imageLineEdit->setText(image);
+ }
+}
+
+void prefDialog::onPool() {
+ QString pool = fileDialog_->getExistingDirectory("Choose a directory", ui_.poolLineEdit->text());
+ if (!pool.isEmpty()) {
+ ui_.poolLineEdit->setText(pool);
+ }
+}
+
+void prefDialog::onStyleSheet()
+{
+ QString qssFile = fileDialog_->getOpenName("Choose a QSS File", "Qt Style Sheets (*.qss *.QSS)");
+ if (!qssFile.isEmpty()) {
+ ui_.styleSheetLineEdit->setText(qssFile);
+ }
+}
+
+void prefDialog::onEditor() {
+ QString editor = fileDialog_->getOpenName("Choose a directory", ui_.editorLineEdit->text());
+ if (!editor.isEmpty()) {
+ ui_.editorLineEdit->setText(editor);
+ }
+}
+} // namespace FQTerm
+
+#include "prefdialog.moc"
diff --git a/src/ui/prefdialog.h b/src/ui/prefdialog.h
new file mode 100644
index 0000000..99e58c6
--- /dev/null
+++ b/src/ui/prefdialog.h
@@ -0,0 +1,66 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_PREF_DIALOG_H
+#define FQTERM_PREF_DIALOG_H
+
+#include "ui_prefdialog.h"
+#include "fqterm_filedialog.h"
+
+class QCloseEvnt;
+
+namespace FQTerm {
+
+class FQTermConfig;
+
+class prefDialog: public QDialog {
+ Q_OBJECT;
+ public:
+ prefDialog(FQTermConfig *, QWidget *parent_ = 0, Qt::WFlags fl = 0);
+ ~prefDialog();
+
+ protected slots:
+ void onOK();
+ void onCancel();
+ void onSound();
+ void onHttp();
+ // void onBeep(int);
+ void onBrowse();
+ void onImage();
+ void onPool();
+ void onStyleSheet();
+ void onEditor();
+ protected:
+ void closeEvent(QCloseEvent*);
+ void connectSlots();
+ void loadSetting();
+ void saveSetting();
+
+ private:
+ Ui::prefDialog ui_;
+ QButtonGroup soundButtonGroup_;
+ QButtonGroup verticalSettingButtonGroup_;
+ FQTermConfig * config_;
+ FQTermFileDialog *fileDialog_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_PREF_DIALOG_H
diff --git a/src/ui/prefdialog.ui b/src/ui/prefdialog.ui
new file mode 100644
index 0000000..9aaf484
--- /dev/null
+++ b/src/ui/prefdialog.ui
@@ -0,0 +1,644 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>prefDialog</class>
+ <widget class="QDialog" name="prefDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>619</width>
+ <height>584</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Preference</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0" colspan="3">
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="TextLabel1_2">
+ <property name="text">
+ <string>Paste Word-Wrap At</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="wordLineEdit3"/>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="smartCheckBox">
+ <property name="text">
+ <string>Enable Smart Word-Wrap</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0" rowspan="2">
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QCheckBox" name="wheelCheckBox">
+ <property name="text">
+ <string>Alternative Mouse Wheel Control</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="urlCheckBox">
+ <property name="text">
+ <string>Detect URL When Mouse Move</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="saveCheckBox">
+ <property name="text">
+ <string>Save Message To File</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="blinkCheckBox">
+ <property name="text">
+ <string>Blink Tab When Receive Message</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="warnCheckBox">
+ <property name="text">
+ <string>Warn When Exit Connected</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="aacheckBox">
+ <property name="text">
+ <string>AntiAlias</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="trayCheckBox">
+ <property name="text">
+ <string>Show As Tray When Close</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="clearCheckBox">
+ <property name="text">
+ <string>Clear ZModem And HTTP Directory When Exit</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="enqCheckBox">
+ <property name="text">
+ <string>Reply when ENQ received</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="asciiEnhanceCheckBox">
+ <property name="text">
+ <string>ASCII Art Enhance Mode</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="1" rowspan="2" colspan="2">
+ <widget class="Line" name="line">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Sound When Receive Messages</string>
+ </property>
+ <layout class="QGridLayout">
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QRadioButton" name="noneRadioButton">
+ <property name="text">
+ <string>None</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QRadioButton" name="beepRadioButton">
+ <property name="text">
+ <string>Beep</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QRadioButton" name="fileRadioButton">
+ <property name="text">
+ <string>Sound File</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QLineEdit" name="wavefileLineEdit"/>
+ </item>
+ <item row="1" column="2">
+ <widget class="QPushButton" name="selectsoundPushButton">
+ <property name="text">
+ <string>Configure</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="TextLabel1">
+ <property name="text">
+ <string>Input Method</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="ximComboBox">
+ <item>
+ <property name="text">
+ <string>GBK</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>BIG5</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Display Offset</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="displayOffsetSlider">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition">
+ <enum>QSlider::TicksBelow</enum>
+ </property>
+ <property name="tickInterval">
+ <number>5</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="verticalDisplayGroupBox">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>40</height>
+ </size>
+ </property>
+ <property name="title">
+ <string>Vertical Display</string>
+ </property>
+ <widget class="QRadioButton" name="topRadioButton">
+ <property name="geometry">
+ <rect>
+ <x>11</x>
+ <y>15</y>
+ <width>84</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Top</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" name="middleRadioButton">
+ <property name="geometry">
+ <rect>
+ <x>123</x>
+ <y>15</y>
+ <width>84</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Middle</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" name="bottomRadioButton">
+ <property name="geometry">
+ <rect>
+ <x>234</x>
+ <y>15</y>
+ <width>84</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Bottom</string>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::MinimumExpanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>287</width>
+ <height>28</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="3" column="0" colspan="3">
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QLabel" name="textLabel1">
+ <property name="text">
+ <string>Zmodem Directory</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="textLabel1_3">
+ <property name="text">
+ <string>HTTP Directory</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="textLabel9">
+ <property name="text">
+ <string>StyleSheet File</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel3">
+ <property name="text">
+ <string>HTTP Browser</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="textLabel1_2">
+ <property name="text">
+ <string>Image Viewer</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="textLabel1_4">
+ <property name="text">
+ <string>Editor &amp; Args</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0" colspan="2">
+ <widget class="QLineEdit" name="zmodemLineEdit"/>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QLineEdit" name="poolLineEdit"/>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <widget class="QLineEdit" name="styleSheetLineEdit"/>
+ </item>
+ <item row="3" column="0" colspan="2">
+ <widget class="QLineEdit" name="httpLineEdit"/>
+ </item>
+ <item row="4" column="0" colspan="2">
+ <widget class="QLineEdit" name="imageLineEdit"/>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLineEdit" name="editorLineEdit"/>
+ </item>
+ <item row="5" column="1">
+ <widget class="QLineEdit" name="editorArgLineEdit"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QPushButton" name="browsePushButton">
+ <property name="text">
+ <string>Browse</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="poolPushButton">
+ <property name="text">
+ <string>Browse</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="styleSheetPushButton">
+ <property name="text">
+ <string>Browse</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="choosehttpPushButton">
+ <property name="text">
+ <string>Choose</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="imagePushButton">
+ <property name="text">
+ <string>Choose</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="editorPushButton">
+ <property name="text">
+ <string>Choose</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item row="4" column="0" colspan="3">
+ <widget class="Line" name="Line1">
+ <property name="frameShape">
+ <enum>QFrame::HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0" colspan="3">
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="okPushButton">
+ <property name="text">
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancelPushButton">
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <tabstops>
+ <tabstop>wordLineEdit3</tabstop>
+ <tabstop>smartCheckBox</tabstop>
+ <tabstop>wheelCheckBox</tabstop>
+ <tabstop>urlCheckBox</tabstop>
+ <tabstop>saveCheckBox</tabstop>
+ <tabstop>blinkCheckBox</tabstop>
+ <tabstop>warnCheckBox</tabstop>
+ <tabstop>aacheckBox</tabstop>
+ <tabstop>trayCheckBox</tabstop>
+ <tabstop>clearCheckBox</tabstop>
+ <tabstop>noneRadioButton</tabstop>
+ <tabstop>beepRadioButton</tabstop>
+ <tabstop>fileRadioButton</tabstop>
+ <tabstop>selectsoundPushButton</tabstop>
+ <tabstop>wavefileLineEdit</tabstop>
+ <tabstop>ximComboBox</tabstop>
+ <tabstop>zmodemLineEdit</tabstop>
+ <tabstop>browsePushButton</tabstop>
+ <tabstop>poolLineEdit</tabstop>
+ <tabstop>poolPushButton</tabstop>
+ <tabstop>httpLineEdit</tabstop>
+ <tabstop>choosehttpPushButton</tabstop>
+ <tabstop>imageLineEdit</tabstop>
+ <tabstop>imagePushButton</tabstop>
+ <tabstop>okPushButton</tabstop>
+ <tabstop>cancelPushButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>noneRadioButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>wavefileLineEdit</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>290</x>
+ <y>95</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>290</x>
+ <y>125</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>noneRadioButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>selectsoundPushButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>360</x>
+ <y>80</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>420</x>
+ <y>120</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>beepRadioButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>wavefileLineEdit</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>393</x>
+ <y>90</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>366</x>
+ <y>129</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>beepRadioButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>selectsoundPushButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>413</x>
+ <y>92</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>449</x>
+ <y>125</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>fileRadioButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>wavefileLineEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>467</x>
+ <y>97</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>380</x>
+ <y>126</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>fileRadioButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>selectsoundPushButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>502</x>
+ <y>86</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>493</x>
+ <y>128</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/ui/progressBar.cpp b/src/ui/progressBar.cpp
new file mode 100644
index 0000000..9da0479
--- /dev/null
+++ b/src/ui/progressBar.cpp
@@ -0,0 +1,100 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QLabel>
+#include <QPixmap>
+#include <QProgressBar>
+#include <QPushButton>
+
+#include "fqterm_trace.h"
+#include "fqterm_path.h"
+#include "progressBar.h"
+
+namespace FQTerm {
+
+ProgressBar::ProgressBar(QWidget *parent, QLabel *label)
+ : QProgressBar(parent),
+ label_(label),
+ isFinished_(false) {
+ //DEBUG_FUNC_INFO
+ setMaximum(100);
+ label_->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+ abortButton_ = new QPushButton("Abort", parent);
+ abortButton_->setObjectName("Abort");
+ abortButton_->hide();
+ //m_abort->setText( tr("Abort") );
+ abortButton_->setIcon(QPixmap(getPath(RESOURCE) + "pic/messagebox_critical.png"));
+ label_->show();
+ show();
+}
+
+ProgressBar::~ProgressBar() {
+ //DEBUG_FUNC_INFO
+}
+
+ProgressBar &ProgressBar::setDescription(const QString &text) {
+ description_ = text;
+ label_->setText(text);
+
+ return *this;
+}
+
+ProgressBar &ProgressBar::setStatus(const QString &text) {
+ QString s = description_;
+ s += " [";
+ s += text;
+ s += ']';
+
+ label_->setText(s);
+ parentWidget()->adjustSize();
+
+ return *this;
+}
+
+ProgressBar &ProgressBar::setAbortSlot(QObject *receiver, const char *slot) {
+ FQ_VERIFY(connect(abortButton_, SIGNAL(clicked()), receiver, slot));
+ FQ_VERIFY(connect(abortButton_, SIGNAL(clicked()), this, SLOT(hide())));
+ abortButton_->show();
+
+ parentWidget()->adjustSize();
+
+ return *this;
+}
+
+void ProgressBar::setDone() {
+ if (!isFinished_) {
+ isFinished_ = true;
+ abortButton_->setEnabled(false);
+ setStatus(tr("Done"));
+ } else {
+ // then we we're aborted
+ setStatus(tr("Aborted"));
+ }
+}
+
+void ProgressBar::hide() {
+ //NOTE naughty
+
+ isFinished_ = true;
+ abortButton_->setEnabled(false);
+ setStatus(tr("Aborting..."));
+}
+
+} // namespace FQTerm
diff --git a/src/ui/progressBar.h b/src/ui/progressBar.h
new file mode 100644
index 0000000..9c2f539
--- /dev/null
+++ b/src/ui/progressBar.h
@@ -0,0 +1,71 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+//WARNING this is not meant for use outside this unit!
+
+#ifndef FQTERM_PROGRESSBAR_H
+#define FQTERM_PROGRESSBAR_H
+
+#include <QProgressBar>
+#include <QLabel>
+
+class QLabel;
+class QPushButton;
+
+namespace FQTerm {
+/**
+ * @class KDE::ProgressBar
+ * @short ProgressBar class with some useful additions
+ */
+class ProgressBar: public QProgressBar {
+ friend class StatusBar;
+
+ public:
+ /** @param text a 1-6 word description of the progress operation */
+ ProgressBar &setDescription(const QString &text);
+
+ /** @param text eg. Scanning, Reading. The state of the operation */
+ ProgressBar &setStatus(const QString &text);
+
+ /** set the recipient slot for the abort button */
+ ProgressBar &setAbortSlot(QObject *receiver, const char *slot);
+
+ void setDone();
+
+ QString description()const {
+ return description_;
+ }
+
+ protected:
+ ProgressBar(QWidget *parent, QLabel *label);
+ ~ProgressBar();
+
+ virtual void hide();
+
+ QLabel *label_;
+ QString description_;
+ bool isFinished_;
+
+ QPushButton *abortButton_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_PROGRESSBAR_H
diff --git a/src/ui/quickdialog.cpp b/src/ui/quickdialog.cpp
new file mode 100644
index 0000000..1ac3888
--- /dev/null
+++ b/src/ui/quickdialog.cpp
@@ -0,0 +1,258 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <stdio.h>
+
+#include <QCloseEvent>
+#include <QComboBox>
+#include <QPixmap>
+#include <QImage>
+#include <QPixmap>
+#include <QMessageBox>
+
+#include "fqterm_trace.h"
+#include "fqterm_path.h"
+#include "fqterm_config.h"
+#include "fqterm_param.h"
+#include "addrdialog.h"
+#include "quickdialog.h"
+
+namespace FQTerm {
+
+//extern QString fileCfg;
+//extern QString addrCfg;
+
+extern void saveAddress(FQTermConfig *, int, const FQTermParam &);
+
+const int quickDialog::ports[3] = {23, 22, 22};
+
+quickDialog::quickDialog(FQTermConfig * config, QWidget *parent, Qt::WFlags fl)
+ : QDialog(parent, fl),
+ config_(config) {
+ ui_.setupUi(this);
+
+ ui_.addPushButton->setIcon(QPixmap(getPath(RESOURCE) + "pic/address_book.png"));
+
+ ui_.addPushButton->setToolTip(tr("Add To AddressBook"));
+
+ ui_.connectPushButton->setDefault(true);
+
+ connectSlots();
+
+ loadHistory();
+
+// adjustSize();
+// setFixedSize(size());
+
+}
+
+quickDialog::~quickDialog() {
+}
+
+void quickDialog::closeEvent(QCloseEvent*) {
+ config_->save(getPath(USER_CONFIG) + "fqterm.cfg");
+ reject();
+}
+
+void quickDialog::loadHistory() {
+ QString defaultIndex = config_->getItemValue("global", "quickdefaultindex");
+ if (defaultIndex.isEmpty()) {
+ config_->setItemValue("global", "quick default index", "0");
+ defaultIndex = "0";
+ }
+ QString strTmp = config_->getItemValue("quick list", "num");
+ QString strSection;
+ for (int i = 0; i < strTmp.toInt(); i++) {
+ strSection = QString("quick %1").arg(i);
+ ui_.historyComboBox->addItem(config_->getItemValue(strSection.toLatin1(), "addr"));
+ }
+
+ int index = defaultIndex.toInt();
+ if (strTmp.toInt() > index) {
+ ui_.historyComboBox->setCurrentIndex(index);
+ listChanged(index);
+ }
+}
+
+void quickDialog::connectSlots() {
+ FQ_VERIFY(connect(ui_.historyComboBox, SIGNAL(activated(int)), this, SLOT(listChanged(int))));
+ FQ_VERIFY(connect(ui_.protocolComboBox, SIGNAL(activated(int)), this, SLOT(onSelectProtocol(int))));
+ FQ_VERIFY(connect(ui_.addPushButton, SIGNAL(clicked()), this, SLOT(onAdd())));
+ FQ_VERIFY(connect(ui_.deletePushButton, SIGNAL(clicked()), this, SLOT(onDelete())));
+ FQ_VERIFY(connect(ui_.advPushButton, SIGNAL(clicked()), this, SLOT(onAdvance())));
+ FQ_VERIFY(connect(ui_.connectPushButton, SIGNAL(clicked()), this, SLOT(onConnect())));
+ FQ_VERIFY(connect(ui_.closePushButton, SIGNAL(clicked()), this, SLOT(onClose())));
+}
+
+void quickDialog::listChanged(int index) {
+ QString strTmp = config_->getItemValue("quick list", "num");
+ if (strTmp == "0") {
+ return ;
+ }
+ loadParam(index);
+ setUIFromParam();
+}
+
+void quickDialog::onAdd() {
+ setParamFromUI();
+
+ FQTermConfig *pAddrConf = new FQTermConfig(getPath(USER_CONFIG) + "address.cfg");
+ QString strTmp;
+ strTmp = pAddrConf->getItemValue("bbs list", "num");
+ int num = strTmp.toInt();
+ strTmp.setNum(num + 1);
+ pAddrConf->setItemValue("bbs list", "num", strTmp);
+ saveAddress(pAddrConf, num, param_);
+ pAddrConf->save(getPath(USER_CONFIG) + "address.cfg");
+}
+
+void quickDialog::onDelete() {
+ int index = ui_.historyComboBox->currentIndex();
+
+ QString strTmp = config_->getItemValue("quick list", "num");
+ int num = strTmp.toInt();
+
+ if (num != 0 && index != -1) {
+ QString strSection = QString("quick %1").arg(index);
+ if (!config_->deleteSection(strSection.toLatin1())) {
+ return ;
+ }
+ ui_.historyComboBox->removeItem(index);
+
+ for (int i = index + 1; i < num; i++) {
+ strTmp = QString("quick %1").arg(i);
+ strSection = QString("quick %1").arg(i - 1);
+ config_->renameSection(strTmp.toLatin1(), strSection.toLatin1());
+ }
+
+ strTmp = config_->getItemValue("quick list", "num");
+ strTmp.setNum(qMax(0, strTmp.toInt() - 1));
+ config_->setItemValue("quick list", "num", strTmp.toLatin1());
+
+ // update
+ if (num > 1) {
+ ui_.historyComboBox->setCurrentIndex(qMin(index, num - 2));
+ listChanged(qMin(index, num - 2));
+ }
+ }
+}
+
+void quickDialog::onAdvance() {
+ setParamFromUI();
+
+ addrDialog set(this, param_, addrDialog::APPLY);
+
+ if (set.exec() == 1) {
+ param_ = set.param();
+ setUIFromParam();
+ }
+}
+
+void quickDialog::onConnect() {
+ if (ui_.historyComboBox->currentText().isEmpty() || ui_.portEdit->text().isEmpty()) {
+ QMessageBox mb("FQTerm", "address or port cant be blank", QMessageBox::Warning,
+ QMessageBox::Ok | QMessageBox::Default, 0, 0);
+ mb.exec();
+ return ;
+ }
+
+ setParamFromUI();
+ FQTermParam newParam = param_;
+ loadParam(ui_.historyComboBox->currentIndex());
+
+ QString strTmp = config_->getItemValue("quick list", "num");
+ if (strTmp.isEmpty() || strTmp == "-1") {
+ strTmp = "0";
+ }
+ int num = strTmp.toInt();
+ if (ui_.historyComboBox->currentIndex() == -1 ||
+ newParam.hostAddress_ != param_.hostAddress_ ||
+ newParam.protocolType_ != param_.protocolType_ ||
+ newParam.port_ != param_.port_) {
+ //changed. add new info
+ param_ = newParam;
+ saveParam(num);
+ ui_.historyComboBox->addItem(param_.hostAddress_);
+ ui_.historyComboBox->setCurrentIndex(num);
+ config_->setItemValue("quick list", "num", QString("%1").arg(num + 1));
+ } else {
+ param_ = newParam;
+ }
+
+ config_->setItemValue("global", "quickdefaultindex",
+ QString("%1").arg(ui_.historyComboBox->currentIndex()));
+ done(1);
+}
+
+void quickDialog::onClose() {
+ done(0);
+}
+
+void quickDialog::onSelectProtocol(int index)
+{
+ ui_.portCheck->setChecked(false);
+ ui_.portEdit->setText(QString("%1").arg(ports[index]));
+}
+
+void quickDialog::setUIFromParam()
+{
+ ui_.historyComboBox->setItemText(ui_.historyComboBox->currentIndex(), param_.hostAddress_);
+ ui_.protocolComboBox->setCurrentIndex(param_.protocolType_);
+ ui_.portEdit->setText(QString("%1").arg(param_.port_));
+ if (param_.port_ != ports[param_.protocolType_]) {
+ ui_.portCheck->setChecked(true);
+ }
+ else {
+ ui_.portCheck->setChecked(false);
+ }
+}
+
+void quickDialog::setParamFromUI()
+{
+ param_.name_ = ui_.historyComboBox->currentText();
+ param_.hostAddress_ = ui_.historyComboBox->currentText();
+ param_.protocolType_ = ui_.protocolComboBox->currentIndex();
+ bool ok;
+ param_.port_ = ui_.portEdit->text().toInt(&ok);
+ if (!ok) {
+ param_.port_ = ports[param_.protocolType_];
+ }
+}
+
+void quickDialog::loadParam(int index)
+{
+ param_ = FQTermParam();
+ QString strSection = QString("quick %1").arg(index);
+ param_.name_ = config_->getItemValue(strSection, "addr");
+ param_.hostAddress_ = param_.name_;
+ param_.protocolType_ = config_->getItemValue(strSection, "protocol").toInt();
+ param_.port_ = config_->getItemValue(strSection, "port").toInt();
+}
+
+void quickDialog::saveParam(int index)
+{
+ QString strSection = QString("quick %1").arg(index);
+ config_->setItemValue(strSection, "addr", param_.hostAddress_);
+ config_->setItemValue(strSection, "protocol", QString("%1").arg(param_.protocolType_));
+ config_->setItemValue(strSection, "port", QString("%1").arg(param_.port_));
+}
+} // namespace FQTerm
+
+#include "quickdialog.moc"
diff --git a/src/ui/quickdialog.h b/src/ui/quickdialog.h
new file mode 100644
index 0000000..bbcae89
--- /dev/null
+++ b/src/ui/quickdialog.h
@@ -0,0 +1,73 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_QUICK_DIALOG_H
+#define FQTERM_QUICK_DIALOG_H
+
+#include "fqterm_param.h"
+#include "ui_quickdialog.h"
+//Added by qt3to4:
+//#include <QCloseEvent>
+
+class QCloseEvent;
+class QResizeEvent;
+
+namespace FQTerm {
+
+class FQTermConfig;
+
+class quickDialog: public QDialog {
+ Q_OBJECT;
+ public:
+ quickDialog(FQTermConfig *, QWidget *parent_ = 0, Qt::WFlags fl = 0);
+ ~quickDialog();
+
+ FQTermParam param_;
+
+ static const int ports[3];
+
+ protected slots:
+ void listChanged(int); //
+ void onAdd();
+ void onDelete();
+ void onAdvance();
+ void onConnect(); //
+ void onClose();
+ void onSelectProtocol(int index);
+
+ private:
+
+ void closeEvent(QCloseEvent*); //
+ void connectSlots();
+ void loadHistory(); //
+ void setUIFromParam();
+ void setParamFromUI();
+ void loadParam(int index);
+ void saveParam(int index);
+
+ FQTermConfig *config_;
+
+ private:
+ Ui::quickDialog ui_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_QUICK_DIALOG_H
diff --git a/src/ui/quickdialog.ui b/src/ui/quickdialog.ui
new file mode 100644
index 0000000..867596d
--- /dev/null
+++ b/src/ui/quickdialog.ui
@@ -0,0 +1,211 @@
+<ui version="4.0" >
+ <class>quickDialog</class>
+ <widget class="QDialog" name="quickDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>394</width>
+ <height>117</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle" >
+ <string>Quick Login</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QLabel" name="TextLabel4" >
+ <property name="frameShape" >
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="text" >
+ <string>Host Name</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="historyComboBox" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="editable" >
+ <bool>true</bool>
+ </property>
+ <property name="insertPolicy" >
+ <enum>QComboBox::NoInsert</enum>
+ </property>
+ <property name="duplicatesEnabled" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="deletePushButton" >
+ <property name="text" >
+ <string>Delete</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="addPushButton" >
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset>
+ <normaloff/>
+ </iconset>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="2" column="0" >
+ <widget class="Line" name="line" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QPushButton" name="advPushButton" >
+ <property name="text" >
+ <string>Advanced</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="connectPushButton" >
+ <property name="text" >
+ <string>Connect</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="closePushButton" >
+ <property name="text" >
+ <string>Close</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0" >
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QLabel" name="TextLabel6" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Minimum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Protocol</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="protocolComboBox" >
+ <item>
+ <property name="text" >
+ <string>Telnet</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>SSH1</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>SSH2</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="portCheck" >
+ <property name="text" >
+ <string>Port</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="portEdit" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Maximum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>23</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <tabstops>
+ <tabstop>historyComboBox</tabstop>
+ <tabstop>deletePushButton</tabstop>
+ <tabstop>addPushButton</tabstop>
+ <tabstop>advPushButton</tabstop>
+ <tabstop>connectPushButton</tabstop>
+ <tabstop>closePushButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>portCheck</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>portEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>151</x>
+ <y>54</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>203</x>
+ <y>54</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/ui/schemadialog.cpp b/src/ui/schemadialog.cpp
new file mode 100644
index 0000000..d5a197b
--- /dev/null
+++ b/src/ui/schemadialog.cpp
@@ -0,0 +1,323 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QFileDialog>
+#include <QColorDialog>
+#include <QComboBox>
+#include <QMessageBox>
+
+#include "fqterm_config.h"
+#include "fqterm_path.h"
+#include "fqterm_trace.h"
+
+#include "schemadialog.h"
+
+namespace FQTerm {
+
+schemaDialog::schemaDialog(QWidget *parent, Qt::WFlags fl)
+ : QDialog(parent, fl),
+ buttonGroup_(this) {
+ ui_.setupUi(this);
+ buttonGroup_.addButton(ui_.noneRadioButton, 0);
+ buttonGroup_.addButton(ui_.imageRadioButton, 1);
+
+ lastItemID_ = -1;
+ isModified_ = false;
+
+ ui_.alphaSlider->setMinimum(0);
+ ui_.alphaSlider->setMaximum(100);
+ ui_.alphaSlider->setSingleStep(1);
+ ui_.alphaSlider->setPageStep(10);
+
+ // ui.bgButtonGroup->setRadioButtonExclusive(true);
+ colorButtons[0] = ui_.clr0Button;
+ colorButtons[1] = ui_.clr1Button;
+ colorButtons[2] = ui_.clr2Button;
+ colorButtons[3] = ui_.clr3Button;
+ colorButtons[4] = ui_.clr4Button;
+ colorButtons[5] = ui_.clr5Button;
+ colorButtons[6] = ui_.clr6Button;
+ colorButtons[7] = ui_.clr7Button;
+ colorButtons[8] = ui_.clr8Button;
+ colorButtons[9] = ui_.clr9Button;
+ colorButtons[10] = ui_.clr10Button;
+ colorButtons[11] = ui_.clr11Button;
+ colorButtons[12] = ui_.clr12Button;
+ colorButtons[13] = ui_.clr13Button;
+ colorButtons[14] = ui_.clr14Button;
+ colorButtons[15] = ui_.clr15Button;
+
+ connectSlots();
+ loadList();
+}
+
+
+schemaDialog::~schemaDialog(){}
+
+
+void schemaDialog::connectSlots() {
+ FQ_VERIFY(connect(ui_.saveButton, SIGNAL(clicked()), this, SLOT(saveSchema())));
+ FQ_VERIFY(connect(ui_.removeButton, SIGNAL(clicked()), this, SLOT(removeSchema())));
+ FQ_VERIFY(connect(ui_.okButton, SIGNAL(clicked()), this, SLOT(onOK())));
+ FQ_VERIFY(connect(ui_.cancelButton, SIGNAL(clicked()), this, SLOT(onCancel())));
+
+ for (int i = 0; i < 16; ++i) {
+ FQ_VERIFY(connect(colorButtons[i], SIGNAL(clicked()), this, SLOT(buttonClicked())));
+ }
+
+ FQ_VERIFY(connect(ui_.nameListWidget, SIGNAL(currentRowChanged(int)),
+ this, SLOT(nameChanged(int))));
+
+
+ FQ_VERIFY(connect(ui_.chooseButton, SIGNAL(clicked()),
+ this, SLOT(chooseImage())));
+
+ FQ_VERIFY(connect(ui_.titleLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(modified(const QString &))));
+ FQ_VERIFY(connect(ui_.imageLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(modified(const QString &))));
+ FQ_VERIFY(connect(ui_.alphaSlider, SIGNAL(valueChanged(int)),
+ this, SLOT(modified(int))));
+ FQ_VERIFY(connect(ui_.optionComboBox, SIGNAL(activated(int)),
+ this, SLOT(modified(int))));
+ FQ_VERIFY(connect(ui_.coverComboBox, SIGNAL(activated(int)),
+ this, SLOT(modified(int))));
+ FQ_VERIFY(connect(ui_.noneRadioButton, SIGNAL(toggled(bool)),
+ this, SLOT(modified(bool))));
+ FQ_VERIFY(connect(ui_.imageRadioButton, SIGNAL(toggled(bool)),
+ this, SLOT(modified(bool))));
+ FQ_VERIFY(connect(ui_.alphaCheckBox, SIGNAL(toggled(bool)),
+ this, SLOT(modified(bool))));
+}
+
+void schemaDialog::loadList() {
+ QFileInfoList lstFile = getSchemaList();
+
+ //if(lstFile != NULL)
+ {
+ foreach(QFileInfo fi, lstFile) {
+ FQTermConfig *pConf = new FQTermConfig(fi.absoluteFilePath());
+ QListWidgetItem* item = new QListWidgetItem(pConf->getItemValue("schema", "title"), ui_.nameListWidget);
+ item->setData(Qt::UserRole, fi.absoluteFilePath());
+ ui_.nameListWidget->addItem(item);
+ delete pConf;
+ }
+ }
+ if (ui_.nameListWidget->count() != 0) {
+ ui_.nameListWidget->setCurrentRow(0);
+ }
+}
+
+void schemaDialog::loadSchema(const QString &strSchemaFile) {
+ FQTermConfig *pConf = new FQTermConfig(strSchemaFile);
+
+ title_ = pConf->getItemValue("schema", "title");
+ //0 -- none 1 -- image
+ int type = pConf->getItemValue("background", "type").toInt();
+ if (type == 0) {
+ ui_.noneRadioButton->setChecked(true);
+ } else if (type == 1) {
+ ui_.imageRadioButton->setChecked(true);
+ }
+ ui_.imageLineEdit->setText(pConf->getItemValue("image", "name"));
+ QString strTmp = pConf->getItemValue("image", "render");
+ ui_.optionComboBox->setCurrentIndex(strTmp.toInt());
+ strTmp = pConf->getItemValue("image", "cover");
+ ui_.coverComboBox->setCurrentIndex(strTmp.toInt());
+ ui_.alphaCheckBox->setChecked(pConf->getItemValue("image", "usealpha").toInt());
+ ui_.alphaSlider->setValue(pConf->getItemValue("image", "alpha").toInt());
+
+ for (int i = 0; i < 16; ++i) {
+ colors[i].setNamedColor(pConf->getItemValue("color", QString("color%1").arg(i)));
+ }
+
+ delete pConf;
+
+ updateView();
+
+}
+
+QFileInfoList schemaDialog::getSchemaList() {
+ QDir dir;
+ dir.setNameFilters(QStringList("*.schema"));
+ dir.setPath(getPath(USER_CONFIG) + "schema");
+ return dir.entryInfoList();
+}
+
+int schemaDialog::saveNumSchema(int n) {
+
+ int saved = n;
+ title_ = ui_.titleLineEdit->text();
+
+ QString schemaFileName = getPath(USER_CONFIG) + "schema/" + title_ + ".schema";
+ QListWidgetItem* item = ui_.nameListWidget->currentItem();
+ // create a new schema if title changed
+ QString test = ui_.nameListWidget->currentItem()->data(Qt::UserRole).toString();
+ if (QFileInfo(schemaFileName) != QFileInfo(ui_.nameListWidget->item(n)->data(Qt::UserRole).toString())) {
+ item = new QListWidgetItem(title_, ui_.nameListWidget);
+ item->setData(Qt::UserRole, schemaFileName);
+ ui_.nameListWidget->addItem(item);
+ saved = ui_.nameListWidget->row(item);
+ }
+
+ FQTermConfig *pConf = new FQTermConfig(ui_.nameListWidget->item(n)->data(Qt::UserRole).toString());
+
+ pConf->setItemValue("schema", "title", title_);
+
+ QString strTmp;
+ //0 -- none 1 -- image
+ int type = 0;
+
+ if (ui_.noneRadioButton->isChecked()) {
+ type = 0;
+ } else if (ui_.imageRadioButton->isChecked()) {
+ type = 1;
+ }
+ strTmp.setNum(type);
+ pConf->setItemValue("background", "type", strTmp);
+
+ pConf->setItemValue("image", "name", ui_.imageLineEdit->text());
+
+
+ strTmp.setNum(ui_.optionComboBox->currentIndex());
+ pConf->setItemValue("image", "render", strTmp);
+
+ strTmp.setNum(ui_.coverComboBox->currentIndex());
+ pConf->setItemValue("image", "cover", strTmp);
+
+ pConf->setItemValue("image", "usealpha", ui_.alphaCheckBox->isChecked() ? "1" : "0");
+
+ strTmp.setNum(ui_.alphaSlider->value());
+ pConf->setItemValue("image", "alpha", strTmp);
+
+
+ for (int i = 0; i < 16; ++i) {
+ pConf->setItemValue("color", QString("color%1").arg(i), colors[i].name());
+ }
+
+ pConf->save(schemaFileName);
+
+ delete pConf;
+
+ clearModified();
+ emit schemaEdited();
+ return saved;
+}
+
+void schemaDialog::updateView() {
+ // title
+ ui_.titleLineEdit->setText(title_);
+ for (int i = 0; i < 16; ++i) {
+ QPalette palette;
+ palette.setColor(QPalette::Button, colors[i]);
+ colorButtons[i]->setPalette(palette);
+ }
+
+ // load from file, nothing changed
+ clearModified();
+}
+
+void schemaDialog::buttonClicked() {
+ QPushButton *button = (QPushButton*)sender();
+ QColor color =
+ QColorDialog::getColor(button->palette().color(button->backgroundRole()));
+ if (color.isValid() == true) {
+ QPalette palette;
+ palette.setColor(QPalette::Button, color);
+ button->setPalette(palette);
+ modified();
+ }
+ for (int i = 0; i < 16; ++i) {
+ if (colorButtons[i] == button) {
+ colors[i] = color;
+ break;
+ }
+ }
+}
+
+void schemaDialog::nameChanged(int item) {
+ if (isModified_) {
+ QMessageBox mb("FQTerm", "Setting changed, do you want to save?",
+ QMessageBox::Warning, QMessageBox::Yes | QMessageBox::Default,
+ QMessageBox::No | QMessageBox::Escape, 0, this);
+ if (mb.exec() == QMessageBox::Yes) {
+ if (lastItemID_ != -1) {
+ saveNumSchema(lastItemID_);
+ }
+ }
+ }
+
+ int n = item; //nameListBox->index(item);
+ lastItemID_ = n;
+
+
+ loadSchema(ui_.nameListWidget->item(n)->data(Qt::UserRole).toString());
+ updateView();
+ ui_.nameListWidget->setCurrentRow(n, QItemSelectionModel::Select);
+}
+
+
+void schemaDialog::chooseImage() {
+ QString img = QFileDialog::getOpenFileName(
+ this, "Choose an image", QDir::currentPath());
+ if (!img.isNull()) {
+ ui_.imageLineEdit->setText(img);
+ isModified_ = true;
+ }
+}
+
+
+
+void schemaDialog::saveSchema() {
+ // get current schema file name
+ int n = ui_.nameListWidget->currentRow();
+ int saved = saveNumSchema(n);
+ lastItemID_ = saved;
+ ui_.nameListWidget->setCurrentRow(saved, QItemSelectionModel::Select);
+}
+
+void schemaDialog::removeSchema() {
+ QFileInfo fi(ui_.nameListWidget->currentItem()->data(Qt::UserRole).toString());
+ if (fi.isWritable()) {
+ QFile::remove(ui_.nameListWidget->currentItem()->data(Qt::UserRole).toString());
+ int n = ui_.nameListWidget->currentRow();
+ delete ui_.nameListWidget->takeItem(n);
+ emit schemaEdited();
+ } else {
+ QMessageBox::warning(this, "Error",
+ "This is a system schema. Permission Denied");
+ }
+}
+
+void schemaDialog::onOK() {
+ saveSchema();
+ done(1);
+}
+
+void schemaDialog::onCancel() {
+ done(0);
+}
+
+
+
+
+} // namespace FQTerm
+
+#include "schemadialog.moc"
diff --git a/src/ui/schemadialog.h b/src/ui/schemadialog.h
new file mode 100644
index 0000000..c2ef977
--- /dev/null
+++ b/src/ui/schemadialog.h
@@ -0,0 +1,80 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SCHEMADIALOG_H
+#define FQTERM_SCHEMADIALOG_H
+
+#include "ui_schemadialog.h"
+#include <QStringList>
+namespace FQTerm {
+
+class schemaDialog: public QDialog {
+ Q_OBJECT;
+ public:
+ schemaDialog(QWidget *parent = 0, Qt::WFlags fl = 0);
+ ~schemaDialog();
+
+ static QFileInfoList getSchemaList();
+ protected:
+ QColor colors[16];
+ QPushButton * colorButtons[16];
+ QString title_;
+ QStringList fileList_;
+
+ bool isModified_;
+ int lastItemID_;
+ private:
+ Ui::schemaDialog ui_;
+ QButtonGroup buttonGroup_;
+
+ protected:
+ void connectSlots();
+
+ void loadList();
+ void loadSchema(const QString &schemaFileName);
+ int saveNumSchema(int n = -1);
+
+ void updateView();
+
+ protected slots:
+ void buttonClicked();
+ void nameChanged(int);
+ void chooseImage();
+
+ void saveSchema();
+ void removeSchema();
+
+ void onOK();
+ void onCancel();
+
+ void modified(const QString&) {modified();}
+ void modified(int) {modified();}
+ void modified(bool) {modified();}
+ void modified() {isModified_ = true;}
+
+ void clearModified() {isModified_ = false;}
+
+signals:
+ void schemaEdited();
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SCHEMADIALOG_H
diff --git a/src/ui/schemadialog.ui b/src/ui/schemadialog.ui
new file mode 100644
index 0000000..0d987bb
--- /dev/null
+++ b/src/ui/schemadialog.ui
@@ -0,0 +1,539 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>schemaDialog</class>
+ <widget class="QDialog" name="schemaDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>612</width>
+ <height>334</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Schema Editor</string>
+ </property>
+ <layout class="QGridLayout">
+ <item row="0" column="0">
+ <layout class="QGridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="textLabel1_2">
+ <property name="text">
+ <string>Title</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="8">
+ <widget class="QLineEdit" name="titleLineEdit"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="textLabel1">
+ <property name="text">
+ <string>0-7</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QPushButton" name="clr0Button">
+ <property name="cursor">
+ <cursorShape>PointingHandCursor</cursorShape>
+ </property>
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QPushButton" name="clr1Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QPushButton" name="clr2Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="4">
+ <widget class="QPushButton" name="clr3Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="5">
+ <widget class="QPushButton" name="clr4Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="6">
+ <widget class="QPushButton" name="clr5Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="7">
+ <widget class="QPushButton" name="clr6Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="8">
+ <widget class="QPushButton" name="clr7Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="textLabel2">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="text">
+ <string>8-15</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QPushButton" name="clr8Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QPushButton" name="clr9Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3">
+ <widget class="QPushButton" name="clr10Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="4">
+ <widget class="QPushButton" name="clr11Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="5">
+ <widget class="QPushButton" name="clr12Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="6">
+ <widget class="QPushButton" name="clr13Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="7">
+ <widget class="QPushButton" name="clr14Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="8">
+ <widget class="QPushButton" name="clr15Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" colspan="8">
+ <widget class="QListWidget" name="nameListWidget"/>
+ </item>
+ <item row="4" column="1" colspan="8">
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QPushButton" name="saveButton">
+ <property name="text">
+ <string>Save</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="removeButton">
+ <property name="text">
+ <string>Remove </string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="1">
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QPushButton" name="okButton">
+ <property name="text">
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancelButton">
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="1">
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Background</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="QRadioButton" name="noneRadioButton">
+ <property name="text">
+ <string>None</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="3">
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="1" column="0">
+ <widget class="QLineEdit" name="imageLineEdit"/>
+ </item>
+ <item row="1" column="1">
+ <widget class="QPushButton" name="chooseButton">
+ <property name="text">
+ <string>Choose</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QRadioButton" name="imageRadioButton">
+ <property name="text">
+ <string>Image</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QComboBox" name="optionComboBox">
+ <item>
+ <property name="text">
+ <string>Tile</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Center</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Scale</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QComboBox" name="coverComboBox">
+ <item>
+ <property name="text">
+ <string>Whole</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Padding</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QLabel" name="TextLabel2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Min</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="alphaSlider">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Max</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="4" column="0">
+ <widget class="QCheckBox" name="alphaCheckBox">
+ <property name="text">
+ <string>Alpha</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Render</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Coverage</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLineEdit" name="ForAlignment">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2">
+ <widget class="QLineEdit" name="ForAlignment_2">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" colspan="3">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Note:
+ Alpha will only apply on background
+ If Coverage is set to Padding
+ Alpha will take no effect
+</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/ui/shortcutdialog.cpp b/src/ui/shortcutdialog.cpp
new file mode 100644
index 0000000..0b73ab3
--- /dev/null
+++ b/src/ui/shortcutdialog.cpp
@@ -0,0 +1,176 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "shortcutdialog.h"
+#include "fqterm_shortcuthelper.h"
+
+#include <QTableWidget>
+#include <QKeyEvent>
+#include <QGridLayout>
+#include <QPushButton>
+#include <QHeaderView>
+#include <QStringList>
+#include <QScrollBar>
+#include <QLabel>
+#include <QSignalMapper>
+namespace FQTerm
+{
+FQTermShortcutDialog::FQTermShortcutDialog(FQTermShortcutHelper* helper, QWidget *parent_, Qt::WFlags fl)
+ : QDialog(parent_, fl),
+ helper_(helper),
+ table_(NULL) {
+ setWindowTitle(tr("Shortcut Setting"));
+ //grabKeyboard();
+ if (helper_)
+ {
+ QSignalMapper* signalMapper = new QSignalMapper(this);
+ int row = FQTermShortcutHelper::FQTERM_APPLICATION_SHORTCUT_END - FQTermShortcutHelper::FQTERM_APPLICATION_SHORTCUT_START - 1;
+ int column = 3;
+ table_ = new QTableWidget(row, column, this);
+ table_->clear();
+ QStringList header;
+ header << tr("Description") << tr("Shortcut") << "";
+ table_->setHorizontalHeaderLabels(header);
+ for (int i = 0; i < row; ++i) {
+ for (int j = 0; j < column; ++j) {
+ if (j == 0) {
+ QTableWidgetItem* item = new QTableWidgetItem;
+ table_->setItem(i, j, item);
+ item->setFlags(item->flags() & ~Qt::ItemIsEditable);
+ item->setText(helper_->getShortcutDescription(i + 1));
+ } else if (j == 1) {
+ FQTermShortcutTableWidget* stw = new FQTermShortcutTableWidget(table_);
+ stw->setReadOnly(true);
+ stw->setText(helper_->getShortcutText(i + 1));
+ table_->setCellWidget(i, j, stw);
+ }else {
+ QPushButton* btn = new QPushButton(tr("default"), table_);
+ table_->setCellWidget(i, j, btn);
+ FQ_VERIFY(connect(btn, SIGNAL(clicked()), signalMapper, SLOT(map())));
+ signalMapper->setMapping(btn, i);
+ }
+ }
+ }
+ table_->resizeColumnsToContents();
+ int tableWidth = table_->horizontalHeader()->length();
+ if (table_->horizontalScrollBar() && table_->horizontalScrollBar()->isVisible()) {
+ tableWidth += table_->horizontalScrollBar()->width();
+ }
+ QPushButton* okBtn = new QPushButton(tr("OK"), this);
+ FQ_VERIFY(connect(okBtn, SIGNAL(clicked()), this, SLOT(okBtnClicked())));
+ QPushButton* applyBtn = new QPushButton(tr("Apply"), this);
+ FQ_VERIFY(connect(applyBtn, SIGNAL(clicked()), this, SLOT(applyBtnClicked())));
+ QPushButton* cancelBtn = new QPushButton(tr("Cancel"), this);
+ FQ_VERIFY(connect(cancelBtn, SIGNAL(clicked()), this, SLOT(cancelBtnClicked())));
+ QPushButton* resetBtn = new QPushButton(tr("Reset All"), this);
+ FQ_VERIFY(connect(resetBtn, SIGNAL(clicked()), this, SLOT(resetBtnClicked())));
+ setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
+ QGridLayout* layout = new QGridLayout(this);
+ QLabel* label = new QLabel(tr("Press key/combines on Shortcut column.\nNote Del is reserved for clear shortcut setting."));
+ layout->addWidget(label, 0, 0, 1, -1);
+ layout->addWidget(table_, 1, 0, 1, -1);
+ layout->addWidget(okBtn, 2, 0);
+ layout->addWidget(applyBtn, 2, 1);
+ layout->addWidget(cancelBtn, 2, 2);
+ layout->addWidget(resetBtn, 2, 3);
+ setLayout(layout);
+ int left = 0;
+ int right = 0;
+ layout->getContentsMargins(&left, NULL, &right, NULL);
+ table_->horizontalHeader()->setStretchLastSection(true);
+ tableWidth *= 1.1;
+ resize(tableWidth + left + right, height());
+ FQ_VERIFY(connect(signalMapper, SIGNAL(mapped(int)),this, SLOT(defaultClicked(int))));
+ }
+}
+
+FQTermShortcutDialog::~FQTermShortcutDialog() {
+ //releaseKeyboard();
+}
+
+void FQTermShortcutDialog::defaultClicked(int row) {
+ ((QLineEdit*)table_->cellWidget(row, 1))->setText(helper_->getShortcutDefaultText(row + 1));
+}
+
+void FQTermShortcutDialog::okBtnClicked() {
+ applyChanges();
+ done(true);
+}
+
+void FQTermShortcutDialog::applyBtnClicked() {
+ applyChanges();
+}
+
+void FQTermShortcutDialog::cancelBtnClicked() {
+ done(false);
+}
+
+void FQTermShortcutDialog::resetBtnClicked() {
+ int row = FQTermShortcutHelper::FQTERM_APPLICATION_SHORTCUT_END - FQTermShortcutHelper::FQTERM_APPLICATION_SHORTCUT_START - 1;
+ for (int i = 0; i < row; ++i) {
+ ((QLineEdit*)table_->cellWidget(i, 1))->setText(helper_->getShortcutDefaultText(i + 1));
+ }
+}
+
+void FQTermShortcutDialog::applyChanges() {
+ int row = FQTermShortcutHelper::FQTERM_APPLICATION_SHORTCUT_END - FQTermShortcutHelper::FQTERM_APPLICATION_SHORTCUT_START - 1;
+ for (int i = 0; i < row; ++i) {
+ helper_->setShortcutText(i + 1, ((QLineEdit*)table_->cellWidget(i, 1))->text());
+ }
+}
+
+void FQTermShortcutTableWidget::keyReleaseEvent(QKeyEvent * event) {
+ if (event) {
+ event->accept();
+ }
+}
+
+void FQTermShortcutTableWidget::keyPressEvent(QKeyEvent * event) {
+ if (event) {
+ event->accept();
+ if (event == QKeySequence::Delete) {
+ setText("");
+ } else {
+ //Thank you hooey.
+ int key = event->key();
+ Qt::KeyboardModifiers mod = event->modifiers();
+
+ if (key == Qt::Key_Shift ||
+ key == Qt::Key_Control ||
+ key == Qt::Key_Meta ||
+ key == Qt::Key_Alt ||
+ key == Qt::Key_AltGr)
+ return;
+ QString text = "";
+ if (mod != Qt::NoModifier) {
+ QKeySequence seqMod(mod);
+ text = seqMod.toString(QKeySequence::NativeText);
+ }
+ QKeySequence seqKey(key);
+ text += seqKey.toString(QKeySequence::NativeText);
+ setText(text);
+ }
+ }
+}
+
+}//namespace FQTerm
+
+
+#include "shortcutdialog.moc"
diff --git a/src/ui/shortcutdialog.h b/src/ui/shortcutdialog.h
new file mode 100644
index 0000000..d8fd109
--- /dev/null
+++ b/src/ui/shortcutdialog.h
@@ -0,0 +1,61 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SHORTCUT_DIALOG_H
+#define FQTERM_SHORTCUT_DIALOG_H
+#include <QDialog>
+#include <QLineEdit>
+class QTableWidget;
+namespace FQTerm
+{
+class FQTermShortcutHelper;
+
+class FQTermShortcutTableWidget : public QLineEdit
+{
+public:
+ FQTermShortcutTableWidget(QWidget* parent) : QLineEdit(parent) {
+ }
+protected:
+ void keyReleaseEvent(QKeyEvent * event);
+ void keyPressEvent(QKeyEvent * event);
+};
+
+class FQTermShortcutDialog : public QDialog
+{
+ Q_OBJECT;
+public:
+ FQTermShortcutDialog(FQTermShortcutHelper* helper, QWidget *parent_ = 0, Qt::WFlags fl = Qt::Dialog);
+ ~FQTermShortcutDialog();
+private:
+ FQTermShortcutHelper* helper_;
+ QTableWidget* table_;
+protected slots:
+ void defaultClicked(int row);
+ void okBtnClicked();
+ void applyBtnClicked();
+ void cancelBtnClicked();
+ void resetBtnClicked();
+private:
+ void applyChanges();
+};
+}//namespace FQTerm
+
+
+#endif //FQTERM_SHORTCUT_DIALOG_H
diff --git a/src/ui/sitemanager.cpp b/src/ui/sitemanager.cpp
new file mode 100644
index 0000000..29f2ccd
--- /dev/null
+++ b/src/ui/sitemanager.cpp
@@ -0,0 +1,412 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QTextCharFormat>
+#include <QDialog>
+#include <QIntValidator>
+#include <QPainter>
+#include <QResizeEvent>
+#include <QPalette>
+#include <QListWidgetItem>
+#include <QMessageBox>
+
+#include "fqterm_config.h"
+#include "fqterm_param.h"
+#include "fqterm_param.h"
+#include "fqterm_path.h"
+#include "fqterm_trace.h"
+
+#include "sitemanager.h"
+
+namespace FQTerm{
+
+int siteDialog::ports[] = {23, 22, 22, 0};
+
+siteDialog::siteDialog(QWidget *parent_ /*= 0*/, Qt::WFlags fl /*= 0*/)
+ : QDialog(parent_, fl) {
+ ui_.setupUi(this);
+
+ config_ = new FQTermConfig(getPath(USER_CONFIG) + "address.cfg");
+ QStringList name_list;
+ loadNameList(config_, name_list);
+ ui_.siteList->addItems(name_list);
+
+ if (ui_.siteList->count() != 0) {
+ setCurrentSite(0);
+ loadCurrentParam();
+ setUIFromParam();
+ }
+ else {
+ ui_.editGroup->setDisabled(true);
+ }
+ connector();
+}
+
+siteDialog::~siteDialog() {
+ config_->save(getPath(USER_CONFIG) + "address.cfg");
+ delete config_;
+}
+
+void siteDialog::onSelectProtocol(int index) {
+ ui_.portCheck->setChecked(false);
+ ui_.portEdit->setText(QString("%1").arg(ports[index]));
+}
+
+void siteDialog::setParamFromUI() {
+ param_.name_ = ui_.nameEdit->text();
+ param_.hostAddress_ = ui_.addrEdit->text();
+ param_.protocolType_ = ui_.protocolCombo->currentIndex();
+ bool ok;
+ int port = ui_.portEdit->text().toInt(&ok);
+ param_.port_ = (ok && port >= 0 && port <= 65535)?port:ports[ui_.protocolCombo->currentIndex()];
+ param_.hostType_ = ui_.hostTypeCombo->currentIndex();
+ if (!ui_.proxyCheck->isChecked()) {
+ param_.proxyType_ = 0;
+ }
+ param_.isAutoLogin_ = ui_.autoLoginCheck->isChecked();
+}
+
+//auto fix errors.
+void siteDialog::setUIFromParam() {
+ ui_.nameEdit->setText(param_.name_);
+ ui_.addrEdit->setText(param_.hostAddress_);
+ ui_.protocolCombo->setCurrentIndex(param_.protocolType_);
+ ui_.portCheck->setCheckState(param_.port_ == ports[ui_.protocolCombo->currentIndex()]?Qt::Unchecked:Qt::Checked);
+ ui_.portEdit->setText(QString("%1").arg(param_.port_));
+ ui_.hostTypeCombo->setCurrentIndex(param_.hostType_);
+ ui_.proxyCheck->setCheckState(param_.proxyType_?Qt::Checked:Qt::Unchecked);
+ ui_.autoLoginCheck->setCheckState(param_.isAutoLogin_?Qt::Checked:Qt::Unchecked);
+
+ previewFont();
+}
+
+void siteDialog::loadCurrentParam() {
+ if (ui_.siteList->count() == 0) {
+ return;
+ }
+ loadAddress(config_, currentSiteIndex(), param_);
+}
+
+void siteDialog::saveCurrentParam() {
+ if (ui_.siteList->count() == 0) {
+ return;
+ }
+ saveAddress(config_, currentSiteIndex(), param_);
+}
+
+void siteDialog::previewFont() {
+ //issue 98
+
+ QPalette palette;
+ palette.setColor(QPalette::Window, param_.backgroundColor_);
+ palette.setColor(QPalette::WindowText, param_.foregroundColor_);
+ ui_.fontPreviewer->setPalette(palette);
+
+ QString sample("<html><body style=\" font-family:'"
+ + param_.englishFontName_ + "'; font-size:"
+ + QString().setNum(param_.englishFontSize_)
+ + "pt;\"><BR>AaBbCc</body></html>");
+ sample += QString("<html><body style=\" font-family:'"
+ + param_.otherFontName_ + "'; font-size:"
+ + QString().setNum(param_.otherFontSize_) + "pt;\">"
+ + param_.otherFontName_ + "<BR></body></html>");
+ ui_.fontPreviewer->setText(sample);
+}
+
+void siteDialog::swapSite(int first, int second) {
+ FQTermParam firstParam;
+ FQTermParam secondParam;
+ loadAddress(config_, first, firstParam);
+ loadAddress(config_, second, secondParam);
+ saveAddress(config_, first, secondParam);
+ saveAddress(config_, second, firstParam);
+
+ QListWidgetItem* firstItem = ui_.siteList->item(first);
+ QListWidgetItem* secondItem = ui_.siteList->item(second);
+ QString tmpStr = firstItem->text();
+ firstItem->setText(secondItem->text());
+ secondItem->setText(tmpStr);
+}
+
+int siteDialog::moveSite(int pos, int offset)
+{
+ int newPos = pos + offset;
+ int step = offset>0?1:-1;
+ if (newPos >= ui_.siteList->count() || newPos < 0) {
+ return pos;
+ }
+ for(int i = pos; i != newPos; i += step) {
+ swapSite(i , i + step);
+ }
+ return newPos;
+}
+
+QMessageBox::StandardButton siteDialog::checkModification(int row) { //with current display
+ FQTermParam originParam;
+ loadAddress(config_, row, originParam);
+ setParamFromUI();
+ QMessageBox::StandardButton ret = QMessageBox::No;
+ if (!(originParam == param_)) {
+ QMessageBox msgBox;
+ msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
+ msgBox.setIcon(QMessageBox::Warning);
+ msgBox.setWindowTitle(tr("Warning"));
+ msgBox.setText(tr("The site configuration has been changed.\nTo save, press Yes.\nTo discard, press No.\nTo continue editing, press Cancel"));
+
+
+ switch(ret = static_cast<QMessageBox::StandardButton>(msgBox.exec())) {
+ case QMessageBox::No:
+ param_ = originParam;
+ break;
+ default:
+ break;
+ }
+ ui_.siteList->item(row)->setText(param_.name_);
+ }
+ return ret;
+}
+
+void siteDialog::onSelectSite(QListWidgetItem* current, QListWidgetItem* previous)
+{
+ int currentRow = ui_.siteList->row(current);
+ int previousRow = ui_.siteList->row(previous);
+ if (currentRow < 0) {
+ ui_.editGroup->setDisabled(true);
+ }
+ else {
+ ui_.editGroup->setEnabled(true);
+ }
+ if (previousRow >= 0){
+ if (checkModification(previousRow) == QMessageBox::Cancel) {
+ forcedSetCurrentSite(previousRow);
+ return;
+ }
+ saveAddress(config_, previousRow, param_);
+ }
+ if (currentRow >= 0){
+ loadAddress(config_, currentRow, param_);
+ setUIFromParam();
+ }
+
+}
+
+//without emit a signal
+void siteDialog::forcedSetCurrentSite(int row)
+{
+ FQ_VERIFY(disconnect(ui_.siteList, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)),
+ this, SLOT(onSelectSite(QListWidgetItem*, QListWidgetItem*))));
+ ui_.siteList->setCurrentRow(row);
+ FQ_VERIFY(connect(ui_.siteList, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)),
+ this, SLOT(onSelectSite(QListWidgetItem*, QListWidgetItem*))));
+}
+
+//emit a signal
+void siteDialog::setCurrentSite(int row)
+{
+ ui_.siteList->setCurrentRow(row);
+}
+
+void siteDialog::removeSite(int row)
+{
+ if (row < 0) {
+ return;
+ }
+ int last = ui_.siteList->count() - 1;
+ setCurrentSite(last - 1);
+ moveSite(row, last - row);
+ config_->deleteSection(QString("%1").arg(last));
+ config_->setItemValue("bbs list", "num", QString("%1").arg(last));
+ delete ui_.siteList->takeItem(last);
+
+ loadCurrentParam();
+ setUIFromParam();
+}
+
+void siteDialog::onNew() {
+ int row = ui_.siteList->count();
+ if (row < 0) {
+ row = 0;
+ }
+ config_->setItemValue("bbs list", "num", QString("%1").arg(row + 1));
+
+ FQTermParam newParam;
+ loadAddress(config_, -1, newParam);
+ saveAddress(config_, row, newParam);
+ ui_.siteList->addItem(newParam.name_);
+ setCurrentSite(row);
+}
+
+void siteDialog::onDelete() {
+ if (ui_.siteList->count() == 0) {
+ return;
+ }
+ QMessageBox msgBox;
+ msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
+ msgBox.setIcon(QMessageBox::Warning);
+ msgBox.setWindowTitle(tr("Warning"));
+ msgBox.setText(tr("Are you sure to DELETE this site?"));
+ switch(msgBox.exec())
+ {
+ case QMessageBox::Yes:
+ removeSite(currentSiteIndex());
+ break;
+ case QMessageBox::No:
+ break;
+ }
+}
+
+void siteDialog::siteNameChanged( QString name ) {
+ QListWidgetItem* item = ui_.siteList->currentItem();
+ if (item) {
+ item->setText(name);
+ }
+}
+
+void siteDialog::setSiteSelected() {
+ int row = currentSiteIndex();
+ if(row >= 0) {
+ ui_.siteList->item(row)->setSelected(true);
+ }
+}
+
+void siteDialog::close(int doneValue) {
+ if (ui_.siteList->count() > 0) {
+ switch(checkModification(currentSiteIndex())) {
+ case QMessageBox::Yes:
+ onApply();
+ break;
+ case QMessageBox::No:
+ loadCurrentParam();
+ break;
+ case QMessageBox::Cancel:
+ return;
+ default:
+ break;
+ }
+ }
+ done(doneValue);
+}
+
+void siteDialog::onReset() {
+ loadCurrentParam();
+ setUIFromParam();
+}
+
+void siteDialog::onApply() {
+ setParamFromUI();
+ saveCurrentParam();
+ setUIFromParam();
+}
+
+void siteDialog::onUp() {
+ int newPos = moveSite(currentSiteIndex(), -1);
+ forcedSetCurrentSite(newPos);
+}
+
+void siteDialog::onDown() {
+ int newPos = moveSite(currentSiteIndex(), 1);
+ forcedSetCurrentSite(newPos);
+}
+
+void siteDialog::onClose() {
+ close(0);
+}
+
+void siteDialog::onConnect() {
+ close(1);
+}
+
+void siteDialog::resizeEvent( QResizeEvent * re ) {
+ previewFont();
+}
+
+FQTermParam siteDialog::currentParameter() {
+ return param_;
+}
+
+int siteDialog::currentSiteIndex() {
+ return ui_.siteList->currentRow();
+}
+
+void siteDialog::onAdvance() {
+ setting(addrDialog::General);
+}
+
+void siteDialog::setting(addrDialog::Tabs tab) {
+ setParamFromUI();
+ addrDialog addr(this, param_, addrDialog::APPLY);
+ addr.setCurrentTabIndex(tab);
+ int res = addr.exec();
+ if (res == 1) {
+ param_ = addr.param();
+ setUIFromParam();
+ }
+}
+
+void siteDialog::onProxy() {
+ setting(addrDialog::Proxy);
+}
+
+void siteDialog::onAutoLogin() {
+ setting(addrDialog::General);
+}
+
+void siteDialog::onDblClicked(QListWidgetItem * item) {
+ onConnect();
+}
+
+void siteDialog::connector() {
+ FQ_VERIFY(connect(ui_.siteList, SIGNAL(itemSelectionChanged()),
+ this, SLOT(setSiteSelected())));
+ FQ_VERIFY(connect(ui_.siteList, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)),
+ this, SLOT(onSelectSite(QListWidgetItem*, QListWidgetItem*))));
+ FQ_VERIFY(connect(ui_.nameEdit, SIGNAL(textChanged(QString)),
+ this, SLOT(siteNameChanged(QString))));
+ FQ_VERIFY(connect(ui_.protocolCombo, SIGNAL(currentIndexChanged(int)),
+ this, SLOT(onSelectProtocol(int))));
+ FQ_VERIFY(connect(ui_.resetButton, SIGNAL(clicked()),
+ this, SLOT(onReset())));
+ FQ_VERIFY(connect(ui_.upButton, SIGNAL(clicked()),
+ this, SLOT(onUp())));
+ FQ_VERIFY(connect(ui_.downButton, SIGNAL(clicked()),
+ this, SLOT(onDown())));
+ FQ_VERIFY(connect(ui_.newButton, SIGNAL(clicked()),
+ this, SLOT(onNew())));
+ FQ_VERIFY(connect(ui_.deleteButton, SIGNAL(clicked()),
+ this, SLOT(onDelete())));
+ FQ_VERIFY(connect(ui_.applyButton, SIGNAL(clicked()),
+ this, SLOT(onApply())));
+ FQ_VERIFY(connect(ui_.closeButton, SIGNAL(clicked()),
+ this, SLOT(onClose())));
+ FQ_VERIFY(connect(ui_.connectButton, SIGNAL(clicked()),
+ this, SLOT(onConnect())));
+ FQ_VERIFY(connect(ui_.advanceButton, SIGNAL(clicked()),
+ this, SLOT(onAdvance())));
+ FQ_VERIFY(connect(ui_.proxyButton, SIGNAL(clicked()),
+ this, SLOT(onProxy())));
+ FQ_VERIFY(connect(ui_.autoLoginButton, SIGNAL(clicked()),
+ this, SLOT(onAutoLogin())));
+ FQ_VERIFY(connect(ui_.siteList, SIGNAL(itemDoubleClicked(QListWidgetItem *)),
+ this, SLOT(onDblClicked(QListWidgetItem *))));
+}
+
+} //namespace FQTerm
+
+#include "sitemanager.moc"
diff --git a/src/ui/sitemanager.h b/src/ui/sitemanager.h
new file mode 100644
index 0000000..6aae387
--- /dev/null
+++ b/src/ui/sitemanager.h
@@ -0,0 +1,104 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SITEMANGER_H
+#define FQTERM_SITEMANGER_H
+
+#include "addrdialog.h"
+
+#include "ui_sitemanager.h"
+#include "ui_quickdialog.h"
+
+class QListWidgetItem;
+
+namespace FQTerm {
+class FQTermParam;
+class FQTermConfig;
+
+class siteDialog: public QDialog {
+ Q_OBJECT;
+ public:
+ siteDialog(QWidget *parent_ = 0, Qt::WFlags fl = 0);;
+ ~siteDialog();
+
+ FQTermParam currentParameter();
+
+ int currentSiteIndex();
+
+ private:
+ void connector();
+
+ void resizeEvent(QResizeEvent * re);
+
+ //Note: changes are made on config_
+ void saveCurrentParam();
+ void loadCurrentParam();
+
+ void setParamFromUI();
+ void setUIFromParam();
+
+ void previewFont();
+
+ void swapSite(int first, int second);
+ int moveSite(int pos, int offset);
+ void forcedSetCurrentSite(int row);
+ void setCurrentSite(int row);
+
+ QMessageBox::StandardButton checkModification(int row);
+
+ void removeSite(int row);
+
+ void close(int doneValue);
+ void setting(addrDialog::Tabs tab);
+
+
+ protected slots:
+ void onSelectSite(QListWidgetItem* current, QListWidgetItem* previous);
+ void siteNameChanged(QString name);
+ void setSiteSelected();
+
+ void onSelectProtocol(int index);
+
+ void onReset();
+ void onApply();
+ void onUp();
+ void onDown();
+ void onNew();
+ void onDelete();
+ void onClose();
+ void onConnect();
+
+ void onAdvance();
+ void onProxy();
+ void onAutoLogin();
+ void onDblClicked(QListWidgetItem * item);
+
+ private:
+ FQTermConfig *config_;
+ FQTermParam param_;
+
+ Ui::siteManager ui_;
+
+ static int ports[]; //telnet, ssh1, ssh2
+};
+
+} //FQTerm namespace
+
+#endif // FQTERM_SITEMANGER_H
diff --git a/src/ui/sitemanager.ui b/src/ui/sitemanager.ui
new file mode 100644
index 0000000..9b085ed
--- /dev/null
+++ b/src/ui/sitemanager.ui
@@ -0,0 +1,593 @@
+<ui version="4.0" >
+ <class>siteManager</class>
+ <widget class="QDialog" name="siteManager" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>481</width>
+ <height>495</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Address Book</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <layout class="QGridLayout" >
+ <item row="0" column="0" colspan="2" >
+ <widget class="QListWidget" name="siteList" />
+ </item>
+ <item row="1" column="0" >
+ <widget class="QPushButton" name="upButton" >
+ <property name="text" >
+ <string>&amp;Up</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QPushButton" name="downButton" >
+ <property name="text" >
+ <string>&amp;Down</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QGroupBox" name="editGroup" >
+ <property name="title" >
+ <string/>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="nameLabel" >
+ <property name="text" >
+ <string>Site Name</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="3" >
+ <widget class="QLineEdit" name="nameEdit" />
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="addrLabel" >
+ <property name="text" >
+ <string>Address</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" colspan="3" >
+ <widget class="QLineEdit" name="addrEdit" />
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="protocolLabel" >
+ <property name="text" >
+ <string>Protocol</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QComboBox" name="protocolCombo" >
+ <item>
+ <property name="text" >
+ <string>Telnet</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>SSH1</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>SSH2</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="2" column="2" >
+ <widget class="QCheckBox" name="portCheck" >
+ <property name="text" >
+ <string>Port</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3" >
+ <widget class="QLineEdit" name="portEdit" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="hostTypeLabel" >
+ <property name="text" >
+ <string>Host Type</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" >
+ <widget class="QComboBox" name="hostTypeCombo" >
+ <item>
+ <property name="text" >
+ <string>BBS</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>*NIX</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="4" column="0" >
+ <widget class="QCheckBox" name="proxyCheck" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Minimum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Use Proxy</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1" >
+ <widget class="QPushButton" name="proxyButton" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>Setting...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0" >
+ <widget class="QCheckBox" name="autoLoginCheck" >
+ <property name="text" >
+ <string>Auto Login</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1" >
+ <widget class="QPushButton" name="autoLoginButton" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Setting...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0" >
+ <widget class="QLabel" name="label_10" >
+ <property name="text" >
+ <string>Font Preview</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1" colspan="3" >
+ <widget class="QLabel" name="fontPreviewer" >
+ <property name="autoFillBackground" >
+ <bool>true</bool>
+ </property>
+ <property name="text" >
+ <string>Font Previewer</string>
+ </property>
+ <property name="textFormat" >
+ <enum>Qt::RichText</enum>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="0" colspan="4" >
+ <layout class="QHBoxLayout" >
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>55</width>
+ <height>25</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="resetButton" >
+ <property name="text" >
+ <string>&amp;Reset</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>54</width>
+ <height>25</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="advanceButton" >
+ <property name="text" >
+ <string>A&amp;dvance</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="7" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2" >
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QPushButton" name="newButton" >
+ <property name="text" >
+ <string>&amp;New</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="deleteButton" >
+ <property name="text" >
+ <string>&amp;Delete</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="connectButton" >
+ <property name="text" >
+ <string>C&amp;onnect</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="applyButton" >
+ <property name="text" >
+ <string>&amp;Save</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="closeButton" >
+ <property name="text" >
+ <string>&amp;Close</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ <widget class="QLabel" name="label" >
+ <property name="geometry" >
+ <rect>
+ <x>9</x>
+ <y>553</y>
+ <width>31</width>
+ <height>0</height>
+ </rect>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_2" >
+ <property name="geometry" >
+ <rect>
+ <x>120</x>
+ <y>553</y>
+ <width>30</width>
+ <height>0</height>
+ </rect>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_3" >
+ <property name="geometry" >
+ <rect>
+ <x>156</x>
+ <y>553</y>
+ <width>78</width>
+ <height>0</height>
+ </rect>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_4" >
+ <property name="geometry" >
+ <rect>
+ <x>240</x>
+ <y>553</y>
+ <width>69</width>
+ <height>0</height>
+ </rect>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_5" >
+ <property name="geometry" >
+ <rect>
+ <x>410</x>
+ <y>553</y>
+ <width>34</width>
+ <height>0</height>
+ </rect>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_6" >
+ <property name="geometry" >
+ <rect>
+ <x>369</x>
+ <y>553</y>
+ <width>35</width>
+ <height>0</height>
+ </rect>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_7" >
+ <property name="geometry" >
+ <rect>
+ <x>46</x>
+ <y>553</y>
+ <width>30</width>
+ <height>0</height>
+ </rect>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_8" >
+ <property name="geometry" >
+ <rect>
+ <x>82</x>
+ <y>553</y>
+ <width>32</width>
+ <height>0</height>
+ </rect>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_9" >
+ <property name="geometry" >
+ <rect>
+ <x>315</x>
+ <y>553</y>
+ <width>48</width>
+ <height>0</height>
+ </rect>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ </widget>
+ <tabstops>
+ <tabstop>siteList</tabstop>
+ <tabstop>nameEdit</tabstop>
+ <tabstop>addrEdit</tabstop>
+ <tabstop>protocolCombo</tabstop>
+ <tabstop>portCheck</tabstop>
+ <tabstop>portEdit</tabstop>
+ <tabstop>hostTypeCombo</tabstop>
+ <tabstop>proxyCheck</tabstop>
+ <tabstop>autoLoginCheck</tabstop>
+ <tabstop>connectButton</tabstop>
+ <tabstop>upButton</tabstop>
+ <tabstop>downButton</tabstop>
+ <tabstop>resetButton</tabstop>
+ <tabstop>advanceButton</tabstop>
+ <tabstop>newButton</tabstop>
+ <tabstop>deleteButton</tabstop>
+ <tabstop>applyButton</tabstop>
+ <tabstop>closeButton</tabstop>
+ <tabstop>proxyButton</tabstop>
+ <tabstop>autoLoginButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>portCheck</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>portEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>372</x>
+ <y>81</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>477</x>
+ <y>83</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>proxyCheck</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>proxyButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>235</x>
+ <y>141</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>285</x>
+ <y>126</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>autoLoginCheck</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>autoLoginButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>232</x>
+ <y>155</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>361</x>
+ <y>172</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/ui/soundconf.cpp b/src/ui/soundconf.cpp
new file mode 100644
index 0000000..2681b83
--- /dev/null
+++ b/src/ui/soundconf.cpp
@@ -0,0 +1,178 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QMessageBox>
+#include <QFileDialog>
+
+#include "fqterm.h"
+#include "fqterm_config.h"
+#include "fqterm_path.h"
+#include "fqterm_sound.h"
+
+#include "soundconf.h"
+
+namespace FQTerm {
+/*
+ * Constructs a fSoundConf which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'
+ *
+ * The dialog will by default be modeless, unless you set 'modal' to
+ * TRUE to construct a modal dialog.
+ */
+
+soundConf::soundConf(FQTermConfig * config, QWidget *parent, Qt::WFlags fl)
+ : QDialog(parent, fl),
+ buttonGroup_(this),
+ config_(config){
+ ui_.setupUi(this);
+ buttonGroup_.addButton(ui_.radioButton1, 0);
+ buttonGroup_.addButton(ui_.radioButton2, 1);
+ sound_ = NULL;
+ loadSetting();
+ FQ_VERIFY(connect(ui_.bfSelect, SIGNAL(clicked()),
+ this, SLOT(onSelectFile())));
+ FQ_VERIFY(connect(ui_.bpSelect, SIGNAL(clicked()),
+ this, SLOT(onSelectProg())));
+ FQ_VERIFY(connect(ui_.bpTest, SIGNAL(clicked()),
+ this, SLOT(onTestPlay())));
+ FQ_VERIFY(connect(ui_.bOK, SIGNAL(clicked()),
+ this, SLOT(accept())));
+ FQ_VERIFY(connect(ui_.bCancel, SIGNAL(clicked()),
+ this, SLOT(reject())));
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+soundConf::~soundConf() {
+ // no need to delete child widgets, Qt does it all for us
+}
+
+/*
+ * public slot
+ */
+void soundConf::onSelectFile() {
+ FQTermFileDialog fileDialog(config_);
+ QString soundfile = fileDialog.getOpenName("Choose a WAVE file", "WAVE Audio Files (*.wav *.WAV)");
+ if (!soundfile.isEmpty()) {
+ ui_.leFile->setText(soundfile);
+ }
+}
+
+/*
+ * public slot
+ */
+void soundConf::onSelectProg() {
+ FQTermFileDialog fileDialog(config_);
+ QString progfile = fileDialog.getOpenName("Choose a program", "");
+ if (!progfile.isEmpty()) {
+ ui_.leProg->setText(progfile);
+ }
+}
+
+/*
+ * public slot
+ */
+void soundConf::onPlayMethod(int id) {
+FQ_TRACE("sconf", 0) << id << ": " << buttonGroup_.checkedId();
+ ui_.bpSelect->setEnabled(id == 1 || buttonGroup_.checkedId() == 1);
+}
+
+void soundConf::onTestPlay() {
+ if (ui_.leFile->text().isEmpty()) {
+ QMessageBox::critical(this, tr("No sound file"),
+ tr("You have to select a file to test the sound"), tr("&Ok"));
+
+ return;
+ }
+
+ sound_ = NULL;
+
+ switch (buttonGroup_.checkedId()) {
+ case 0:
+ sound_ = new FQTermSystemSound(ui_.leFile->text());
+ break;
+ case 1:
+ if (ui_.leProg->text().isEmpty()) {
+ QMessageBox::critical(this, tr("No player"),
+ tr("You have to specify an external player"), tr("&Ok"));
+
+ break;
+ }
+
+ sound_ = new FQTermExternalSound(ui_.leProg->text(), ui_.leFile->text());
+ break;
+ }
+
+ if (sound_) {
+ sound_->start();
+ }
+}
+
+void soundConf::loadSetting() {
+
+ QString strTmp;
+
+ strTmp = config_->getItemValue("preference", "wavefile");
+ if (!strTmp.isEmpty()) {
+ ui_.leFile->setText(strTmp);
+ }
+
+ strTmp = config_->getItemValue("preference", "playmethod");
+
+ int valTmp = !strTmp.isEmpty()? strTmp.toInt(): -1;
+
+ if (valTmp >= 0 && valTmp <= 1) {
+ buttonGroup_.button(valTmp)->setChecked(true);
+ if (valTmp == 1) {
+ strTmp = config_->getItemValue("preference", "externalplayer");
+ if (!strTmp.isEmpty()) {
+ ui_.leProg->setText(strTmp);
+ }
+ }
+ }
+}
+
+void soundConf::saveSetting() {
+
+ QString strTmp;
+
+ config_->setItemValue("preference", "beep", "2");
+
+ config_->setItemValue("preference", "wavefile", ui_.leFile->text());
+
+ strTmp.setNum(buttonGroup_.checkedId());
+ config_->setItemValue("preference", "playmethod", strTmp);
+
+ if (strTmp == "1") {
+ config_->setItemValue("preference", "externalplayer", ui_.leProg->text());
+ }
+
+ config_->save(getPath(USER_CONFIG) + "fqterm.cfg");
+}
+
+void soundConf::accept() {
+ saveSetting();
+ QDialog::accept();
+}
+
+} // namespace FQTerm
+
+#include "soundconf.moc"
diff --git a/src/ui/soundconf.h b/src/ui/soundconf.h
new file mode 100644
index 0000000..5b4fe4c
--- /dev/null
+++ b/src/ui/soundconf.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SOUND_CONF_H
+#define FQTERM_SOUND_CONF_H
+
+#include "ui_soundconf.h"
+#include "fqterm_filedialog.h"
+
+namespace FQTerm {
+
+class FQTermSound;
+class FQTermConfig;
+
+class soundConf: public QDialog {
+ Q_OBJECT;
+ public:
+ soundConf(FQTermConfig *, QWidget *parent_ = 0, Qt::WFlags fl = 0);
+ ~soundConf();
+ void loadSetting();
+ void saveSetting();
+
+ public slots:
+ void onSelectFile();
+ void onSelectProg();
+ void onPlayMethod(int id);
+ void onTestPlay();
+ protected slots:
+ void accept();
+
+ private:
+ FQTermSound *sound_;
+ Ui::soundConf ui_;
+ QButtonGroup buttonGroup_;
+ FQTermConfig * config_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SOUND_CONF_H
diff --git a/src/ui/soundconf.ui b/src/ui/soundconf.ui
new file mode 100644
index 0000000..9cfe761
--- /dev/null
+++ b/src/ui/soundconf.ui
@@ -0,0 +1,162 @@
+<ui version="4.0" >
+ <class>soundConf</class>
+ <widget class="QDialog" name="soundConf" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>308</width>
+ <height>269</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Configure</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" colspan="2" >
+ <widget class="QGroupBox" name="groupBox" >
+ <property name="title" >
+ <string>Sound File:</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QLineEdit" name="leFile" />
+ </item>
+ <item row="0" column="2" >
+ <widget class="QPushButton" name="bfSelect" >
+ <property name="text" >
+ <string>Select...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2" >
+ <widget class="QGroupBox" name="groupBox_2" >
+ <property name="title" >
+ <string>Play With:</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QRadioButton" name="radioButton1" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ <property name="text" >
+ <string>Internal</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QRadioButton" name="radioButton2" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ <property name="text" >
+ <string>External</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="4" >
+ <widget class="QPushButton" name="bpTest" >
+ <property name="text" >
+ <string>Test</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="2" >
+ <widget class="QGroupBox" name="groupBox_3" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="title" >
+ <string>External Program:</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QLineEdit" name="leProg" />
+ </item>
+ <item row="0" column="2" >
+ <widget class="QPushButton" name="bpSelect" >
+ <property name="text" >
+ <string>Select...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="3" column="1" >
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QPushButton" name="bOK" >
+ <property name="text" >
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="bCancel" >
+ <property name="text" >
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <resources/>
+ <connections>
+ <connection>
+ <sender>radioButton2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>groupBox_3</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>124</x>
+ <y>136</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>123</x>
+ <y>176</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/ui/sshlogin.ui b/src/ui/sshlogin.ui
new file mode 100644
index 0000000..8794a57
--- /dev/null
+++ b/src/ui/sshlogin.ui
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SSHLogin</class>
+ <widget class="QDialog" name="SSHLogin">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>295</width>
+ <height>170</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Login</string>
+ </property>
+ <layout class="QGridLayout">
+ <item row="0" column="0" colspan="3">
+ <widget class="QLabel" name="textLabel2_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Please enter your username and password</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="textLabel1">
+ <property name="text">
+ <string>UserName:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" colspan="2">
+ <widget class="QLineEdit" name="leUserName"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="textLabel2">
+ <property name="text">
+ <string>Password:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" colspan="2">
+ <widget class="QLineEdit" name="lePassword"/>
+ </item>
+ <item row="3" column="0">
+ <widget class="QPushButton" name="bOK">
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="text">
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2">
+ <widget class="QPushButton" name="bCancel">
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/ui/sshlogindialog.cpp b/src/ui/sshlogindialog.cpp
new file mode 100644
index 0000000..cd858cb
--- /dev/null
+++ b/src/ui/sshlogindialog.cpp
@@ -0,0 +1,80 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QString>
+#include <QLineEdit>
+
+#include "fqterm_trace.h"
+#include "sshlogindialog.h"
+
+namespace FQTerm {
+
+/*
+ * Constructs a fSSHLogin which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'
+ *
+ * The dialog will by default be modeless, unless you set 'modal' to
+ * TRUE to construct a modal dialog.
+ */
+SSHLoginDialog::SSHLoginDialog(QString *username, QString *password,
+ QWidget *parent_, Qt::WFlags fl)
+ : QDialog(parent_, fl) {
+ ui_.setupUi(this);
+ setWindowTitle(parent_->windowTitle());
+ strUserName = username;
+ strPassword = password;
+ ui_.lePassword->setEchoMode(QLineEdit::Password);
+ ui_.leUserName->setText(*username);
+ ui_.lePassword->setText(*password);
+ if (!username->isEmpty()) {
+ ui_.leUserName->setDisabled(true);
+ ui_.lePassword->setFocus();
+ } else {
+ ui_.leUserName->setDisabled(false);
+ ui_.leUserName->setFocus();
+ }
+
+ FQ_VERIFY(connect(ui_.bOK, SIGNAL(clicked()), this, SLOT(accept())));
+ FQ_VERIFY(connect(ui_.bCancel, SIGNAL(clicked()), this, SLOT(reject())));
+ FQ_VERIFY(connect(ui_.leUserName, SIGNAL(returnPressed()), this, SLOT(moveFocus())));
+ FQ_VERIFY(connect(ui_.lePassword, SIGNAL(returnPressed()), this, SLOT(accept())));
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+SSHLoginDialog::~SSHLoginDialog() {
+ // no need to delete child widgets, Qt does it all for us
+}
+
+void SSHLoginDialog::accept() {
+ *strUserName = ui_.leUserName->text();
+ *strPassword = ui_.lePassword->text();
+ QDialog::accept();
+}
+
+void SSHLoginDialog::moveFocus()
+{
+ ui_.lePassword->setFocus();
+}
+
+} // namespace FQTerm
+
+#include "sshlogindialog.moc"
diff --git a/src/ui/sshlogindialog.h b/src/ui/sshlogindialog.h
new file mode 100644
index 0000000..e3295cc
--- /dev/null
+++ b/src/ui/sshlogindialog.h
@@ -0,0 +1,45 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_LOGIN_H
+#define FQTERM_SSH_LOGIN_H
+
+#include "ui_sshlogin.h"
+
+namespace FQTerm {
+
+class SSHLoginDialog: public QDialog {
+ Q_OBJECT;
+public:
+ SSHLoginDialog(QString *username, QString *password,
+ QWidget *parent_ = 0, Qt::WFlags fl = 0);
+ ~SSHLoginDialog();
+private:
+ QString *strUserName;
+ QString *strPassword;
+ Ui::SSHLogin ui_;
+private slots:
+ void accept();
+ void moveFocus();
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SSH_LOGIN_H
diff --git a/src/ui/statusBar.cpp b/src/ui/statusBar.cpp
new file mode 100644
index 0000000..be48fc4
--- /dev/null
+++ b/src/ui/statusBar.cpp
@@ -0,0 +1,530 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QPaintEvent>
+#include <QEvent>
+#include <QHBoxLayout>
+#include <QCustomEvent>
+#include <QProgressBar>
+#include <QToolButton>
+#include <QPushButton>
+#include <QPainter>
+#include <QPixmap>
+#include <QMessageBox>
+#include <QApplication>
+#include <QToolTip>
+
+#include "fqterm_trace.h"
+#include "fqterm_path.h"
+
+#include "popupMessage.h"
+#include "progressBar.h"
+#include "overlayWidget.h"
+#include "statusBar.h"
+
+namespace FQTerm {
+
+//TODO allow for uncertain progress periods
+
+StatusBar *StatusBar::singletonStatusBar_ = 0;
+
+StatusBar::StatusBar(QWidget *parent, const char *name)
+ : QWidget(parent) {
+ setObjectName(name);
+ singletonStatusBar_ = this;
+ QBoxLayout *mainlayout = new QHBoxLayout(this); //, 2, /*spacing*/5 );
+ mainlayout->setMargin(0);
+ mainlayout->setSpacing(5);
+
+ //we need extra spacing due to the way we paint the surrounding boxes
+ QBoxLayout *layout = new QHBoxLayout;
+ layout->setSpacing(5);
+ mainlayout->addLayout(layout);
+
+ m_mainTextLabel = new QLabel(this);
+ m_mainTextLabel->setObjectName("mainTextLabel");
+ m_mainTextLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored);
+
+ QWidget *mainProgressBarBox = new QWidget(this);
+ mainProgressBarBox->setObjectName("progressBox");
+
+ QHBoxLayout *mainProgressBarLayout = new QHBoxLayout(mainProgressBarBox);
+ mainProgressBarLayout->setContentsMargins(0, 0, 0, 0);
+
+ QToolButton *b1 = new QToolButton(mainProgressBarBox);
+ b1->setObjectName("cancelButton");
+ b1->setContentsMargins(0, 0, 0, 0);
+ b1->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored);
+ mainProgressBarLayout->addWidget(b1);
+
+ mainProgressBar_ = new QProgressBar(mainProgressBarBox);
+ mainProgressBar_->setObjectName("mainProgressBar");
+ mainProgressBarLayout->addWidget(mainProgressBar_);
+
+ QToolButton *b2 = new QToolButton(mainProgressBarBox);
+ b2->setObjectName("showAllProgressDetails");
+ b2->setContentsMargins(0,0,0,0);
+ b2->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored);
+ mainProgressBarLayout->addWidget(b2);
+
+ mainProgressBarLayout->setSpacing(2);
+ mainProgressBarBox->hide();
+
+ layout->addWidget(mainProgressBarBox);
+ layout->addWidget(m_mainTextLabel);
+
+ layout->setStretchFactor(m_mainTextLabel, 2);
+ layout->setStretchFactor(mainProgressBarBox, 1);
+
+ otherWidgetLayout_ = new QHBoxLayout;
+ otherWidgetLayout_->setSpacing(0);
+ mainlayout->addLayout(otherWidgetLayout_);
+
+ mainlayout->setStretchFactor(layout, 6);
+ mainlayout->setStretchFactor(otherWidgetLayout_, 4);
+
+ b1->setIcon(QPixmap(getPath(RESOURCE) + "pic/messagebox_critical.png"));
+ b2->setIcon(QPixmap(getPath(RESOURCE) + "pic/messagebox_info.png"));
+ b2->setCheckable(true);
+ b1->setToolTip(tr("Abort all background-operations"));
+ b2->setToolTip(tr("Show progress detail"));
+
+ FQ_VERIFY(connect(b1, SIGNAL(clicked()), SLOT(abortAllProgressOperations())));
+ FQ_VERIFY(connect(b2, SIGNAL(toggled(bool)), SLOT(toggleProgressWindow(bool))));
+
+ popupProgressMessage_ = new PopupMessage(this, mainProgressBarBox, 0);
+ popupProgressMessage_->showCloseButton(false);
+ popupProgressMessage_->showCounter(false);
+
+ popupProgressMessage_->setFrameStyle(QFrame::Box | QFrame::Raised);
+ popupProgressMessage_->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+}
+
+void StatusBar::addWidget(QWidget *widget) {
+ otherWidgetLayout_->addWidget(widget);
+}
+
+
+/// reimplemented functions
+
+void StatusBar::ensurePolished() {
+ QWidget::ensurePolished();
+
+ int h = 0;
+ QObjectList list = children();
+
+ //for( QObject * o = list.first(); o; o = list.next() ) {
+ foreach(QObject *o, list) {
+ if (o->inherits("QWidget")) {
+ int _h = static_cast < QWidget * > (o)->minimumSizeHint().height();
+ if (_h > h) {
+ h = _h;
+ }
+
+
+ if (o->inherits("QLabel")) {
+ static_cast < QLabel * > (o)->setIndent(4);
+ }
+ }
+ }
+
+ h -= 4; // it's too big usually
+
+ //for ( QObject * o = list.first(); o; o = list.next() )
+ foreach(QObject *o, list)static_cast < QWidget * > (o)->setFixedHeight(h);
+
+ //delete list;
+}
+
+void StatusBar::paintEvent(QPaintEvent*) {
+ QObjectList list = children(); //queryList( "QWidget", 0, false, false );
+ QPainter p(this);
+
+ //for( QObject * o = list.first(); o; o = list.next() ) {
+ foreach(QObject *o, list) {
+ if (o->inherits("QWidget")) {
+ QWidget *w = (QWidget*)o;
+
+ if (!w->isVisible()) {
+ continue;
+ }
+
+ /*style().drawPrimitive(
+ QStyle::PE_StatusBarSection,
+ &p,
+ QRect( w->x() - 1, w->y() - 1, w->width() + 2, w->height() + 2 ),
+ colorGroup(),
+ QStyle::State_None,
+ QStyleOption( w ) );*/
+ }
+ }
+
+ //delete list;
+}
+
+bool StatusBar::event(QEvent *e) {
+ if (e->type() == QEvent::LayoutRequest) {
+ update();
+ }
+
+ return QWidget::event(e);
+}
+
+
+/// Messaging system
+
+void StatusBar::setMainText(const QString &text) {
+ mainText_ = text;
+
+ // it may not be appropriate for us to set the mainText yet
+ resetMainText();
+}
+
+void StatusBar::shortMessage(const QString &text) {
+ m_mainTextLabel->setText(text);
+ m_mainTextLabel->setPalette(QToolTip::palette());
+
+ //SingleShotPool::startTimer( 5000, this, SLOT(resetMainText()) );
+ resetMainText();
+}
+
+void StatusBar::resetMainText() {
+ /*
+ if( sender() )
+ debug() << sender()->name() << endl;
+
+ // don't reset if we are showing a shortMessage
+ if( SingleShotPool::isActive( this, SLOT(resetMainText()) ) )
+ return;
+ */
+ m_mainTextLabel->setPalette(QPalette());
+
+ if (allDone()) {
+ m_mainTextLabel->setText(mainText_);
+ }
+
+ else {
+ //m_mainTextLabel->setPaletteBackgroundColor( m_mainTextLabel->paletteBackgroundColor().dark( 110 ) );
+ m_mainTextLabel->setPalette(QToolTip::palette());
+
+ ProgressBar *bar = 0;
+ uint count = 0;
+
+ for (ProgressMap::ConstIterator it = progressMap_.begin();
+ it != progressMap_.end(); ++it ) {
+ if (!(*it)->isFinished_) {
+ bar = *it;
+ count++;
+ }
+ }
+
+ if (count == 1) {
+ m_mainTextLabel->setText(bar->description() + "...");
+ } else {
+ m_mainTextLabel->setText(tr("Multiple background-tasks running"));
+ }
+ }
+}
+/*
+ void
+ StatusBar::shortLongMessage( const QString &_short, const QString &_long )
+ {
+ shortMessage( _short );
+
+ if ( !_long.isEmpty() ) {
+ AMAROK_NOTIMPLEMENTED
+ }
+ }
+*/
+//void
+//StatusBar::longMessage( const QString &text, int /*type*/ )
+/*{
+ PopupMessage * message;
+ message = new PopupMessage( this, m_mainTextLabel );
+ message->setText( text );
+
+ if ( !m_messageQueue.isEmpty() )
+ message->stackUnder( m_messageQueue.last() );
+
+ message->reposition();
+ message->display();
+
+ raise();
+
+ m_messageQueue += message;
+ }
+*/
+
+//void
+//StatusBar::longMessageThreadSafe( const QString &text, int /*type*/ )
+/*{
+ QCustomEvent * e = new QCustomEvent( 1000 );
+ e->setData( new QString( text ) );
+ QApplication::postEvent( this, e );
+ }
+*/
+// void
+// StatusBar::customEvent( QCustomEvent *e )
+// {
+// QString *s = static_cast<QString*>( e->data() );
+// shortMessage( *s );
+// delete s;
+//}
+
+
+/// application wide progress monitor
+
+inline bool StatusBar::allDone() {
+ for (ProgressMap::Iterator it = progressMap_.begin(), end =
+ progressMap_.end(); it != end; ++it)
+ if ((*it)->isFinished_ == false) {
+ return false;
+ }
+
+ return true;
+}
+
+ProgressBar &StatusBar::newProgressOperation(QObject *owner) {
+ if (progressMap_.contains(owner)) {
+ return *progressMap_[owner];
+ }
+
+ if (allDone()) {
+ // if we're allDone then we need to remove the old progressBars before
+ // we start anything new or the total progress will not be accurate
+ pruneProgressBars();
+ } else {
+ (progressBox()->findChild < QWidget * > ("showAllProgressDetails"))->show();
+ }
+
+ QWidget *hbox = new QWidget(popupProgressMessage_);
+ QHBoxLayout *hlayout = new QHBoxLayout(hbox);
+ QLabel *label = new QLabel(hbox);
+ hlayout->addWidget(label);
+ ProgressBar *pBar = new ProgressBar(hbox, label);
+ hlayout->addWidget(pBar);
+ hbox->show();
+ popupProgressMessage_->addWidget(hbox);
+ progressMap_.insert(owner, pBar);
+
+
+ FQ_VERIFY(connect(owner, SIGNAL(destroyed(QObject*)), SLOT(endProgressOperation(QObject*))));
+
+ // so we can show the correct progress information
+ // after the ProgressBar is setup
+ //SingleShotPool::startTimer( 0, this, SLOT(updateProgressAppearance()) );
+ updateProgressAppearance();
+
+ progressBox()->show();
+ cancelButton()->setEnabled(true);
+
+ return *progressMap_[owner];
+}
+/*
+ ProgressBar&
+ StatusBar::newProgressOperation( KIO::Job *job )
+ {
+ ProgressBar & bar = newProgressOperation( (QObject*)job );
+ bar.setTotalSteps( 100 );
+
+ if(!allDone())
+ static_cast<QWidget*>(progressBox()->child("showAllProgressDetails"))->show();
+ QVERIFY(connect( job, SIGNAL(result( KIO::Job* )), SLOT(endProgressOperation())));
+ //TODO QVERIFY(connect( job, SIGNAL(infoMessage( KIO::Job *job, const QString& )), SLOT() ));
+ QVERIFY(connect( job, SIGNAL(percent( KIO::Job*, unsigned long )), SLOT(setProgress( KIO::Job*, unsigned long ))));
+
+ return bar;
+ }
+*/
+/*
+ void
+ StatusBar::endProgressOperation()
+ {
+ QObject *owner = (QObject*)sender(); //HACK deconsting it
+ KIO::Job *job = dynamic_cast<KIO::Job*>( owner );
+
+ //FIXME doesn't seem to work for KIO::DeleteJob, it has it's own error handler and returns no error too
+ // if you try to delete http urls for instance <- KDE SUCKS!
+
+ if( job && job->error() )
+ longMessage( job->errorString(), Error );
+
+ endProgressOperation( owner );
+ }
+*/
+void StatusBar::endProgressOperation(QObject *owner) {
+ //the owner of this progress operation has been deleted
+ //we need to stop listening for progress from it
+ //NOTE we don't delete it yet, as this upsets some
+ //things, we just call setDone().
+
+ if (!progressMap_.contains(owner)) {
+ return ;
+ }
+
+ progressMap_[owner]->setDone();
+
+ if (allDone() && popupProgressMessage_->isHidden()) {
+ cancelButton()->setEnabled(false);
+ //SingleShotPool::startTimer( 2000, this, SLOT(hideMainProgressBar()) );
+ hideMainProgressBar();
+ }
+
+ updateTotalProgress();
+}
+
+void StatusBar::abortAllProgressOperations() { //slot
+ for (ProgressMap::Iterator it = progressMap_.begin(), end =
+ progressMap_.end(); it != end; ++it) {
+ (*it)->abortButton_->animateClick();
+ }
+
+ m_mainTextLabel->setText(tr("Aborting all jobs..."));
+
+ cancelButton()->setEnabled(false);
+}
+
+void StatusBar::toggleProgressWindow(bool show) { //slot
+ popupProgressMessage_->adjustSize();
+ //FIXME shouldn't be needed, adding bars doesn't seem to do this
+ popupProgressMessage_->setShown(show);
+
+ if (!show) {
+ hideMainProgressBar();
+ }
+ //SingleShotPool::startTimer( 2000, this, SLOT(hideMainProgressBar()) );
+}
+
+void StatusBar::showMainProgressBar() {
+ if (!allDone()) {
+ progressBox()->show();
+ }
+}
+
+void StatusBar::hideMainProgressBar() {
+ if (allDone() && popupProgressMessage_->isHidden()) {
+ pruneProgressBars();
+
+ resetMainText();
+
+ mainProgressBar_->setValue(0);
+ progressBox()->close();
+ }
+}
+
+void StatusBar::setProgress(int steps) {
+ setProgress(sender(), steps);
+}
+/*
+ void
+ StatusBar::setProgress( KIO::Job *job, unsigned long percent )
+ {
+ setProgress( ( QObject* ) job, percent );
+ }
+*/
+void StatusBar::setProgress(const QObject *owner, int steps) {
+ if (!progressMap_.contains(owner)) {
+ return ;
+ }
+
+ progressMap_[owner]->setValue(steps);
+
+ updateTotalProgress();
+}
+
+void StatusBar::setProgressStatus(const QObject *owner, const QString &text) {
+ if (!progressMap_.contains(owner)) {
+ return ;
+ }
+
+ progressMap_[owner]->setStatus(text);
+}
+
+void StatusBar::incrementProgress() {
+ incrementProgress(sender());
+}
+
+void StatusBar::incrementProgress(const QObject *owner) {
+ if (!progressMap_.contains(owner)) {
+ return ;
+ }
+
+ progressMap_[owner]->setValue(progressMap_[owner]->value() + 1);
+
+ updateTotalProgress();
+}
+
+void StatusBar::updateTotalProgress() {
+ uint totalSteps = 0;
+ uint progress = 0;
+
+ for (ProgressMap::ConstIterator it = progressMap_.begin();
+ it != progressMap_.end(); ++it ) {
+ totalSteps += (*it)->maximum();
+ progress += (*it)->value();
+ }
+
+ if (totalSteps == 0 && progress == 0) {
+ return ;
+ }
+
+ mainProgressBar_->setMaximum(totalSteps);
+ mainProgressBar_->setValue(progress);
+
+ pruneProgressBars();
+}
+
+void StatusBar::updateProgressAppearance() {
+ toggleProgressWindowButton()->setShown(progressMap_.count() > 1);
+
+ resetMainText();
+
+ updateTotalProgress();
+}
+
+void StatusBar::pruneProgressBars() {
+ ProgressMap::Iterator it = progressMap_.begin();
+ const ProgressMap::Iterator end = progressMap_.end();
+ int count = 0;
+ bool removedBar = false;
+ while (it != end)
+ if ((*it)->isFinished_ == true) {
+ delete (*it)->label_;
+ delete (*it)->abortButton_;
+ delete (*it);
+
+ ProgressMap::Iterator jt = it;
+ ++it;
+ progressMap_.erase(jt);
+ removedBar = true;
+ } else {
+ ++it;
+ ++count;
+ }
+ if (count == 1 && removedBar) { //if its gone from 2 or more bars to one bar...
+ resetMainText();
+ (progressBox()->findChild < QWidget * > ("showAllProgressDetails"))->hide();
+ popupProgressMessage_->setShown(false);
+ }
+}
+
+} //namespace FQTerm
+
+#include "statusBar.moc"
diff --git a/src/ui/statusBar.h b/src/ui/statusBar.h
new file mode 100644
index 0000000..9737f90
--- /dev/null
+++ b/src/ui/statusBar.h
@@ -0,0 +1,148 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_STATUSBAR_H
+#define FQTERM_STATUSBAR_H
+
+#include "progressBar.h" //convenience
+// #include <qwidget.h> //baseclass
+// #include <qmap.h> //stack allocated
+// #include <q3valuelist.h> //stack allocated
+//Added by qt3to4:
+// #include <QCustomEvent>
+#include <QLabel>
+#include <QEvent>
+#include <QPaintEvent>
+#include <QMap>
+#include <QList>
+#include <QWidget>
+#include <QProgressBar>
+
+class QString;
+class QLayout;
+class QLabel;
+class QString;
+
+namespace FQTerm {
+
+class PopupMessage;
+typedef QMap < const QObject *, ProgressBar * > ProgressMap;
+
+class StatusBar: public QWidget {
+ Q_OBJECT;
+ public:
+ StatusBar(QWidget *parent_, const char *name = "mainStatusBar");
+ static StatusBar *instance() {
+ return singletonStatusBar_
+ ;
+ }
+ /**
+ * Start a progress operation, if owner is 0, the return value is
+ * undefined - the application will probably crash.
+ * @param owner controls progress for this operation
+ * @return the progressBar so you can configure its parameters
+ * @see setProgress( QObject*, int )
+ * @see incrementProgress( QObject* )
+ * @see setProgressStatus( const QObject*, const QString& )
+ */
+ ProgressBar &newProgressOperation(QObject *owner);
+
+ void setProgress(const QObject *owner, int steps);
+ void incrementProgress(const QObject *owner);
+ void setProgressStatus(const QObject *owner, const QString &text);
+ public slots:
+ void setMainText(const QString &text);
+ void resetMainText();
+ void shortMessage(const QString &text);
+ /** Stop anticipating progress from sender() */
+ //void endProgressOperation();
+
+ /** Stop anticipating progress from @param owner */
+ void endProgressOperation(QObject *owner);
+
+ /**
+ * Convenience function works like setProgress( QObject*, int )
+ * Uses the return value from sender() to determine the owner of
+ * the progress bar in question
+ */
+ void setProgress(int steps);
+
+ /**
+ * Convenience function works like incrementProgress( QObject* )
+ * Uses the return value from sender() to determine the owner of
+ * the progress bar in question
+ */
+ void incrementProgress();
+
+ public slots:
+ void toggleProgressWindow(bool show);
+ void abortAllProgressOperations();
+
+ private slots:
+ /** For internal use against KIO::Jobs */
+ //void setProgress( KIO::Job*, unsigned long percent );
+ void showMainProgressBar();
+ void hideMainProgressBar();
+ void updateProgressAppearance();
+
+ protected:
+ virtual void ensurePolished();
+ // virtual void customEvent( QCustomEvent* );
+ virtual void paintEvent(QPaintEvent*);
+ virtual bool event(QEvent*);
+
+ /**
+ * You must parent the widget to the statusbar, we won't do that
+ * for you! The widget will be added to the right of the layout.
+ * Currently you must add widgets before the statusbar gets shown
+ * for the first time, because we are not currently very flexible.
+ */
+ void addWidget(QWidget *widget);
+
+ QLabel *m_mainTextLabel;
+ private:
+ void updateTotalProgress();
+ bool allDone(); ///@return true if all progress operations are complete
+ void pruneProgressBars(); /// deletes old progress bars
+
+ QWidget *cancelButton() {
+ return findChild<QWidget *>("cancelButton");
+ }
+ QWidget *toggleProgressWindowButton() {
+ return findChild<QWidget *>("showAllProgressDetails");
+ }
+ QWidget *progressBox() {
+ return findChild <QWidget *>("progressBox");
+ }
+
+ PopupMessage *popupProgressMessage_;
+ QProgressBar *mainProgressBar_;
+
+ ProgressMap progressMap_;
+ // QList<QWidget *> m_messageQueue;
+ QString mainText_;
+
+ QLayout *otherWidgetLayout_;
+ static StatusBar *singletonStatusBar_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_STATUSBAR_H
diff --git a/src/ui/zmodemdialog.cpp b/src/ui/zmodemdialog.cpp
new file mode 100644
index 0000000..629a40a
--- /dev/null
+++ b/src/ui/zmodemdialog.cpp
@@ -0,0 +1,73 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QMessageBox>
+
+#include "fqterm_trace.h"
+#include "zmodemdialog.h"
+
+namespace FQTerm {
+
+zmodemDialog::zmodemDialog(QWidget *parent_, Qt::WFlags fl)
+ : QDialog(parent_, fl) {
+ ui_.setupUi(this);
+ FQ_VERIFY(connect(ui_.buttonCancel, SIGNAL(clicked()), this, SLOT(slotCancel())));
+}
+
+zmodemDialog::~zmodemDialog(){}
+
+void zmodemDialog::setProgress(int offset) {
+ ui_.pbProgress->setValue(offset);
+ QString strTmp;
+ strTmp = QString("%1 out of %2 bytes").arg(offset).arg(ui_.pbProgress->maximum()
+ );
+ ui_.labelStatus->setText(strTmp);
+}
+
+void zmodemDialog::setFileInfo(const QString &name, int size) {
+ ui_.labelFileName->setText(name);
+ ui_.pbProgress->setMaximum(size);
+}
+
+void zmodemDialog::addErrorLog(const QString &err) {
+ // FIXME:display error message;
+ //browserError->append(err);
+}
+
+void zmodemDialog::clearErrorLog() {
+ //browserError->clear();
+}
+
+void zmodemDialog::slotCancel() {
+ QMessageBox mb("FQTerm", "We dont support cancel operation yet. "
+ "But you can try, it will crash when downloading.\n"
+ "Do you want to continue?",
+ QMessageBox::Warning, QMessageBox::Yes,
+ QMessageBox::No | QMessageBox::Escape | QMessageBox::Default,
+ 0, this);
+ if (mb.exec() == QMessageBox::Yes) {
+ emit canceled();
+ hide();
+ }
+}
+
+} // namespace FQTerm
+
+#include "zmodemdialog.moc"
diff --git a/src/ui/zmodemdialog.h b/src/ui/zmodemdialog.h
new file mode 100644
index 0000000..f310b64
--- /dev/null
+++ b/src/ui/zmodemdialog.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_ZMODEM_DIALOG_H
+#define FQTERM_ZMODEM_DIALOG_H
+
+#include "ui_zmodemdialog.h"
+
+namespace FQTerm {
+
+class zmodemDialog: public QDialog {
+ Q_OBJECT;
+ public:
+ zmodemDialog(QWidget *parent_ = 0, Qt::WFlags fl = 0);
+ ~zmodemDialog();
+
+ void setFileInfo(const QString &, int);
+ void addErrorLog(const QString &);
+ void clearErrorLog();
+ void setProgress(int);
+
+ public slots:
+ void slotCancel();
+
+ signals:
+ void canceled();
+
+ private:
+ Ui::zmodemDialog ui_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_ZMODEM_DIALOG_H
diff --git a/src/ui/zmodemdialog.ui b/src/ui/zmodemdialog.ui
new file mode 100644
index 0000000..9f2bb2b
--- /dev/null
+++ b/src/ui/zmodemdialog.ui
@@ -0,0 +1,105 @@
+<ui version="4.0" >
+ <class>zmodemDialog</class>
+ <widget class="QDialog" name="zmodemDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>333</width>
+ <height>259</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Zmodem Status</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" colspan="3" >
+ <widget class="QLabel" name="labelFileName" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Minimum" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>textLabel1</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>121</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="4" column="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>111</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="4" column="1" >
+ <widget class="QPushButton" name="buttonCancel" >
+ <property name="text" >
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="3" >
+ <widget class="QTextBrowser" name="textBrowser" />
+ </item>
+ <item row="2" column="0" colspan="3" >
+ <widget class="QLabel" name="labelStatus" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>textLabel2</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="3" >
+ <widget class="QProgressBar" name="pbProgress" >
+ <property name="value" >
+ <number>24</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/unite/CMakeLists.txt b/src/unite/CMakeLists.txt
new file mode 100644
index 0000000..b093576
--- /dev/null
+++ b/src/unite/CMakeLists.txt
@@ -0,0 +1,46 @@
+set(fqunite_SRCS
+ fqterm_mini_server.h
+ fqterm_mini_server.cpp
+)
+
+set(fqunite_internal_SRCS
+ internal/unite.h
+ internal/user.h
+ internal/user.cpp
+ internal/board.h
+ internal/board.cpp
+ internal/article.h
+ internal/article.cpp
+ internal/session.h
+ internal/session.cpp
+ internal/state.h
+ internal/state.cpp
+ internal/statebuilder.h
+ internal/statebuilder.cpp
+)
+
+qt4_automoc(
+ ${fqunite_SRCS}
+ ${fqunite_internal_SRCS}
+)
+
+include_directories(
+ ${QT_INCLUDE_DIR}
+ ${QT_QTCORE_INCLUDE_DIR}
+ ${QT_QTNETWORK_INCLUDE_DIR}
+ ${QT_QTXML_INCLUDE_DIR}
+ ${QT_QTGUI_INCLUDE_DIR}
+ ${OPENSSL_INCLUDE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/internal
+ ${CMAKE_CURRENT_SOURCE_DIR}/../common
+ ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+add_library(fqterm_unite
+ ${fqunite_SRCS}
+ ${fqunite_internal_SRCS}
+)
+
+add_dependencies(fqterm_unite
+ fqterm_common
+)
diff --git a/src/unite/fqterm_mini_server.cpp b/src/unite/fqterm_mini_server.cpp
new file mode 100644
index 0000000..2b18faf
--- /dev/null
+++ b/src/unite/fqterm_mini_server.cpp
@@ -0,0 +1,71 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+
+#include "fqterm_mini_server.h"
+#include "fqterm_trace.h"
+#include "fqterm_path.h"
+#include "fqterm.h"
+#include <QByteArray>
+#include <QTimer>
+#include <QFile>
+#include <QtGui/QApplication>
+#include <queue>
+namespace FQTerm {
+
+
+void FQTermMiniServerThread::run()
+{
+ setTerminationEnabled();
+ FQTermMiniServer miniServer;
+ //miniServer.setMaxPendingConnections(1);
+ miniServer.listen(QHostAddress::LocalHost, 35172);
+ exec();
+ miniServer.close();
+ miniServer.finalizeMiniServer();
+}
+
+FQTermMiniServer::FQTermMiniServer(QObject * parent)
+ : QTcpServer(parent) {
+}
+
+
+FQTermMiniServer::~FQTermMiniServer() {
+}
+
+void FQTermMiniServer::incomingConnection( int socketDescriptor ) {
+ FQTermUniteSession* session = new FQTermUniteSession(socketDescriptor);
+ FQ_VERIFY(connect(this, SIGNAL(quit()), session, SLOT(quit()), Qt::QueuedConnection));
+ session->start();
+}
+
+void FQTermMiniServer::finalizeMiniServer() {
+ emit quit();
+}
+
+
+
+
+
+
+
+
+} //namespace FQTerm
+
+#include "fqterm_mini_server.moc"
diff --git a/src/unite/fqterm_mini_server.h b/src/unite/fqterm_mini_server.h
new file mode 100644
index 0000000..3295137
--- /dev/null
+++ b/src/unite/fqterm_mini_server.h
@@ -0,0 +1,69 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+
+#ifndef FQTERM_MINI_SERVER_H
+#define FQTERM_MINI_SERVER_H
+
+#include <QThread>
+#include <QByteArray>
+#include <map>
+#include <vector>
+#include <algorithm>
+#include <QString>
+#include "internal/session.h"
+
+namespace FQTerm {
+
+
+class FQTermMiniServer : public QTcpServer {
+ Q_OBJECT;
+public:
+ FQTermMiniServer( QObject * parent = 0 );
+ ~FQTermMiniServer();
+ void finalizeMiniServer();
+protected:
+ void incomingConnection(int socketDescriptor);
+signals:
+ void quit();
+};
+
+
+class FQTermMiniServerThread : public QThread{
+protected:
+ virtual void run();
+
+};
+//----------------------------------------------------------------------------------
+// this for FSM
+class FQTermUniteDecode;
+
+//----------------------------------------------------------------------------------
+
+
+class FQTermUniteSession;
+class FQTermUniteState;
+
+
+
+//use XML to describe the site.
+//each session contains user info, not in the reverse way.
+//each session has 1. state (edit, read, menu), 2. strategy (decided by state) 3. context (with which strategy could decide next step. i.e. inner state)
+} //namespace FQTerm
+#endif
diff --git a/src/unite/internal/article.cpp b/src/unite/internal/article.cpp
new file mode 100644
index 0000000..c5905f8
--- /dev/null
+++ b/src/unite/internal/article.cpp
@@ -0,0 +1,19 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
diff --git a/src/unite/internal/article.h b/src/unite/internal/article.h
new file mode 100644
index 0000000..43ca0cb
--- /dev/null
+++ b/src/unite/internal/article.h
@@ -0,0 +1,28 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+
+#ifndef FQTERM_UNITE_ARTICLE
+#define FQTERM_UNITE_ARTICLE
+
+namespace FQTerm {
+
+} //namespace FQTerm
+
+#endif //FQTERM_UNITE_USER \ No newline at end of file
diff --git a/src/unite/internal/board.cpp b/src/unite/internal/board.cpp
new file mode 100644
index 0000000..c5905f8
--- /dev/null
+++ b/src/unite/internal/board.cpp
@@ -0,0 +1,19 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
diff --git a/src/unite/internal/board.h b/src/unite/internal/board.h
new file mode 100644
index 0000000..a23db18
--- /dev/null
+++ b/src/unite/internal/board.h
@@ -0,0 +1,28 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+
+#ifndef FQTERM_UNITE_BOARD
+#define FQTERM_UNITE_BOARD
+
+namespace FQTerm {
+
+} //namespace FQTerm
+
+#endif //FQTERM_UNITE_USER \ No newline at end of file
diff --git a/src/unite/internal/session.cpp b/src/unite/internal/session.cpp
new file mode 100644
index 0000000..6964287
--- /dev/null
+++ b/src/unite/internal/session.cpp
@@ -0,0 +1,138 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+
+#include "state.h"
+#include "fqterm.h"
+#include <QApplication>
+#include <algorithm>
+#include "statebuilder.h"
+namespace FQTerm{
+
+void FQTermUniteSessionContext::write(const QByteArray& str) {
+ session_->write(str);
+}
+
+FQTermUniteSessionContext::FQTermUniteSessionContext(FQTermUniteSession* session) : QObject(session), session_(session) {
+ stateTable_[WELCOME] = new FQTermWelcomeState(this);
+ stateTable_[EXITING] = new FQTermExitState(this);
+ stateTable_[READING] = new FQTermReadingState(this);
+ stateTable_[HELP] = new FQTermHelpState(this);
+ setCurrentState(WELCOME);
+}
+
+void FQTermUniteSessionContext::processInput(const QByteArray& input) {
+ inputBuffer_ += input;
+ while(true) {
+ int consumed = currentState_->processInput(inputBuffer_);
+ inputBuffer_ = inputBuffer_.mid(consumed);
+ if (!consumed || inputBuffer_.size() == 0) {
+ break;
+ }
+ }
+}
+
+void FQTermUniteSessionContext::quit() {
+ session_->quit();
+}
+
+
+
+FQTermUniteState* FQTermUniteSessionContext::setCurrentState(int state, bool init /*= true*/) {
+ StateTableIterator it = stateTable_.find(state);
+ if (it != stateTable_.end()) {
+ currentState_ = it->second;
+ if (init)
+ currentState_->initialize();
+ }
+ return currentState_;
+}
+
+
+
+FQTermUniteSession::FQTermUniteSession(int socketDescriptor ) : context_(NULL) {
+ moveToThread(this);
+ socket_ = new QTcpSocket;
+ FQ_VERIFY(connect(socket_, SIGNAL(readyRead()),
+ this, SLOT(readyRead()),Qt::DirectConnection));
+ FQ_VERIFY(connect(socket_, SIGNAL(disconnected()),
+ this, SLOT(disconnected()),Qt::DirectConnection));
+ FQ_VERIFY(connect(socket_, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
+ this, SLOT(stateChanged(QAbstractSocket::SocketState)),Qt::DirectConnection));
+ FQ_VERIFY(connect(socket_, SIGNAL(error(QAbstractSocket::SocketError)),
+ this, SLOT(error(QAbstractSocket::SocketError)),Qt::DirectConnection));
+
+ // FQ_VERIFY(connect(socket_, SIGNAL(connected()),
+ // this, SLOT(welcome()),Qt::DirectConnection));
+
+ socket_->setSocketDescriptor(socketDescriptor);
+ socket_->moveToThread(this);
+ setTerminationEnabled();
+
+ StateBuilder sb;
+ sb.BuildState();
+}
+
+
+FQTermUniteSession::~FQTermUniteSession() {
+ socket_->close();
+ delete socket_;
+ socket_ = NULL;
+}
+
+void FQTermUniteSession::welcome()
+{
+ context_ = new FQTermUniteSessionContext(this);
+}
+
+void FQTermUniteSession::readyRead() {
+ if (context_) {
+ context_->processInput(socket_->readAll());
+ }
+}
+
+void FQTermUniteSession::write( const QByteArray& output ) {
+ socket_->write(output);
+}
+
+void FQTermUniteSession::run() {
+ welcome();
+ exec();
+ disconnected();
+}
+
+
+void FQTermUniteSession::disconnected() {
+ if (!isRunning())
+ return;
+ quit();
+ moveToThread(QApplication::instance()->thread());
+ deleteLater();
+}
+
+void FQTermUniteSession::stateChanged( QAbstractSocket::SocketState socketState ) {
+}
+
+void FQTermUniteSession::error(QAbstractSocket::SocketError socketError) {
+}
+
+
+}
+
+#include "session.moc" \ No newline at end of file
diff --git a/src/unite/internal/session.h b/src/unite/internal/session.h
new file mode 100644
index 0000000..a5959a1
--- /dev/null
+++ b/src/unite/internal/session.h
@@ -0,0 +1,77 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+#ifndef FQTERM_UNITE_SESSION
+#define FQTERM_UNITE_SESSION
+
+#include <QObject>
+#include <QThread>
+#include <QTcpServer>
+#include <QTcpSocket>
+#include <map>
+namespace FQTerm {
+
+class FQTermUniteState;
+class FQTermUniteSession;
+class FQTermUniteSessionContext : public QObject {
+ Q_OBJECT;
+public:
+ FQTermUniteSessionContext(FQTermUniteSession* session);
+ void write(const QByteArray& str);
+ void processInput(const QByteArray& input);
+ void quit();
+ enum STATE{WELCOME = 0, EXITING = 1, READING = 2, HELP = 3};
+ FQTermUniteState* setCurrentState(int state, bool init = true);
+
+ int row() {return 24;}
+ int column() {return 80;}
+private:
+ FQTermUniteSession* session_;
+ FQTermUniteState* currentState_;
+ QByteArray inputBuffer_;
+ typedef std::map<int, FQTermUniteState*> StateTable;
+ typedef std::map<int, FQTermUniteState*>::iterator StateTableIterator;
+ StateTable stateTable_;
+};
+
+
+class FQTermUniteSession : public QThread {
+ Q_OBJECT;
+public:
+ FQTermUniteSession(int socketDescriptor);
+ ~FQTermUniteSession();
+ void write(const QByteArray& output);
+
+protected:
+ virtual void run();
+ protected slots:
+ void readyRead();
+ void disconnected();
+ void stateChanged(QAbstractSocket::SocketState socketState);
+ void error(QAbstractSocket::SocketError socketError);
+ void welcome();
+private:
+ QTcpSocket* socket_;
+ FQTermUniteSessionContext* context_;
+
+};
+
+} //namespace FQTerm
+
+#endif //FQTERM_UNITE_USER \ No newline at end of file
diff --git a/src/unite/internal/state.cpp b/src/unite/internal/state.cpp
new file mode 100644
index 0000000..39241b0
--- /dev/null
+++ b/src/unite/internal/state.cpp
@@ -0,0 +1,676 @@
+#include "fqterm.h"
+#include "fqterm_path.h"
+#include <algorithm>
+#include "state.h"
+#include <QDomDocument>
+
+namespace FQTerm{
+
+int FQTermUniteMenu::addEntry( char key )
+{
+ entries_.push_back(tolower(key));
+ return entries_.size() - 1;
+}
+
+int FQTermUniteMenu::findEntry( char key )
+{
+ std::vector<char>::iterator it = std::find(entries_.begin(), entries_.end(), tolower(key));
+ if (it == entries_.end()) {return -1;}
+ return std::distance(entries_.begin(), it);
+}
+
+void FQTermUniteMenu::clearEntry()
+{
+ entries_.clear();
+ clearPointer(current_);
+ current_ = 0;
+}
+
+int FQTermUniteMenu::currentEntry()
+{
+ return current_;
+}
+
+int FQTermUniteMenu::setCurrentEntry( char key )
+{
+ int next = findEntry(key);
+ if (next == -1)
+ return currentEntry();
+ clearPointer(current_);
+ current_ = next;
+ drawPointer(current_);
+ return current_;
+}
+
+int FQTermUniteMenu::setCurrentIndex( int index )
+{
+ clearPointer(current_);
+ current_ = index;
+ drawPointer(current_);
+ return current_;
+}
+
+int FQTermUniteMenu::nextEntry()
+{
+ if (!entries_.size())
+ return current_;
+ clearPointer(current_);
+ current_++;
+ current_ %= entries_.size();
+ drawPointer(current_);
+ return current_;
+}
+
+int FQTermUniteMenu::prevEntry()
+{
+ if (!entries_.size())
+ return current_;
+ clearPointer(current_);
+ current_--;
+ current_ += entries_.size();
+ current_ %= entries_.size();
+ drawPointer(current_);
+ return current_;
+}
+
+
+StateOption FQTermUniteDecode::EscStateMachine::normal_state_[] = {
+ {
+ CHAR_ESC, 0, esc_state_
+ }, {
+ CHAR_NORMAL, &FQTermUniteDecode::normalInput, normal_state_
+ }
+};
+
+// state after a ESC_CHAR
+StateOption FQTermUniteDecode::EscStateMachine::esc_state_[] = {
+ {
+ '[', &FQTermUniteDecode::clearParam, bracket_state_
+ }, {
+ CHAR_ESC, &FQTermUniteDecode::doubleEsc, normal_state_
+ },{
+ CHAR_NORMAL, 0, normal_state_
+ }
+};
+
+// state after ESC [
+StateOption FQTermUniteDecode::EscStateMachine::bracket_state_[] = {
+ {
+ '0', &FQTermUniteDecode::paramDigit, bracket_state_
+ }, {
+ '1', &FQTermUniteDecode::paramDigit, bracket_state_
+ }, {
+ '2', &FQTermUniteDecode::paramDigit, bracket_state_
+ }, {
+ '3', &FQTermUniteDecode::paramDigit, bracket_state_
+ }, {
+ '4', &FQTermUniteDecode::paramDigit, bracket_state_
+ }, {
+ '5', &FQTermUniteDecode::paramDigit, bracket_state_
+ }, {
+ '6', &FQTermUniteDecode::paramDigit, bracket_state_
+ }, {
+ '7', &FQTermUniteDecode::paramDigit, bracket_state_
+ }, {
+ '8', &FQTermUniteDecode::paramDigit, bracket_state_
+ }, {
+ '9', &FQTermUniteDecode::paramDigit, bracket_state_
+ }, {
+ 'A', &FQTermUniteDecode::cursorUp, normal_state_
+ }, {
+ 'B', &FQTermUniteDecode::cursorDown, normal_state_
+ }, {
+ 'C', &FQTermUniteDecode::cursorRight, normal_state_
+ }, {
+ 'D', &FQTermUniteDecode::cursorLeft, normal_state_
+ }, {
+ '~', &FQTermUniteDecode::functionKey, normal_state_
+ }, {
+ CHAR_NORMAL, 0, normal_state_
+ }
+};
+
+int FQTermUniteDecode::processInput(const QByteArray& input) {
+ data_ = input.data();
+ currentByte_ = 0;
+ inputLength_ = input.size();
+ /*
+ for (int i = 0; i < input.size(); ++i) {
+ bool res = keyReceived(input[i]);
+ if (!res) {
+ return i + 1;
+ }
+ }
+ */
+
+ int i;
+ StateOption *lastState;
+
+ while (currentByte_ < inputLength_) {
+ // current state always be initialized to point to the beginning of three structures
+ // ( normalState, escState, bracketState )
+ i = 0;
+ while (current_state_[i].byte != CHAR_NORMAL && current_state_[i].byte !=
+ data_[currentByte_]) {
+ i++;
+ }
+
+ lastState = current_state_ + i;
+
+ bool stopDecode;
+ if (lastState->action != 0) {
+ stopDecode = (this->*(lastState->action))();
+ }
+
+ // reinit current state
+ current_state_ = lastState->nextState;
+
+ currentByte_++;
+ if (stopDecode)
+ break;
+
+ }
+
+ return currentByte_;
+}
+
+FQTermUniteDecode::FQTermUniteDecode() {
+ current_state_ = EscStateMachine::normal_state_;
+ data_ = NULL;
+ inputLength_ = 0;
+ currentByte_ = 0;
+}
+
+bool FQTermUniteDecode::clearParam() {
+ param_ = -1;
+ return true;
+}
+
+bool FQTermUniteDecode::cursorLeft() {
+ return keyReceived(LEFT);
+}
+
+bool FQTermUniteDecode::cursorDown() {
+ return keyReceived(DOWN);
+}
+
+bool FQTermUniteDecode::cursorRight() {
+ return keyReceived(RIGHT);
+}
+
+bool FQTermUniteDecode::cursorUp() {
+ return keyReceived(UP);
+}
+
+bool FQTermUniteDecode::normalInput() {
+ return keyReceived(data_[currentByte_]);
+}
+
+bool FQTermUniteDecode::doubleEsc() {
+ return keyReceived(DOUBLEESC);
+}
+
+bool FQTermUniteDecode::paramDigit() {
+ if (param_ < 0) {
+ param_ = 0;
+ }
+ param_ = param_ * 10 + (data_[currentByte_] - '0');
+ return true;
+}
+
+bool FQTermUniteDecode::functionKey() {
+ int key;
+ switch (param_) {
+ case 1: key = HOME; break;
+ case 3: key = DELETE; break;
+ case 4: key = END; break;
+ case 5: key = PGUP; break;
+ case 6: key = PGDOWN; break;
+ case 11: key = F1; break;
+ case 12: key = F2; break;
+ case 13: key = F3; break;
+ case 14: key = F4; break;
+ case 15: key = F5; break;
+ case 17: key = F6; break;
+ case 18: key = F7; break;
+ case 19: key = F8; break;
+ case 20: key = F9; break;
+ case 21: key = F10; break;
+ case 23: key = F11; break;
+ case 24: key = F12; break;
+ default:
+ break;
+ }
+ return keyReceived(key);
+}
+
+FQTermUniteState::FQTermUniteState(FQTermUniteSessionContext* context) : context_(context) {
+
+}
+
+void FQTermUniteState::write( const QByteArray& output ) {
+ context_->write(output);
+}
+
+QByteArray FQTermUniteState::escape() {
+ return "\x1b";
+}
+
+void FQTermUniteState::moveCursorRelative(int dx, int dy) {
+ //Esc[ValueA Move cursor up n lines CUU
+ //Esc[ValueB Move cursor down n lines CUD
+ //Esc[ValueC Move cursor right n lines CUF
+ //Esc[ValueD Move cursor left n lines CUB
+ if (dy > 0) {
+ write(escape() + QString("[%1").arg(dy).toLocal8Bit() + "B");
+ }
+ if (dy < 0) {
+ write(escape() + QString("[%1").arg(-dy).toLocal8Bit() + "A");
+ }
+ if (dx > 0) {
+ write(escape() + QString("[%1").arg(dx).toLocal8Bit() + "C");
+ }
+ if (dx < 0) {
+ write(escape() + QString("[%1").arg(-dx).toLocal8Bit() + "D");
+ }
+
+}
+
+
+void FQTermUniteState::moveCursorAbsolute(int x, int y) {
+ //Esc[Line;ColumnH Move cursor to screen location v,h CUP
+ write(escape() + QString("[%1;%2H").arg(y).arg(x).toLocal8Bit());
+}
+
+void FQTermUniteState::moveCursorHome() {
+ write(escape() + "[H");
+}
+
+void FQTermUniteState::scrollWindow(int dy) {
+ //EscD Move/scroll window up one line IND
+ //EscM Move/scroll window down one line RI
+
+ if (dy > 0) {
+ for (int i = 0; i < dy; ++i)
+ write(escape() + "D");
+ }
+ if (dy < 0) {
+ dy = -dy;
+ for (int i = 0; i < dy; ++i)
+ write(escape() + "M");
+ }
+}
+
+void FQTermUniteState::moveCursorNextLine() {
+ //EscE Move to next line NEL
+ write(escape() + "E");
+
+}
+
+void FQTermUniteState::saveCursor() {
+ //Esc7 Save cursor position and attributes DECSC
+ write(escape() + "7");
+}
+
+void FQTermUniteState::restoreCursor() {
+ //Esc8 Restore cursor position and attributes DECSC
+ write(escape() + "8");
+}
+
+void FQTermUniteState::setAttr(int attr) {
+ if (attr == -1) {
+ write(escape() + "[m");
+ } else {
+ write(escape() + QString("[%1m").arg(attr).toLocal8Bit());
+ }
+}
+
+void FQTermUniteState::setForegroundColor(int color, bool highlight /*= true*/) {
+ int hl = highlight?1:0;
+ write(escape() + QString("[%1;3%2m").arg(hl).arg(color).toLocal8Bit());
+}
+
+void FQTermUniteState::setBackgroundColor(int color) {
+ write(escape() + QString("[4%1m").arg(color).toLocal8Bit());
+}
+
+void FQTermUniteState::clearLine(int part) {
+ write(escape() + QString("[%1K").arg(part).toLocal8Bit());
+}
+
+void FQTermUniteState::clearScreen(int part) {
+ write(escape() + QString("[%1J").arg(part).toLocal8Bit());
+}
+
+void FQTermUniteState::setWindowRange(int startLine, int endLine) {
+ write(escape() + QString("[%1;%2r").arg(startLine).arg(endLine).toLocal8Bit());
+}
+
+
+QByteArray FQTermUniteState::cursorStr() {
+ QChar c(0x25c6);
+ QString str(c);
+ return str.toUtf8();
+}
+FQTermWelcomeState::FQTermWelcomeState( FQTermUniteSessionContext* context ) : FQTermUniteState(context) {
+ addEntry('h');
+ addEntry('x');
+}
+
+void FQTermWelcomeState::initialize() {
+ moveCursorHome();
+ clearScreen(WHOLESCREEN);
+
+
+
+ QFile welcomeFile(getPath(RESOURCE) + "unite/welcome");
+ welcomeFile.open(QIODevice::ReadOnly);
+ QByteArray str = welcomeFile.readAll();
+ write(str);
+ setCurrentIndex(currentEntry());
+ return;
+}
+
+bool FQTermWelcomeState::keyReceived(int key) {
+ if (tolower(key) == 'j' || key == UP) {
+ prevEntry();
+ } else if (tolower(key) == 'k' || key == DOWN) {
+ nextEntry();
+ } else if (key == '\r' || key == RIGHT) {
+ enterEntry();
+ return false;
+ } else if (tolower(key) <= 'z' && tolower(key) >= 'a') {
+ setCurrentEntry(key);
+ }
+ return true;
+}
+
+void FQTermWelcomeState::enterEntry() {
+ if (currentEntry() == 1) {
+ setNextState(FQTermUniteSessionContext::EXITING);
+ } else if (currentEntry() == 0) {
+ setNextState(FQTermUniteSessionContext::HELP);
+ }
+}
+
+void FQTermWelcomeState::clearPointer(int index) {
+ moveCursorAbsolute(7, 11 + index);
+ write(" ");
+ moveCursorHome();
+}
+
+void FQTermWelcomeState::drawPointer(int index) {
+ moveCursorAbsolute(7, 11 + index);
+ write(cursorStr());
+ moveCursorHome();
+}
+
+
+
+void FQTermExitState::initialize() {
+ clearScreen(WHOLESCREEN);
+ QFile welcomeFile(getPath(RESOURCE) + "unite/exit");
+ welcomeFile.open(QIODevice::ReadOnly);
+ QByteArray str = welcomeFile.readAll();
+ write(str);
+ setCurrentIndex(0);
+}
+
+void FQTermExitState::clearPointer(int index) {
+ moveCursorAbsolute(28, 10 + index);
+ setBackgroundColor(BLUE);
+ write(" ");
+ //moveCursorHome();
+}
+
+void FQTermExitState::drawPointer( int index ) {
+ moveCursorAbsolute(28, 10 + index);
+ setBackgroundColor(BLUE);
+ write(cursorStr());
+ //moveCursorHome();
+}
+
+void FQTermExitState::enterEntry() {
+ if (currentEntry() == 1) {
+ quit();
+ } else {
+ setNextState(FQTermUniteSessionContext::WELCOME);
+ }
+}
+
+bool FQTermExitState::keyReceived( int key )
+{
+ if (tolower(key) == 'j' || key == UP) {
+ prevEntry();
+ } else if (tolower(key) == 'k' || key == DOWN) {
+ nextEntry();
+ } else if (key == '\r') {
+ enterEntry();
+ return false;
+ } else if (key >= '0' && key <= '9') {
+ setCurrentEntry(key);
+ } else if (tolower(key) == 'c') {
+ setCurrentIndex(0);
+ enterEntry();
+ return false;
+ }
+ //moveCursorHome();
+ return true;
+}
+
+FQTermExitState::FQTermExitState( FQTermUniteSessionContext* context ) : FQTermUniteState(context) {
+ addEntry('1');
+ addEntry('2');
+}
+
+SplittedArticleBuffer::SplittedArticleBuffer(const QByteArray& utf8Content, int column, int row) {
+ std::vector<QString> strList;
+ QString content = QString::fromUtf8(utf8Content);
+ lines_.reserve(row);
+ int start = 0;
+ for(;;) {
+ int newStart = findNextLine(content, start, column);
+ if (newStart == -1) {
+ lines_.push_back(content.mid(start).toUtf8());
+ break;
+ } else {
+ lines_.push_back(content.mid(start, newStart - start).toUtf8());
+ start = newStart;
+ }
+ }
+}
+
+int SplittedArticleBuffer::findNextLine(const QString& str, int start, int column) {
+ int count = 0;
+ for (int i = start; i < str.length(); ++i) {
+ if (str[i] == '\t') {
+ count += 2;
+ } else {
+ count += str[i] <= 0x7F ? 1 : 2;
+ }
+ if (count > column) {
+ return i;
+ }
+ if (str[i] == '\n') {
+ if (i + 1 < str.length())
+ return i + 1;
+ }
+ }
+ return -1;
+}
+
+void FQTermReadingState::initialize() {
+ clearScreen(WHOLESCREEN);
+ moveCursorHome();
+ drawLines(row() - 1, 1);
+ drawFooter();
+ moveCursorAbsolute(column(), row());
+}
+
+
+void FQTermReadingState::setFile(const QString& filename) {
+ currentStartLine_ = 0;
+ QFile file(filename);
+ file.open(QIODevice::ReadOnly);
+ content_ = file.readAll();
+ delete saBuffer_;
+ saBuffer_ = new SplittedArticleBuffer(content_, column(), row());
+}
+
+FQTermReadingState::FQTermReadingState( FQTermUniteSessionContext* context ) : FQTermUniteState(context) {
+ returnState_ = FQTermUniteSessionContext::WELCOME;
+ currentStartLine_ = 0;
+ saBuffer_ = 0;
+}
+
+bool FQTermReadingState::keyReceived( int key ) {
+ if (tolower(key) == 'q' || key == LEFT || !saBuffer_) {
+ setNextState(returnState_);
+ return false;
+ } else if (tolower(key) == 'k' || key == DOWN) {
+ adjustLineByDiff(1);
+ drawLines(row() - 1, 1);
+ drawFooter();
+ } else if (tolower(key) == 'j' || key == UP) {
+ adjustLineByDiff(-1);
+ drawLines(row() - 1, 1);
+ drawFooter();
+ } else if (key == PGDOWN || key == ' ' || key == RIGHT) {
+ adjustLineByDiff(row() - 2);
+ drawLines(row() - 1, 1);
+ drawFooter();
+ } else if (key == PGUP) {
+ adjustLineByDiff(-row() + 2);
+ drawLines(row() - 1, 1);
+ drawFooter();
+ } else if (key == HOME) {
+ adjustLineByDiff(-saBuffer_->count());
+ drawLines(row() - 1, 1);
+ drawFooter();
+ } else if (key == END) {
+ adjustLineByDiff(saBuffer_->count());
+ drawLines(row() - 1, 1);
+ drawFooter();
+ }
+ return true;
+}
+
+void FQTermReadingState::drawFooter() {
+ if (!saBuffer_)
+ return;
+ cursorGuard(*this);
+ moveCursorAbsolute(1, row());
+ setBackgroundColor(BLUE);
+ QByteArray footer = QString("Current Line: (%1-%2) Total: %3").arg(currentStartLine_ + 1).arg(qMin(saBuffer_->count(), currentStartLine_ + row() - 1)).arg(saBuffer_->count()).toLocal8Bit();
+ footer += QByteArray(column() - footer.size(), ' ');
+ write(footer);
+ setAttr(CLEARATTR);
+}
+
+void FQTermReadingState::adjustLineByDiff(int delta) {
+ if (!saBuffer_)
+ return;
+ currentStartLine_ += delta;
+ if (currentStartLine_ + row() - 1 >= saBuffer_->count())
+ currentStartLine_ = saBuffer_->count() - (row() - 1);
+ if (currentStartLine_ < 0)
+ currentStartLine_ = 0;
+}
+
+
+void FQTermReadingState::drawLines(int count, int yPos) {
+ if (!saBuffer_)
+ return;
+ cursorGuard cg(*this);
+ QByteArray blankLine(column(), ' ');
+ for (int i = 0; i < count; ++i) {
+ moveCursorAbsolute(1, yPos + i);
+ clearLine(WHOLELINE);
+ if (currentStartLine_ + yPos + i - 1 >= saBuffer_->count()) {
+ write(blankLine);
+ } else {
+ write(saBuffer_->retriveLine(currentStartLine_ + yPos + i - 1));
+ }
+ }
+}
+
+FQTermReadingState::~FQTermReadingState() {
+ delete saBuffer_;
+}
+
+
+
+
+
+FQTermHelpState::FQTermHelpState(FQTermUniteSessionContext* context) : FQTermUniteState(context) {
+ addEntry('s'); //0.entry for script
+ addEntry('t'); //1.entry for shortcut
+ addEntry('u'); //2.entry for unix host
+ addEntry('x'); //3.entry for quit to welcome
+}
+
+void FQTermHelpState::initialize() {
+ moveCursorHome();
+ clearScreen(WHOLESCREEN);
+ QFile welcomeFile(getPath(RESOURCE) + "unite/help");
+ welcomeFile.open(QIODevice::ReadOnly);
+ QByteArray str = welcomeFile.readAll();
+ write(str);
+ setCurrentIndex(currentEntry());
+ return;
+}
+
+bool FQTermHelpState::keyReceived(int key) {
+ if (tolower(key) == 'j' || key == UP) {
+ prevEntry();
+ } else if (tolower(key) == 'k' || key == DOWN) {
+ nextEntry();
+ } else if (key == '\r' || key == RIGHT) {
+ enterEntry();
+ return false;
+ } else if (tolower(key) <= 'z' && tolower(key) >= 'a') {
+ setCurrentEntry(key);
+ }
+ return true;
+}
+
+void FQTermHelpState::enterEntry() {
+ if (currentEntry() == 3) {
+ setNextState(FQTermUniteSessionContext::WELCOME);
+ return;
+ }
+
+ QString doc;
+ switch(currentEntry())
+ {
+ case 0:
+ doc = "script-doc";
+ break;
+ case 1:
+ doc = "shortcut-doc";
+ break;
+ case 2:
+ doc = "ssh-unix-doc";
+ break;
+ }
+ FQTermUniteState* reader = setNextState(FQTermUniteSessionContext::READING, false);
+ ((FQTermReadingState*)reader)->setFile(getPath(RESOURCE) + "unite/" + doc);
+ ((FQTermReadingState*)reader)->setReturnState(FQTermUniteSessionContext::HELP);
+ reader->initialize();
+}
+
+void FQTermHelpState::clearPointer(int index) {
+ moveCursorAbsolute(7, 11 + index);
+ write(" ");
+ moveCursorHome();
+}
+
+void FQTermHelpState::drawPointer(int index) {
+ moveCursorAbsolute(7, 11 + index);
+ write(cursorStr());
+ moveCursorHome();
+}
+
+} // namespace FQTerm
+
+#include "state.moc" \ No newline at end of file
diff --git a/src/unite/internal/state.h b/src/unite/internal/state.h
new file mode 100644
index 0000000..e294372
--- /dev/null
+++ b/src/unite/internal/state.h
@@ -0,0 +1,219 @@
+#ifndef FQTERM_UNITE_STATE
+#define FQTERM_UNITE_STATE
+
+#include <QByteArray>
+#include "session.h"
+
+namespace FQTerm {
+class FQTermUniteDecode;
+typedef bool (FQTermUniteDecode:: *StateFunc)();
+
+struct StateOption {
+ int byte; // char value to look for; -1==end/default
+ StateFunc action;
+ StateOption *nextState;
+};
+
+
+
+class FQTermUniteDecode {
+public:
+ FQTermUniteDecode();
+ virtual ~FQTermUniteDecode() {}
+ //should return number of chars consumed
+ virtual int processInput(const QByteArray& input);
+protected:
+ virtual bool keyReceived(int key) = 0;
+ //tab = 7, backspace = 8, delete is *[3~, page up is 5~, page down is 6~, home is 1~, end is 4~, double esc is double esc,
+ //up is A, down is B, left is D, right is C.
+ //F1 - F12 11~ 12~ 13~ 14~ 15~ 17~ 18~ 19~ 20~ 21~ 23~ 24~
+ //static char* specialKeys[];
+ enum SPECIALKEY{SPECIALKEYSTART = 0x10000, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
+ UP, DOWN, LEFT, RIGHT, DOUBLEESC, INSERT, HOME, END, PGUP, PGDOWN, DELETE};
+
+ // Virtual Keys: move cursor
+ bool cursorLeft();
+ bool cursorDown();
+ bool cursorRight();
+ bool cursorUp();
+
+ // other escape sequence actions
+ bool normalInput();
+
+ //double esc pressed
+ bool doubleEsc();
+
+ // action parameters
+ bool clearParam();
+ bool paramDigit();
+ //function key map
+ bool functionKey();
+private:
+ // ********** decoder states ****************
+ StateOption *current_state_;
+ int param_; //valid when > 0.
+ const char* data_;
+ int inputLength_;
+ int currentByte_;
+ QByteArray leftToDecode_;
+ struct EscStateMachine {
+ static StateOption normal_state_[], esc_state_[], bracket_state_[];
+ };
+};
+
+class FQTermUniteState : public QObject,
+ public FQTermUniteDecode {
+ Q_OBJECT;
+public:
+ FQTermUniteState(FQTermUniteSessionContext* context);
+ virtual ~FQTermUniteState() {}
+ virtual void initialize() = 0;
+
+
+protected:
+ //util functions
+ //cursor manipulations
+ void moveCursorRelative(int dx, int dy);
+ void moveCursorAbsolute(int x, int y);
+ void moveCursorHome();
+ //To scroll up, dy < 0, scroll down, dy > 0.
+ void scrollWindow(int dy);
+ void moveCursorNextLine();
+ void saveCursor();
+ void restoreCursor();
+
+ //attr control
+ enum CHARATTR{DEFAULTATTR = -1, CLEARATTR = 0, BOLD = 1, LOWINTENSITY = 2, UNDERLINE = 4, BLINK = 5, REVERSECOLOR = 7, INVISIBLE = 8};
+ void setAttr(int attr);
+ enum CHARCOLOR{BLACK = 0, RED = 1, GREEN = 2, YELLOW = 3, BLUE = 4, PURPLE = 5, INDIGO = 6, WHITE = 7};
+ void setForegroundColor(int color, bool highlight = true);
+ void setBackgroundColor(int color);
+
+ //clear lines/screen
+ enum CLEARLINE{CURSORRIGHT = 0, CURSORLEFT = 1, WHOLELINE = 2};
+ void clearLine(int part);
+ enum CLEARSCREEN{CURSORDOWN = 0, CURSORUP = 1, WHOLESCREEN = 2};
+ void clearScreen(int part);
+
+ //window setting
+ void setWindowRange(int startLine, int endLine);
+
+ QByteArray escape();
+ QByteArray cursorStr();
+ void write(const QByteArray& output);
+ void quit() {context_->quit();}
+ FQTermUniteState* setNextState(int state, bool init = true) {return context_->setCurrentState(state, init);}
+ int row() {return context_->row();}
+ int column() {return context_->column();}
+
+
+ friend struct cursorGuard;
+ struct cursorGuard {
+ cursorGuard(FQTermUniteState& state) : state_(state) {state_.saveCursor();}
+ ~cursorGuard() {state_.restoreCursor();}
+ private:
+ FQTermUniteState& state_;
+ };
+private:
+ FQTermUniteSessionContext* context_;
+ int lastState_;
+};
+
+class FQTermUniteMenu {
+public:
+ FQTermUniteMenu() {current_ = 0;}
+ virtual ~FQTermUniteMenu() {}
+protected:
+ int addEntry(char key);
+ int findEntry(char key);
+ void clearEntry();
+ int currentEntry();
+ int setCurrentEntry(char key);
+ int setCurrentIndex(int index);
+
+ int nextEntry();
+ int prevEntry();
+ virtual void clearPointer(int index) = 0;
+ virtual void drawPointer(int index) = 0;
+ virtual void enterEntry() = 0;
+private:
+ std::vector<char> entries_;
+ int current_;
+};
+
+
+class FQTermWelcomeState : public FQTermUniteState, public FQTermUniteMenu {
+ Q_OBJECT;
+public:
+ FQTermWelcomeState(FQTermUniteSessionContext* context);
+ virtual void initialize();
+protected:
+ virtual bool keyReceived(int key);
+private:
+ virtual void clearPointer(int index);
+ virtual void drawPointer(int index);
+ virtual void enterEntry();
+};
+
+class FQTermExitState : public FQTermUniteState, public FQTermUniteMenu {
+ Q_OBJECT;
+public:
+ FQTermExitState(FQTermUniteSessionContext* context);
+ virtual void initialize();
+protected:
+ virtual bool keyReceived(int key);
+private:
+ virtual void clearPointer(int index);
+ virtual void drawPointer(int index);
+ void enterEntry();
+};
+
+class SplittedArticleBuffer {
+public:
+ SplittedArticleBuffer(const QByteArray& utf8Content, int column, int row = 24);
+ ~SplittedArticleBuffer() {}
+ int count() {return lines_.size();}
+ QByteArray& retriveLine(size_t index) {return lines_[index];}
+private:
+ static int findNextLine(const QString& str, int start, int column);
+ std::vector<QByteArray> lines_;
+};
+
+//TODO: content should be shared.
+//TODO: buffer should be opt-ed.
+class FQTermReadingState : public FQTermUniteState {
+ Q_OBJECT;
+public:
+ FQTermReadingState(FQTermUniteSessionContext* context);
+ ~FQTermReadingState();
+ virtual void initialize();
+ void setFile(const QString& filename);
+ void setReturnState(int state) {returnState_ = state;}
+protected:
+ virtual bool keyReceived(int key);
+private:
+ void drawLines(int count, int yPos);
+ void drawFooter();
+ void adjustLineByDiff(int delta);
+ SplittedArticleBuffer* saBuffer_;
+ QByteArray content_;
+ int currentStartLine_;
+ int returnState_;
+};
+
+
+class FQTermHelpState : public FQTermUniteState, public FQTermUniteMenu {
+ Q_OBJECT;
+public:
+ FQTermHelpState(FQTermUniteSessionContext* context);
+ virtual void initialize();
+protected:
+ virtual bool keyReceived(int key);
+private:
+ virtual void clearPointer(int index);
+ virtual void drawPointer(int index);
+ virtual void enterEntry();
+};
+
+} // namespace FQTerm
+#endif \ No newline at end of file
diff --git a/src/unite/internal/statebuilder.cpp b/src/unite/internal/statebuilder.cpp
new file mode 100644
index 0000000..48ea6f6
--- /dev/null
+++ b/src/unite/internal/statebuilder.cpp
@@ -0,0 +1,32 @@
+
+#include "statebuilder.h"
+#include "fqterm.h"
+#include "fqterm_path.h"
+
+#include <QDomDocument>
+#include <QFile>
+
+namespace FQTerm {
+
+void StateBuilder::BuildState()
+{
+ QDomDocument domDocument;
+ QFile welcome(getPath(RESOURCE) + "unite/welcom.xml");
+ welcome.open(QIODevice::ReadOnly);
+ QString errorStr;
+ int errorLine;
+ int errorColumn;
+ domDocument.setContent(welcome.readAll(), true, &errorStr, &errorLine, &errorColumn);
+ QDomElement root = domDocument.firstChildElement("page");
+ if (root.isNull())
+ {
+
+ }
+ QDomAttr a = root.attributeNode("type");
+ //cout << a.value() << endl;
+
+
+}
+
+
+} \ No newline at end of file
diff --git a/src/unite/internal/statebuilder.h b/src/unite/internal/statebuilder.h
new file mode 100644
index 0000000..f323ecd
--- /dev/null
+++ b/src/unite/internal/statebuilder.h
@@ -0,0 +1,16 @@
+
+#ifndef FQTERM_UNITE_STATEBUILDER
+#define FQTERM_UNITE_STATEBUILDER
+
+namespace FQTerm {
+
+class FQTermState;
+
+class StateBuilder
+{
+public:
+ void BuildState();
+};
+
+}
+#endif \ No newline at end of file
diff --git a/src/unite/internal/unite.h b/src/unite/internal/unite.h
new file mode 100644
index 0000000..cc614a7
--- /dev/null
+++ b/src/unite/internal/unite.h
@@ -0,0 +1,35 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+
+#ifndef FQTERM_UNITE_USER
+#define FQTERM_UNITE_USER
+
+namespace FQTerm {
+//to make it more clear, a general method to serialize c++
+//classes is needed.
+class FQUUser {
+public:
+private:
+
+};
+
+} //namespace FQTerm
+
+#endif //FQTERM_UNITE_USER \ No newline at end of file
diff --git a/src/unite/internal/user.cpp b/src/unite/internal/user.cpp
new file mode 100644
index 0000000..c5905f8
--- /dev/null
+++ b/src/unite/internal/user.cpp
@@ -0,0 +1,19 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
diff --git a/src/unite/internal/user.h b/src/unite/internal/user.h
new file mode 100644
index 0000000..cc614a7
--- /dev/null
+++ b/src/unite/internal/user.h
@@ -0,0 +1,35 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+
+#ifndef FQTERM_UNITE_USER
+#define FQTERM_UNITE_USER
+
+namespace FQTerm {
+//to make it more clear, a general method to serialize c++
+//classes is needed.
+class FQUUser {
+public:
+private:
+
+};
+
+} //namespace FQTerm
+
+#endif //FQTERM_UNITE_USER \ No newline at end of file
diff --git a/src/utilities/CMakeLists.txt b/src/utilities/CMakeLists.txt
new file mode 100644
index 0000000..af3c169
--- /dev/null
+++ b/src/utilities/CMakeLists.txt
@@ -0,0 +1,33 @@
+set(fqterm_utilities_SRCS
+ fqterm_convert.h
+ fqterm_http.h
+ fqterm_ip_location.h
+ fqterm_convert.cpp
+ fqterm_http.cpp
+ fqterm_ip_location.cpp
+)
+
+set(fq_SRCS
+ fqwcwidth.h
+ fqwcwidth.cpp
+)
+
+qt4_automoc(${fqterm_utilities_SRCS})
+
+include_directories(
+ ${QT_INCLUDE_DIR}
+ ${QT_QTCORE_INCLUDE_DIR}
+ ${QT_QTGUI_INCLUDE_DIR}
+ ${QT_QTNETWORK_INCLUDE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../common
+ ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+add_library(fqterm_utilities
+ ${fqterm_utilities_SRCS}
+ ${fq_SRCS}
+)
+
+add_dependencies(fqterm_utilities
+ fqterm_common
+)
diff --git a/src/utilities/fqterm_convert.cpp b/src/utilities/fqterm_convert.cpp
new file mode 100644
index 0000000..3ac821d
--- /dev/null
+++ b/src/utilities/fqterm_convert.cpp
@@ -0,0 +1,3485 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_convert.h"
+
+namespace FQTerm {
+
+const char BtoG_bad1 = '\xa1';
+const char BtoG_bad2 = '\xf5';
+const char GtoB_bad1 = '\xa1';
+const char GtoB_bad2 = '\xbc';
+
+#define HIGHBYTE(word) (word)>>8 & 0x00ff
+#define LOWBYTE(word) (word) & 0x00ff
+#define MAKEWORD(c1,c2) ( (c1)<<8 & 0xff00 ) | c2
+FQTermConvert::FQTermConvert(){}
+
+FQTermConvert::~FQTermConvert(){}
+
+char *FQTermConvert::G2B(const char *string, int length) {
+ static char save = '\0';
+ if (length == 0) {
+ return 0;
+ }
+ char *s = new char[length + 2]; //because we may have the save char
+ int len = length;
+ const char *p = string;
+ int n = 0;
+
+ if (save != '\0') {
+ g2b(save, *p, s);
+ n = 2;
+ p++;
+ save = '\0';
+ len++;
+ }
+
+ while (p < string + length && *p != '\0') {
+ if (*p &0x80) {
+ // reach the end this is half of a word, save it
+ if (p == string + length - 1) {
+ save = *p;
+ len--;
+ break;
+ }
+
+ g2b(*p, *(p + 1), s + n);
+ n += 2;
+ p += 2;
+ } else {
+ s[n] = *p;
+ p++;
+ n++;
+ }
+ }
+
+ s[len] = '\0';
+ return s;
+}
+
+void FQTermConvert::g2b(unsigned char c1, unsigned char c2, char *s) {
+ unsigned int i;
+ if ((c2 >= 0xa1) && (c2 <= 0xfe)) {
+ if ((c1 >= 0xa1) && (c1 <= 0xa9)) {
+ i = ((c1 - 0xa1) *94+(c2 - 0xa1)) *2;
+ s[0] = GtoB[i++];
+ s[1] = GtoB[i];
+ return ;
+ } else if ((c1 >= 0xb0) && (c1 <= 0xf7)) {
+ i = ((c1 - 0xb0 + 9) *94+(c2 - 0xa1)) *2;
+ s[0] = GtoB[i++];
+ s[1] = GtoB[i];
+ return ;
+ }
+ }
+ s[0] = GtoB_bad1;
+ s[1] = GtoB_bad2;
+}
+
+char *FQTermConvert::B2G(const char *string, int length) {
+ static char save = '\0';
+ if (length == 0) {
+ return 0;
+ }
+ char *s = new char[length + 2]; //because we may have the save char
+ int len = length;
+ const char *p = string;
+ int n = 0;
+
+ if (save != '\0') {
+ b2g(save, *p, s);
+ n = 2;
+ p++;
+ save = '\0';
+ len++;
+ }
+
+ while (p < string + length && *p != '\0') {
+ if (*p &0x80) {
+ // reach the end this is half of a word, save it
+ if (p == string + length - 1) {
+ save = *p;
+ len--;
+ break;
+ }
+
+ b2g(*p, *(p + 1), s + n);
+ p += 2;
+ n += 2;
+ } else {
+ s[n] = *p;
+ p++;
+ n++;
+ }
+ }
+
+ s[len] = '\0';
+ return s;
+}
+
+void FQTermConvert::b2g(unsigned char c1, unsigned char c2, char *s) {
+ unsigned int i;
+ if ((c1 >= 0xa1) && (c1 <= 0xf9)) {
+ if ((c2 >= 0x40) && (c2 <= 0x7e)) {
+ i = ((c1 - 0xa1) *157+(c2 - 0x40)) *2;
+ s[0] = BtoG[i++];
+ s[1] = BtoG[i];
+ return ;
+ } else if ((c2 >= 0xa1) && (c2 <= 0xfe)) {
+ i = ((c1 - 0xa1) *157+(c2 - 0xa1) + 63) *2;
+ s[0] = BtoG[i++];
+ s[1] = BtoG[i];
+ return ;
+ }
+ }
+ s[0] = BtoG_bad1;
+ s[1] = BtoG_bad2;
+}
+
+unsigned char FQTermConvert::GtoB[] = {
+ 0xa1, 0x40, 0xa1, 0x42, 0xa1, 0x43, 0xa1, 0x4f, 0xa1, 0xc2, 0xa1, 0xbc, 0xa1,
+ 0x4c, 0xa1, 0xb2, 0xa1, 0xbc, 0xa2, 0x77, 0xa1, 0xe3, 0xa1, 0xfc, 0xa1, 0x4b,
+ 0xa1, 0xa5, 0xa1, 0xa6, 0xa1, 0xa7, 0xa1, 0xa8, 0xa1, 0x65, 0xa1, 0x66, 0xa1,
+ 0x71, 0xa1, 0x72, 0xa1, 0x6d, 0xa1, 0x6e, 0xa1, 0x75, 0xa1, 0x76, 0xa1, 0x79,
+ 0xa1, 0x7a, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0x69, 0xa1, 0x6a, 0xa1, 0xd3, 0xa1,
+ 0xd1, 0xa1, 0xd2, 0xa1, 0x4a, 0xa3, 0x4e, 0xa1, 0xbc, 0xa3, 0x55, 0xa3, 0x53,
+ 0xa1, 0xe5, 0xa1, 0xe4, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xd4, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xe7, 0xa1, 0xbc, 0xa1, 0xf3, 0xa1, 0xec, 0xa1, 0xed, 0xa1, 0xdd,
+ 0xa1, 0xbc, 0xa1, 0xdc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xda, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xd8, 0xa1, 0xd9, 0xa1, 0xdb, 0xa1, 0xee, 0xa1, 0xef, 0xa1, 0xf1,
+ 0xa1, 0xf0, 0xa2, 0x58, 0xa1, 0xac, 0xa1, 0xaa, 0xa2, 0x4a, 0xa2, 0x43, 0xa1,
+ 0xbc, 0xa2, 0x46, 0xa2, 0x47, 0xa1, 0xbc, 0xa1, 0xb1, 0xa1, 0xbc, 0xa1, 0xb8,
+ 0xa1, 0xb9, 0xa1, 0xb3, 0xa1, 0xb4, 0xa1, 0xb7, 0xa1, 0xba, 0xa1, 0xbb, 0xa1,
+ 0xbc, 0xa1, 0xbd, 0xa1, 0xb5, 0xa1, 0xb6, 0xa1, 0xb0, 0xa1, 0xf7, 0xa1, 0xf6,
+ 0xa1, 0xf4, 0xa1, 0xf5, 0xa2, 0xa4, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa2, 0xb9, 0xa2,
+ 0xba, 0xa2, 0xbb, 0xa2, 0xbc, 0xa2, 0xbd, 0xa2, 0xbe, 0xa2, 0xbf, 0xa2, 0xc0,
+ 0xa2, 0xc1, 0xa2, 0xc2, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0x49, 0xa1, 0xa9, 0xa1, 0xad, 0xa2, 0x43, 0xa2, 0x48, 0xa1, 0xae, 0xa1, 0xac,
+ 0xa1, 0x5d, 0xa1, 0x5e, 0xa1, 0xaf, 0xa1, 0xcf, 0xa1, 0x41, 0xa1, 0xd0, 0xa1,
+ 0x44, 0xa1, 0xfe, 0xa2, 0xaf, 0xa2, 0xb0, 0xa2, 0xb1, 0xa2, 0xb2, 0xa2, 0xb3,
+ 0xa2, 0xb4, 0xa2, 0xb5, 0xa2, 0xb6, 0xa2, 0xb7, 0xa2, 0xb8, 0xa1, 0x47, 0xa1,
+ 0x46, 0xa1, 0xd5, 0xa1, 0xd7, 0xa1, 0xd6, 0xa1, 0x48, 0xa2, 0x49, 0xa2, 0xcf,
+ 0xa2, 0xd0, 0xa2, 0xd1, 0xa2, 0xd2, 0xa2, 0xd3, 0xa2, 0xd4, 0xa2, 0xd5, 0xa2,
+ 0xd6, 0xa2, 0xd7, 0xa2, 0xd8, 0xa2, 0xd9, 0xa2, 0xda, 0xa2, 0xdb, 0xa2, 0xdc,
+ 0xa2, 0xdd, 0xa2, 0xde, 0xa2, 0xdf, 0xa2, 0xe0, 0xa2, 0xe1, 0xa2, 0xe2, 0xa2,
+ 0xe3, 0xa2, 0xe4, 0xa2, 0xe5, 0xa2, 0xe6, 0xa2, 0xe7, 0xa2, 0xe8, 0xa1, 0xa3,
+ 0xa2, 0x40, 0xa1, 0xa4, 0xa1, 0x73, 0xa1, 0x5a, 0xa1, 0xab, 0xa2, 0xe9, 0xa2,
+ 0xea, 0xa2, 0xeb, 0xa2, 0xec, 0xa2, 0xed, 0xa2, 0xee, 0xa2, 0xef, 0xa2, 0xf0,
+ 0xa2, 0xf1, 0xa2, 0xf2, 0xa2, 0xf3, 0xa2, 0xf4, 0xa2, 0xf5, 0xa2, 0xf6, 0xa2,
+ 0xf7, 0xa2, 0xf8, 0xa2, 0xf9, 0xa2, 0xfa, 0xa2, 0xfb, 0xa2, 0xfc, 0xa2, 0xfd,
+ 0xa2, 0xfe, 0xa3, 0x40, 0xa3, 0x41, 0xa3, 0x42, 0xa3, 0x43, 0xa1, 0x61, 0xa1,
+ 0x55, 0xa1, 0x62, 0xa1, 0xc2, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa3, 0x44, 0xa3, 0x45, 0xa3, 0x46, 0xa3, 0x47, 0xa3,
+ 0x48, 0xa3, 0x49, 0xa3, 0x4a, 0xa3, 0x4b, 0xa3, 0x4c, 0xa3, 0x4d, 0xa3, 0x4e,
+ 0xa3, 0x4f, 0xa3, 0x50, 0xa3, 0x51, 0xa3, 0x52, 0xa3, 0x53, 0xa3, 0x54, 0xa3,
+ 0x55, 0xa3, 0x56, 0xa3, 0x57, 0xa3, 0x58, 0xa3, 0x59, 0xa3, 0x5a, 0xa3, 0x5b,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa3, 0x5c, 0xa3, 0x5d, 0xa3, 0x5e, 0xa3, 0x5f, 0xa3, 0x60,
+ 0xa3, 0x61, 0xa3, 0x62, 0xa3, 0x63, 0xa3, 0x64, 0xa3, 0x65, 0xa3, 0x66, 0xa3,
+ 0x67, 0xa3, 0x68, 0xa3, 0x69, 0xa3, 0x6a, 0xa3, 0x6b, 0xa3, 0x6c, 0xa3, 0x6d,
+ 0xa3, 0x6e, 0xa3, 0x6f, 0xa3, 0x70, 0xa3, 0x71, 0xa3, 0x72, 0xa3, 0x73, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa3, 0x74, 0xa3,
+ 0x75, 0xa3, 0x76, 0xa3, 0x77, 0xa3, 0x78, 0xa3, 0x79, 0xa3, 0x7a, 0xa3, 0x7b,
+ 0xa3, 0x7c, 0xa3, 0x7d, 0xa3, 0x7e, 0xa3, 0xa1, 0xa3, 0xa2, 0xa3, 0xa3, 0xa3,
+ 0xa4, 0xa3, 0xa5, 0xa3, 0xa6, 0xa3, 0xa7, 0xa3, 0xa8, 0xa3, 0xa9, 0xa3, 0xaa,
+ 0xa3, 0xab, 0xa3, 0xac, 0xa3, 0xad, 0xa3, 0xae, 0xa3, 0xaf, 0xa3, 0xb0, 0xa3,
+ 0xb1, 0xa3, 0xb2, 0xa3, 0xb3, 0xa3, 0xb4, 0xa3, 0xb5, 0xa3, 0xb6, 0xa3, 0xb7,
+ 0xa3, 0xb8, 0xa3, 0xb9, 0xa3, 0xba, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa2, 0x77, 0xa1, 0xbc, 0xa2, 0x78, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa2, 0x7a, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa2, 0x7b, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa2, 0x7c, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa2, 0x7d,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa2, 0x75, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa2, 0x74, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa2,
+ 0x73, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa2, 0x72, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa2, 0x71, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xb0, 0xda, 0xaa, 0xfc, 0xae, 0x4a, 0xae, 0xc1, 0xab, 0x75, 0xad,
+ 0xfc, 0xab, 0x73, 0xbd, 0x4a, 0xc0, 0xf9, 0xc4, 0xa7, 0xb8, 0x47, 0xa6, 0xe3,
+ 0xc3, 0xaa, 0xb7, 0x52, 0xb9, 0x69, 0xbe, 0x62, 0xae, 0xf2, 0xa6, 0x77, 0xad,
+ 0xcd, 0xab, 0xf6, 0xb7, 0x74, 0xa9, 0xa4, 0xd3, 0x69, 0xae, 0xd7, 0xbb, 0xea,
+ 0xa9, 0xf9, 0xaf, 0x73, 0xa5, 0x57, 0xb1, 0xce, 0xbc, 0xf5, 0xbf, 0xac, 0xc3,
+ 0xcd, 0xb6, 0xc6, 0xb6, 0xf8, 0xbe, 0xd2, 0xbf, 0x44, 0xaa, 0xdd, 0xae, 0xc3,
+ 0xa5, 0xb6, 0xa5, 0x7a, 0xa7, 0x61, 0xaf, 0xb9, 0xa4, 0x4b, 0xac, 0xcd, 0xa4,
+ 0xda, 0xa9, 0xde, 0xb6, 0x5b, 0xb9, 0x76, 0xa7, 0xe2, 0xaf, 0xd2, 0xc5, 0xf2,
+ 0xc5, 0x51, 0xbd, 0x7d, 0xaa, 0xa8, 0xa5, 0xd5, 0xac, 0x66, 0xa6, 0xca, 0xc2,
+ 0x5c, 0xa8, 0xd5, 0xb1, 0xd1, 0xab, 0xf4, 0xde, 0xfb, 0xb4, 0xb3, 0xaf, 0x5a,
+ 0xb7, 0x68, 0xa7, 0xe6, 0xaf, 0xeb, 0xb9, 0x7b, 0xaa, 0x4f, 0xaa, 0xa9, 0xa7,
+ 0xea, 0xa9, 0xd5, 0xa6, 0xf1, 0xc3, 0xa4, 0xa5, 0x62, 0xbf, 0xec, 0xb2, 0xcc,
+ 0xa8, 0xb9, 0xc0, 0xb0, 0xb1, 0xf5, 0xba, 0x5d, 0xbb, 0x48, 0xb8, 0x6a, 0xb4,
+ 0xce, 0xbd, 0x53, 0xb0, 0x46, 0xc2, 0xe9, 0xb3, 0xc4, 0xc1, 0xbd, 0xad, 0x63,
+ 0xad, 0x4d, 0xa5, 0x5d, 0xbd, 0xc7, 0xad, 0xe9, 0xc1, 0xa1, 0xb9, 0x72, 0xab,
+ 0x4f, 0xb3, 0xf9, 0xb9, 0xa1, 0xc4, 0x5f, 0xa9, 0xea, 0xb3, 0xf8, 0xbc, 0xc9,
+ 0xb0, 0x5c, 0xc0, 0x6a, 0xc3, 0x7a, 0xaa, 0x4d, 0xb8, 0x4f, 0xb4, 0x64, 0xa8,
+ 0xf5, 0xa5, 0x5f, 0xbd, 0xfa, 0xad, 0x49, 0xa8, 0xa9, 0xbe, 0x58, 0xad, 0xbf,
+ 0xaf, 0x56, 0xb3, 0xc6, 0xbe, 0xce, 0xb5, 0x48, 0xb3, 0x51, 0xa9, 0x62, 0xad,
+ 0x66, 0xa5, 0xbb, 0xb2, 0xc2, 0xb1, 0x59, 0xc1, 0x5e, 0xac, 0xc7, 0xac, 0xa6,
+ 0xc2, 0xdb, 0xb0, 0x6e, 0xb9, 0x47, 0xbb, 0xf3, 0xa4, 0xf1, 0xbb, 0xc0, 0xb5,
+ 0xa7, 0xa9, 0xbc, 0xba, 0xd1, 0xe3, 0xc9, 0xbd, 0xaa, 0xb2, 0xa6, 0xc0, 0xc5,
+ 0xcf, 0x68, 0xb9, 0xf4, 0xa7, 0xc8, 0xde, 0xcd, 0xb3, 0xac, 0xb1, 0xcd, 0xb9,
+ 0xfa, 0xa5, 0xb2, 0xb9, 0x40, 0xbe, 0xc0, 0xc1, 0x75, 0xc1, 0xd7, 0xb0, 0xa1,
+ 0xc3, 0x40, 0xc3, 0xe4, 0xbd, 0x73, 0xb6, 0x53, 0xab, 0xf3, 0xab, 0x4b, 0xc5,
+ 0xdc, 0xa4, 0xcb, 0xbf, 0xeb, 0xc5, 0x47, 0xc4, 0x7c, 0xb9, 0x4d, 0xbc, 0xd0,
+ 0xb3, 0x43, 0xbd, 0xa8, 0xaa, 0xed, 0xc5, 0xbe, 0xe5, 0x78, 0xa7, 0x4f, 0xc3,
+ 0xa7, 0xb1, 0x6c, 0xd9, 0x79, 0xc3, 0x78, 0xc0, 0xd8, 0xbb, 0xab, 0xec, 0xe8,
+ 0xa7, 0x4c, 0xa6, 0x42, 0xac, 0x60, 0xa4, 0xfe, 0xaa, 0xc3, 0xbb, 0xe6, 0xac,
+ 0xb1, 0xaf, 0x66, 0xa8, 0xc3, 0xac, 0xc1, 0xb5, 0xd4, 0xbc, 0xbd, 0xbc, 0xb7,
+ 0xd2, 0xdc, 0xaa, 0x69, 0xb3, 0xd5, 0xab, 0x6b, 0xb7, 0x69, 0xb9, 0x60, 0xba,
+ 0xe4, 0xa7, 0x42, 0xa9, 0xad, 0xb2, 0xed, 0xb2, 0xe4, 0xbb, 0x4b, 0xb4, 0xf1,
+ 0xaa, 0x79, 0xbb, 0xe9, 0xae, 0xb7, 0xa4, 0x52, 0xad, 0xf7, 0xb8, 0xc9, 0xb0,
+ 0xf0, 0xa4, 0xa3, 0xa5, 0xac, 0xa8, 0x42, 0xc3, 0xaf, 0xb3, 0xa1, 0xa9, 0xc6,
+ 0xc0, 0xbf, 0xb2, 0x71, 0xb5, 0xf4, 0xa7, 0xf7, 0xa4, 0x7e, 0xb0, 0x5d, 0xb8,
+ 0x42, 0xbd, 0xf2, 0xb1, 0xc4, 0xb1, 0x6d, 0xb5, 0xe6, 0xbd, 0xb2, 0xc0, 0x5c,
+ 0xb0, 0xd1, 0xc5, 0xfa, 0xb4, 0xdd, 0xba, 0x46, 0xba, 0x47, 0xc0, 0xe9, 0xbb,
+ 0x61, 0xbf, 0xb5, 0xad, 0xdc, 0xb7, 0xc9, 0xc2, 0xc3, 0xbe, 0xde, 0xc1, 0x57,
+ 0xbc, 0xd1, 0xb1, 0xe4, 0xaf, 0xf3, 0xb4, 0x5a, 0xb5, 0xa6, 0xb0, 0xbc, 0xa5,
+ 0x55, 0xb4, 0xfa, 0xbc, 0x68, 0xf3, 0x4f, 0xb4, 0xa1, 0xa4, 0x65, 0xd3, 0xb3,
+ 0xaf, 0xf9, 0xac, 0x64, 0xe2, 0xed, 0xb7, 0x67, 0xb9, 0xee, 0xa7, 0xc3, 0xae,
+ 0x74, 0xb8, 0xd2, 0xa9, 0xee, 0xae, 0xe3, 0xb0, 0x5b, 0xc4, 0x65, 0xba, 0x55,
+ 0xc2, 0xcd, 0xc6, 0x61, 0xc5, 0xfe, 0xc4, 0xf1, 0xc3, 0xea, 0xb2, 0xa3, 0xc4,
+ 0xc4, 0xc5, 0xb8, 0xa9, 0xf7, 0xb2, 0x73, 0xb3, 0xf5, 0xb9, 0xc1, 0xb1, 0x60,
+ 0xaa, 0xf8, 0xc0, 0x76, 0xb8, 0x7a, 0xbc, 0x74, 0xb4, 0xaf, 0xba, 0x5a, 0xb0,
+ 0xdb, 0xad, 0xd2, 0xb6, 0x57, 0xa7, 0xdb, 0xb6, 0x72, 0xb4, 0xc2, 0xbc, 0x4a,
+ 0xbc, 0xe9, 0xb1, 0x5f, 0xa7, 0x6e, 0xaa, 0xa3, 0xa8, 0xae, 0xa7, 0xe8, 0xba,
+ 0x4d, 0xb4, 0x77, 0xb9, 0xfd, 0xba, 0xab, 0xd7, 0xeb, 0xa6, 0xda, 0xa8, 0xb0,
+ 0xb9, 0xd0, 0xb1, 0xe1, 0xa7, 0xd5, 0xa8, 0x49, 0xb3, 0xaf, 0xb6, 0x58, 0xc5,
+ 0xa8, 0xbc, 0xb5, 0xba, 0xd9, 0xab, 0xb0, 0xbe, 0xed, 0xa6, 0xa8, 0xa7, 0x65,
+ 0xad, 0xbc, 0xb5, 0x7b, 0xc3, 0x67, 0xbc, 0xe1, 0xb8, 0xdb, 0xa9, 0xd3, 0xb3,
+ 0x78, 0xc1, 0xfe, 0xaf, 0xaf, 0xa6, 0x59, 0xb7, 0xf6, 0xab, 0xf9, 0xb0, 0xcd,
+ 0xa6, 0xc0, 0xbf, 0xf0, 0xa6, 0xa2, 0xb9, 0xa3, 0xae, 0xa2, 0xbe, 0xa6, 0xa8,
+ 0xd7, 0xa4, 0xd8, 0xa8, 0xaa, 0xaf, 0xcd, 0xa5, 0xb8, 0xbf, 0x4b, 0xa5, 0x52,
+ 0xa8, 0x52, 0xc2, 0xce, 0xb1, 0x52, 0xc3, 0x64, 0xa9, 0xe2, 0xb9, 0x53, 0xc3,
+ 0xa5, 0xc5, 0x43, 0xb8, 0x59, 0xb7, 0x54, 0xc4, 0x77, 0xa4, 0xb3, 0xba, 0xf7,
+ 0xe2, 0xe4, 0xc1, 0xe0, 0xaf, 0xe4, 0xaa, 0xec, 0xa5, 0x58, 0xc3, 0x6f, 0xbc,
+ 0x70, 0xc3, 0xdc, 0xbe, 0x53, 0xc2, 0xfa, 0xde, 0x51, 0xb0, 0xa3, 0xb7, 0xa1,
+ 0xc2, 0xa6, 0xc0, 0x78, 0xc5, 0xf7, 0xdd, 0x7a, 0xc4, 0xb2, 0xb3, 0x42, 0xb4,
+ 0xa2, 0xa4, 0x74, 0xac, 0xef, 0xdd, 0xdc, 0xb6, 0xc7, 0xb2, 0xee, 0xb3, 0xdd,
+ 0xa6, 0xea, 0xbd, 0x48, 0xb5, 0xa1, 0xbc, 0x6c, 0xa7, 0xc9, 0xc2, 0xf4, 0xb3,
+ 0xd0, 0xa7, 0x6a, 0xaa, 0xa4, 0xb4, 0xa8, 0xc1, 0xe8, 0xab, 0xab, 0xac, 0x4b,
+ 0xdd, 0xcf, 0xbe, 0x4a, 0xae, 0x42, 0xb2, 0x45, 0xaf, 0xc2, 0xc4, 0xf8, 0xc2,
+ 0x57, 0xba, 0xef, 0xb2, 0xab, 0xaf, 0xfd, 0xba, 0xcf, 0xbb, 0xdb, 0xc3, 0xe3,
+ 0xb7, 0x4f, 0xb2, 0xa1, 0xb5, 0xfc, 0xa6, 0xb9, 0xa8, 0xeb, 0xbd, 0xe7, 0xa6,
+ 0xb8, 0xc1, 0x6f, 0xbd, 0xb5, 0xa7, 0x77, 0xa5, 0x5e, 0xb1, 0x71, 0xc2, 0x4f,
+ 0xb4, 0xea, 0xb2, 0xca, 0xbe, 0x4c, 0xc1, 0x4c, 0xab, 0x50, 0xf9, 0x4f, 0xbf,
+ 0x79, 0xc2, 0xab, 0xba, 0x52, 0xb1, 0x5a, 0xb6, 0xca, 0xaf, 0xdc, 0xb7, 0xf1,
+ 0xba, 0xe9, 0xb2, 0x66, 0xbb, 0x41, 0xa7, 0xf8, 0xa6, 0x73, 0xa4, 0x6f, 0xbd,
+ 0x52, 0xbc, 0xbc, 0xb7, 0x62, 0xb1, 0xb9, 0xae, 0xc0, 0xbf, 0xf9, 0xb7, 0x66,
+ 0xb9, 0x46, 0xb5, 0xaa, 0xbd, 0x44, 0xa5, 0xb4, 0xa4, 0x6a, 0xa7, 0x62, 0xa4,
+ 0xef, 0xd8, 0x56, 0xc0, 0xb9, 0xb1, 0x61, 0xac, 0x70, 0xa5, 0x4e, 0xb6, 0x55,
+ 0xb3, 0x55, 0xab, 0xdd, 0xb6, 0x65, 0xab, 0xe5, 0xaf, 0xd4, 0xbe, 0xe1, 0xa4,
+ 0xa6, 0xb3, 0xe6, 0xe8, 0x58, 0xe5, 0xb8, 0xc1, 0x78, 0xa5, 0xb9, 0xb4, 0xe1,
+ 0xa6, 0xfd, 0xbc, 0xaa, 0xb2, 0x48, 0xbd, 0xcf, 0xbc, 0x75, 0xb3, 0x4a, 0xb7,
+ 0xed, 0xbe, 0xd7, 0xc4, 0xd2, 0xc0, 0xfa, 0xc0, 0xc9, 0xa4, 0x4d, 0xb7, 0x6f,
+ 0xc1, 0xd0, 0xad, 0xcb, 0xae, 0x71, 0xc3, 0xab, 0xbe, 0xc9, 0xa8, 0xec, 0xbd,
+ 0x5f, 0xb1, 0xa5, 0xb9, 0x44, 0xb5, 0x73, 0xbc, 0x77, 0xb1, 0x6f, 0xaa, 0xba,
+ 0xc3, 0xde, 0xbf, 0x4f, 0xb5, 0x6e, 0xb5, 0xa5, 0xc0, 0xfc, 0xb9, 0xb9, 0xbe,
+ 0x48, 0xb3, 0xf6, 0xa7, 0x43, 0xba, 0x77, 0xad, 0x7d, 0xbc, 0xc4, 0xb2, 0xc3,
+ 0xa8, 0x66, 0xba, 0xb0, 0xbb, 0x43, 0xb9, 0xde, 0xa9, 0xe8, 0xa9, 0xb3, 0xa6,
+ 0x61, 0xb8, 0xa6, 0xb2, 0xc4, 0xab, 0xd2, 0xa7, 0xcc, 0xbb, 0xbc, 0xbd, 0x6c,
+ 0xc4, 0x41, 0xd5, 0x69, 0xb7, 0xbf, 0xb8, 0x4b, 0xc2, 0x49, 0xa8, 0xe5, 0xc0,
+ 0x51, 0xb9, 0xd4, 0xb9, 0x71, 0xa6, 0xfa, 0xa8, 0x6c, 0xa9, 0xb1, 0xb1, 0x7d,
+ 0xb3, 0xfe, 0xbe, 0xfd, 0xb7, 0xb5, 0xb8, 0x4d, 0xa5, 0x70, 0xc0, 0x4a, 0xad,
+ 0xe4, 0xa4, 0x4e, 0xb1, 0xbc, 0xa6, 0x51, 0xb3, 0xa8, 0xbd, 0xd5, 0xb6, 0x5e,
+ 0xaf, 0x52, 0xba, 0xd0, 0xbd, 0xba, 0xad, 0xa1, 0xbf, 0xd2, 0xc5, 0x7c, 0xa4,
+ 0x42, 0xa8, 0x6e, 0xa5, 0x6d, 0xb0, 0x76, 0xb3, 0xbb, 0xb9, 0xa9, 0xbf, 0xf5,
+ 0xa9, 0x77, 0xad, 0x71, 0xa5, 0xe1, 0xaa, 0x46, 0xa5, 0x56, 0xb8, 0xb3, 0xc0,
+ 0xb4, 0xb0, 0xca, 0xb4, 0xc9, 0xcb, 0xbe, 0xab, 0xf0, 0xad, 0xe1, 0xac, 0x7d,
+ 0xb0, 0xc2, 0xa7, 0xdd, 0xb0, 0xab, 0xb0, 0x7e, 0xa8, 0xa7, 0xb3, 0x72, 0xb5,
+ 0x6b, 0xb3, 0xa3, 0xb7, 0xfe, 0xac, 0x72, 0xc3, 0x7d, 0xbf, 0x57, 0xc5, 0xaa,
+ 0xb0, 0xf4, 0xb8, 0x40, 0xbd, 0xe4, 0xa7, 0xf9, 0xc1, 0xe1, 0xa8, 0x7b, 0xab,
+ 0xd7, 0xb4, 0xe7, 0xa7, 0xaa, 0xba, 0xdd, 0xb5, 0x75, 0xc1, 0xeb, 0xac, 0x71,
+ 0xc2, 0x5f, 0xbd, 0x76, 0xb0, 0xef, 0xa7, 0x49, 0xb6, 0xa4, 0xb9, 0xef, 0xbc,
+ 0x5b, 0xbe, 0xb7, 0xc3, 0xdb, 0xb4, 0xb0, 0xb9, 0x79, 0xa7, 0x79, 0xb6, 0x77,
+ 0xac, 0xde, 0xb9, 0x50, 0xd5, 0x73, 0xce, 0x47, 0xa6, 0x68, 0xb9, 0xdc, 0xce,
+ 0x57, 0xb8, 0xfa, 0xa6, 0xb7, 0xb8, 0xf6, 0xb2, 0xeb, 0xa8, 0xef, 0xb4, 0x6b,
+ 0xbc, 0x5a, 0xb8, 0xbf, 0xae, 0x6f, 0xc3, 0x5a, 0xab, 0x58, 0xc3, 0x42, 0xb3,
+ 0x5f, 0xae, 0x5a, 0xb4, 0x63, 0xa4, 0xcc, 0xa7, 0xe3, 0xb9, 0x4b, 0xb6, 0x6b,
+ 0xbe, 0x6a, 0xae, 0xa6, 0xa6, 0xd3, 0xa8, 0xe0, 0xa6, 0xd5, 0xba, 0xb8, 0xbb,
+ 0xe7, 0xac, 0x7c, 0xa4, 0x47, 0xb6, 0x4c, 0xb5, 0x6f, 0xbb, 0x40, 0xb5, 0xad,
+ 0xa5, 0xef, 0xa5, 0x46, 0xbb, 0xd6, 0xaa, 0x6b, 0xb5, 0x57, 0xc3, 0xbf, 0xa6,
+ 0x7c, 0xb5, 0x66, 0xc2, 0xbd, 0xbc, 0xd4, 0xc4, 0x73, 0xb3, 0xab, 0xc1, 0x63,
+ 0xa4, 0x5a, 0xb7, 0xd0, 0xa4, 0xcf, 0xaa, 0xf0, 0xad, 0x53, 0xb3, 0x63, 0xa5,
+ 0xc7, 0xb6, 0xba, 0xaa, 0x78, 0xa7, 0x7b, 0xaa, 0xda, 0xa4, 0xe8, 0xaa, 0xd5,
+ 0xa9, 0xd0, 0xa8, 0xbe, 0xa7, 0xab, 0xa5, 0xe9, 0xb3, 0x58, 0xaf, 0xbc, 0xa9,
+ 0xf1, 0xb5, 0xe1, 0xab, 0x44, 0xb0, 0xd8, 0xad, 0xb8, 0xaa, 0xce, 0xad, 0xea,
+ 0xbd, 0xda, 0xa7, 0x70, 0xaa, 0xcd, 0xbc, 0x6f, 0xaa, 0x6d, 0xb6, 0x4f, 0xaa,
+ 0xe2, 0xd7, 0xf4, 0xa7, 0x68, 0xaa, 0x5e, 0xa4, 0xc0, 0xaf, 0xc9, 0xbc, 0x58,
+ 0xb5, 0x49, 0xa8, 0x57, 0xaf, 0xbb, 0xbe, 0xc4, 0xa5, 0xf7, 0xa9, 0xc1, 0xbc,
+ 0xab, 0xc1, 0x54, 0xc2, 0xd7, 0xab, 0xca, 0xb7, 0xac, 0xb8, 0xc1, 0xae, 0x70,
+ 0xbe, 0x57, 0xad, 0xb7, 0xba, 0xc6, 0xb2, 0x6c, 0xb3, 0x7b, 0xb6, 0xbe, 0xc1,
+ 0x5f, 0xbf, 0xd8, 0xa9, 0x5e, 0xbb, 0xf1, 0xa6, 0xf2, 0xa7, 0x5f, 0xa4, 0xd2,
+ 0xbc, 0xc5, 0xbd, 0xa7, 0xb9, 0xe5, 0xa7, 0xdf, 0xa9, 0xd8, 0xbf, 0xe7, 0xb4,
+ 0x54, 0xac, 0x74, 0xb2, 0xc5, 0xa5, 0xf1, 0xab, 0x52, 0xaa, 0x41, 0xaf, 0x42,
+ 0xb2, 0x65, 0xba, 0xd6, 0xb5, 0xf6, 0xa5, 0xb1, 0xa8, 0x6a, 0xbc, 0xbe, 0xbb,
+ 0xb2, 0xad, 0xc1, 0xb0, 0x79, 0xa9, 0xf2, 0xb2, 0xe3, 0xb5, 0xc6, 0xa9, 0xb2,
+ 0xbb, 0x47, 0xad, 0x75, 0xb0, 0xc6, 0xc2, 0xd0, 0xbd, 0xe1, 0xb4, 0x5f, 0xb3,
+ 0xc5, 0xa5, 0x49, 0xaa, 0xfa, 0xa4, 0xf7, 0xb8, 0xa1, 0xad, 0x74, 0xb4, 0x49,
+ 0xad, 0x72, 0xaa, 0xfe, 0xb0, 0xfc, 0xbf, 0xa3, 0xa9, 0x4a, 0xbe, 0xbf, 0xb9,
+ 0xc7, 0xb8, 0xd3, 0xa7, 0xef, 0xb7, 0xa7, 0xb6, 0x74, 0xbb, 0x5c, 0xb5, 0x40,
+ 0xb7, 0x46, 0xa5, 0xcc, 0xb1, 0xec, 0xac, 0x61, 0xac, 0xf1, 0xa8, 0x78, 0xbb,
+ 0xb0, 0xb7, 0x50, 0xb5, 0x7a, 0xb4, 0xb1, 0xc6, 0x42, 0xa9, 0xa3, 0xad, 0xe8,
+ 0xbf, 0xfb, 0xac, 0xfb, 0xa8, 0x7a, 0xba, 0xf5, 0xb1, 0x5e, 0xb4, 0xe4, 0xba,
+ 0x62, 0xbf, 0x74, 0xaf, 0x6f, 0xb0, 0xaa, 0xbb, 0x49, 0xaf, 0xcc, 0xbf, 0x7c,
+ 0xb7, 0x64, 0xc2, 0xee, 0xbd, 0x5a, 0xa7, 0x69, 0xad, 0xf4, 0xba, 0x71, 0xc0,
+ 0xc1, 0xa4, 0xe0, 0xc2, 0x46, 0xaf, 0xde, 0xaa, 0xb8, 0xb3, 0xce, 0xad, 0xb2,
+ 0xb8, 0xaf, 0xae, 0xe6, 0xb5, 0xf0, 0xbb, 0xd5, 0xb9, 0x6a, 0xbb, 0xcc, 0xad,
+ 0xd3, 0xa6, 0x55, 0xb5, 0xb9, 0xae, 0xda, 0xb8, 0xf2, 0xaf, 0xd1, 0xa7, 0xf3,
+ 0xa9, 0xb0, 0xc3, 0xbc, 0xae, 0x47, 0xaf, 0xd5, 0xb1, 0xf0, 0xa4, 0x75, 0xa7,
+ 0xf0, 0xa5, 0x5c, 0xae, 0xa5, 0xc5, 0xc7, 0xa8, 0xd1, 0xb0, 0x60, 0xa4, 0xbd,
+ 0xae, 0x63, 0xa4, 0x7d, 0xbe, 0x64, 0xa8, 0x45, 0xab, 0xfd, 0xb0, 0x5e, 0xa6,
+ 0x40, 0xb9, 0x5f, 0xa4, 0xc4, 0xb7, 0xbe, 0xad, 0x65, 0xaa, 0xaf, 0xab, 0xaf,
+ 0xba, 0x63, 0xc1, 0xca, 0xb0, 0xf7, 0xb6, 0x64, 0xdb, 0xa3, 0xa9, 0x42, 0xe3,
+ 0x54, 0xa6, 0xf4, 0xaa, 0x66, 0xa9, 0x74, 0xa9, 0x68, 0xb9, 0xaa, 0xa5, 0x6a,
+ 0xc5, 0xdb, 0xb0, 0xa9, 0xa8, 0xa6, 0xaa, 0xd1, 0xac, 0x47, 0xc5, 0x55, 0xa9,
+ 0x54, 0xb6, 0xb1, 0xa8, 0xed, 0xa5, 0xca, 0xd4, 0x6c, 0xb9, 0xe8, 0xb1, 0xbe,
+ 0xbb, 0x6f, 0xa8, 0xc4, 0xa9, 0xe4, 0xa9, 0xc7, 0xb4, 0xc3, 0xc3, 0xf6, 0xa9,
+ 0x78, 0xab, 0x61, 0xc6, 0x5b, 0xba, 0xde, 0xc0, 0x5d, 0xc5, 0xf8, 0xba, 0x44,
+ 0xc4, 0xe9, 0xb3, 0x65, 0xa5, 0xfa, 0xbc, 0x73, 0xb3, 0x7d, 0xba, 0xc0, 0xb3,
+ 0x57, 0xa6, 0x63, 0xd6, 0xba, 0xc2, 0x6b, 0xc0, 0x74, 0xbb, 0xd3, 0xad, 0x79,
+ 0xb0, 0xad, 0xb8, 0xde, 0xac, 0xd1, 0xae, 0xdb, 0xc2, 0x64, 0xb8, 0xf7, 0xb6,
+ 0x51, 0xbc, 0x44, 0xbe, 0x40, 0xba, 0x75, 0xb4, 0xd2, 0xc1, 0xe7, 0xb3, 0xa2,
+ 0xb0, 0xea, 0xaa, 0x47, 0xbb, 0x71, 0xb9, 0x4c, 0xab, 0xa2, 0xc0, 0x65, 0xab,
+ 0xc4, 0xae, 0xfc, 0xae, 0xf3, 0xa5, 0xe8, 0xae, 0x60, 0xc0, 0x62, 0xb6, 0x6f,
+ 0xe9, 0x77, 0xcd, 0xd5, 0xc1, 0xfa, 0xa7, 0x74, 0xb2, 0x5b, 0xb4, 0x48, 0xa8,
+ 0xe7, 0xb3, 0xdb, 0xa8, 0x75, 0xbf, 0xab, 0xbe, 0xd9, 0xae, 0xc2, 0xa7, 0xf2,
+ 0xbe, 0xd1, 0xae, 0xab, 0xb2, 0x6b, 0xa6, 0xbd, 0xba, 0x7e, 0xc9, 0x71, 0xaa,
+ 0x43, 0xaf, 0xe8, 0xc0, 0xa2, 0xc0, 0x7a, 0xbb, 0xa8, 0xb2, 0x40, 0xb0, 0x71,
+ 0xa6, 0x6e, 0xaf, 0xd3, 0xb8, 0xb9, 0xaf, 0x45, 0xa8, 0xfe, 0xb3, 0xdc, 0xb2,
+ 0xfc, 0xdb, 0x5d, 0xae, 0xd6, 0xa5, 0xdd, 0xa9, 0x4d, 0xa6, 0xf3, 0xa6, 0x58,
+ 0xb2, 0xb0, 0xb8, 0xe8, 0xbb, 0xd2, 0xaa, 0x65, 0xb2, 0x55, 0xbb, 0xae, 0xbd,
+ 0xc5, 0xc5, 0x62, 0xb6, 0x50, 0xbc, 0x4b, 0xb6, 0xc2, 0xb2, 0xaa, 0xab, 0xdc,
+ 0xac, 0xbd, 0xab, 0xeb, 0xad, 0xf3, 0xa6, 0xeb, 0xbe, 0xee, 0xbf, 0xc5, 0xab,
+ 0xed, 0xc5, 0x46, 0xab, 0xa1, 0xaf, 0x4d, 0xad, 0x69, 0xc2, 0x45, 0xac, 0x78,
+ 0xa7, 0xbb, 0xa5, 0xb0, 0xac, 0xf5, 0xb3, 0xef, 0xab, 0x4a, 0xb5, 0x55, 0xa7,
+ 0x71, 0xab, 0x70, 0xad, 0xd4, 0xab, 0xe1, 0xa9, 0x49, 0xa5, 0x47, 0xa9, 0xbf,
+ 0xb7, 0xe4, 0xb3, 0xfd, 0xb8, 0xac, 0xad, 0x4a, 0xbd, 0xb9, 0xaa, 0xb0, 0xbd,
+ 0x6b, 0xb4, 0xf2, 0xa9, 0xb7, 0xaa, 0xea, 0xb0, 0xe4, 0xc5, 0x40, 0xa4, 0xac,
+ 0xba, 0xad, 0xa4, 0xe1, 0xaa, 0xe1, 0xbc, 0x4d, 0xb5, 0xd8, 0xb7, 0xe2, 0xb7,
+ 0xc6, 0xb5, 0x65, 0xb9, 0xba, 0xa4, 0xc6, 0xb8, 0xdc, 0xba, 0x69, 0xab, 0xde,
+ 0xc3, 0x68, 0xb2, 0x61, 0xc3, 0x61, 0xc5, 0x77, 0xc0, 0xf4, 0xae, 0xd9, 0xc1,
+ 0xd9, 0xbd, 0x77, 0xb4, 0xab, 0xb1, 0x77, 0xb3, 0xea, 0xba, 0xc8, 0xb8, 0xe6,
+ 0xb7, 0xd8, 0xb5, 0x41, 0xab, 0xc6, 0xa4, 0xdb, 0xaf, 0xee, 0xb7, 0x57, 0xb6,
+ 0xc0, 0xc1, 0x44, 0xbd, 0xc0, 0xc2, 0xae, 0xac, 0xd3, 0xb0, 0xc4, 0xb4, 0x71,
+ 0xb7, 0xd7, 0xae, 0xcc, 0xb7, 0x45, 0xab, 0xe9, 0xc1, 0xc0, 0xa6, 0xc7, 0xb4,
+ 0xa7, 0xbd, 0xf7, 0xc0, 0xb2, 0xab, 0xec, 0xb5, 0xee, 0xa6, 0x5e, 0xb7, 0xb4,
+ 0xae, 0xac, 0xbc, 0x7a, 0xa5, 0x63, 0xb4, 0x66, 0xb1, 0xe2, 0xb8, 0xec, 0xc2,
+ 0xa9, 0xb7, 0x7c, 0xc0, 0xed, 0xb6, 0xd7, 0xbf, 0xd0, 0xbb, 0xa3, 0xc3, 0xb8,
+ 0xb8, 0xa7, 0xa9, 0xfc, 0xb1, 0x42, 0xbb, 0xee, 0xb4, 0xfd, 0xb2, 0x56, 0xc1,
+ 0xc5, 0xac, 0xa1, 0xa5, 0xeb, 0xa4, 0xf5, 0xc0, 0xf2, 0xa9, 0xce, 0xb4, 0x62,
+ 0xc0, 0x4e, 0xb3, 0x66, 0xba, 0xd7, 0xc0, 0xbb, 0xa7, 0xa3, 0xb0, 0xf2, 0xbe,
+ 0xf7, 0xb7, 0xee, 0xbd, 0x5d, 0xbf, 0x6e, 0xba, 0xdf, 0xa6, 0xd9, 0xc4, 0xc8,
+ 0xb8, 0xf1, 0xbf, 0x45, 0xc3, 0xd5, 0xc2, 0xfb, 0xae, 0x56, 0xc1, 0x5a, 0xbd,
+ 0x72, 0xa6, 0x4e, 0xb7, 0xa5, 0xb4, 0xc6, 0xbf, 0xe8, 0xc4, 0x79, 0xb6, 0xb0,
+ 0xa4, 0xce, 0xab, 0xe6, 0xaf, 0x65, 0xa8, 0x56, 0xa7, 0x59, 0xb6, 0xfa, 0xaf,
+ 0xc5, 0xc0, 0xbd, 0xb4, 0x58, 0xaf, 0xe1, 0xa4, 0x76, 0xc1, 0xaa, 0xa7, 0xde,
+ 0xbe, 0xac, 0xa9, 0x75, 0xc9, 0xab, 0xb2, 0xbd, 0xbe, 0xaf, 0xb1, 0xaa, 0xc0,
+ 0xd9, 0xb1, 0x48, 0xb1, 0x49, 0xad, 0x70, 0xb0, 0x4f, 0xac, 0x4a, 0xa7, 0xd2,
+ 0xbb, 0xda, 0xa7, 0xb2, 0xc4, 0x7e, 0xac, 0xf6, 0xb9, 0xc5, 0xcf, 0x45, 0xa7,
+ 0xa8, 0xa8, 0xce, 0xae, 0x61, 0xa5, 0x5b, 0xb2, 0xf3, 0xc0, 0x55, 0xb8, 0xeb,
+ 0xa5, 0xd2, 0xb9, 0x5b, 0xb0, 0xb2, 0xbd, 0x5b, 0xbb, 0xf9, 0xac, 0x5b, 0xbe,
+ 0x72, 0xb6, 0xf9, 0xc4, 0xe8, 0xba, 0xca, 0xb0, 0xed, 0xa6, 0x79, 0xba, 0xe0,
+ 0xb6, 0xa1, 0xb7, 0xce, 0xad, 0xdd, 0xaa, 0xd3, 0xc1, 0x7d, 0xab, 0xc1, 0xbd,
+ 0x70, 0xc3, 0xb5, 0xc0, 0xcb, 0xac, 0x5a, 0xc6, 0x50, 0xc6, 0x50, 0xb4, 0x7a,
+ 0xbe, 0xdf, 0xc2, 0xb2, 0xbb, 0xfc, 0xb0, 0xc5, 0xb4, 0xee, 0xc2, 0xcb, 0xc2,
+ 0x65, 0xc5, 0xb3, 0xbd, 0xee, 0xbd, 0xe2, 0xa8, 0xa3, 0xc1, 0xe4, 0xbd, 0x62,
+ 0xa5, 0xf3, 0xb0, 0xb7, 0xc4, 0xa5, 0xbc, 0x43, 0xc0, 0x5e, 0xba, 0xa5, 0xc2,
+ 0x71, 0xbc, 0xee, 0xab, 0xd8, 0xbb, 0xf8, 0xab, 0xb8, 0xb1, 0x4e, 0xbc, 0xdf,
+ 0xa6, 0xbf, 0xc3, 0xa6, 0xbd, 0xb1, 0xbc, 0xd5, 0xbc, 0xfa, 0xc1, 0xbf, 0xa6,
+ 0x4b, 0xc2, 0xe6, 0xad, 0xb0, 0xbf, 0xbc, 0xb4, 0xd4, 0xc1, 0x47, 0xb5, 0x4a,
+ 0xbd, 0xa6, 0xa5, 0xe6, 0xad, 0xa5, 0xbc, 0xe5, 0xc5, 0xba, 0xbc, 0x62, 0xc4,
+ 0x5a, 0xc5, 0xcd, 0xbb, 0xc7, 0xc1, 0x42, 0xb9, 0xae, 0xb8, 0x7d, 0xac, 0xbe,
+ 0xa8, 0xa4, 0xbb, 0xe5, 0xc3, 0xba, 0xb5, 0xb1, 0xb6, 0xcf, 0xb1, 0xd0, 0xbb,
+ 0xc3, 0xc3, 0xe2, 0xb8, 0xfb, 0xa5, 0x73, 0xb5, 0xa2, 0xb4, 0xa6, 0xb1, 0xb5,
+ 0xac, 0xd2, 0xd6, 0xc5, 0xb5, 0xf3, 0xb6, 0xa5, 0xba, 0x49, 0xa7, 0x54, 0xb8,
+ 0x60, 0xae, 0xdc, 0xb3, 0xc7, 0xb1, 0xb6, 0xb7, 0xfb, 0xba, 0xdc, 0xbc, 0xe4,
+ 0xb5, 0xb2, 0xb8, 0xd1, 0xa9, 0x6a, 0xa7, 0xd9, 0xc2, 0xc7, 0xaa, 0xe3, 0xac,
+ 0xc9, 0xad, 0xc9, 0xa4, 0xb6, 0xac, 0xce, 0xbb, 0x7c, 0xa9, 0xa1, 0xa4, 0x79,
+ 0xb5, 0xac, 0xa4, 0xe7, 0xaa, 0xf7, 0xa4, 0xb5, 0xac, 0x7a, 0xc3, 0xcc, 0xba,
+ 0xf2, 0xc0, 0x41, 0xb6, 0xc8, 0xc2, 0xd4, 0xb6, 0x69, 0xe0, 0xda, 0xae, 0xca,
+ 0xb8, 0x54, 0xaa, 0xf1, 0xc2, 0x75, 0xae, 0xfb, 0xba, 0xc9, 0xab, 0x6c, 0xaf,
+ 0xf0, 0xb9, 0xb8, 0xb2, 0xf4, 0xb7, 0xfa, 0xb4, 0xb9, 0xc4, 0x48, 0xa8, 0xca,
+ 0xc5, 0xe5, 0xba, 0xeb, 0xb8, 0x65, 0xb8, 0x67, 0xa4, 0xab, 0xc4, 0xb5, 0xb4,
+ 0xba, 0xc0, 0x56, 0xc0, 0x52, 0xb9, 0xd2, 0xb7, 0x71, 0xc3, 0xe8, 0xae, 0x7c,
+ 0xb5, 0x6a, 0xb9, 0x74, 0xb3, 0xba, 0xc4, 0x76, 0xd0, 0xe4, 0xac, 0xb3, 0xb5,
+ 0x7e, 0xb4, 0xaa, 0xa8, 0x73, 0xaa, 0xc8, 0xa8, 0x68, 0xad, 0xb4, 0xa4, 0x5b,
+ 0xa8, 0x62, 0xa4, 0x45, 0xb0, 0x73, 0xb4, 0x5c, 0xb1, 0xcf, 0xc2, 0xc2, 0xa6,
+ 0xdd, 0xb8, 0xa4, 0xa9, 0x53, 0xb4, 0x4e, 0xaa, 0xb9, 0xc1, 0xf9, 0xa9, 0xeb,
+ 0xaa, 0xae, 0xaf, 0x6a, 0xa9, 0x7e, 0xbe, 0x73, 0xb5, 0xe2, 0xa7, 0xbd, 0xa9,
+ 0x43, 0xaf, 0x78, 0xc1, 0x7c, 0xaa, 0x71, 0xbb, 0x45, 0xa9, 0xda, 0xbe, 0xda,
+ 0xa5, 0xa8, 0xa8, 0xe3, 0xb6, 0x5a, 0xbd, 0xf5, 0xbf, 0xf7, 0xad, 0xd1, 0xa5,
+ 0x79, 0xc4, 0xdf, 0xac, 0xb2, 0xbc, 0x40, 0xae, 0xbd, 0xc3, 0x59, 0xae, 0x53,
+ 0xad, 0xc2, 0xb2, 0xb2, 0xa8, 0xf7, 0xb8, 0x68, 0xe5, 0xb1, 0xc5, 0xcc, 0xa7,
+ 0xe0, 0xb1, 0xb8, 0xad, 0xcf, 0xc0, 0xef, 0xc4, 0xb1, 0xa8, 0x4d, 0xb3, 0x5a,
+ 0xb5, 0xb4, 0xa7, 0xa1, 0xb5, 0xdf, 0xb6, 0x76, 0xad, 0x78, 0xa7, 0x67, 0xae,
+ 0x6d, 0xab, 0x54, 0xb5, 0xa4, 0xc0, 0xe0, 0xb0, 0x70, 0xc2, 0x40, 0xb3, 0xd8,
+ 0xa9, 0x40, 0xa5, 0x64, 0xab, 0xa3, 0xb6, 0x7d, 0xb4, 0x7b, 0xb7, 0xa2, 0xb3,
+ 0xcd, 0xb4, 0x6e, 0xa5, 0x5a, 0xb3, 0xf4, 0xb0, 0xc9, 0xa7, 0xa2, 0xac, 0xe5,
+ 0xac, 0xdd, 0xb1, 0x64, 0xba, 0x42, 0xc1, 0x52, 0xa6, 0xaa, 0xa7, 0xdc, 0xa4,
+ 0xae, 0xaa, 0xa1, 0xa6, 0xd2, 0xab, 0xfe, 0xaf, 0x4e, 0xbe, 0x61, 0xa9, 0x56,
+ 0xad, 0x56, 0xac, 0x5f, 0xb4, 0xca, 0xbd, 0x57, 0xc1, 0xfb, 0xac, 0xec, 0xb4,
+ 0xdf, 0xab, 0x79, 0xa5, 0x69, 0xb4, 0xf7, 0xa7, 0x4a, 0xa8, 0xe8, 0xab, 0xc8,
+ 0xbd, 0xd2, 0xaa, 0xd6, 0xb0, 0xd9, 0xbe, 0xc1, 0xc0, 0xb5, 0xa7, 0x7c, 0xa7,
+ 0x5c, 0xaa, 0xc5, 0xae, 0xa3, 0xa4, 0xd5, 0xb1, 0xb1, 0xe1, 0xe0, 0xa4, 0x66,
+ 0xa6, 0xa9, 0xb1, 0x46, 0xac, 0x5c, 0xad, 0xfa, 0xb8, 0x5d, 0xad, 0x57, 0xbb,
+ 0xc5, 0xae, 0x77, 0xbf, 0xc7, 0xa6, 0x6a, 0xab, 0xb1, 0xce, 0xd8, 0xb8, 0xf3,
+ 0xaf, 0xe3, 0xb6, 0xf4, 0xb8, 0x5f, 0xbb, 0xfb, 0xa7, 0xd6, 0xbc, 0x65, 0xb4,
+ 0xda, 0xa6, 0x4a, 0xb5, 0xa8, 0xa8, 0x67, 0xae, 0xd8, 0xc4, 0x71, 0xb2, 0xb5,
+ 0xc3, 0x6d, 0xaa, 0x70, 0xc1, 0xab, 0xb2, 0xaf, 0xf5, 0xc9, 0xbf, 0x73, 0xb8,
+ 0xaa, 0xab, 0xb6, 0xbb, 0xed, 0xb3, 0xc8, 0xf5, 0x58, 0xb7, 0x5c, 0xbc, 0xec,
+ 0xa9, 0x5b, 0xa9, 0xf8, 0xae, 0xb9, 0xa7, 0x78, 0xac, 0x41, 0xc2, 0x58, 0xb9,
+ 0xf8, 0xc1, 0xef, 0xa9, 0x55, 0xa9, 0xd4, 0xb3, 0xe2, 0xc4, 0xfa, 0xc3, 0xbe,
+ 0xbb, 0xb6, 0xb0, 0xd5, 0xb5, 0xdc, 0xa8, 0xd3, 0xbf, 0xe0, 0xc2, 0xc5, 0xb0,
+ 0xfd, 0xc4, 0xe6, 0xc4, 0x64, 0xc4, 0x78, 0xc1, 0xf1, 0xc4, 0xf5, 0xc4, 0x69,
+ 0xf8, 0xc2, 0xc5, 0xf3, 0xc4, 0xfd, 0xc3, 0x69, 0xc6, 0x6c, 0xc4, 0xea, 0xc0,
+ 0xdd, 0xb2, 0x77, 0xb7, 0x7d, 0xaf, 0x54, 0xb4, 0x59, 0xad, 0xa6, 0xae, 0xd4,
+ 0xae, 0xf6, 0xbc, 0xb4, 0xb3, 0xd2, 0xa8, 0x63, 0xa6, 0xd1, 0xa8, 0xd0, 0xab,
+ 0xbe, 0xb9, 0x54, 0xaf, 0x4f, 0xe5, 0xfc, 0xb0, 0xc7, 0xbc, 0xd6, 0xb9, 0x70,
+ 0xc5, 0x4a, 0xc1, 0xa2, 0xbd, 0x55, 0xb2, 0xd6, 0xc0, 0x77, 0xc2, 0x53, 0xbe,
+ 0xdd, 0xa6, 0xd8, 0xc3, 0xfe, 0xb2, 0x5c, 0xd9, 0xb1, 0xb7, 0xab, 0xa7, 0x4e,
+ 0xcd, 0xf9, 0xb1, 0xf9, 0xb2, 0x70, 0xbe, 0xa4, 0xc6, 0x58, 0xbb, 0xa9, 0xc2,
+ 0xf7, 0xba, 0x76, 0xb2, 0x7a, 0xa7, 0xf5, 0xb8, 0xcc, 0xc3, 0x55, 0xc2, 0xa7,
+ 0xb2, 0xfa, 0xaf, 0xef, 0xa6, 0x4f, 0xae, 0xdf, 0xc4, 0x52, 0xbc, 0x46, 0xc0,
+ 0x79, 0xc4, 0x74, 0xbe, 0xfa, 0xa7, 0x51, 0xe0, 0xf4, 0xa8, 0xd2, 0xab, 0x57,
+ 0xb5, 0x67, 0xa5, 0xdf, 0xb2, 0xc9, 0xc3, 0x77, 0xc1, 0xf5, 0xa4, 0x4f, 0xbc,
+ 0xfe, 0xad, 0xf9, 0xad, 0xc7, 0xc1, 0x70, 0xbd, 0xac, 0xb3, 0x73, 0xc5, 0x49,
+ 0xb7, 0x47, 0xbc, 0xa6, 0xba, 0xa7, 0xc3, 0xae, 0xc0, 0xc4, 0xc1, 0x79, 0xc3,
+ 0xec, 0xc5, 0xca, 0xb7, 0xd2, 0xbd, 0x6d, 0xc2, 0xb3, 0xb2, 0x44, 0xbc, 0xd9,
+ 0xb8, 0x64, 0xa8, 0x7d, 0xa8, 0xe2, 0xbd, 0xf8, 0xb6, 0x71, 0xb4, 0xbd, 0xab,
+ 0x47, 0xbd, 0xcc, 0xbc, 0xba, 0xb2, 0xe1, 0xb9, 0xb1, 0xc0, 0xf8, 0xbf, 0x52,
+ 0xb9, 0xe9, 0xbf, 0xf1, 0xbc, 0xe3, 0xa4, 0x46, 0xe1, 0xe6, 0xf4, 0xef, 0xb9,
+ 0xf9, 0xae, 0xc6, 0xa6, 0x43, 0xb5, 0xf5, 0xaf, 0x50, 0xa6, 0x48, 0xc2, 0x79,
+ 0xb5, 0x59, 0xaa, 0x4c, 0xc1, 0x43, 0xc0, 0x4d, 0xc1, 0x7b, 0xbe, 0x46, 0xc5,
+ 0xec, 0xb2, 0x4f, 0xbb, 0xfe, 0xb8, 0xee, 0xa7, 0x5b, 0xa9, 0xf0, 0xac, 0xc2,
+ 0xb5, 0xd9, 0xb9, 0x73, 0xc4, 0xd6, 0xb9, 0x61, 0xa7, 0x44, 0xb2, 0xdc, 0xad,
+ 0xe2, 0xc6, 0x46, 0xb3, 0xae, 0xc0, 0xad, 0xbb, 0xe2, 0xa5, 0x74, 0xa5, 0x4f,
+ 0xb7, 0xc8, 0xaf, 0x5b, 0xba, 0x68, 0xb2, 0xb8, 0xc3, 0x48, 0xaf, 0x64, 0xbc,
+ 0x42, 0xbd, 0x46, 0xac, 0x79, 0xac, 0x68, 0xa4, 0xbb, 0xc0, 0x73, 0xc5, 0xa4,
+ 0xc4, 0x56, 0xc5, 0xa2, 0xc1, 0x4b, 0xb6, 0xa9, 0xc3, 0x62, 0xc3, 0x6c, 0xc3,
+ 0xf7, 0xbc, 0xd3, 0xb0, 0xfa, 0xba, 0x4f, 0xc1, 0x4d, 0xba, 0x7c, 0xad, 0xae,
+ 0xc4, 0xaa, 0xbf, 0x63, 0xc6, 0x60, 0xc3, 0x66, 0xc4, 0x6c, 0xbe, 0xdb, 0xb3,
+ 0xbf, 0xb8, 0xb8, 0xbe, 0x7c, 0xc4, 0x53, 0xb8, 0x4c, 0xc5, 0x53, 0xb8, 0xf4,
+ 0xb8, 0xef, 0xb3, 0xc0, 0xe9, 0xf0, 0xb8, 0x53, 0xbf, 0xfd, 0xb3, 0xb0, 0xbc,
+ 0xae, 0xc6, 0x6a, 0xa7, 0x66, 0xbe, 0x54, 0xab, 0x51, 0xae, 0xc8, 0xbc, 0x69,
+ 0xb9, 0xf0, 0xc1, 0x5c, 0xbc, 0x7b, 0xb4, 0xe2, 0xab, 0xdf, 0xb2, 0x76, 0xc2,
+ 0x6f, 0xba, 0xf1, 0xc5, 0x72, 0xc5, 0xcb, 0xc5, 0x70, 0xc6, 0x65, 0xa7, 0x5a,
+ 0xb6, 0xc3, 0xb1, 0xb0, 0xb2, 0xa4, 0xb1, 0xc1, 0xbd, 0xfc, 0xad, 0xdb, 0xa8,
+ 0xda, 0xb2, 0x5f, 0xba, 0xfa, 0xbd, 0xd7, 0xc5, 0xda, 0xc1, 0xb3, 0xc3, 0xb9,
+ 0xc5, 0xde, 0xc6, 0x72, 0xc6, 0x59, 0xc5, 0x5b, 0xbb, 0x72, 0xb8, 0xa8, 0xac,
+ 0xa5, 0xc0, 0x64, 0xb5, 0xb8, 0xb6, 0xfd, 0xb3, 0xc2, 0xba, 0xbf, 0xbd, 0x58,
+ 0xbf, 0xc2, 0xb0, 0xa8, 0xbd, 0x7c, 0xb9, 0xc0, 0xb6, 0xdc, 0xae, 0x49, 0xb6,
+ 0x52, 0xb3, 0xc1, 0xbd, 0xe6, 0xc1, 0xda, 0xaf, 0xdf, 0xbf, 0x66, 0xc4, 0x43,
+ 0xc6, 0x5a, 0xba, 0xa1, 0xbd, 0xaf, 0xb0, 0xd2, 0xba, 0x43, 0xba, 0xa9, 0xf0,
+ 0xe3, 0xa8, 0x7e, 0xaf, 0xed, 0xaa, 0xbc, 0xaa, 0x5d, 0xa6, 0xa3, 0xb2, 0xf5,
+ 0xbf, 0xdf, 0xad, 0x54, 0xc1, 0xe3, 0xa4, 0xf2, 0xa5, 0xd9, 0xb9, 0x67, 0xa5,
+ 0x66, 0xad, 0x5a, 0xab, 0x5f, 0xb4, 0x55, 0xbb, 0xaa, 0xb6, 0x54, 0xbb, 0xf2,
+ 0xaa, 0xb4, 0xaa, 0x54, 0xb1, 0xf6, 0xa1, 0xbc, 0xbe, 0x60, 0xb7, 0xd1, 0xa8,
+ 0x53, 0xac, 0xdc, 0xb4, 0x43, 0xc1, 0xe2, 0xa8, 0x43, 0xac, 0xfc, 0xac, 0x4e,
+ 0xb4, 0x4b, 0xa9, 0x66, 0xb4, 0x41, 0xaa, 0xf9, 0xb4, 0x65, 0xad, 0xcc, 0xb5,
+ 0xde, 0xbb, 0x58, 0xc2, 0x63, 0xb7, 0xf9, 0xbf, 0xf8, 0xb2, 0x72, 0xb9, 0xda,
+ 0xa9, 0x73, 0xd6, 0xa9, 0xee, 0xc5, 0xc3, 0xfb, 0xc1, 0x53, 0xb0, 0x67, 0xc1,
+ 0xbc, 0xc0, 0xb1, 0xa6, 0xcc, 0xaf, 0xb5, 0xb3, 0x56, 0xaa, 0x63, 0xbb, 0x65,
+ 0xb1, 0x4b, 0xbe, 0xad, 0xb4, 0xd6, 0xaf, 0x76, 0xba, 0xf8, 0xb0, 0xc3, 0xa7,
+ 0x4b, 0xab, 0x6a, 0xae, 0x59, 0xbd, 0x71, 0xad, 0xb1, 0xad, 0x5d, 0xb4, 0x79,
+ 0xba, 0xcb, 0xc2, 0xc6, 0xac, 0xed, 0xb4, 0xf9, 0xbc, 0x71, 0xa7, 0xae, 0xbd,
+ 0xb0, 0xb7, 0xc0, 0xa5, 0xc1, 0xa9, 0xd7, 0xa5, 0xd7, 0xb1, 0xd3, 0xbc, 0xa7,
+ 0xbb, 0xd4, 0xa9, 0xfa, 0xbf, 0xc1, 0xbb, 0xef, 0xbb, 0xca, 0xa6, 0x57, 0xa9,
+ 0x52, 0xc2, 0xd5, 0xba, 0x4e, 0xbc, 0xb1, 0xc4, 0xa8, 0xbc, 0xd2, 0xbd, 0xa4,
+ 0xbf, 0x69, 0xbc, 0xaf, 0xc5, 0x5d, 0xa9, 0xd9, 0xa5, 0xbd, 0xb2, 0xf6, 0xbe,
+ 0xa5, 0xc0, 0x71, 0xaa, 0x6a, 0xba, 0x7a, 0xb9, 0xe6, 0xad, 0xaf, 0xbf, 0xd1,
+ 0xa6, 0xc8, 0xac, 0x59, 0xa9, 0xe6, 0xa8, 0x64, 0xaf, 0x61, 0xa9, 0x69, 0xa5,
+ 0xc0, 0xb9, 0xd3, 0xbc, 0xc7, 0xb9, 0xf5, 0xb6, 0xd2, 0xbc, 0x7d, 0xa4, 0xec,
+ 0xa5, 0xd8, 0xb7, 0xfc, 0xaa, 0xaa, 0xbf, 0x70, 0xae, 0xb3, 0xad, 0xfe, 0xa7,
+ 0x6f, 0xb6, 0x75, 0xa8, 0xba, 0xae, 0x52, 0xaf, 0xc7, 0xa6, 0xbb, 0xa4, 0x44,
+ 0xa5, 0xa4, 0xad, 0x40, 0xa9, 0x60, 0xab, 0x6e, 0xa8, 0x6b, 0xc3, 0xf8, 0xc5,
+ 0x6e, 0xbc, 0xb8, 0xb8, 0xa3, 0xb4, 0x6f, 0xbe, 0x78, 0xd5, 0xef, 0xa9, 0x4f,
+ 0xbe, 0x6b, 0xa4, 0xba, 0xb9, 0xe0, 0xaf, 0xe0, 0xa9, 0x67, 0xc0, 0x4f, 0xad,
+ 0xd9, 0xaa, 0x64, 0xa5, 0xa7, 0xc0, 0xc0, 0xa7, 0x41, 0xb0, 0xce, 0xbf, 0xb0,
+ 0xb0, 0x66, 0xb7, 0xc4, 0xe7, 0x59, 0xa9, 0xe0, 0xa6, 0x7e, 0xbd, 0x56, 0xc2,
+ 0x5b, 0xb1, 0xc9, 0xa9, 0xc0, 0xae, 0x51, 0xc6, 0x43, 0xb3, 0xbe, 0xa7, 0xbf,
+ 0xae, 0xba, 0xc2, 0xbf, 0xc4, 0x5e, 0xef, 0xbf, 0xc6, 0x68, 0xc2, 0xec, 0xaf,
+ 0x49, 0xb1, 0x7a, 0xc2, 0x66, 0xc0, 0xf1, 0xbe, 0xae, 0xb9, 0xe7, 0xc0, 0xbe,
+ 0xc0, 0xd7, 0xa4, 0xfb, 0xa7, 0xe1, 0xb6, 0x73, 0xaf, 0xc3, 0xc1, 0x77, 0xbf,
+ 0x40, 0xb9, 0x41, 0xa7, 0xcb, 0xa5, 0xa3, 0xa7, 0x56, 0xab, 0xe3, 0xa4, 0x6b,
+ 0xb7, 0x78, 0xad, 0x68, 0xba, 0xc4, 0xae, 0xbf, 0xc0, 0xb6, 0xc4, 0x7a, 0xbf,
+ 0xd5, 0xae, 0x40, 0xbc, 0xda, 0xc5, 0xc3, 0xbc, 0xde, 0xc3, 0xc2, 0xb9, 0xc3,
+ 0xb0, 0xb8, 0xe2, 0x78, 0xb0, 0xd4, 0xad, 0x77, 0xaa, 0xa6, 0xa9, 0xac, 0xa9,
+ 0xc8, 0xb5, 0x5d, 0xa9, 0xe7, 0xb1, 0xc6, 0xb5, 0x50, 0xb1, 0x72, 0xb4, 0xfb,
+ 0xac, 0xa3, 0xc3, 0x6b, 0xbc, 0xef, 0xbd, 0x4c, 0xbd, 0x59, 0xac, 0xdf, 0xaf,
+ 0x60, 0xa7, 0x50, 0xab, 0x71, 0xa5, 0xe3, 0xc3, 0x65, 0xae, 0xc7, 0xea, 0xe5,
+ 0xad, 0x44, 0xa9, 0xdf, 0xa9, 0x48, 0xa7, 0x53, 0xac, 0xb6, 0xb3, 0x54, 0xb6,
+ 0x5d, 0xaa, 0x77, 0xa9, 0x41, 0xad, 0x46, 0xb0, 0xf6, 0xbb, 0x70, 0xbd, 0xdf,
+ 0xb3, 0xad, 0xb0, 0x74, 0xa8, 0xd8, 0xa8, 0x4b, 0xbc, 0x51, 0xac, 0xd6, 0xaf,
+ 0x79, 0xa9, 0xe1, 0xb2, 0x69, 0xbc, 0xea, 0xb4, 0x5e, 0xbd, 0xb4, 0xb4, 0xd7,
+ 0xb8, 0x4e, 0xc1, 0x4f, 0xbf, 0xb1, 0xaa, 0x42, 0xc4, 0x50, 0xb1, 0xb7, 0xb8,
+ 0x49, 0xcb, 0xf2, 0xcf, 0xec, 0xc5, 0x52, 0xa7, 0xe5, 0xa9, 0xdc, 0xbc, 0x41,
+ 0xb5, 0x5c, 0xac, 0x73, 0xb0, 0xe0, 0xb5, 0xca, 0xaf, 0x68, 0xa5, 0xd6, 0xa4,
+ 0xc7, 0xb5, 0x6c, 0xbb, 0xf7, 0xa7, 0xbe, 0xc4, 0xb4, 0xbd, 0x67, 0xb0, 0xbe,
+ 0xa4, 0xf9, 0xc4, 0x46, 0xc4, 0xc6, 0xba, 0x7d, 0xbf, 0x5d, 0xb2, 0xbc, 0xba,
+ 0x4a, 0xbf, 0x68, 0xab, 0xf7, 0xc0, 0x57, 0xb3, 0x68, 0xab, 0x7e, 0xb8, 0x75,
+ 0xa5, 0xe2, 0xa9, 0x57, 0xc4, 0xab, 0xb5, 0xd3, 0xa5, 0xad, 0xbe, 0xcc, 0xb2,
+ 0x7e, 0xb5, 0xfb, 0xab, 0xcc, 0xa9, 0x59, 0xbc, 0xe2, 0xbb, 0xe1, 0xb1, 0x43,
+ 0xaf, 0x7d, 0xbe, 0x7a, 0xad, 0xa2, 0xb2, 0xcb, 0xad, 0xe5, 0xbc, 0xb3, 0xe7,
+ 0x45, 0xb9, 0xb2, 0xb3, 0x40, 0xb8, 0xb2, 0xb5, 0xd0, 0xbb, 0x5a, 0xae, 0x48,
+ 0xbe, 0xeb, 0xae, 0x45, 0xb4, 0xb6, 0xae, 0xfa, 0xc3, 0xd0, 0xc3, 0x6e, 0xc2,
+ 0x72, 0xb4, 0xc1, 0xb4, 0xdb, 0xb4, 0xcf, 0xb1, 0xad, 0xa9, 0x64, 0xa4, 0x43,
+ 0xd0, 0xe2, 0xba, 0xa3, 0xac, 0x6d, 0xcb, 0x50, 0xa8, 0xe4, 0xb4, 0xd1, 0xa9,
+ 0x5f, 0xaa, 0x5b, 0xb2, 0xa5, 0xb1, 0x54, 0xc2, 0xc0, 0xbb, 0xf4, 0xba, 0x58,
+ 0xac, 0xe8, 0xaa, 0xc2, 0xc3, 0x4d, 0xb0, 0x5f, 0xb0, 0x5a, 0xa4, 0x5e, 0xa5,
+ 0xf8, 0xb1, 0xd2, 0xab, 0xb4, 0xac, 0xe4, 0xbe, 0xb9, 0xae, 0xf0, 0xa8, 0xb4,
+ 0xb1, 0xf3, 0xa8, 0x54, 0xaa, 0x5f, 0xb0, 0x57, 0xd5, 0x74, 0xab, 0xea, 0xac,
+ 0xa2, 0xb2, 0x6f, 0xc9, 0xe7, 0xa1, 0xbc, 0xb9, 0x5d, 0xa4, 0x64, 0xbe, 0x45,
+ 0xc3, 0xb1, 0xa5, 0x61, 0xc1, 0xbe, 0xb0, 0xae, 0xc0, 0x72, 0xbf, 0xfa, 0xb9,
+ 0x58, 0xab, 0x65, 0xbc, 0xe7, 0xbb, 0xba, 0xb2, 0x4c, 0xc4, 0xfe, 0xb9, 0xd5,
+ 0xb4, 0x4f, 0xa4, 0xed, 0xba, 0x70, 0xba, 0x6a, 0xb6, 0xe6, 0xb5, 0xc4, 0xaa,
+ 0xca, 0xc0, 0xf0, 0xc1, 0xa5, 0xb1, 0x6a, 0xb7, 0x6d, 0xbe, 0xf5, 0xc1, 0xea,
+ 0xba, 0x56, 0xae, 0xa8, 0xbe, 0xf4, 0xc1, 0x40, 0xb3, 0xec, 0xb9, 0xb4, 0xa5,
+ 0xa9, 0xc0, 0x54, 0xbc, 0xc0, 0xc2, 0xbc, 0xae, 0x6b, 0xab, 0x4e, 0xc2, 0xac,
+ 0xa4, 0xc1, 0xad, 0x58, 0xa5, 0x42, 0xa9, 0xc4, 0xc5, 0xd1, 0xb4, 0xdc, 0xab,
+ 0x49, 0xbf, 0xcb, 0xaf, 0xb3, 0xb5, 0x5e, 0xb6, 0xd4, 0xaa, 0xe0, 0xbe, 0xe0,
+ 0xb8, 0x56, 0xb9, 0xec, 0xa8, 0x47, 0xab, 0x43, 0xbb, 0xb4, 0xb2, 0x42, 0xb6,
+ 0xc9, 0xad, 0xeb, 0xb2, 0x4d, 0xc0, 0xba, 0xb4, 0xb8, 0xd9, 0xe6, 0xb1, 0xa1,
+ 0xb3, 0xbc, 0xbd, 0xd0, 0xbc, 0x79, 0xc3, 0xa3, 0xbd, 0x61, 0xac, 0xee, 0xa5,
+ 0x43, 0xaa, 0xf4, 0xb2, 0x79, 0xa8, 0x44, 0xa5, 0x7d, 0xad, 0xa9, 0xaa, 0x73,
+ 0xc1, 0xcd, 0xb0, 0xcf, 0xb3, 0x49, 0xa6, 0xb1, 0xc2, 0xdf, 0xa9, 0x7d, 0xc5,
+ 0x58, 0xb4, 0xeb, 0xa8, 0xfa, 0xb0, 0xf9, 0xc6, 0x54, 0xbd, 0xec, 0xa5, 0x68,
+ 0xb0, 0xe9, 0xf9, 0xaf, 0xc5, 0x76, 0xee, 0xc7, 0xac, 0x75, 0xa5, 0xfe, 0xb2,
+ 0xac, 0xae, 0xb1, 0xa4, 0xfc, 0xa8, 0xe9, 0xc4, 0x55, 0xaf, 0xca, 0xcd, 0x50,
+ 0xbf, 0x61, 0xab, 0x6f, 0xc4, 0x4e, 0xba, 0x65, 0xbd, 0x54, 0xb3, 0xb6, 0xb8,
+ 0xc8, 0xb8, 0x73, 0xb5, 0x4d, 0xbf, 0x55, 0xa5, 0x54, 0xac, 0x56, 0xc5, 0x7b,
+ 0xc4, 0x5b, 0xc4, 0x63, 0xc4, 0x57, 0xc5, 0xfd, 0xc4, 0xc7, 0xc2, 0x5a, 0xc2,
+ 0xb6, 0xb7, 0x53, 0xbc, 0xf6, 0xa4, 0xd0, 0xa4, 0xaf, 0xa4, 0x48, 0xa7, 0xd4,
+ 0xb6, 0xb4, 0xa5, 0xf4, 0xbb, 0x7b, 0xa4, 0x62, 0xa7, 0xb3, 0xac, 0xf7, 0xa5,
+ 0xb5, 0xa4, 0xb4, 0xa4, 0xe9, 0xa6, 0xa5, 0xaf, 0xf1, 0xbb, 0x54, 0xba, 0x61,
+ 0xbf, 0xc4, 0xba, 0xb2, 0xb7, 0xbb, 0xae, 0x65, 0xb5, 0xb3, 0xa4, 0xbe, 0xb4,
+ 0x7c, 0xac, 0x58, 0xa6, 0xd7, 0xaf, 0xf8, 0xc4, 0xaf, 0xbe, 0xa7, 0xc0, 0xa9,
+ 0xa6, 0x70, 0xb0, 0x64, 0xa8, 0xc5, 0xa6, 0xbc, 0xa4, 0x4a, 0xbf, 0xc8, 0xb3,
+ 0x6e, 0xa8, 0xbf, 0xbf, 0xb6, 0xb7, 0xe7, 0xbe, 0x55, 0xb6, 0x7c, 0xbc, 0xed,
+ 0xad, 0x59, 0xae, 0x7a, 0xbc, 0xbb, 0xcf, 0x73, 0xc2, 0xc4, 0xb8, 0x7c, 0xc4,
+ 0xce, 0xb6, 0xeb, 0xc1, 0xc9, 0xa4, 0x54, 0xa4, 0x54, 0xb3, 0xca, 0xb4, 0xb2,
+ 0xae, 0xe1, 0xb6, 0xda, 0xb3, 0xe0, 0xb7, 0x6b, 0xc4, 0xcc, 0xb1, 0xbd, 0xb7,
+ 0x41, 0xb7, 0xe6, 0xa6, 0xe2, 0xc0, 0xdf, 0xb4, 0xcb, 0xb9, 0xac, 0xb2, 0xef,
+ 0xac, 0xe2, 0xb1, 0xfe, 0xab, 0x62, 0xa8, 0x46, 0xaf, 0xbd, 0xb6, 0xcc, 0xd4,
+ 0xa3, 0xb7, 0xd9, 0xbf, 0x7a, 0xc5, 0xce, 0xac, 0xc0, 0xd0, 0x73, 0xa7, 0xfc,
+ 0xa4, 0x73, 0xa7, 0x52, 0xba, 0xb4, 0xad, 0x6d, 0xb0, 0x7b, 0xb0, 0xa2, 0xbe,
+ 0xd5, 0xc4, 0xba, 0xbf, 0xaf, 0xb5, 0xbd, 0xa6, 0xc2, 0xae, 0xb0, 0xc2, 0xb5,
+ 0xe1, 0x61, 0xb6, 0xcb, 0xb0, 0xd3, 0xbd, 0xe0, 0xae, 0xce, 0xa4, 0x57, 0xa9,
+ 0x7c, 0xbb, 0x6e, 0xb1, 0xe9, 0xae, 0xb4, 0xb5, 0x79, 0xbf, 0x4e, 0xa8, 0xa2,
+ 0xa4, 0x63, 0xbb, 0xe0, 0xa4, 0xd6, 0xad, 0xef, 0xaa, 0xf2, 0xb2, 0xd0, 0xb0,
+ 0xf8, 0xbb, 0xad, 0xb3, 0x44, 0xa6, 0xde, 0xaa, 0xd9, 0xb3, 0x6a, 0xc4, 0xe1,
+ 0xae, 0x67, 0xc4, 0xe0, 0xaf, 0x41, 0xaa, 0xc0, 0xb3, 0x5d, 0xaf, 0x7e, 0xa5,
+ 0xd3, 0xa9, 0x44, 0xa6, 0xf9, 0xa8, 0xad, 0xb2, 0x60, 0xae, 0x57, 0xb2, 0xd4,
+ 0xaf, 0xab, 0xa8, 0x48, 0xbc, 0x66, 0xc2, 0x54, 0xac, 0xc6, 0xb5, 0xc7, 0xb7,
+ 0x56, 0xba, 0xaf, 0xc1, 0x6e, 0xa5, 0xcd, 0xb5, 0x63, 0xac, 0xb9, 0xa4, 0xc9,
+ 0xc3, 0xb7, 0xac, 0xd9, 0xb2, 0xb1, 0xb3, 0xd1, 0xb3, 0xd3, 0xb8, 0x74, 0xae,
+ 0x76, 0xa5, 0xa2, 0xb7, 0xe0, 0xac, 0x49, 0xc0, 0xe3, 0xb8, 0xd6, 0xab, 0xcd,
+ 0xbd, 0xbe, 0xa4, 0x51, 0xa5, 0xdb, 0xac, 0x42, 0xae, 0xc9, 0xa4, 0xb0, 0xad,
+ 0xb9, 0xbb, 0x6b, 0xb9, 0xea, 0xc3, 0xd1, 0xa5, 0x76, 0xa5, 0xda, 0xa8, 0xcf,
+ 0xab, 0xcb, 0xbe, 0x70, 0xa9, 0x6c, 0xa6, 0xa1, 0xa5, 0xdc, 0xa4, 0x68, 0xa5,
+ 0x40, 0xac, 0x55, 0xa8, 0xc6, 0xab, 0xf8, 0xbb, 0x7d, 0xb3, 0x75, 0xb6, 0xd5,
+ 0xac, 0x4f, 0xb6, 0xdd, 0xbe, 0xbd, 0xbe, 0x41, 0xa5, 0x4b, 0xa8, 0xcd, 0xc4,
+ 0xc0, 0xb9, 0xa2, 0xa4, 0xf3, 0xa5, 0xab, 0xab, 0xee, 0xab, 0xc7, 0xb5, 0xf8,
+ 0xb8, 0xd5, 0xa6, 0xac, 0xa4, 0xe2, 0xad, 0xba, 0xa6, 0x75, 0xb9, 0xd8, 0xb1,
+ 0xc2, 0xb0, 0xe2, 0xa8, 0xfc, 0xbd, 0x47, 0xc3, 0x7e, 0xbd, 0xad, 0xbc, 0xcf,
+ 0xae, 0xde, 0xae, 0xed, 0xa7, 0xe7, 0xbf, 0xe9, 0xa8, 0xfb, 0xb5, 0xce, 0xb2,
+ 0x51, 0xb2, 0xa8, 0xae, 0xd1, 0xc5, 0xab, 0xb1, 0x45, 0xbc, 0xf4, 0xc1, 0xa6,
+ 0xb4, 0xbb, 0xc0, 0xc6, 0xb8, 0x70, 0xb8, 0xbe, 0xb6, 0xc1, 0xb9, 0xab, 0xc4,
+ 0xdd, 0xb3, 0x4e, 0xad, 0x7a, 0xbe, 0xf0, 0xa7, 0xf4, 0xa6, 0xa7, 0xbd, 0xdd,
+ 0xb9, 0xd6, 0xb1, 0x66, 0xbc, 0xc6, 0xba, 0xa4, 0xae, 0xa4, 0xa8, 0xea, 0xad,
+ 0x41, 0xba, 0x4c, 0xb0, 0x49, 0xa5, 0xcf, 0xab, 0xd3, 0xae, 0xea, 0xac, 0x43,
+ 0xc1, 0xf7, 0xc2, 0xf9, 0xb2, 0x6e, 0xbd, 0xd6, 0xa4, 0xf4, 0xba, 0xce, 0xb5,
+ 0x7c, 0xa7, 0x6d, 0xc0, 0xfe, 0xb6, 0xb6, 0xb5, 0xcf, 0xbb, 0xa1, 0xba, 0xd3,
+ 0xae, 0xd2, 0xc3, 0x7b, 0xb4, 0xb5, 0xbc, 0xb9, 0xbc, 0x52, 0xab, 0xe4, 0xa8,
+ 0x70, 0xa5, 0x71, 0xb5, 0xb7, 0xa6, 0xba, 0xb8, 0x76, 0xa6, 0x78, 0xb6, 0xe0,
+ 0xa5, 0x7c, 0xa6, 0xf8, 0xa6, 0xfc, 0xb9, 0x7d, 0xa4, 0x78, 0xc3, 0x50, 0xc1,
+ 0x71, 0xbc, 0xa3, 0xb9, 0x7c, 0xb0, 0x65, 0xa7, 0xba, 0xb3, 0x5e, 0xbb, 0x77,
+ 0xb7, 0x6a, 0xbf, 0xb4, 0xc2, 0x5d, 0xb9, 0xc2, 0xc4, 0xac, 0xb6, 0x70, 0xab,
+ 0x55, 0xaf, 0xc0, 0xb3, 0x74, 0xb5, 0xaf, 0xe0, 0xf4, 0xb6, 0xec, 0xb7, 0xb9,
+ 0xb1, 0x4a, 0xb6, 0x44, 0xb5, 0xc2, 0xbb, 0xc4, 0xbb, 0x5b, 0xba, 0xe2, 0xc1,
+ 0xf6, 0xb6, 0xa6, 0xc0, 0x48, 0xb8, 0x6b, 0xc5, 0xe8, 0xb8, 0x48, 0xb7, 0xb3,
+ 0xc1, 0x4a, 0xb9, 0x45, 0xc0, 0x47, 0xaf, 0xa9, 0xae, 0x5d, 0xb7, 0x6c, 0xb5,
+ 0xab, 0xbb, 0x62, 0xb1, 0xf4, 0xad, 0xf6, 0xc1, 0x59, 0xba, 0xbe, 0xaf, 0xc1,
+ 0xc2, 0xea, 0xa9, 0xd2, 0xb6, 0xf2, 0xa5, 0x4c, 0xa5, 0xa6, 0xa6, 0x6f, 0xb6,
+ 0xf0, 0xc3, 0xa1, 0xbe, 0xd8, 0xc1, 0xcf, 0xbd, 0xf1, 0xad, 0x4c, 0xad, 0x61,
+ 0xa9, 0xef, 0xa5, 0x78, 0xae, 0xf5, 0xa1, 0xbc, 0xa4, 0xd3, 0xba, 0x41, 0xa8,
+ 0x4f, 0xa7, 0x7e, 0xc5, 0x75, 0xb3, 0x67, 0xc5, 0xf5, 0xc5, 0x79, 0xbe, 0xc2,
+ 0xc0, 0xc8, 0xb7, 0xf0, 0xbc, 0xe6, 0xc3, 0xd3, 0xbd, 0xcd, 0xa9, 0x5a, 0xb4,
+ 0xe0, 0xb3, 0x52, 0xba, 0xd2, 0xb1, 0xb4, 0xb9, 0xc4, 0xac, 0xb4, 0xb4, 0xf6,
+ 0xb6, 0xed, 0xb7, 0x65, 0xb0, 0xf3, 0xb4, 0xc5, 0xbd, 0xa3, 0xad, 0xf0, 0xbf,
+ 0x7d, 0xad, 0xd5, 0xbd, 0xf6, 0xb2, 0x49, 0xbd, 0xeb, 0xbf, 0x53, 0xb1, 0xc7,
+ 0xc0, 0xdc, 0xb7, 0xca, 0xb8, 0x6c, 0xb5, 0xe5, 0xae, 0xe7, 0xb0, 0x6b, 0xb2,
+ 0x5e, 0xb3, 0xb3, 0xb0, 0x51, 0xae, 0x4d, 0xaf, 0x53, 0xc4, 0xf0, 0xc4, 0xcb,
+ 0xaf, 0x6b, 0xc1, 0xc3, 0xb1, 0xe8, 0xad, 0xe7, 0xbd, 0xf0, 0xbe, 0x4f, 0xb4,
+ 0xa3, 0xc3, 0x44, 0xbf, 0xe1, 0xb3, 0xda, 0xc5, 0xe9, 0xb4, 0xc0, 0xc0, 0xa1,
+ 0xb1, 0xa7, 0xae, 0xf7, 0xab, 0x63, 0xb1, 0x50, 0xa4, 0xd1, 0xb2, 0x4b, 0xb6,
+ 0xf1, 0xa5, 0xd0, 0xb2, 0xa2, 0xab, 0xef, 0xbb, 0x51, 0xb5, 0xc9, 0xac, 0x44,
+ 0xb1, 0xf8, 0xad, 0x7c, 0xb2, 0xb7, 0xb8, 0xf5, 0xb6, 0x4b, 0xc5, 0x4b, 0xa9,
+ 0xab, 0xc6, 0x55, 0xc5, 0xa5, 0xd6, 0x4c, 0xa5, 0xc5, 0xa7, 0xca, 0xb0, 0xb1,
+ 0xab, 0x46, 0xae, 0x78, 0xae, 0xbc, 0xb8, 0xa5, 0xb3, 0x71, 0xae, 0xe4, 0xe0,
+ 0xac, 0xc0, 0xfb, 0xa6, 0x50, 0xbb, 0xc9, 0xa7, 0xcd, 0xb5, 0xa3, 0xb1, 0xed,
+ 0xd1, 0xb6, 0xb5, 0xa9, 0xb2, 0xce, 0xb5, 0x68, 0xb0, 0xbd, 0xa7, 0xeb, 0xc0,
+ 0x59, 0xb3, 0x7a, 0xa5, 0x59, 0xa8, 0x72, 0xac, 0xf0, 0xb9, 0xcf, 0xae, 0x7b,
+ 0xb3, 0x7e, 0xb6, 0xee, 0xb1, 0x4f, 0xa4, 0x67, 0xa6, 0x52, 0xa8, 0xdf, 0xb4,
+ 0xf8, 0xb9, 0xce, 0xb1, 0xc0, 0xc0, 0x5a, 0xbb, 0x4c, 0xb8, 0xc0, 0xbf, 0xc6,
+ 0xb0, 0x68, 0xa7, 0x5d, 0xa4, 0xd9, 0xc1, 0x76, 0xa9, 0xec, 0xa6, 0xab, 0xb2,
+ 0xe6, 0xc0, 0x6b, 0xaa, 0xfb, 0xb9, 0xa4, 0xbe, 0x6d, 0xbe, 0xf2, 0xa7, 0xb4,
+ 0xa9, 0xdd, 0xb3, 0xe8, 0xab, 0xf5, 0xab, 0x7a, 0xb5, 0xec, 0xba, 0xda, 0xab,
+ 0xbd, 0xa5, 0xcb, 0xc4, 0xfb, 0xac, 0x6e, 0xa5, 0x7e, 0xbd, 0xdc, 0xc5, 0x73,
+ 0xc6, 0x57, 0xaa, 0xb1, 0xb9, 0x78, 0xa4, 0x59, 0xd6, 0x4a, 0xa7, 0xb9, 0xb8,
+ 0x4a, 0xae, 0xbe, 0xb1, 0xdf, 0xb5, 0x70, 0xb1, 0x7b, 0xa9, 0x7b, 0xb0, 0xfb,
+ 0xb8, 0x55, 0xb5, 0xc3, 0xa8, 0x4c, 0xa4, 0xfd, 0xa4, 0x60, 0xaa, 0x50, 0xba,
+ 0xf4, 0xa9, 0xb9, 0xa9, 0xf4, 0xb1, 0xe6, 0xa7, 0xd1, 0xa6, 0x6b, 0xab, 0xc2,
+ 0xc4, 0xde, 0xb7, 0x4c, 0xa6, 0x4d, 0xad, 0xb3, 0xb9, 0x48, 0xae, 0xe9, 0xb3,
+ 0xf2, 0xb0, 0xdf, 0xb1, 0xa9, 0xac, 0xb0, 0xc0, 0xe5, 0xba, 0xfb, 0xb8, 0xab,
+ 0xb5, 0xe4, 0xa9, 0x65, 0xb0, 0xb6, 0xb0, 0xb0, 0xa7, 0xc0, 0xbd, 0x6e, 0xa5,
+ 0xbc, 0xbd, 0xab, 0xa8, 0xfd, 0xac, 0xc8, 0xad, 0x47, 0xb3, 0xde, 0xc3, 0x51,
+ 0xa6, 0xec, 0xb4, 0xf4, 0xbf, 0xd7, 0xb1, 0x4c, 0xbc, 0xa2, 0xbd, 0xc3, 0xbd,
+ 0x45, 0xb7, 0xc5, 0xb0, 0x41, 0xa4, 0xe5, 0xbb, 0x44, 0xaf, 0xbe, 0xa7, 0x6b,
+ 0xc3, 0xad, 0xaf, 0xbf, 0xb0, 0xdd, 0xb6, 0xe4, 0xaf, 0xce, 0xc2, 0x7c, 0xbe,
+ 0xe2, 0xbd, 0xbd, 0xb4, 0xf5, 0xba, 0xdb, 0xa7, 0xda, 0xba, 0x57, 0xaa, 0xd7,
+ 0xb4, 0xa4, 0xa8, 0x55, 0xa7, 0xc5, 0xb6, 0xe3, 0xc2, 0xeb, 0xaf, 0x51, 0xa6,
+ 0xc3, 0xbb, 0x7a, 0xab, 0xce, 0xb5, 0x4c, 0xbf, 0xbe, 0xb1, 0xef, 0xa7, 0x5e,
+ 0xa7, 0x64, 0xa4, 0xf0, 0xaa, 0x5a, 0xa4, 0xad, 0xae, 0xb8, 0xa4, 0xc8, 0xbb,
+ 0x52, 0xa5, 0xee, 0xab, 0x56, 0xb6, 0xf5, 0xa5, 0xb3, 0xc3, 0xfa, 0xb1, 0xe0,
+ 0xaa, 0xab, 0xa4, 0xc5, 0xb0, 0xc8, 0xae, 0xa9, 0xbb, 0x7e, 0xa9, 0xf5, 0xba,
+ 0xb3, 0xaa, 0x52, 0xa6, 0xe8, 0xd6, 0xb4, 0xaa, 0xbf, 0xb4, 0xb7, 0xbc, 0x48,
+ 0xa7, 0x6c, 0xbf, 0xfc, 0xc4, 0xeb, 0xb5, 0x7d, 0xae, 0xa7, 0xa7, 0xc6, 0xb1,
+ 0x78, 0xbd, 0xa5, 0xa4, 0x69, 0xb1, 0xa4, 0xba, 0xb6, 0xb2, 0x6d, 0xb7, 0xcb,
+ 0xa6, 0xc1, 0xb5, 0x52, 0xc0, 0xca, 0xc5, 0xa7, 0xae, 0x75, 0xb2, 0xdf, 0xb7,
+ 0x40, 0xb3, 0xdf, 0xbb, 0xd1, 0xac, 0x7e, 0xa8, 0x74, 0xbb, 0xd8, 0xc0, 0xb8,
+ 0xb2, 0xd3, 0xbd, 0x4d, 0xbd, 0xbc, 0xa7, 0x58, 0xc1, 0xf8, 0xc1, 0xd2, 0xb7,
+ 0x76, 0xae, 0x6c, 0xab, 0x4c, 0xaf, 0x55, 0xa4, 0x55, 0xb7, 0x48, 0xae, 0x4c,
+ 0xc0, 0x7e, 0xb1, 0xc8, 0xa1, 0xbc, 0xa5, 0xfd, 0xa5, 0x50, 0xc2, 0x41, 0xc5,
+ 0xd6, 0xab, 0x77, 0xbd, 0xe5, 0xbb, 0xce, 0xb2, 0xec, 0xb6, 0xa2, 0xb2, 0x43,
+ 0xa9, 0xb6, 0xb6, 0xfb, 0xc5, 0xe3, 0xc0, 0x49, 0xb2, 0x7b, 0xc4, 0x6d, 0xbf,
+ 0xa4, 0xb8, 0xa2, 0xc0, 0x60, 0xb8, 0x72, 0xbe, 0xcb, 0xb3, 0xb4, 0xad, 0xad,
+ 0xbd, 0x75, 0xac, 0xdb, 0xb4, 0x5b, 0xc6, 0x5e, 0xad, 0xbb, 0xbd, 0x63, 0xc1,
+ 0xb8, 0xb4, 0xf0, 0xb6, 0x6d, 0xb5, 0xbe, 0xb2, 0xbb, 0xb8, 0xd4, 0xb7, 0x51,
+ 0xc5, 0x54, 0xa8, 0xc9, 0xb6, 0xb5, 0xab, 0xd1, 0xbe, 0xf3, 0xb9, 0xb3, 0xa6,
+ 0x56, 0xb6, 0x48, 0xbf, 0xbd, 0xb5, 0x76, 0xbe, 0x5d, 0xab, 0x64, 0xad, 0xfd,
+ 0xc4, 0xdb, 0xbe, 0x50, 0xae, 0xf8, 0xae, 0x64, 0xb2, 0x63, 0xbe, 0xe5, 0xa4,
+ 0x70, 0xa7, 0xb5, 0xae, 0xd5, 0xa8, 0x76, 0xbc, 0x53, 0xaf, 0xba, 0xae, 0xc4,
+ 0xb7, 0xa4, 0xa8, 0xc7, 0xb7, 0xb2, 0xc3, 0xc8, 0xbe, 0x63, 0xa8, 0xf3, 0xae,
+ 0xb5, 0xc4, 0xe2, 0xa8, 0xb8, 0xb1, 0xd7, 0xaf, 0xd9, 0xbf, 0xd3, 0xbc, 0x67,
+ 0xb1, 0xf1, 0xa8, 0xf8, 0xc3, 0xc9, 0xbe, 0xd3, 0xaa, 0x6e, 0xc2, 0x6d, 0xc1,
+ 0xc2, 0xae, 0x68, 0xc1, 0x7e, 0xaa, 0xe4, 0xbe, 0x4e, 0xaa, 0x59, 0xa8, 0xaf,
+ 0xb7, 0x73, 0xca, 0xe3, 0xa4, 0xdf, 0xab, 0x48, 0xf4, 0xb5, 0xac, 0x50, 0xb8,
+ 0x7b, 0xb5, 0x56, 0xb4, 0x69, 0xbf, 0xb3, 0xa6, 0x44, 0xab, 0xac, 0xa7, 0xce,
+ 0xa8, 0xb7, 0xa6, 0xe6, 0xbf, 0xf4, 0xa9, 0xaf, 0xa7, 0xf6, 0xa9, 0xca, 0xa9,
+ 0x6d, 0xa5, 0x53, 0xa5, 0xfb, 0xaf, 0xdd, 0xa6, 0x49, 0xac, 0xa4, 0xb6, 0xaf,
+ 0xba, 0xb5, 0xa5, 0xf0, 0xad, 0xd7, 0xb2, 0xdb, 0xa6, 0xb4, 0xb6, 0xe5, 0xc4,
+ 0xc3, 0xa8, 0x71, 0xb3, 0x53, 0xc2, 0xb8, 0xbc, 0x56, 0xa6, 0xa6, 0xbb, 0xdd,
+ 0xb5, 0xea, 0xbc, 0x4e, 0xb6, 0xb7, 0xae, 0x7d, 0xb3, 0x5c, 0xbb, 0x57, 0xb3,
+ 0xa4, 0xb1, 0xd4, 0xa6, 0xb0, 0xa7, 0xc7, 0xaf, 0x62, 0xab, 0xf2, 0xb5, 0xb6,
+ 0xb4, 0x42, 0xba, 0xfc, 0xc4, 0xf2, 0xb0, 0x61, 0xb3, 0xd9, 0xab, 0xc5, 0xc4,
+ 0x61, 0xb1, 0xdb, 0xa5, 0xc8, 0xbf, 0xef, 0xc5, 0x7e, 0xaf, 0x74, 0xb5, 0xba,
+ 0xb9, 0x75, 0xc1, 0xa7, 0xbe, 0xc7, 0xa5, 0xde, 0xb3, 0xb7, 0xa6, 0xe5, 0xb3,
+ 0xd4, 0xe2, 0xc0, 0xb4, 0x60, 0xa6, 0xaf, 0xb8, 0xdf, 0xb4, 0x4d, 0xb9, 0xa5,
+ 0xa8, 0xb5, 0xae, 0xee, 0xa6, 0xc4, 0xb0, 0x56, 0xb0, 0x54, 0xbb, 0xb9, 0xa8,
+ 0xb3, 0xc0, 0xa3, 0xa9, 0xe3, 0xbe, 0x7e, 0xc0, 0x6e, 0xa7, 0x72, 0xa4, 0x58,
+ 0xaa, 0xde, 0xa4, 0xfa, 0xb0, 0x48, 0xb1, 0x56, 0xb8, 0xc5, 0xb2, 0x50, 0xb6,
+ 0xae, 0xb0, 0xd7, 0xa8, 0xc8, 0xb3, 0x59, 0xb2, 0x6a, 0xc3, 0x60, 0xec, 0x49,
+ 0xb7, 0xcf, 0xb2, 0x54, 0xc6, 0x51, 0xc4, 0x59, 0xac, 0xe3, 0xe3, 0xe9, 0xc5,
+ 0xc9, 0xa9, 0xb5, 0xa8, 0xa5, 0xc3, 0x43, 0xc0, 0x46, 0xaa, 0xa2, 0xaa, 0x75,
+ 0xa9, 0x61, 0xb1, 0xbb, 0xb2, 0xb4, 0xad, 0x6c, 0xba, 0x74, 0xc6, 0x41, 0xb3,
+ 0xf7, 0xbf, 0x50, 0xb9, 0xbd, 0xb5, 0x78, 0xb6, 0xad, 0xad, 0xf1, 0xab, 0xdb,
+ 0xbf, 0x56, 0xae, 0x62, 0xbf, 0xce, 0xc5, 0xe7, 0xac, 0x6f, 0xa5, 0xa1, 0xc0,
+ 0x6d, 0xaf, 0xb1, 0xb7, 0xa8, 0xb4, 0xad, 0xa8, 0xcb, 0xba, 0xc5, 0xa6, 0xcf,
+ 0xac, 0x76, 0xb6, 0xa7, 0xae, 0xf1, 0xa5, 0xf5, 0xc4, 0x6f, 0xbe, 0x69, 0xbc,
+ 0xcb, 0xba, 0x79, 0xc1, 0xdc, 0xb8, 0x79, 0xa7, 0xaf, 0xba, 0xbd, 0xb7, 0x6e,
+ 0xb3, 0xf3, 0xbb, 0xbb, 0xbd, 0x60, 0xc1, 0xc1, 0xab, 0xc0, 0xab, 0x72, 0xaf,
+ 0xe6, 0xc3, 0xc4, 0xad, 0x6e, 0xc4, 0xa3, 0xb7, 0xa6, 0xbc, 0x4f, 0xad, 0x43,
+ 0xb7, 0xdd, 0xb3, 0xa5, 0xa7, 0x4d, 0xa4, 0x5d, 0xad, 0xb6, 0xb1, 0xb3, 0xb7,
+ 0x7e, 0xb8, 0xad, 0xa6, 0xb2, 0xb5, 0xc5, 0xa9, 0x5d, 0xb2, 0x47, 0xa4, 0x40,
+ 0xb3, 0xfc, 0xc2, 0xe5, 0xb4, 0xa5, 0xe4, 0x76, 0xa8, 0xcc, 0xa5, 0xec, 0xa6,
+ 0xe7, 0xc0, 0x5b, 0xa6, 0x69, 0xbf, 0xf2, 0xb2, 0xbe, 0xbb, 0xf6, 0xaf, 0xd8,
+ 0xba, 0xc3, 0xa8, 0x5e, 0xa9, 0x79, 0xab, 0xbc, 0xc2, 0x55, 0xb4, 0xc8, 0xc3,
+ 0xc6, 0xad, 0xca, 0xa4, 0x77, 0xa4, 0x41, 0xa8, 0x6f, 0xa5, 0x48, 0xc3, 0xc0,
+ 0xa7, 0xed, 0xa9, 0xf6, 0xa8, 0xb6, 0xa6, 0x7a, 0xbb, 0xf5, 0xa7, 0xd0, 0xc1,
+ 0x72, 0xb6, 0x68, 0xb8, 0x77, 0xac, 0xcc, 0xa5, 0xe7, 0xb8, 0xc7, 0xb7, 0x4e,
+ 0xbc, 0xdd, 0xbe, 0xd0, 0xb8, 0x71, 0xaf, 0x71, 0xb7, 0xb8, 0xb8, 0xda, 0xc4,
+ 0xb3, 0xbd, 0xcb, 0xc4, 0xb6, 0xb2, 0xa7, 0xc1, 0x6c, 0xb2, 0xdd, 0xc3, 0xb6,
+ 0xaf, 0xf4, 0xbd, 0xae, 0xa6, 0x5d, 0xae, 0xef, 0xad, 0xb5, 0xb3, 0xb1, 0xab,
+ 0xc3, 0xa7, 0x75, 0xbb, 0xc8, 0xb2, 0x5d, 0xb1, 0x47, 0xb6, 0xbc, 0xa4, 0xa8,
+ 0xa4, 0xde, 0xc1, 0xf4, 0xa6, 0x4c, 0xad, 0x5e, 0xc4, 0xe5, 0xc0, 0xa6, 0xc6,
+ 0x4e, 0xc0, 0xb3, 0xc5, 0xd5, 0xbc, 0xfc, 0xbf, 0xc3, 0xc0, 0xe7, 0xba, 0xb7,
+ 0xc3, 0xc7, 0xaa, 0xef, 0xc4, 0xb9, 0xac, 0xd5, 0xbc, 0x76, 0xbf, 0x6f, 0xb5,
+ 0x77, 0xac, 0x4d, 0xb3, 0xe9, 0xbe, 0xd6, 0xb6, 0xc4, 0xc1, 0x73, 0xf7, 0xea,
+ 0xb1, 0x65, 0xb9, 0x6c, 0xbf, 0xe3, 0xb8, 0xba, 0xb5, 0xfa, 0xaa, 0x61, 0xb4,
+ 0xe9, 0xa5, 0xc3, 0xb1, 0x76, 0xab, 0x69, 0xa5, 0xce, 0xab, 0xd5, 0xc0, 0x75,
+ 0xb1, 0x79, 0xbc, 0x7e, 0xa4, 0xd7, 0xa5, 0xd1, 0xb6, 0x6c, 0xb9, 0x5c, 0xb5,
+ 0x53, 0xaa, 0x6f, 0xb9, 0x43, 0xa8, 0xbb, 0xa6, 0xb3, 0xa4, 0xcd, 0xa5, 0x6b,
+ 0xa6, 0xf6, 0xb9, 0x56, 0xbb, 0xa4, 0xa4, 0x53, 0xa5, 0xae, 0xa8, 0xb1, 0xb2,
+ 0x4a, 0xa9, 0xf3, 0xaa, 0xbb, 0xb7, 0xae, 0xb8, 0xb7, 0xb7, 0x4d, 0xc1, 0xd6,
+ 0xa7, 0x45, 0xab, 0x5c, 0xb9, 0x4f, 0xb3, 0xbd, 0xb4, 0x72, 0xb4, 0xfc, 0xba,
+ 0xae, 0xb6, 0xa8, 0xa4, 0xa9, 0xae, 0x54, 0xab, 0x42, 0xbb, 0x50, 0xc0, 0xac,
+ 0xac, 0xea, 0xa6, 0x74, 0xbb, 0x79, 0xa6, 0xd0, 0xa5, 0xc9, 0xb0, 0xec, 0xa8,
+ 0xa1, 0xc6, 0x7b, 0xa6, 0x53, 0xb9, 0x4a, 0xb3, 0xeb, 0xae, 0x6e, 0xb1, 0x73,
+ 0xc2, 0xa1, 0xb1, 0xfd, 0xba, 0xbb, 0xa8, 0x7c, 0xc5, 0x41, 0xaf, 0x44, 0xb4,
+ 0x4a, 0xb8, 0xce, 0xb9, 0x77, 0xbf, 0xdd, 0xb6, 0xbf, 0xc0, 0x70, 0xb2, 0x57,
+ 0xad, 0xde, 0xa4, 0xb8, 0xab, 0xae, 0xb0, 0x4b, 0xad, 0xec, 0xb4, 0xa9, 0xc1,
+ 0xd5, 0xb6, 0xe9, 0xad, 0xfb, 0xb6, 0xea, 0xb7, 0xe1, 0xb7, 0xbd, 0xbd, 0x74,
+ 0xbb, 0xb7, 0xad, 0x62, 0xc4, 0x40, 0xab, 0xe8, 0xb0, 0x7c, 0xa4, 0xea, 0xac,
+ 0xf9, 0xb6, 0x56, 0xc5, 0x44, 0xc6, 0x5f, 0xa9, 0xa8, 0xb8, 0x66, 0xa4, 0xeb,
+ 0xae, 0xae, 0xbe, 0x5c, 0xaf, 0xd0, 0xb6, 0xb3, 0xe0, 0xa8, 0xa4, 0xc3, 0xb9,
+ 0x6b, 0xa4, 0xb9, 0xb9, 0x42, 0xc4, 0xad, 0xc1, 0xdf, 0xb7, 0x77, 0xc3, 0xfd,
+ 0xa5, 0xa5, 0xa5, 0x60, 0xaf, 0x7b, 0xc2, 0xf8, 0xae, 0xe2, 0xab, 0x76, 0xa8,
+ 0x61, 0xae, 0x5f, 0xb8, 0xfc, 0xa6, 0x41, 0xa6, 0x62, 0xab, 0xa5, 0xf6, 0xe3,
+ 0xbc, 0xc8, 0xc6, 0x67, 0xc5, 0x42, 0xc5, 0xa6, 0xb8, 0xae, 0xbe, 0x44, 0xc1,
+ 0x56, 0xc6, 0x77, 0xc4, 0xa6, 0xb4, 0xc7, 0xa6, 0xad, 0xbe, 0xfe, 0xb0, 0x44,
+ 0xc4, 0xbc, 0xbe, 0xb8, 0xb3, 0x79, 0xa8, 0x6d, 0xa8, 0x5f, 0xc0, 0xea, 0xb3,
+ 0x64, 0xbe, 0xdc, 0xab, 0x68, 0xbf, 0x41, 0xb8, 0xe9, 0xab, 0xe7, 0xbc, 0x57,
+ 0xbc, 0xa8, 0xb4, 0xbf, 0xc3, 0xd8, 0xb2, 0xcf, 0xb3, 0xe5, 0xb4, 0xed, 0xa5,
+ 0xbe, 0xaa, 0xee, 0xee, 0xd4, 0xb9, 0x68, 0xaf, 0x77, 0xac, 0x5d, 0xba, 0x5e,
+ 0xa9, 0x51, 0xa5, 0x45, 0xac, 0xb5, 0xb6, 0x42, 0xba, 0x4b, 0xc2, 0x4e, 0xa6,
+ 0x76, 0xaf, 0xb6, 0xb6, 0xc5, 0xb9, 0xeb, 0xc2, 0xa4, 0xc0, 0xd6, 0xb8, 0xe2,
+ 0xd6, 0xdf, 0xaa, 0x67, 0xb7, 0xf8, 0xb1, 0xd9, 0xc1, 0xd3, 0xb9, 0xf1, 0xae,
+ 0x69, 0xc5, 0xd9, 0xb4, 0xcc, 0xa6, 0xfb, 0xbe, 0xd4, 0xaf, 0xb8, 0xb4, 0xef,
+ 0xba, 0xec, 0xbc, 0xcc, 0xb3, 0xb9, 0xb9, 0xfc, 0xba, 0x73, 0xb1, 0x69, 0xb4,
+ 0x78, 0xba, 0xa6, 0xa7, 0xfa, 0xa4, 0x56, 0xb1, 0x62, 0xbd, 0xe3, 0xa5, 0x4d,
+ 0xb5, 0xc8, 0xbf, 0x60, 0xbb, 0xd9, 0xa9, 0xdb, 0xac, 0x4c, 0xa7, 0xe4, 0xaa,
+ 0x68, 0xbb, 0xaf, 0xb7, 0xd3, 0xb8, 0x6e, 0xa5, 0xfc, 0xbb, 0x46, 0xa5, 0x6c,
+ 0xbe, 0x42, 0xa7, 0xe9, 0xad, 0xf5, 0xee, 0x68, 0xc2, 0xe1, 0xaa, 0xcc, 0xeb,
+ 0xe3, 0xbd, 0xa9, 0xb3, 0x6f, 0xae, 0xfd, 0xac, 0xc3, 0xb7, 0x72, 0xaf, 0x75,
+ 0xba, 0xc2, 0xaf, 0x7a, 0xbf, 0xb2, 0xad, 0x73, 0xb0, 0x77, 0xb0, 0xbb, 0xaa,
+ 0x45, 0xaf, 0x6c, 0xb6, 0x45, 0xbe, 0x5f, 0xae, 0xb6, 0xc2, 0xed, 0xb0, 0x7d,
+ 0xbb, 0x5d, 0xb1, 0xc3, 0xb8, 0x43, 0xa9, 0xba, 0xb2, 0x75, 0xaa, 0xa7, 0xa9,
+ 0xc3, 0xbe, 0xe3, 0xac, 0x40, 0xa5, 0xbf, 0xac, 0x46, 0xb4, 0x56, 0xc4, 0x70,
+ 0xbe, 0x47, 0xb5, 0xfd, 0xaa, 0xdb, 0xaa, 0x4b, 0xa4, 0xe4, 0xa7, 0x73, 0xbb,
+ 0x6a, 0xaa, 0xbe, 0xaa, 0xcf, 0xaf, 0xd7, 0xa5, 0xc4, 0xa4, 0xa7, 0xc2, 0xb4,
+ 0xc2, 0xbe, 0xaa, 0xbd, 0xb4, 0xd3, 0xb4, 0xde, 0xb0, 0xf5, 0xad, 0xc8, 0xcb,
+ 0xbb, 0xa7, 0x7d, 0xab, 0xfc, 0xa4, 0xee, 0xb3, 0x6b, 0xb0, 0xa6, 0xa6, 0xae,
+ 0xaf, 0xc8, 0xa7, 0xd3, 0xbc, 0xb0, 0xc2, 0x59, 0xa6, 0xdc, 0xad, 0x50, 0xb8,
+ 0x6d, 0xbc, 0x6d, 0xab, 0xcf, 0xa8, 0xee, 0xb4, 0xbc, 0xaf, 0xb4, 0xb8, 0x58,
+ 0xbd, 0xe8, 0xaa, 0xa5, 0xb2, 0xa9, 0xba, 0xa2, 0xaa, 0x76, 0xb2, 0xbf, 0xa4,
+ 0xa4, 0xac, 0xd8, 0xa9, 0xbe, 0xc4, 0xc1, 0xb0, 0x4a, 0xb2, 0xd7, 0xba, 0xd8,
+ 0xb8, 0x7e, 0xad, 0xab, 0xa5, 0xf2, 0xb2, 0xb3, 0xa6, 0xe0, 0xa9, 0x50, 0xa6,
+ 0x7b, 0xac, 0x77, 0xee, 0xa4, 0xb5, 0xb0, 0xb6, 0x62, 0xa8, 0x79, 0xa9, 0xaa,
+ 0xa9, 0x47, 0xbd, 0x4b, 0xa9, 0x7a, 0xb1, 0xde, 0xc6, 0x4a, 0xaf, 0x5d, 0xae,
+ 0xe8, 0xb5, 0xef, 0xa6, 0xb6, 0xbd, 0xde, 0xbd, 0xd1, 0xb8, 0xdd, 0xb3, 0x76,
+ 0xa6, 0xcb, 0xc0, 0xeb, 0xb5, 0x4e, 0xa9, 0xd6, 0xc6, 0x66, 0xc5, 0xf1, 0xa5,
+ 0x44, 0xb5, 0xdb, 0xac, 0x57, 0xa7, 0x55, 0xb3, 0x45, 0xb6, 0x4a, 0xc5, 0xb1,
+ 0xbf, 0x76, 0xa6, 0xed, 0xaa, 0x60, 0xaf, 0xac, 0xbe, 0x6e, 0xa7, 0xec, 0xa4,
+ 0xf6, 0xab, 0xfb, 0xb1, 0x4d, 0xbf, 0x6a, 0xc2, 0xe0, 0xbc, 0xb6, 0xc1, 0xc8,
+ 0xbd, 0x66, 0xbc, 0xce, 0xb2, 0xf8, 0xb8, 0xcb, 0xa7, 0xa9, 0xbc, 0xb2, 0xa7,
+ 0xa7, 0xaa, 0xac, 0xb4, 0xd5, 0xc0, 0x40, 0xb0, 0x6c, 0xc2, 0xd8, 0xbc, 0x59,
+ 0xba, 0xf3, 0xbd, 0xce, 0xb7, 0xc7, 0xae, 0xbb, 0xa9, 0xe5, 0xa8, 0xf4, 0xae,
+ 0xe0, 0xb5, 0x5a, 0xad, 0x5f, 0xb0, 0x75, 0xb0, 0xd6, 0xb5, 0xdb, 0xa8, 0x60,
+ 0xbf, 0x42, 0xaf, 0xf7, 0xab, 0x74, 0xb8, 0xea, 0xab, 0xba, 0xb4, 0xfe, 0xb2,
+ 0x64, 0xa7, 0xb6, 0xb5, 0xb5, 0xa5, 0x4a, 0xac, 0xf3, 0xb7, 0xba, 0xa4, 0x6c,
+ 0xa6, 0xdb, 0xba, 0x7b, 0xa6, 0x72, 0xc3, 0x4f, 0xb4, 0xc4, 0xc2, 0xdc, 0xa9,
+ 0x76, 0xba, 0xee, 0xc1, 0x60, 0xc1, 0x61, 0xb9, 0x51, 0xa8, 0xab, 0xab, 0xb5,
+ 0xb4, 0x7e, 0xaf, 0xb2, 0xa8, 0xac, 0xa8, 0xf2, 0xb1, 0xda, 0xaf, 0xaa, 0xb6,
+ 0x41, 0xaa, 0xfd, 0xb2, 0xd5, 0xc6, 0x70, 0xc4, 0xa1, 0xbc, 0x4c, 0xbe, 0x4b,
+ 0xb3, 0xcc, 0xb8, 0x6f, 0xb4, 0x4c, 0xbf, 0xed, 0xac, 0x51, 0xa5, 0xaa, 0xa6,
+ 0xf5, 0xac, 0x67, 0xb0, 0xb5, 0xa7, 0x40, 0xa7, 0xa4, 0xae, 0x79, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xc9, 0x48, 0xc9, 0x46, 0xa4,
+ 0x61, 0xa4, 0xa2, 0xa4, 0xdc, 0xa4, 0xca, 0xa5, 0x41, 0xa5, 0xe5, 0xa5, 0xe0,
+ 0xb0, 0xac, 0xd1, 0x65, 0xbe, 0xb5, 0xa1, 0xbc, 0xac, 0xeb, 0xa1, 0xbc, 0xa4,
+ 0x50, 0xc9, 0x47, 0xa4, 0xd4, 0xa4, 0xf8, 0xa5, 0x67, 0xa5, 0xc2, 0xc9, 0xc7,
+ 0xad, 0x4e, 0xd8, 0x50, 0xb7, 0xb6, 0xe2, 0xe9, 0xa1, 0xbc, 0xa1, 0xbc, 0xab,
+ 0x45, 0xe8, 0xf3, 0xc9, 0x41, 0xa5, 0xe4, 0xc9, 0x51, 0xaa, 0xcb, 0xa7, 0xb8,
+ 0xb6, 0xde, 0xe1, 0x4c, 0xa4, 0xb7, 0xcd, 0xf8, 0xad, 0xed, 0xf1, 0xef, 0xb3,
+ 0xd6, 0xbc, 0x72, 0xc5, 0xe2, 0xc5, 0xac, 0xc9, 0x43, 0xa5, 0x72, 0xd4, 0x6f,
+ 0xb9, 0xbc, 0xb0, 0xd0, 0xf0, 0xf3, 0xa8, 0xf6, 0xca, 0x72, 0xa1, 0xbc, 0xa4,
+ 0xc2, 0xa6, 0x46, 0xcd, 0xf0, 0xcb, 0xd2, 0xe4, 0xf3, 0xb3, 0xcf, 0xab, 0x66,
+ 0xd0, 0xe9, 0xd0, 0xe6, 0xad, 0xe6, 0xe3, 0xc7, 0xb6, 0xd1, 0xb9, 0xbb, 0xe1,
+ 0x42, 0xa1, 0xbc, 0xbe, 0xb0, 0xa1, 0xbc, 0xaa, 0xc9, 0xa1, 0xbc, 0xa4, 0xb1,
+ 0xc9, 0x53, 0xc9, 0x52, 0xc9, 0x65, 0xc9, 0x68, 0xa1, 0xbc, 0xa5, 0x51, 0xdc,
+ 0xba, 0xa5, 0xf6, 0xc9, 0xb7, 0xca, 0x5f, 0xc9, 0xae, 0xad, 0xce, 0xb3, 0xc9,
+ 0xa5, 0xea, 0xa6, 0xee, 0xa6, 0xf0, 0xca, 0x61, 0xa7, 0xf1, 0xa7, 0x48, 0xa7,
+ 0x46, 0xca, 0x63, 0xa6, 0xef, 0xa1, 0xbc, 0xa6, 0xf7, 0xcb, 0xb8, 0xcb, 0xb9,
+ 0xa8, 0xdd, 0xcb, 0xba, 0xa8, 0xd4, 0xa8, 0xdc, 0xa8, 0xdb, 0xa8, 0xd9, 0xbe,
+ 0xab, 0xcb, 0xb3, 0xbb, 0xfa, 0xcb, 0xc6, 0xbe, 0xa9, 0xc5, 0x6b, 0xc4, 0xd7,
+ 0xcd, 0xde, 0xab, 0x5a, 0xcd, 0xe3, 0xcd, 0xe5, 0xab, 0x4d, 0xab, 0x53, 0xad,
+ 0xc4, 0xad, 0xc5, 0xb0, 0xb4, 0xad, 0xd6, 0xd0, 0xd3, 0xb0, 0xbf, 0xa1, 0xbc,
+ 0xad, 0xd8, 0xad, 0xda, 0xd0, 0xd7, 0xad, 0xbe, 0xad, 0xc3, 0xad, 0xd0, 0xe0,
+ 0xf3, 0xb0, 0xb3, 0xb0, 0xba, 0xd4, 0x55, 0xb0, 0xb9, 0xb6, 0xcd, 0xdc, 0xbc,
+ 0xc5, 0x6c, 0xbe, 0xaa, 0xf5, 0xc0, 0xdc, 0xbf, 0xb9, 0xaf, 0xe4, 0xea, 0xb9,
+ 0xb0, 0xe0, 0xfa, 0xe0, 0xf0, 0xb9, 0xad, 0xe4, 0xeb, 0xe4, 0xee, 0xc9, 0x69,
+ 0xc9, 0xf8, 0xca, 0x65, 0xdc, 0xc2, 0xab, 0x5b, 0xef, 0xb6, 0xc9, 0xf8, 0xf7,
+ 0x40, 0xa4, 0xbc, 0xb4, 0x53, 0xc6, 0x64, 0xef, 0x55, 0xf6, 0xd8, 0xc4, 0xdc,
+ 0xa1, 0xbc, 0xab, 0x6d, 0xd0, 0xb1, 0xb0, 0xcb, 0xe0, 0xed, 0xa6, 0x67, 0xa8,
+ 0xe1, 0xa1, 0xbc, 0xab, 0x5e, 0xad, 0xbd, 0xb3, 0x4f, 0xd7, 0xc0, 0xc1, 0xb6,
+ 0xf9, 0x43, 0xb8, 0xcf, 0xb8, 0x5b, 0xbe, 0xc6, 0xf2, 0xdd, 0xc3, 0xbd, 0xa1,
+ 0xbc, 0xc9, 0xbc, 0xa8, 0xe6, 0xcb, 0xce, 0xa1, 0xbc, 0xa1, 0xbc, 0xb6, 0xef,
+ 0xad, 0xdf, 0xf3, 0x65, 0xb0, 0x50, 0xb0, 0x52, 0xb0, 0x53, 0xf0, 0xdd, 0xdb,
+ 0xd6, 0xb3, 0x5b, 0xb5, 0xfe, 0xb6, 0x46, 0xb6, 0x43, 0xdb, 0xdc, 0xb6, 0x40,
+ 0xdb, 0xdf, 0xe0, 0x46, 0xe0, 0x4c, 0xe0, 0x47, 0xb8, 0xd7, 0xb8, 0xd9, 0xe0,
+ 0x4d, 0xb8, 0xe1, 0xb8, 0xe0, 0xbd, 0xd8, 0xeb, 0xa1, 0xe0, 0x48, 0xbb, 0xa6,
+ 0xbb, 0xa2, 0xbb, 0xa5, 0xe4, 0x4d, 0xe7, 0xd4, 0xe7, 0xd8, 0xbd, 0xd3, 0xbd,
+ 0xdb, 0xe7, 0xdc, 0xbd, 0xd4, 0xbd, 0xd9, 0xbf, 0xdb, 0xbf, 0xcf, 0xeb, 0xa6,
+ 0xbf, 0xd6, 0xeb, 0xa7, 0xbf, 0xd9, 0xbf, 0xdc, 0xbf, 0xda, 0xbf, 0xcd, 0xbf,
+ 0xd4, 0xeb, 0xab, 0xc2, 0xd3, 0xc6, 0x6d, 0xee, 0xa2, 0xee, 0xb0, 0xc1, 0xc4,
+ 0xc2, 0xd6, 0xf7, 0x56, 0xf2, 0xfb, 0xc3, 0xd7, 0xc3, 0xd4, 0xf9, 0xa9, 0xc4,
+ 0xb8, 0xc6, 0x40, 0xa1, 0xbc, 0xce, 0xaf, 0xa1, 0xbc, 0xca, 0x56, 0xa6, 0xe9,
+ 0xa8, 0xc0, 0xa8, 0xc1, 0xcd, 0xd9, 0xcd, 0xda, 0xab, 0x40, 0xb0, 0xa4, 0xd0,
+ 0xc2, 0xd4, 0x46, 0xdc, 0xa1, 0xb3, 0xb5, 0xb6, 0xab, 0xb3, 0xb2, 0xdc, 0x7e,
+ 0xb6, 0xaa, 0xe0, 0xd4, 0xee, 0xf5, 0xca, 0x52, 0xca, 0x54, 0xf1, 0x4b, 0xca,
+ 0x51, 0xe0, 0xa9, 0xcb, 0xa8, 0xcd, 0xd4, 0xcd, 0xd6, 0xaa, 0xf5, 0xbf, 0xf3,
+ 0xaa, 0xf3, 0xcd, 0xd7, 0xd3, 0xf7, 0xd0, 0xbb, 0xd0, 0xbc, 0xeb, 0xd7, 0xa1,
+ 0xbc, 0xd0, 0xbd, 0xdc, 0x50, 0xc5, 0xb0, 0xb0, 0x72, 0xd3, 0xfc, 0xd3, 0xfb,
+ 0xd3, 0xfa, 0xd7, 0xef, 0xd7, 0xe8, 0xb6, 0x6e, 0xdc, 0x52, 0xe4, 0x6b, 0xbb,
+ 0xc2, 0xe4, 0x68, 0xbe, 0x49, 0xe8, 0x54, 0xc1, 0xdd, 0xf4, 0xe1, 0xf6, 0x5a,
+ 0xaf, 0xec, 0xab, 0xb7, 0xe4, 0xf4, 0xa7, 0x57, 0xca, 0x6f, 0xa8, 0xf0, 0xd0,
+ 0xf8, 0xa1, 0xbc, 0xd4, 0x6d, 0xbc, 0x45, 0xad, 0xee, 0xc0, 0xe8, 0xf4, 0x77,
+ 0xa1, 0xbc, 0xc9, 0x42, 0xa1, 0xbc, 0xd4, 0x4a, 0xa1, 0xbc, 0xa5, 0xaf, 0xaf,
+ 0x63, 0xd0, 0x57, 0xca, 0xac, 0xb0, 0xee, 0xa1, 0xbc, 0xb9, 0xd1, 0xe9, 0x4f,
+ 0xbe, 0xc3, 0xc0, 0xa4, 0xa6, 0x66, 0xa6, 0x64, 0xc9, 0xc9, 0xa6, 0x60, 0xc2,
+ 0x52, 0xc9, 0xc8, 0xa6, 0x65, 0xc3, 0x63, 0xa7, 0xa6, 0xa1, 0xbc, 0xa9, 0x58,
+ 0xa1, 0xbc, 0xcb, 0xf5, 0xf1, 0xf6, 0xa9, 0x5c, 0xcb, 0xfb, 0xcc, 0x40, 0xcb,
+ 0xf4, 0xcb, 0xf8, 0xcb, 0xfc, 0xd4, 0xc1, 0xce, 0x53, 0xce, 0x54, 0xdc, 0xe5,
+ 0xd4, 0xba, 0xa1, 0xbc, 0xa1, 0xbc, 0xab, 0xb2, 0xab, 0xad, 0xd1, 0x4c, 0xb6,
+ 0xf6, 0xb3, 0xfa, 0xdc, 0xe4, 0xd1, 0x4d, 0xd1, 0x52, 0xd4, 0xb2, 0xa1, 0xbc,
+ 0xd4, 0xb7, 0xb0, 0xf1, 0xa1, 0xbc, 0xd4, 0xb8, 0xd4, 0xcb, 0xd4, 0xb5, 0xd4,
+ 0xb4, 0xd4, 0xb3, 0xd8, 0xa2, 0xd8, 0xa1, 0xa1, 0xbc, 0xb3, 0xfb, 0xdc, 0xed,
+ 0xa1, 0xbc, 0xe1, 0x5b, 0xe1, 0x56, 0xa1, 0xbc, 0xbc, 0x55, 0xc4, 0xc9, 0xc5,
+ 0x67, 0xc5, 0x74, 0xa1, 0xbc, 0xca, 0x4d, 0xca, 0x4e, 0xcb, 0x7a, 0xcb, 0xa1,
+ 0xcd, 0xbf, 0xcb, 0xa3, 0xcb, 0x7c, 0xcb, 0x7d, 0xeb, 0x52, 0xaa, 0xdc, 0xcd,
+ 0xb4, 0xea, 0xfc, 0xaa, 0xe8, 0xaa, 0xe7, 0xf4, 0xbe, 0xa1, 0xbc, 0xad, 0x55,
+ 0xcd, 0xb6, 0xaa, 0xe9, 0xcd, 0xba, 0xb3, 0x41, 0xb5, 0xe7, 0xe7, 0x76, 0xcd,
+ 0xc1, 0xcd, 0xbe, 0xcd, 0xc0, 0xa1, 0xbc, 0xaa, 0xdf, 0xa1, 0xbc, 0xad, 0x52,
+ 0xcd, 0xc3, 0xd0, 0x77, 0xad, 0x5b, 0xa1, 0xbc, 0xd0, 0xa1, 0xf4, 0xb8, 0xd0,
+ 0x6e, 0xad, 0x60, 0xd0, 0x75, 0xad, 0x5c, 0xa1, 0xbc, 0xd0, 0x7a, 0xd0, 0x7b,
+ 0xad, 0x64, 0xe7, 0x72, 0xa1, 0xbc, 0xad, 0x67, 0xb6, 0xf7, 0xde, 0x72, 0xd0,
+ 0xa2, 0xd0, 0x71, 0xd3, 0x7d, 0xd3, 0x77, 0xea, 0xfe, 0xe7, 0x6e, 0xd3, 0xa5,
+ 0xb2, 0xf7, 0xd3, 0xa6, 0xaf, 0xf5, 0xaf, 0xfc, 0xd7, 0x6c, 0xeb, 0x4c, 0xd3,
+ 0xac, 0xaf, 0xf6, 0xd3, 0xae, 0xaf, 0xfe, 0xee, 0x50, 0xaf, 0xfb, 0xaf, 0xfa,
+ 0xc2, 0xc9, 0xd3, 0x74, 0xd0, 0x72, 0xd3, 0x73, 0xba, 0xba, 0xe2, 0x6c, 0xeb,
+ 0x43, 0xd3, 0xa3, 0xf0, 0xb0, 0xa1, 0xbc, 0xbb, 0x5e, 0xdf, 0xd2, 0xa1, 0xbc,
+ 0xd7, 0x74, 0xb2, 0xf2, 0xe3, 0xc2, 0xb8, 0xb1, 0xb2, 0xfb, 0xd7, 0x6d, 0xb2,
+ 0xf9, 0xa1, 0xbc, 0xbb, 0x59, 0xb2, 0xfe, 0xee, 0x56, 0xd7, 0x67, 0xd7, 0x68,
+ 0xeb, 0x4f, 0xb2, 0xfd, 0xb2, 0xf1, 0xb2, 0xf0, 0xd7, 0x5b, 0xc5, 0x61, 0xa1,
+ 0xbc, 0xb5, 0xd7, 0xdb, 0x6d, 0xdb, 0x6f, 0xdb, 0x70, 0xd4, 0xbb, 0xa1, 0xbc,
+ 0xb5, 0xd6, 0xdb, 0x6e, 0xb5, 0xe0, 0xdb, 0x75, 0xa1, 0xbc, 0xb5, 0xe3, 0xdb,
+ 0x7b, 0xdb, 0x7c, 0xb5, 0xe8, 0xb5, 0xe9, 0xdb, 0x79, 0xb5, 0xd1, 0xb5, 0xd2,
+ 0xdb, 0x5e, 0xdb, 0xa5, 0xb5, 0xd5, 0xdb, 0x60, 0xbf, 0xa2, 0xb5, 0xdd, 0xdb,
+ 0x72, 0xa1, 0xbc, 0xdf, 0xb1, 0xdf, 0xb8, 0xdf, 0xb9, 0xdf, 0xbb, 0xeb, 0x41,
+ 0xa1, 0xbc, 0xdf, 0xc2, 0xeb, 0x44, 0xdf, 0xc4, 0xb8, 0xb0, 0xb8, 0xb6, 0xb8,
+ 0xb4, 0xdf, 0xac, 0xe7, 0x6f, 0xdf, 0xd5, 0xb8, 0xa9, 0xb8, 0xb5, 0xe3, 0xb8,
+ 0xe3, 0xb9, 0xe3, 0xbd, 0xc5, 0x5a, 0xa1, 0xbc, 0xbb, 0x5f, 0xbb, 0x63, 0xbb,
+ 0x55, 0xe3, 0xb0, 0xf7, 0xf0, 0xe3, 0xae, 0xe3, 0xb6, 0xe3, 0xb7, 0xe3, 0xac,
+ 0xf1, 0x6a, 0xee, 0x40, 0xe7, 0x5c, 0xbf, 0x5f, 0xa1, 0xbc, 0xe7, 0x75, 0xf5,
+ 0xfd, 0xe7, 0x54, 0xc4, 0xa9, 0xea, 0xf8, 0xe7, 0x4d, 0xbd, 0xb6, 0xe7, 0x64,
+ 0xbf, 0xb7, 0xbf, 0xb8, 0xbf, 0xb9, 0xeb, 0x42, 0xbf, 0xbf, 0xee, 0x44, 0xea,
+ 0x7b, 0xbf, 0xbb, 0xf4, 0xbf, 0xed, 0xfb, 0xed, 0xfc, 0xc1, 0xa9, 0xc1, 0xa8,
+ 0xed, 0xf5, 0xee, 0x52, 0xc3, 0xc1, 0xc1, 0xa3, 0xee, 0x51, 0xc2, 0xca, 0xf0,
+ 0xb8, 0xc2, 0xc8, 0xc4, 0xf6, 0xa1, 0xbc, 0xf2, 0xd4, 0xf4, 0xb9, 0xf5, 0xf8,
+ 0xf4, 0xc1, 0xf5, 0xfc, 0xc4, 0xf4, 0xf7, 0xf3, 0xa4, 0x7b, 0xab, 0xd9, 0xc9,
+ 0xcb, 0xb9, 0xdd, 0xd0, 0x55, 0xab, 0xb3, 0xae, 0x4f, 0xae, 0x4e, 0xb0, 0xcc,
+ 0xa4, 0x71, 0xc9, 0xd5, 0xa7, 0xbc, 0xc0, 0xaa, 0xa1, 0xbc, 0xb1, 0xbf, 0xe1,
+ 0xde, 0xcc, 0xbd, 0xcc, 0xb9, 0xa9, 0xe9, 0xa9, 0xed, 0xab, 0xfa, 0xe5, 0xb9,
+ 0xce, 0xdf, 0xd1, 0xba, 0xd1, 0xbb, 0xd1, 0xb8, 0xd5, 0x6d, 0xd9, 0x5e, 0xb1,
+ 0xba, 0xb1, 0xcc, 0xd5, 0x71, 0xba, 0x51, 0xd5, 0x79, 0xb1, 0xc5, 0xd5, 0x68,
+ 0xb1, 0xca, 0xd5, 0x7a, 0xe1, 0xe8, 0xd9, 0x60, 0xa1, 0xbc, 0xd9, 0x5d, 0xbc,
+ 0xc3, 0xd9, 0x67, 0xa1, 0xbc, 0xd9, 0x55, 0xb4, 0xac, 0xb4, 0x7d, 0xd9, 0x64,
+ 0xef, 0xd2, 0xdd, 0xae, 0xdd, 0xb6, 0xdd, 0xb8, 0xdd, 0x7d, 0xdd, 0xaa, 0xdd,
+ 0xab, 0xdd, 0xba, 0xe1, 0xe7, 0xf4, 0x4c, 0xba, 0x54, 0xe5, 0xaf, 0xba, 0x50,
+ 0xc2, 0x5e, 0xef, 0xd7, 0xbc, 0xc1, 0xf5, 0xcd, 0xa1, 0xbc, 0xe9, 0xa6, 0xe9,
+ 0xa4, 0xec, 0xec, 0xc0, 0xc2, 0xf2, 0x45, 0xf7, 0xdd, 0xf8, 0xef, 0xa4, 0x7c,
+ 0xca, 0xd6, 0xa1, 0xbc, 0xb7, 0x49, 0xa1, 0xbc, 0xa5, 0x77, 0xbc, 0x54, 0xa5,
+ 0x6e, 0xa5, 0x6f, 0xa5, 0x7b, 0xa6, 0x5c, 0xa1, 0xbc, 0xa6, 0x5b, 0xa1, 0xbc,
+ 0xe5, 0x46, 0xc5, 0x6d, 0xca, 0x79, 0xf1, 0xf2, 0xa7, 0x63, 0xa1, 0xbc, 0xd0,
+ 0xf9, 0xce, 0x4a, 0xa1, 0xbc, 0xa1, 0xbc, 0xcb, 0xdf, 0xa1, 0xbc, 0xa9, 0x45,
+ 0xa9, 0x4b, 0xcb, 0xef, 0xa9, 0x4e, 0xc0, 0x7b, 0xa9, 0x46, 0xa9, 0x4c, 0xcb,
+ 0xe7, 0xa1, 0xbc, 0xa1, 0xbc, 0xcd, 0xfc, 0xab, 0x7b, 0xa1, 0xbc, 0xe8, 0xfd,
+ 0xab, 0xa8, 0xab, 0x78, 0xe4, 0xf9, 0xb9, 0xcd, 0xce, 0x4d, 0xa1, 0xbc, 0xe9,
+ 0x41, 0xab, 0xa6, 0xab, 0xa9, 0xa1, 0xbc, 0xe9, 0x44, 0xa1, 0xbc, 0xec, 0xc1,
+ 0xab, 0xa7, 0xab, 0x7d, 0xa1, 0xbc, 0xbe, 0xba, 0xcd, 0xfe, 0xce, 0x4e, 0xe1,
+ 0x4d, 0xd0, 0xf4, 0xbc, 0x47, 0xae, 0x43, 0xad, 0xf8, 0xd0, 0xf5, 0xdc, 0xd4,
+ 0xa1, 0xbc, 0xae, 0x44, 0xd0, 0xfc, 0xae, 0x41, 0xd4, 0x77, 0xb9, 0xc9, 0xd8,
+ 0x6f, 0xd8, 0x70, 0xa1, 0xbc, 0xc4, 0xda, 0xb0, 0xe7, 0xb0, 0xde, 0xa1, 0xbc,
+ 0xd4, 0x75, 0xd4, 0x73, 0xad, 0xf2, 0xb0, 0xdc, 0xd4, 0x71, 0xd4, 0x72, 0xd8,
+ 0x6a, 0xb0, 0xe6, 0xd4, 0x7c, 0xb0, 0xe3, 0xb3, 0xe3, 0xdc, 0xd6, 0xb3, 0xe4,
+ 0xb3, 0xed, 0xa1, 0xbc, 0xd8, 0x6e, 0xd8, 0x71, 0xb3, 0xe7, 0xb3, 0xee, 0xdc,
+ 0xdb, 0xd8, 0x66, 0xb3, 0xd7, 0xb6, 0xd8, 0xb9, 0xc6, 0xf4, 0x41, 0xb3, 0xe1,
+ 0xb3, 0xf1, 0xa1, 0xbc, 0xb9, 0xc8, 0xb6, 0xe8, 0xb9, 0xca, 0xb6, 0xdf, 0xc4,
+ 0xd9, 0xa1, 0xbc, 0xdc, 0xd2, 0xb6, 0xdb, 0xdc, 0xd0, 0xdc, 0xd3, 0xb6, 0xe2,
+ 0xb6, 0xe7, 0xdc, 0xdd, 0xbe, 0xbc, 0xdc, 0xcc, 0xdc, 0xde, 0xb6, 0xd9, 0xa1,
+ 0xbc, 0xb6, 0xe1, 0xc5, 0xaf, 0xa1, 0xbc, 0xb9, 0xcb, 0xe1, 0x49, 0xe1, 0x4e,
+ 0xc4, 0x58, 0xa1, 0xbc, 0xb9, 0xbe, 0xb9, 0xbf, 0xe1, 0x47, 0xa1, 0xbc, 0xe4,
+ 0xfe, 0xbc, 0x49, 0xbc, 0x50, 0xe5, 0x44, 0xa1, 0xbc, 0xbe, 0xbe, 0xbe, 0xb2,
+ 0xc2, 0x50, 0xe4, 0xf8, 0xa1, 0xbc, 0xec, 0xc3, 0xbe, 0xb6, 0xbe, 0xbb, 0xbe,
+ 0xb3, 0xa1, 0xbc, 0xa1, 0xbc, 0xc0, 0x7d, 0xec, 0xc0, 0xa1, 0xbc, 0xf8, 0xee,
+ 0xc9, 0x49, 0xa6, 0x5f, 0xc9, 0xc6, 0xd4, 0xac, 0xa7, 0x7a, 0xcb, 0xf1, 0xab,
+ 0xaa, 0xae, 0x46, 0xd4, 0xab, 0xb0, 0xeb, 0xe9, 0x47, 0xb4, 0x57, 0xcc, 0x6f,
+ 0xcc, 0x6e, 0xa9, 0xae, 0xec, 0xdb, 0xe1, 0xb2, 0xb9, 0xf6, 0xb1, 0x63, 0xd8,
+ 0xf2, 0xb9, 0xf7, 0xb9, 0xf3, 0xa1, 0xbc, 0xbc, 0x6e, 0xa7, 0xc4, 0xc9, 0xd7,
+ 0xca, 0xc0, 0xa7, 0xc1, 0xb9, 0xf2, 0xca, 0xc2, 0xae, 0x73, 0xa1, 0xbc, 0xa7,
+ 0xc2, 0xb4, 0x50, 0xa1, 0xbc, 0xcc, 0x5e, 0xcc, 0x65, 0xa1, 0xbc, 0xcc, 0x61,
+ 0xa9, 0xa6, 0xa9, 0xa7, 0xcc, 0x63, 0xa1, 0xbc, 0xa9, 0xa2, 0xe9, 0x61, 0xab,
+ 0xd0, 0xe5, 0x69, 0xce, 0x7d, 0xb1, 0x57, 0xe5, 0x63, 0xd4, 0xfb, 0xb1, 0x5d,
+ 0xd4, 0xfc, 0xd5, 0x44, 0xb1, 0x5c, 0xd4, 0xf4, 0xb1, 0x53, 0xb1, 0x55, 0xc0,
+ 0xaf, 0xa1, 0xbc, 0xb4, 0x51, 0xd8, 0xe6, 0xdd, 0x52, 0xd8, 0xe3, 0xb7, 0x44,
+ 0xe1, 0xa8, 0xd8, 0xdb, 0xd8, 0xdd, 0xdd, 0x4f, 0xb7, 0x43, 0xa1, 0xbc, 0xe1,
+ 0xa3, 0xe5, 0x62, 0xbc, 0x6a, 0xc1, 0xc7, 0xec, 0xda, 0xc5, 0x71, 0xc9, 0x4c,
+ 0xa7, 0xcf, 0xcc, 0x75, 0xab, 0xe0, 0xab, 0xe2, 0xab, 0xe1, 0xb1, 0x74, 0xb1,
+ 0x70, 0xb1, 0x75, 0xb4, 0x61, 0xdd, 0x64, 0xbc, 0x78, 0xe9, 0x75, 0xc5, 0xfc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xc9, 0xa6, 0xca, 0x43, 0xc2, 0x78, 0xa1, 0xbc, 0xcb,
+ 0x63, 0xcb, 0x65, 0xaa, 0xad, 0xa1, 0xbc, 0xcd, 0x61, 0xcf, 0xc0, 0xea, 0x61,
+ 0xac, 0xbc, 0xde, 0xac, 0xd2, 0xa5, 0xaf, 0x58, 0xd2, 0xaa, 0xd2, 0xa8, 0xea,
+ 0x60, 0xd2, 0xa4, 0xd2, 0xa9, 0xd6, 0x61, 0xb2, 0x74, 0xc5, 0x7a, 0xd6, 0x65,
+ 0xd6, 0x69, 0xd6, 0x60, 0xf4, 0x6e, 0xda, 0x70, 0xa1, 0xbc, 0xb5, 0x54, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xda, 0x71, 0xba, 0xbc, 0xe2, 0xcb, 0xbc, 0xfb, 0xe6, 0x79,
+ 0xea, 0x5e, 0xed, 0x65, 0xf5, 0xdd, 0xa6, 0xdf, 0xb9, 0xd9, 0xb6, 0xb8, 0xb9,
+ 0xdb, 0xa1, 0xbc, 0xa1, 0xbc, 0xef, 0x4f, 0xb6, 0xbb, 0xf1, 0xad, 0xb6, 0xb9,
+ 0xdc, 0xae, 0xb6, 0xbd, 0xb9, 0x7e, 0xbb, 0xe8, 0xe8, 0xc1, 0xbe, 0x6c, 0xc0,
+ 0x5f, 0xa1, 0xbc, 0xc3, 0x49, 0xf3, 0xb1, 0xf3, 0xaf, 0xc4, 0x44, 0xa1, 0xbc,
+ 0xf5, 0x57, 0xa1, 0xbc, 0xc9, 0x79, 0xe5, 0x75, 0xca, 0xcd, 0xa9, 0xb4, 0xce,
+ 0xba, 0xab, 0xd6, 0xd5, 0x49, 0xb1, 0x67, 0xb1, 0x68, 0xd5, 0x4b, 0xbd, 0xe9,
+ 0xe1, 0xbc, 0xe1, 0xb6, 0xe5, 0x73, 0xe9, 0x72, 0xe9, 0x6f, 0xc1, 0x74, 0xa1,
+ 0xbc, 0xc9, 0x7b, 0xa6, 0xa4, 0xc4, 0x62, 0xbc, 0xad, 0xca, 0xdb, 0xe1, 0xd3,
+ 0xca, 0xdd, 0xca, 0xde, 0xb7, 0x5a, 0xb1, 0xa3, 0xb7, 0x5b, 0xa7, 0xd8, 0xca,
+ 0xd9, 0xa7, 0xd7, 0xcc, 0x7c, 0xa9, 0xc5, 0xcc, 0x7b, 0xa9, 0xcd, 0xa9, 0xc2,
+ 0xcc, 0xa9, 0xa9, 0xcb, 0xa9, 0xcc, 0xcc, 0xa2, 0xe9, 0x7d, 0xa9, 0xc9, 0xba,
+ 0x45, 0xec, 0xe6, 0xb4, 0x6c, 0xb7, 0x5f, 0xce, 0xcb, 0xab, 0xf1, 0xd9, 0x40,
+ 0xae, 0xaf, 0xae, 0xaa, 0xe1, 0xc7, 0xd1, 0xa7, 0xd1, 0xa8, 0xd1, 0xa5, 0xae,
+ 0xad, 0xd1, 0xaa, 0xb4, 0x67, 0xb1, 0xa2, 0xd5, 0x5e, 0xd5, 0x5c, 0xb1, 0xa6,
+ 0xb1, 0xa8, 0xb1, 0xab, 0xb1, 0x7c, 0xb7, 0x59, 0xe5, 0xa6, 0xb4, 0x6a, 0xb4,
+ 0x68, 0xb4, 0x6d, 0xb4, 0x73, 0xb4, 0x70, 0xdd, 0x68, 0xdd, 0x67, 0xba, 0x48,
+ 0xbc, 0xa9, 0xbc, 0xac, 0xbc, 0xa5, 0xa1, 0xbc, 0xbe, 0xcf, 0xc3, 0x6a, 0xa9,
+ 0xbd, 0xf1, 0x6f, 0xad, 0xac, 0xd8, 0x45, 0xc1, 0xf2, 0xb6, 0xa3, 0xb6, 0x7b,
+ 0xdc, 0x7a, 0xf6, 0x6b, 0xbe, 0x5b, 0xe8, 0xa7, 0xf9, 0xc4, 0xe8, 0xa6, 0xec,
+ 0x48, 0xec, 0x4b, 0xf1, 0xbe, 0xec, 0x4c, 0xec, 0x4e, 0xec, 0x46, 0xee, 0xf1,
+ 0xc1, 0xf0, 0xc2, 0xf3, 0xc2, 0xf5, 0xc2, 0xf6, 0xf5, 0x45, 0xa1, 0xbc, 0xc9,
+ 0x62, 0xa9, 0xcf, 0xa1, 0xbc, 0xc9, 0xfd, 0xc9, 0xfa, 0xc9, 0xfc, 0xf5, 0xd3,
+ 0xa8, 0x4a, 0xa8, 0x4e, 0xa8, 0x5c, 0xa8, 0x50, 0xa8, 0x51, 0xcb, 0x53, 0xa8,
+ 0x58, 0xa8, 0x5a, 0xa8, 0x59, 0xd9, 0xec, 0xcc, 0xf8, 0xcc, 0xf4, 0xcc, 0xf5,
+ 0xf2, 0x5d, 0xc3, 0x79, 0xaa, 0x74, 0xaa, 0x72, 0xa1, 0xbc, 0xaa, 0x7e, 0xaa,
+ 0x7d, 0xef, 0xf6, 0xcc, 0xf0, 0xcc, 0xf1, 0xaa, 0x62, 0xaa, 0x6c, 0xaa, 0x7b,
+ 0xae, 0xf9, 0xac, 0xa7, 0xac, 0xa8, 0xac, 0x7b, 0xaf, 0x48, 0xd9, 0xfe, 0xcf,
+ 0xa7, 0xcf, 0x77, 0xcf, 0x78, 0xac, 0xad, 0xac, 0xae, 0xe9, 0xf8, 0xac, 0xab,
+ 0xac, 0xac, 0xcf, 0x7a, 0xc2, 0x73, 0xe2, 0x71, 0xbc, 0xf1, 0xcf, 0x76, 0xd2,
+ 0x50, 0xd2, 0x4f, 0xd5, 0xe9, 0xe6, 0x5c, 0xd2, 0x55, 0xae, 0xfe, 0xaf, 0x4b,
+ 0xa1, 0xbc, 0xd2, 0x57, 0xd2, 0x5a, 0xd2, 0x46, 0xb2, 0x5a, 0xb2, 0x4e, 0xb2,
+ 0x58, 0xb2, 0x53, 0xc2, 0x70, 0xb2, 0x67, 0xd5, 0xed, 0xbf, 0x49, 0xb2, 0x68,
+ 0xd5, 0xf3, 0xb2, 0x46, 0xc2, 0x6e, 0xd5, 0xe1, 0xd5, 0xf1, 0xb2, 0x52, 0xd9,
+ 0xf1, 0xb4, 0xf3, 0xb5, 0x42, 0xda, 0x47, 0xde, 0x59, 0xb5, 0x47, 0xe2, 0xa9,
+ 0xda, 0x4b, 0xb4, 0xe6, 0xb4, 0xe8, 0xb4, 0xec, 0xb5, 0x44, 0xf9, 0xd0, 0xde,
+ 0x4c, 0xb7, 0xc2, 0xf5, 0xd4, 0xe2, 0xa5, 0xef, 0xef, 0xb7, 0xc1, 0xb7, 0xcc,
+ 0xde, 0x50, 0xa1, 0xbc, 0xde, 0x54, 0xe6, 0x5f, 0xb7, 0xcd, 0xde, 0x58, 0xde,
+ 0x46, 0xb7, 0xbc, 0xde, 0x48, 0xe6, 0x43, 0xf2, 0x5e, 0xc3, 0x74, 0xa1, 0xbc,
+ 0xba, 0xa8, 0xe2, 0xa3, 0xba, 0xaa, 0xe2, 0xa1, 0xc4, 0x6b, 0xef, 0xf5, 0xba,
+ 0xac, 0xe2, 0x75, 0xba, 0x78, 0xe6, 0x41, 0xe6, 0x40, 0xe6, 0x42, 0xbc, 0xe8,
+ 0xe6, 0x4c, 0xbc, 0xe0, 0xbc, 0xeb, 0xc3, 0x75, 0xea, 0x41, 0xbf, 0x43, 0xbf,
+ 0x46, 0xbf, 0x47, 0xbe, 0xfc, 0xc0, 0xe1, 0xc0, 0xe4, 0xed, 0x57, 0xc0, 0xda,
+ 0xc0, 0xde, 0xc3, 0x76, 0xf2, 0x63, 0xc3, 0x73, 0xf4, 0x65, 0xf4, 0x5c, 0xf8,
+ 0xaf, 0xc5, 0xf4, 0xa1, 0xbc, 0xc9, 0x73, 0xcc, 0x58, 0xcc, 0x57, 0xab, 0xc9,
+ 0xae, 0x66, 0xda, 0xac, 0xc4, 0xca, 0xba, 0x53, 0xb9, 0xed, 0xbc, 0x64, 0xeb,
+ 0x72, 0xbe, 0xc8, 0xee, 0xbf, 0xee, 0xaa, 0xa1, 0xbc, 0xcd, 0xce, 0xcd, 0xd1,
+ 0xad, 0x7e, 0xd0, 0xb5, 0xad, 0xa3, 0xc2, 0xe2, 0xad, 0x7b, 0xb3, 0x77, 0xad,
+ 0xa4, 0xb0, 0x6d, 0xd3, 0xef, 0xd7, 0xe3, 0xc5, 0xdd, 0xd7, 0xe4, 0xb3, 0x70,
+ 0xb3, 0x7c, 0xd7, 0xe7, 0xb6, 0x66, 0xb6, 0x6a, 0xdc, 0x4d, 0xdc, 0x4f, 0xe0,
+ 0xa1, 0xb9, 0x4e, 0xe0, 0x7d, 0xb9, 0x49, 0xbe, 0x43, 0xbb, 0xb8, 0xbb, 0xbd,
+ 0xbb, 0xbf, 0xbe, 0xe6, 0xbf, 0xee, 0xc1, 0xd8, 0xc1, 0xdb, 0xc2, 0xe4, 0xc2,
+ 0xe3, 0xc3, 0xe5, 0xa1, 0xbc, 0xb1, 0x6b, 0xce, 0xbd, 0xd8, 0xf4, 0xc9, 0x75,
+ 0xab, 0xa4, 0xae, 0x6a, 0xd4, 0xf3, 0xb4, 0x47, 0xe1, 0xa2, 0xc0, 0xab, 0xc4,
+ 0xf3, 0xd1, 0x79, 0xa9, 0xb8, 0xab, 0xda, 0xd7, 0x58, 0xb4, 0x5d, 0xf7, 0xa7,
+ 0xc9, 0x4b, 0xa6, 0x71, 0xa6, 0x6d, 0xa7, 0xb0, 0xbc, 0x61, 0xb9, 0xe1, 0xa7,
+ 0xad, 0xca, 0xb5, 0xa9, 0x6e, 0xd8, 0xb5, 0xa7, 0xac, 0xa7, 0xb1, 0xa9, 0x71,
+ 0xcc, 0x48, 0xa9, 0x6f, 0xa9, 0x6b, 0xa9, 0x63, 0xd4, 0xd5, 0xbc, 0x63, 0xce,
+ 0x67, 0xf6, 0xdc, 0xab, 0xbb, 0xab, 0xb9, 0xa1, 0xbc, 0xae, 0x5b, 0xae, 0x5c,
+ 0xb4, 0x45, 0xbc, 0x5f, 0xae, 0x50, 0xae, 0x58, 0xae, 0x55, 0xb0, 0xfe, 0xd4,
+ 0xd1, 0xb1, 0x44, 0xd4, 0xd0, 0xb1, 0x40, 0xb1, 0x41, 0xbc, 0x60, 0xa1, 0xbc,
+ 0xb6, 0xfe, 0xb4, 0x44, 0xb4, 0x40, 0xd8, 0xb8, 0xb6, 0xfc, 0xe1, 0x72, 0xb7,
+ 0x42, 0xe9, 0x54, 0xc0, 0xa7, 0xdc, 0xf7, 0xe1, 0x75, 0xb9, 0xe4, 0xe9, 0x52,
+ 0xb9, 0xe2, 0xb9, 0xdf, 0xb9, 0xe3, 0xe1, 0x6b, 0xbc, 0x5e, 0xe9, 0x51, 0xe9,
+ 0x58, 0xec, 0xd0, 0xc0, 0xa8, 0xc4, 0x5c, 0xc9, 0xd4, 0xa1, 0xbc, 0xa7, 0xb7,
+ 0xcc, 0x56, 0xb4, 0x46, 0xa4, 0x6d, 0xa4, 0x6e, 0xcc, 0x55, 0xe8, 0xca, 0xbe,
+ 0x6f, 0xbe, 0x74, 0xf5, 0x5f, 0xc5, 0xe6, 0xbe, 0x71, 0xe8, 0xce, 0xc5, 0xbb,
+ 0xf7, 0x7e, 0xc0, 0x63, 0xc6, 0x7a, 0xf1, 0xaf, 0xf1, 0xb2, 0xf1, 0xb6, 0xf6,
+ 0x7c, 0xf5, 0x63, 0xc4, 0x45, 0xf6, 0x7d, 0xf5, 0x61, 0xf5, 0x62, 0xc5, 0x59,
+ 0xf6, 0x7b, 0xf7, 0x7c, 0xc6, 0x6b, 0xf9, 0xb3, 0xa1, 0xbc, 0xac, 0xfa, 0xac,
+ 0xf4, 0xac, 0xf8, 0xd0, 0x4b, 0xf5, 0xe7, 0xaf, 0xc6, 0xaf, 0xc4, 0xd3, 0x56,
+ 0xd6, 0xe6, 0xb2, 0xd8, 0xb2, 0xd9, 0xbf, 0xa8, 0xb2, 0xd1, 0xb2, 0xd2, 0xd6,
+ 0xed, 0xa1, 0xbc, 0xda, 0xfb, 0xb5, 0xbc, 0xdf, 0x58, 0xdf, 0x60, 0xdf, 0x57,
+ 0xba, 0xf0, 0xba, 0xf6, 0xe3, 0x6e, 0xa1, 0xbc, 0xe3, 0x6c, 0xbd, 0x78, 0xba,
+ 0xfe, 0xe3, 0x71, 0xe3, 0x65, 0xba, 0xed, 0xba, 0xfd, 0xbd, 0x79, 0xe6, 0xe7,
+ 0xbd, 0x7b, 0xbd, 0x7a, 0xf0, 0x72, 0xe6, 0xeb, 0xe6, 0xec, 0xe6, 0xed, 0xea,
+ 0xd8, 0xe6, 0xe8, 0xbf, 0xa7, 0xbf, 0xa6, 0xea, 0xd0, 0xbf, 0xa5, 0xed, 0xd0,
+ 0xbf, 0x7e, 0xbf, 0xa1, 0xc4, 0x7d, 0xc1, 0x65, 0xc1, 0x67, 0xc1, 0x5d, 0xc1,
+ 0x5b, 0xc1, 0x62, 0xf5, 0xe9, 0xc2, 0xb7, 0xc2, 0xb9, 0xc5, 0xb7, 0xf4, 0xad,
+ 0xf2, 0xb2, 0xf2, 0xb4, 0xf9, 0x40, 0xa1, 0xbc, 0xbd, 0x42, 0xa1, 0xbc, 0xcd,
+ 0x72, 0xb0, 0x6f, 0xca, 0x45, 0xbf, 0x59, 0xde, 0xb3, 0xcd, 0x6a, 0xaa, 0xb3,
+ 0xaa, 0xb2, 0xcf, 0xc8, 0xc4, 0x6e, 0xac, 0xbf, 0xac, 0xc5, 0xac, 0xc4, 0xa1,
+ 0xbc, 0xcf, 0xc9, 0xd2, 0xad, 0xd2, 0xac, 0xb9, 0x7a, 0xb2, 0x78, 0xd2, 0xb2,
+ 0xd2, 0xb0, 0xaf, 0x5f, 0xc3, 0xa2, 0xb7, 0xe9, 0xe6, 0xa3, 0xb5, 0x58, 0xb7,
+ 0xeb, 0xb5, 0x61, 0xb5, 0x5b, 0xb5, 0x62, 0xda, 0x7c, 0xda, 0x7a, 0xda, 0x7b,
+ 0xb5, 0x60, 0xda, 0xa1, 0xb7, 0xe8, 0xb7, 0xec, 0xde, 0xb6, 0xb7, 0xe5, 0xb7,
+ 0xea, 0xc0, 0xf5, 0xba, 0xc1, 0xbd, 0x40, 0xbf, 0x58, 0xc4, 0xed, 0xbd, 0x41,
+ 0xe6, 0xa6, 0xe6, 0xa2, 0xbc, 0xfd, 0xbf, 0x5c, 0xc0, 0xf6, 0xc0, 0xf3, 0xed,
+ 0x69, 0xc2, 0x7a, 0xc5, 0xd0, 0xf4, 0x6f, 0xf1, 0xa4, 0xf3, 0xa5, 0xc3, 0xfc,
+ 0xcb, 0x42, 0xa8, 0x40, 0xa7, 0xfb, 0xcb, 0x43, 0xe2, 0x59, 0xf4, 0x55, 0xaa,
+ 0x4a, 0xaa, 0x57, 0xaa, 0x48, 0xcc, 0xd9, 0xa1, 0xbc, 0xaa, 0x53, 0xd9, 0xb3,
+ 0xbc, 0xd7, 0xb1, 0xfa, 0xaa, 0x44, 0xaa, 0x49, 0xaa, 0x56, 0xcf, 0x55, 0xc0,
+ 0xcd, 0xcf, 0x43, 0xf4, 0x53, 0xac, 0x5e, 0xac, 0x69, 0xf4, 0x56, 0xac, 0x6a,
+ 0xcf, 0x4a, 0xac, 0x63, 0xcf, 0x4c, 0xac, 0x6c, 0xb1, 0xf7, 0xcf, 0x61, 0xac,
+ 0x65, 0xac, 0x6b, 0xf2, 0x52, 0xce, 0xfb, 0xec, 0xf7, 0xd1, 0xdc, 0xd1, 0xdd,
+ 0xd9, 0xb2, 0xbe, 0xf8, 0xd1, 0xe8, 0xb7, 0xa9, 0xd1, 0xe9, 0xe2, 0x4e, 0xb1,
+ 0xf2, 0xd1, 0xeb, 0xa1, 0xbc, 0xbe, 0xec, 0xae, 0xec, 0xc0, 0xcc, 0xae, 0xe5,
+ 0xf7, 0xe1, 0xa1, 0xbc, 0xd1, 0xdb, 0xae, 0xdd, 0xb1, 0xeb, 0xd5, 0xc0, 0xd5,
+ 0xbe, 0xd5, 0xc1, 0xb1, 0xea, 0xd5, 0xc4, 0xf9, 0xbb, 0xb4, 0xd8, 0xd9, 0xc8,
+ 0xc3, 0x70, 0xe5, 0xde, 0xb4, 0xcd, 0xf7, 0xe2, 0xdd, 0xde, 0xd9, 0xca, 0xbc,
+ 0xcd, 0xdd, 0xd4, 0xb4, 0xd0, 0xd9, 0xb9, 0xdd, 0xce, 0xdd, 0xd2, 0xb7, 0xa3,
+ 0xdd, 0xd3, 0xb7, 0xaf, 0xc6, 0x56, 0xb7, 0xaa, 0xa1, 0xbc, 0xa1, 0xbc, 0xdd,
+ 0xdf, 0xdd, 0xe0, 0xba, 0x6c, 0xc4, 0x68, 0xc3, 0x71, 0xe2, 0x41, 0xf5, 0xd1,
+ 0xdd, 0xc9, 0xb7, 0xb0, 0xb7, 0xad, 0xba, 0x64, 0xe2, 0x49, 0xba, 0x66, 0xba,
+ 0x67, 0xba, 0x6b, 0xe2, 0x52, 0xe1, 0xfc, 0xba, 0x60, 0xe2, 0x54, 0xc2, 0x62,
+ 0xba, 0x5f, 0xf2, 0x4c, 0xe2, 0x4a, 0xe5, 0xd3, 0xc0, 0xce, 0xbc, 0xd8, 0xe5,
+ 0xcc, 0xe5, 0xe8, 0xf2, 0x55, 0xe5, 0xda, 0xbe, 0xf1, 0xe9, 0xc4, 0xc0, 0xd2,
+ 0xe9, 0xd1, 0xe9, 0xc8, 0xbe, 0xf6, 0xec, 0xfe, 0xc3, 0x72, 0xbe, 0xea, 0xe9,
+ 0xca, 0xbe, 0xef, 0xf2, 0x58, 0xed, 0x44, 0xc0, 0xd1, 0xec, 0xf5, 0xc0, 0xd0,
+ 0xa1, 0xbc, 0xb7, 0xdf, 0xe6, 0x76, 0xaa, 0x5c, 0xcf, 0x65, 0xbc, 0xdc, 0xcf,
+ 0x66, 0xe2, 0x66, 0xc0, 0xd4, 0xd5, 0xdc, 0xe9, 0xe3, 0xdd, 0xfb, 0xc2, 0x6c,
+ 0xe9, 0xe2, 0xb0, 0x62, 0xb3, 0x6d, 0xa1, 0xbc, 0xb6, 0x61, 0xf8, 0x47, 0xdc,
+ 0x40, 0xb6, 0x63, 0xdc, 0x48, 0xa1, 0xbc, 0xf7, 0x65, 0xdb, 0xfe, 0xb8, 0xfd,
+ 0xb8, 0xfe, 0xe0, 0x79, 0xe0, 0x78, 0xbb, 0xb3, 0xbd, 0xfb, 0xbd, 0xfe, 0xbd,
+ 0xf9, 0xbd, 0xfd, 0xbf, 0xea, 0xf1, 0x46, 0xc3, 0xe1, 0xa1, 0xbc, 0xcc, 0xb1,
+ 0xe1, 0xd7, 0xb1, 0xae, 0xb4, 0x75, 0xb7, 0x61, 0xb7, 0x60, 0xdd, 0x75, 0xdd,
+ 0x76, 0xe1, 0xd6, 0xbb, 0x4e, 0xbf, 0x5e, 0xd2, 0xbe, 0xde, 0xc0, 0xed, 0x72,
+ 0xed, 0x70, 0xf0, 0x49, 0xa1, 0xbc, 0xc9, 0xee, 0xc9, 0xed, 0xca, 0xf8, 0xa9,
+ 0xfe, 0xbe, 0xe8, 0xaa, 0x58, 0xcc, 0xca, 0xa9, 0xfd, 0xa9, 0xfb, 0xcd, 0x52,
+ 0xac, 0x54, 0xce, 0xf5, 0xce, 0xf6, 0xac, 0x52, 0xce, 0xeb, 0xbc, 0xca, 0xaf,
+ 0xcf, 0xd1, 0xd4, 0xbe, 0xe7, 0xae, 0xd0, 0xae, 0xcb, 0xb7, 0x75, 0xd5, 0xaa,
+ 0xa1, 0xbc, 0xb4, 0xbe, 0xb7, 0x79, 0xdd, 0xc0, 0xc0, 0xc7, 0xba, 0x5c, 0xe9,
+ 0xb4, 0xef, 0xdb, 0xc2, 0x60, 0xc4, 0x66, 0xc4, 0xe4, 0xb6, 0x4e, 0xdb, 0xea,
+ 0xdb, 0xe8, 0xb6, 0x4d, 0xf0, 0xf4, 0xb8, 0xed, 0xb8, 0xf0, 0xf6, 0x52, 0xbb,
+ 0xac, 0xe7, 0xec, 0xe4, 0x53, 0xa1, 0xbc, 0xe7, 0xee, 0xc1, 0xcc, 0xdb, 0xd1,
+ 0xc1, 0xbb, 0xe4, 0x44, 0xf7, 0x53, 0xbf, 0xcc, 0xee, 0x7a, 0xc2, 0xd1, 0xf2,
+ 0xf3, 0xcf, 0xbd, 0xa1, 0xbc, 0xa6, 0xc9, 0xa1, 0xbc, 0xac, 0xba, 0xd6, 0x5c,
+ 0xd6, 0x5f, 0xb5, 0x51, 0xda, 0x6c, 0xde, 0xa5, 0xa1, 0xbc, 0xba, 0xb9, 0xae,
+ 0xb2, 0xd5, 0x66, 0xd9, 0x54, 0xe1, 0xee, 0xc0, 0xbc, 0xac, 0xfe, 0xa1, 0xbc,
+ 0xd9, 0xe5, 0xb7, 0xb7, 0xe5, 0xf7, 0xde, 0x40, 0xbe, 0xfb, 0xf2, 0x5b, 0xe9,
+ 0xe8, 0xf6, 0xe7, 0xc9, 0x7e, 0xc9, 0xf7, 0xcb, 0x49, 0xcb, 0x4a, 0xcf, 0x6c,
+ 0xb4, 0xe3, 0xae, 0xf4, 0xd5, 0xdf, 0xba, 0x72, 0xa1, 0xbc, 0xb1, 0xd5, 0xa1,
+ 0xbc, 0xc3, 0x7c, 0xb7, 0xde, 0xbc, 0xf8, 0xac, 0xb8, 0xe7, 0x7e, 0xa6, 0x47,
+ 0xa1, 0xbc, 0xcb, 0x78, 0xa8, 0x77, 0xa1, 0xbc, 0xcc, 0xd2, 0xa1, 0xbc, 0xaa,
+ 0xd0, 0xaa, 0xd2, 0xcd, 0xb0, 0xaa, 0xd4, 0xa1, 0xbc, 0xc4, 0x67, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xc4, 0xa4, 0xad, 0x4b, 0xd0, 0x5b, 0xad, 0x48, 0xd0, 0x5f, 0xd0,
+ 0x67, 0xd0, 0x65, 0xce, 0xfa, 0xad, 0x4f, 0xd7, 0x48, 0xaf, 0xd6, 0xaf, 0xdb,
+ 0xaf, 0xda, 0xc1, 0x7a, 0xa1, 0xbc, 0xd3, 0x6a, 0xaf, 0xe2, 0xae, 0xd3, 0xa1,
+ 0xbc, 0xb3, 0x62, 0xdf, 0xa2, 0xd7, 0x4c, 0xd7, 0x4b, 0xd7, 0x45, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xb5, 0xcb, 0xb5, 0xcc, 0xb5, 0xcd, 0xa1, 0xbc, 0xa1, 0xbc, 0xb8,
+ 0x78, 0xdf, 0x73, 0xdf, 0x76, 0xa1, 0xbc, 0xe3, 0xa6, 0xa1, 0xbc, 0xdf, 0x7d,
+ 0xdc, 0xe6, 0xdc, 0xf9, 0xbb, 0x4a, 0xbb, 0x4d, 0xc2, 0xc1, 0xbc, 0xf0, 0xe6,
+ 0xfd, 0xa1, 0xbc, 0xed, 0xea, 0xc2, 0x61, 0xed, 0xeb, 0xed, 0xe8, 0xa1, 0xbc,
+ 0xea, 0xe9, 0xc2, 0x6a, 0xd5, 0xd8, 0xd9, 0xda, 0xdd, 0xf7, 0xdd, 0xf5, 0xbe,
+ 0xf9, 0xe4, 0xcd, 0xbb, 0xe3, 0xc1, 0xfc, 0xc4, 0x42, 0xf6, 0x74, 0xa1, 0xbc,
+ 0xc9, 0x5f, 0xdd, 0x62, 0xc1, 0xd4, 0xee, 0x7d, 0xb4, 0xb4, 0xf8, 0x7e, 0xc4,
+ 0xe3, 0xa9, 0xf3, 0xd1, 0xcf, 0xd1, 0xd1, 0xd1, 0xd0, 0xb1, 0xdc, 0xb1, 0xdd,
+ 0xd9, 0x7e, 0xba, 0x59, 0xb7, 0xd5, 0xde, 0x6d, 0xbf, 0x4c, 0xe2, 0xc4, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xcf, 0xae, 0xac, 0xaf, 0xcf, 0xb1, 0xea, 0x4d, 0xaf, 0x4c,
+ 0xd6, 0x51, 0xd6, 0x55, 0xbf, 0x54, 0xda, 0x5a, 0xda, 0x5d, 0xa1, 0xbc, 0xb7,
+ 0xd4, 0xb7, 0xdb, 0xa1, 0xbc, 0xde, 0x73, 0xa1, 0xbc, 0xde, 0x74, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xe6, 0x72, 0xe6, 0x69, 0xbc, 0xf7, 0xe6, 0x66, 0xc0, 0xee, 0xea,
+ 0x4f, 0xc0, 0xe6, 0xef, 0xfb, 0xf5, 0xda, 0xc6, 0x79, 0xa1, 0xbc, 0xc2, 0x76,
+ 0xb7, 0xd6, 0xbf, 0x51, 0xa9, 0xd1, 0xcc, 0xb2, 0xce, 0xd3, 0xb1, 0xaf, 0xb4,
+ 0x76, 0xa1, 0xbc, 0xaa, 0xc1, 0xac, 0xe6, 0xac, 0xe7, 0xd7, 0xb6, 0xd2, 0xe9,
+ 0xd2, 0xea, 0xaf, 0xae, 0xf2, 0xa5, 0xaf, 0xad, 0xaf, 0xa8, 0xba, 0xd5, 0xd6,
+ 0xbd, 0xb8, 0x52, 0xc1, 0x49, 0xe2, 0xf9, 0xe6, 0xcb, 0xc1, 0x48, 0xc5, 0xa1,
+ 0xca, 0xd7, 0xca, 0xd8, 0xef, 0xc8, 0xd1, 0x7c, 0xd1, 0x7d, 0xd1, 0x7e, 0xd1,
+ 0xa1, 0xae, 0x7e, 0xae, 0xa1, 0xe1, 0xc3, 0xb7, 0x5e, 0xb7, 0x5d, 0xbc, 0x7c,
+ 0xbe, 0xcd, 0xe9, 0x76, 0xc0, 0xb7, 0xc2, 0x56, 0xf9, 0xba, 0xa1, 0xbc, 0xa6,
+ 0xd6, 0xcc, 0xee, 0xed, 0x4f, 0xd9, 0xe7, 0xc1, 0x46, 0xcd, 0x7a, 0xe2, 0xee,
+ 0xcf, 0xf1, 0xda, 0xcf, 0xa1, 0xbc, 0xcf, 0xeb, 0xac, 0x48, 0xaf, 0xa2, 0xa1,
+ 0xbc, 0xaf, 0x7c, 0xa1, 0xbc, 0xc4, 0x72, 0xf5, 0xe2, 0xaf, 0xa4, 0xa1, 0xbc,
+ 0xaf, 0xa1, 0xd2, 0xda, 0xd2, 0xd9, 0xd2, 0xe2, 0xb2, 0xba, 0xda, 0xc9, 0xda,
+ 0xc6, 0xed, 0xa6, 0xd6, 0xb9, 0xd6, 0xbb, 0xa1, 0xbc, 0xd6, 0xb8, 0xda, 0xcb,
+ 0xbf, 0x6c, 0xb8, 0x50, 0xde, 0xe5, 0xde, 0xe4, 0xea, 0xa7, 0xde, 0xec, 0xba,
+ 0xd4, 0xe2, 0xeb, 0xa1, 0xbc, 0xe2, 0xf3, 0xe6, 0xc6, 0xa1, 0xbc, 0xe6, 0xca,
+ 0xbf, 0x6b, 0xed, 0xaa, 0xed, 0xab, 0xc1, 0x45, 0xf0, 0x58, 0xf4, 0x7d, 0xf2,
+ 0xa4, 0xf2, 0xa1, 0xf7, 0xce, 0xdc, 0xb0, 0xef, 0xb0, 0xf3, 0xf5, 0xcd, 0x77,
+ 0xcf, 0xe2, 0xa1, 0xbc, 0xac, 0xda, 0xac, 0xe0, 0xcf, 0xe0, 0xd2, 0xd6, 0xd2,
+ 0xd7, 0xd2, 0xd5, 0xd6, 0xaa, 0xd6, 0xb0, 0xd6, 0xb2, 0xb2, 0xb6, 0xb7, 0xfd,
+ 0xc2, 0xa5, 0xda, 0xbb, 0xa1, 0xbc, 0xde, 0xdd, 0xb8, 0x45, 0xb8, 0x46, 0xb8,
+ 0x44, 0xba, 0xcd, 0xe6, 0xbc, 0xba, 0xcc, 0xe2, 0xe7, 0xbd, 0x4f, 0xbd, 0x50,
+ 0xbf, 0x67, 0xbf, 0x65, 0xc0, 0xfd, 0xed, 0x7a, 0xc2, 0xa2, 0xcb, 0x6d, 0xcd,
+ 0x71, 0xac, 0xca, 0xac, 0xcb, 0xcf, 0xdb, 0xd2, 0xc1, 0xda, 0xae, 0xde, 0xc4,
+ 0xa1, 0xbc, 0xd0, 0x4d, 0xd3, 0x5c, 0xaf, 0xcb, 0xdb, 0xe0, 0xdf, 0x6a, 0xf2,
+ 0xbc, 0xa1, 0xbc, 0xbf, 0xa9, 0xc5, 0xf9, 0xed, 0xe3, 0xaf, 0x72, 0xbf, 0x64,
+ 0xf7, 0xf8, 0xa1, 0xbc, 0xd0, 0xc1, 0xd0, 0xc0, 0xb0, 0x7a, 0xb0, 0x78, 0xd4,
+ 0x42, 0xd8, 0x41, 0xb3, 0xa9, 0xd7, 0xfc, 0xeb, 0xea, 0xb3, 0xa6, 0xd7, 0xfd,
+ 0xa1, 0xbc, 0xdc, 0x67, 0xb9, 0x64, 0xb6, 0x7a, 0xb6, 0x78, 0xdc, 0x62, 0xdc,
+ 0x70, 0xdc, 0x6f, 0xdc, 0x64, 0xdc, 0x6a, 0xe0, 0xb1, 0xe0, 0xb2, 0xb9, 0x57,
+ 0xe0, 0xb3, 0xa1, 0xbc, 0xb9, 0x5a, 0xb9, 0x59, 0xe0, 0xb5, 0xe0, 0xbb, 0xe0,
+ 0xba, 0xb9, 0x66, 0xc5, 0xe0, 0xe0, 0xb0, 0xb9, 0x62, 0xe0, 0xae, 0xb9, 0x63,
+ 0xe0, 0xb7, 0xb9, 0x65, 0xc5, 0x4d, 0xbe, 0x52, 0xe4, 0x7b, 0xe4, 0x7a, 0xe4,
+ 0x7d, 0xe4, 0xa8, 0xe8, 0x68, 0xc4, 0xc2, 0xa1, 0xbc, 0xc5, 0x4c, 0xa1, 0xbc,
+ 0xe4, 0xa1, 0xf1, 0x5a, 0xbb, 0xcb, 0xe8, 0x6f, 0xe4, 0xb7, 0xf4, 0xf3, 0xbb,
+ 0xcd, 0xe4, 0xa6, 0xf3, 0x6a, 0xe4, 0xa2, 0xbf, 0xfe, 0xe4, 0xa3, 0xe0, 0xb6,
+ 0xf4, 0xe7, 0xbb, 0xcf, 0xe4, 0xa7, 0xf4, 0xf9, 0xeb, 0xe4, 0xe8, 0x69, 0xc3,
+ 0xf4, 0xa1, 0xbc, 0xbe, 0x59, 0xe8, 0x70, 0xe8, 0x72, 0xbe, 0x56, 0xe8, 0x6e,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xe8, 0x63, 0xe8, 0x6a, 0xe8, 0x76, 0xeb,
+ 0xe8, 0xeb, 0xe1, 0xa1, 0xbc, 0xeb, 0xe6, 0xa1, 0xbc, 0xeb, 0xe9, 0xc0, 0x43,
+ 0xc0, 0x44, 0xa1, 0xbc, 0xa1, 0xbc, 0xeb, 0xdf, 0xeb, 0xe0, 0xc0, 0x45, 0xc1,
+ 0xe6, 0xee, 0xd2, 0xee, 0xd6, 0xc1, 0xee, 0xee, 0xd0, 0xf1, 0x5c, 0xc1, 0xec,
+ 0xa1, 0xbc, 0xc3, 0xf3, 0xc3, 0xf2, 0xf4, 0xf0, 0xa1, 0xbc, 0xf3, 0x68, 0xc2,
+ 0xf0, 0xc5, 0x4f, 0xa1, 0xbc, 0xf1, 0x5e, 0xc2, 0xef, 0xf1, 0x53, 0xf7, 0x67,
+ 0xc3, 0xf0, 0xc3, 0xed, 0xc3, 0xee, 0xc3, 0xf1, 0xf3, 0x60, 0xc3, 0xeb, 0xf3,
+ 0x61, 0xc3, 0xe9, 0xf4, 0xec, 0xa1, 0xbc, 0xf4, 0xf5, 0xa1, 0xbc, 0xf4, 0xe8,
+ 0xf9, 0x53, 0xf4, 0xea, 0xa1, 0xbc, 0xf3, 0x66, 0xf4, 0xf1, 0xf7, 0x69, 0xc5,
+ 0x4e, 0xf6, 0x5e, 0xa1, 0xbc, 0xc5, 0xdf, 0xc1, 0xe9, 0xcf, 0xe8, 0xda, 0xc4,
+ 0xb9, 0x6e, 0xcf, 0xf9, 0xd2, 0xf1, 0xaf, 0xb0, 0xd2, 0xed, 0xa1, 0xbc, 0xb4,
+ 0x52, 0xda, 0xd8, 0xda, 0xd6, 0xb8, 0x5c, 0xb8, 0x5a, 0xe6, 0xd2, 0xbd, 0x5e,
+ 0xc2, 0xa8, 0xc2, 0x48, 0xc3, 0x4c, 0xf6, 0xf8, 0xac, 0xd4, 0xb2, 0xae, 0xb5,
+ 0x71, 0xde, 0xd5, 0xed, 0x78, 0xd2, 0xbc, 0xb2, 0x7d, 0xa8, 0x69, 0xb9, 0xa7,
+ 0xbb, 0xf0, 0xe8, 0xe9, 0xbe, 0x7d, 0xc0, 0x6c, 0xf3, 0xf0, 0xf9, 0xb7, 0xec,
+ 0xa9, 0xec, 0xae, 0xc5, 0xee, 0xef, 0x7b, 0xf7, 0xc1, 0xef, 0x7e, 0xef, 0xa2,
+ 0xc6, 0x7d, 0xf1, 0xd0, 0xf9, 0xcf, 0xc3, 0x5b, 0xf1, 0xd9, 0xf8, 0x71, 0xf1,
+ 0xcf, 0xc4, 0x4d, 0xa1, 0xbc, 0xc4, 0x4f, 0xf3, 0xed, 0xc4, 0x4c, 0xf5, 0x7c,
+ 0xf5, 0xa7, 0xa1, 0xbc, 0xa1, 0xbc, 0xf5, 0xad, 0xc5, 0x63, 0xf6, 0xb4, 0xc6,
+ 0x78, 0xc5, 0xc2, 0xf7, 0xba, 0xf8, 0x63, 0xf8, 0x6b, 0xf8, 0x6c, 0xf8, 0x66,
+ 0xa1, 0xbc, 0xc6, 0x4f, 0xc6, 0x7c, 0xa1, 0xbc, 0xcb, 0x6f, 0xf0, 0x4b, 0xc2,
+ 0x7e, 0xaa, 0xb7, 0xa1, 0xbc, 0xac, 0xd0, 0xaf, 0x69, 0xde, 0xcb, 0xaf, 0x6e,
+ 0xd2, 0xc6, 0xaf, 0x70, 0xd2, 0xc3, 0xa1, 0xbc, 0xaf, 0x6d, 0xa1, 0xbc, 0xb2,
+ 0xad, 0xb5, 0x69, 0xc0, 0xf7, 0xda, 0xb2, 0xda, 0xb5, 0xed, 0x77, 0xda, 0xaf,
+ 0xde, 0xc9, 0xb7, 0xf3, 0xde, 0xcc, 0xb7, 0xf5, 0xde, 0xcf, 0xb7, 0xef, 0xed,
+ 0x76, 0xe2, 0xdc, 0xe6, 0xb0, 0xe2, 0xdf, 0xe6, 0xaf, 0xa1, 0xbc, 0xe2, 0xdd,
+ 0xe6, 0xb1, 0xe6, 0xb7, 0xea, 0x70, 0xbd, 0x49, 0xbd, 0x43, 0xa1, 0xbc, 0xea,
+ 0x6c, 0xea, 0x73, 0xf6, 0xf4, 0xea, 0x71, 0xed, 0x74, 0xc5, 0x7d, 0xea, 0x6f,
+ 0xa1, 0xbc, 0xc4, 0xee, 0xa1, 0xbc, 0xf0, 0x4a, 0xc2, 0x7d, 0xc5, 0xf6, 0xa1,
+ 0xbc, 0xd6, 0xf6, 0xda, 0xdc, 0xcd, 0xa5, 0xaa, 0xc6, 0xcf, 0xfe, 0xd2, 0xf6,
+ 0xaf, 0xb7, 0xb2, 0xc0, 0xc4, 0x75, 0xb8, 0x5e, 0xe3, 0x4c, 0xe3, 0x4a, 0xea,
+ 0xb2, 0xe6, 0xd5, 0xa1, 0xbc, 0xd0, 0xae, 0xd3, 0xd4, 0xb0, 0x4d, 0xd3, 0xd7,
+ 0xb0, 0x4c, 0xd7, 0xb5, 0xc3, 0xcb, 0xdb, 0xcb, 0xdb, 0xca, 0xdb, 0xcf, 0xee,
+ 0x72, 0xdf, 0xf4, 0xf2, 0xf0, 0xf0, 0xd9, 0xe3, 0xf7, 0xbb, 0x75, 0xe3, 0xfc,
+ 0xbb, 0x74, 0xe3, 0xfa, 0xe4, 0x40, 0xbf, 0xca, 0xe7, 0xc8, 0xbd, 0xc8, 0xc1,
+ 0xb9, 0xbd, 0xca, 0xc4, 0xb0, 0xbf, 0xc9, 0xc1, 0xb7, 0xee, 0x75, 0xf4, 0xcb,
+ 0xf9, 0x4b, 0xa5, 0xd4, 0xad, 0x45, 0xe2, 0xe1, 0xb5, 0x72, 0xac, 0xe1, 0xa6,
+ 0xd4, 0xd0, 0x54, 0xd3, 0x66, 0xb2, 0xe0, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xbd, 0xa2, 0xed, 0xe7, 0xea, 0xe6, 0xbf, 0xae, 0xa1, 0xbc, 0xb5, 0xc0, 0xcd,
+ 0xaa, 0xd7, 0x43, 0xb2, 0xe2, 0xf4, 0xb2, 0xb5, 0xc1, 0xf0, 0x7c, 0xc1, 0x6d,
+ 0xb5, 0xf7, 0xdc, 0xac, 0xe0, 0xe0, 0xe0, 0xde, 0xbe, 0x65, 0xbe, 0x67, 0xbf,
+ 0x6f, 0xe8, 0xb8, 0xc0, 0x58, 0xc3, 0x45, 0xc3, 0x46, 0xf9, 0xae, 0xf5, 0x4f,
+ 0xf3, 0xa8, 0xc5, 0x56, 0xa1, 0xbc, 0xc6, 0x49, 0xca, 0x4f, 0xb0, 0x40, 0xcd,
+ 0xc8, 0xf0, 0xca, 0xf2, 0xe3, 0xad, 0x6b, 0xd0, 0xa8, 0xad, 0x6a, 0xd3, 0xba,
+ 0xd3, 0xbc, 0xd3, 0xc2, 0xb8, 0xc3, 0xc4, 0xae, 0xd3, 0xc8, 0xb0, 0x47, 0xb0,
+ 0x42, 0xb0, 0x43, 0xb0, 0x45, 0xb3, 0x46, 0xb3, 0x47, 0xb3, 0x48, 0xc4, 0xf7,
+ 0xd7, 0xa5, 0xd7, 0xa4, 0xb3, 0x4b, 0xb3, 0x4c, 0xb3, 0x4d, 0xf2, 0xde, 0xd7,
+ 0xab, 0xdb, 0xbc, 0xdf, 0xe6, 0xc2, 0xcc, 0xb5, 0xed, 0xeb, 0x6b, 0xb5, 0xf1,
+ 0xb8, 0xbb, 0xb5, 0xf2, 0xf4, 0xc5, 0xb5, 0xeb, 0xdb, 0xb1, 0xdb, 0xbf, 0xb8,
+ 0xc2, 0xb8, 0xbd, 0xdf, 0xea, 0xb8, 0xbc, 0xb8, 0xc4, 0xdf, 0xef, 0xdf, 0xec,
+ 0xe3, 0xd6, 0xbb, 0x66, 0xe3, 0xdb, 0xbb, 0x68, 0xe3, 0xda, 0xe3, 0xf2, 0xe3,
+ 0xe2, 0xc1, 0xb4, 0xbb, 0x69, 0xe3, 0xeb, 0xbb, 0x6d, 0xbb, 0x6c, 0xbb, 0x64,
+ 0xbd, 0xb8, 0xbb, 0x67, 0xa1, 0xbc, 0xf4, 0xc6, 0xe7, 0xbc, 0xbd, 0xbb, 0xa1,
+ 0xbc, 0xbd, 0xc1, 0xe7, 0xb8, 0xa1, 0xbc, 0xbd, 0xc2, 0xe7, 0xa2, 0xc1, 0xb2,
+ 0xe7, 0xa3, 0xbd, 0xbf, 0xe7, 0xba, 0xeb, 0x5e, 0xee, 0x67, 0xa1, 0xbc, 0xc1,
+ 0xaf, 0xc1, 0xb0, 0xeb, 0x60, 0xeb, 0x67, 0xee, 0x5a, 0xeb, 0x5d, 0xbf, 0xc0,
+ 0xc1, 0xb1, 0xf0, 0xc1, 0xee, 0x5d, 0xee, 0x5f, 0xc1, 0xae, 0xc1, 0xb5, 0xf0,
+ 0xc7, 0xee, 0x6e, 0xc1, 0xad, 0xc1, 0xac, 0xee, 0x69, 0xf0, 0xbe, 0xf0, 0xc0,
+ 0xc2, 0xcf, 0xa1, 0xbc, 0xf4, 0xc9, 0xf4, 0xc8, 0xc3, 0xca, 0xf2, 0xe7, 0xf6,
+ 0x42, 0xc4, 0xf9, 0xc5, 0xfb, 0xf9, 0x6e, 0xa6, 0xce, 0xc4, 0xa2, 0xc1, 0x6a,
+ 0xed, 0xe1, 0xaf, 0xe7, 0xaa, 0xc7, 0xac, 0xf2, 0xd3, 0x44, 0xbf, 0x77, 0xd3,
+ 0x40, 0xb8, 0x63, 0xd3, 0x45, 0xd6, 0xd7, 0xd3, 0x43, 0xd6, 0xcc, 0xd6, 0xdb,
+ 0xd6, 0xd4, 0xb2, 0xc6, 0xb2, 0xc8, 0xd6, 0xd6, 0xb2, 0xc1, 0xd6, 0xce, 0xd6,
+ 0xd1, 0xd6, 0xd2, 0xf8, 0xfb, 0xb2, 0xc7, 0xda, 0xe5, 0xed, 0xc3, 0xda, 0xe6,
+ 0xba, 0xe1, 0xda, 0xe2, 0xba, 0xe5, 0xb8, 0x61, 0xb8, 0x62, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xdf, 0x4b, 0xdf, 0x4e, 0xe3, 0x52, 0xed, 0xbd, 0xe6, 0xd7, 0xba, 0xe6,
+ 0xe6, 0xd9, 0xba, 0xe3, 0xf6, 0xfb, 0xe3, 0x58, 0xc2, 0xb0, 0xe3, 0x4f, 0xa1,
+ 0xbc, 0xc2, 0xad, 0xbd, 0x65, 0xc2, 0xb1, 0xbd, 0x68, 0xbd, 0x6a, 0xea, 0xba,
+ 0xea, 0xbd, 0xea, 0xbc, 0xbf, 0x7b, 0xea, 0xc1, 0xc1, 0x50, 0xc1, 0x4e, 0xa1,
+ 0xbc, 0xed, 0xbb, 0xf8, 0xb8, 0xed, 0xc2, 0xf0, 0x65, 0xc2, 0xaf, 0xf0, 0x68,
+ 0xc3, 0xb0, 0xc5, 0xa3, 0xc3, 0xb3, 0xaa, 0xd8, 0xd3, 0x70, 0xb2, 0xea, 0xbc,
+ 0xf3, 0xaf, 0xe5, 0xd3, 0xd0, 0xd0, 0x69, 0xad, 0x51, 0xf2, 0xc3, 0xa1, 0xbc,
+ 0xd3, 0x71, 0xaf, 0xea, 0xaf, 0xe9, 0xd7, 0x53, 0xf7, 0x46, 0xd7, 0x54, 0xd7,
+ 0x56, 0xa1, 0xbc, 0xdf, 0xa5, 0xdf, 0xa4, 0xbb, 0x53, 0xe7, 0x46, 0xed, 0xf1,
+ 0xf0, 0xa2, 0xf4, 0xb6, 0xd3, 0xda, 0xb8, 0xcd, 0xb3, 0x50, 0xb8, 0xca, 0xb8,
+ 0xc6, 0xc3, 0xce, 0xd6, 0xf4, 0xdf, 0x6d, 0xdf, 0x6e, 0xbd, 0x7e, 0xe6, 0xf3,
+ 0xbf, 0xaa, 0xaa, 0xc4, 0xae, 0xc5, 0xd3, 0x4a, 0xf5, 0xe6, 0xf8, 0xfd, 0xda,
+ 0xe8, 0xda, 0xe7, 0xdf, 0x54, 0xe3, 0x60, 0xba, 0xea, 0xc1, 0x58, 0xa1, 0xbc,
+ 0xe6, 0xe1, 0xa1, 0xbc, 0xe6, 0xe0, 0xe6, 0xdf, 0xea, 0xc9, 0xed, 0xcf, 0xa6,
+ 0xe1, 0xba, 0x5b, 0xac, 0xfd, 0xb2, 0xde, 0xb5, 0xbf, 0xe3, 0x7d, 0xbb, 0x42,
+ 0xe6, 0xf9, 0xbd, 0xa1, 0xbf, 0xad, 0xc1, 0x6b, 0xa6, 0xcd, 0xed, 0xde, 0xe3,
+ 0x75, 0xe3, 0x76, 0xed, 0xd9, 0xf9, 0x41, 0xbe, 0xa2, 0xc4, 0x54, 0xad, 0x76,
+ 0xdb, 0xed, 0xe0, 0x64, 0xe0, 0x5e, 0xf9, 0x6f, 0xb3, 0x69, 0xbd, 0xea, 0xd3,
+ 0xde, 0xb3, 0x61, 0xad, 0xaa, 0xd3, 0xfe, 0xd4, 0x40, 0xd4, 0x41, 0xdc, 0x5e,
+ 0xdc, 0x60, 0xdc, 0x5d, 0xa1, 0xbc, 0xb9, 0x55, 0xe0, 0xad, 0xc6, 0x6f, 0xf9,
+ 0x71, 0xe4, 0x73, 0xbb, 0xc6, 0xe4, 0x74, 0xa1, 0xbc, 0xe8, 0x5b, 0xeb, 0xd9,
+ 0xeb, 0xdb, 0xeb, 0xda, 0xee, 0xc6, 0xc1, 0xde, 0xf1, 0x52, 0xf3, 0x5f, 0xc3,
+ 0xe7, 0xf1, 0x51, 0xf4, 0xe4, 0xc4, 0xbf, 0xc5, 0x48, 0xa8, 0xa8, 0xf6, 0xc9,
+ 0xc4, 0xbb, 0xe0, 0x72, 0xe4, 0x60, 0xc2, 0xd9, 0xf1, 0x44, 0xd3, 0xe5, 0xd7,
+ 0xd9, 0xd7, 0xd6, 0xb3, 0x6c, 0xee, 0xbe, 0xdb, 0xf4, 0xdb, 0xfa, 0xb6, 0x5c,
+ 0xf7, 0x60, 0xb6, 0x59, 0xdb, 0xf6, 0xb6, 0x5f, 0xb6, 0x60, 0xe0, 0x69, 0xc3,
+ 0xdf, 0xc2, 0xde, 0xe0, 0x6e, 0xf7, 0x5f, 0xc5, 0x45, 0xb8, 0xf8, 0xe4, 0x57,
+ 0xe4, 0x5b, 0xe8, 0x40, 0xbd, 0xef, 0xbd, 0xf3, 0xc5, 0xae, 0xe7, 0xf7, 0xe7,
+ 0xf4, 0xc5, 0xad, 0xa1, 0xbc, 0xeb, 0xc0, 0xbf, 0xe5, 0xbf, 0xe6, 0xeb, 0xc4,
+ 0xbf, 0xe2, 0xc1, 0xce, 0xeb, 0xc5, 0xbf, 0xe4, 0xc6, 0x5c, 0xc2, 0xda, 0xc1,
+ 0xd1, 0xf7, 0x5d, 0xc3, 0xdd, 0xc3, 0xda, 0xf3, 0x53, 0xc3, 0xe0, 0xc4, 0xbd,
+ 0xc6, 0x6e, 0xf7, 0x5e, 0xf7, 0x61, 0xf9, 0x70, 0xf8, 0xc3, 0xcb, 0xa4, 0xb6,
+ 0x49, 0xb8, 0xe7, 0xe0, 0x5a, 0xf0, 0xf1, 0xee, 0xb7, 0xb1, 0xd8, 0xd7, 0xc6,
+ 0xc2, 0xd2, 0xdb, 0xd4, 0xe0, 0x43, 0xdf, 0xfd, 0xe4, 0x48, 0xf2, 0xf5, 0xb8,
+ 0xe4, 0xf0, 0xe7, 0xe8, 0xb0, 0xb3, 0xb8, 0xc6, 0x45, 0xb6, 0xb2, 0xbe, 0x5e,
+ 0xc5, 0xb4, 0xe8, 0xae, 0xc0, 0x50, 0xc0, 0x4b, 0xc3, 0xf9, 0xc6, 0x47, 0xc4,
+ 0xc5, 0xc5, 0xb5, 0xef, 0xb5, 0xc4, 0xd4, 0xf5, 0xbe, 0xf5, 0xbb, 0xc5, 0x68,
+ 0xc5, 0x69, 0xc5, 0xc5, 0xc5, 0xc6, 0xc6, 0x53, 0xe0, 0xef, 0xef, 0xb1, 0xf9,
+ 0x65, 0xab, 0x41, 0xd4, 0x47, 0xb9, 0x6d, 0xe0, 0xd5, 0xbb, 0xdc, 0xc2, 0xa3,
+ 0xf8, 0x41, 0xe4, 0xa9, 0xc6, 0x71, 0xe8, 0x74, 0xc3, 0xf5, 0xee, 0xde, 0xf3,
+ 0x6c, 0xee, 0xdc, 0xa1, 0xbc, 0xf8, 0xca, 0xbe, 0x7b, 0xe8, 0xdb, 0xf8, 0x5b,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xc6, 0x74, 0xbf, 0x71, 0xec, 0x7b, 0xc6, 0x4d, 0xec,
+ 0x7c, 0xc2, 0x44, 0xef, 0x6a, 0xc2, 0x43, 0xef, 0x6c, 0xf9, 0x5c, 0xc2, 0x42,
+ 0xf3, 0xd0, 0xf8, 0x58, 0xf1, 0xc7, 0xf9, 0xce, 0xc5, 0xbf, 0xf7, 0xae, 0xf6,
+ 0xad, 0xf7, 0xb2, 0xc3, 0x58, 0xc3, 0x54, 0xf1, 0xc3, 0xc3, 0x56, 0xc4, 0x4a,
+ 0xf3, 0xc7, 0xf3, 0xc8, 0xf3, 0xd6, 0xf3, 0xcb, 0xc4, 0x49, 0xa1, 0xbc, 0xf3,
+ 0xcd, 0xf3, 0xce, 0xc4, 0x4b, 0xa1, 0xbc, 0xf3, 0xcf, 0xa1, 0xbc, 0xf5, 0x6b,
+ 0xc6, 0x73, 0xc4, 0xcf, 0xf5, 0x6e, 0xf5, 0x76, 0xa1, 0xbc, 0xa1, 0xbc, 0xf7,
+ 0xb4, 0xc5, 0x5f, 0xf6, 0xae, 0xc5, 0x60, 0xf6, 0xaf, 0xf7, 0xaf, 0xc5, 0xc0,
+ 0xf7, 0xab, 0xc5, 0xc1, 0xa1, 0xbc, 0xa1, 0xbc, 0xc5, 0xed, 0xc5, 0xeb, 0xf8,
+ 0x57, 0xf8, 0xd7, 0xbb, 0xde, 0xbb, 0xdf, 0xc5, 0xb6, 0xa1, 0xbc, 0xec, 0x56,
+ 0xc6, 0x69, 0xf1, 0x7c, 0xc2, 0xfd, 0xa1, 0xbc, 0xa1, 0xbc, 0xe4, 0xda, 0xbb,
+ 0xeb, 0xbe, 0x75, 0xf6, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xc0, 0x66, 0xc3, 0x4e,
+ 0xf1, 0xb9, 0xc5, 0x5c, 0xf3, 0xc1, 0xc6, 0x62, 0xf8, 0xd4, 0xc5, 0xea, 0xbe,
+ 0x79, 0xe8, 0xd9, 0xc6, 0x4c, 0xc3, 0x52, 0xef, 0x69, 0xc3, 0x53, 0xc5, 0x5e,
+ 0xc5, 0x57, 0xc5, 0xe4, 0xc3, 0x4b, 0xc5, 0xb9, 0xf7, 0x76, 0xd4, 0x49, 0xb9,
+ 0xa6, 0xbb, 0xec, 0xbe, 0x77, 0xe8, 0xd4, 0xc0, 0x67, 0xc0, 0x68, 0xec, 0x70,
+ 0xf1, 0xbb, 0xa1, 0xbc, 0xc6, 0x4b, 0xf8, 0x55, 0xc6, 0x63, 0xbb, 0xf2, 0xbe,
+ 0xa3, 0xed, 0xdd, 0xb9, 0xa8, 0xec, 0xb1, 0xec, 0xaf, 0xc2, 0x47, 0xc4, 0x51,
+ 0xc3, 0xef, 0xc5, 0x65, 0xc5, 0xef, 0xc2, 0x4c, 0xc2, 0x4a, 0xc2, 0x4b, 0xc3,
+ 0x5c, 0xf1, 0xe0, 0xa1, 0xbc, 0xc6, 0x75, 0xf5, 0xb6, 0xf5, 0xb4, 0xf8, 0x76,
+ 0xc5, 0x66, 0xef, 0xb4, 0xc3, 0x5e, 0xc4, 0xd3, 0xc5, 0xc4, 0xf8, 0x7b, 0xec,
+ 0xb8, 0xc2, 0x4d, 0xa1, 0xbc,
+};
+
+unsigned char FQTermConvert::BtoG[] = {
+ 0xa1, 0xa1, 0xa3, 0xac, 0xa1, 0xa2, 0xa1, 0xa3, 0xa3, 0xae, 0xa3, 0xae, 0xa3,
+ 0xbb, 0xa3, 0xba, 0xa3, 0xbf, 0xa3, 0xa1, 0xa1, 0xc3, 0xa1, 0xad, 0xa1, 0xa7,
+ 0xa3, 0xac, 0xa1, 0xa2, 0xa1, 0xa4, 0xa1, 0xa4, 0xa3, 0xbb, 0xa3, 0xba, 0xa3,
+ 0xbf, 0xa3, 0xa1, 0xa3, 0xfc, 0xa1, 0xf5, 0xa3, 0xfc, 0xa1, 0xf5, 0xa3, 0xfc,
+ 0xa3, 0xdf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa3, 0xa8, 0xa3, 0xa9, 0xa3, 0xa8, 0xa3,
+ 0xa9, 0xa3, 0xfb, 0xa3, 0xfd, 0xa3, 0xfb, 0xa3, 0xfd, 0xa1, 0xb2, 0xa1, 0xb3,
+ 0xa1, 0xb2, 0xa1, 0xb3, 0xa1, 0xbe, 0xa1, 0xbf, 0xa1, 0xbe, 0xa1, 0xbf, 0xa1,
+ 0xb6, 0xa1, 0xb7, 0xa1, 0xb6, 0xa1, 0xb7, 0xa1, 0xb4, 0xa1, 0xb5, 0xa3, 0xde,
+ 0xa1, 0xb5, 0xa1, 0xb8, 0xa1, 0xb9, 0xa1, 0xb8, 0xa1, 0xb9, 0xa1, 0xba, 0xa1,
+ 0xbb, 0xa1, 0xba, 0xa1, 0xbb, 0xa3, 0xa8, 0xa3, 0xa9, 0xa3, 0xfb, 0xa3, 0xfd,
+ 0xa3, 0xdb, 0xa3, 0xdd, 0xa1, 0xae, 0xa1, 0xaf, 0xa1, 0xb0, 0xa1, 0xb1, 0xa3,
+ 0xa2, 0xa1, 0xe5, 0xa3, 0xe0, 0xa1, 0xe4, 0xa3, 0xa3, 0xa3, 0xa6, 0xa3, 0xaa,
+ 0xa1, 0xf9, 0xa1, 0xec, 0xa1, 0xa8, 0xa1, 0xf0, 0xa1, 0xf1, 0xa1, 0xf7, 0xa1,
+ 0xf8, 0xa1, 0xf2, 0xa1, 0xee, 0xa1, 0xef, 0xa1, 0xf3, 0xa1, 0xf4, 0xa1, 0xf5,
+ 0xa1, 0xf6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xa5, 0xa1,
+ 0xf5, 0xa3, 0xdf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa3, 0xa3, 0xa3, 0xa6, 0xa3, 0xaa, 0xa3, 0xab, 0xa3,
+ 0xad, 0xa1, 0xc1, 0xa1, 0xc2, 0xa1, 0xc0, 0xa1, 0xcc, 0xa3, 0xbc, 0xa3, 0xbe,
+ 0xa3, 0xbd, 0xa1, 0xdc, 0xa1, 0xdd, 0xa1, 0xd9, 0xa1, 0xde, 0xa1, 0xd6, 0xa1,
+ 0xd4, 0xa3, 0xab, 0xa3, 0xad, 0xa3, 0xbc, 0xa3, 0xbe, 0xa3, 0xbd, 0xa1, 0xab,
+ 0xa1, 0xc9, 0xa1, 0xc8, 0xa1, 0xf5, 0xa1, 0xcf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xd2, 0xa1, 0xd3, 0xa1, 0xdf, 0xa1, 0xe0, 0xa1, 0xe2,
+ 0xa1, 0xe1, 0xa1, 0xf5, 0xa1, 0xd1, 0xa1, 0xfc, 0xa1, 0xfd, 0xa1, 0xfb, 0xa1,
+ 0xfa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xac, 0xa1, 0xf5,
+ 0xa3, 0xaf, 0xa3, 0xdc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xe7, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xe9, 0xa1, 0xea, 0xa3, 0xa5, 0xa3, 0xc0, 0xa1, 0xe6, 0xa1, 0xf5,
+ 0xa1, 0xe7, 0xa3, 0xa5, 0xa3, 0xc0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xe3,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa9, 0xe0, 0xa9, 0xd8,
+ 0xa9, 0xd0, 0xa9, 0xc8, 0xa9, 0xc0, 0xa1, 0xf5, 0xa1, 0xaa, 0xa9, 0xa6, 0xa1,
+ 0xf5, 0xa9, 0xb0, 0xa9, 0xb4, 0xa9, 0xb8, 0xa9, 0xbc, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xfe, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa3, 0xb0, 0xa3, 0xb1, 0xa3, 0xb2, 0xa3, 0xb3, 0xa3, 0xb4, 0xa3, 0xb5, 0xa3,
+ 0xb6, 0xa3, 0xb7, 0xa3, 0xb8, 0xa3, 0xb9, 0xa2, 0xf1, 0xa2, 0xf2, 0xa2, 0xf3,
+ 0xa2, 0xf4, 0xa2, 0xf5, 0xa2, 0xf6, 0xa2, 0xf7, 0xa2, 0xf8, 0xa2, 0xf9, 0xa2,
+ 0xfa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa3,
+ 0xc1, 0xa3, 0xc2, 0xa3, 0xc3, 0xa3, 0xc4, 0xa3, 0xc5, 0xa3, 0xc6, 0xa3, 0xc7,
+ 0xa3, 0xc8, 0xa3, 0xc9, 0xa3, 0xca, 0xa3, 0xcb, 0xa3, 0xcc, 0xa3, 0xcd, 0xa3,
+ 0xce, 0xa3, 0xcf, 0xa3, 0xd0, 0xa3, 0xd1, 0xa3, 0xd2, 0xa3, 0xd3, 0xa3, 0xd4,
+ 0xa3, 0xd5, 0xa3, 0xd6, 0xa3, 0xd7, 0xa3, 0xd8, 0xa3, 0xd9, 0xa3, 0xda, 0xa3,
+ 0xe1, 0xa3, 0xe2, 0xa3, 0xe3, 0xa3, 0xe4, 0xa3, 0xe5, 0xa3, 0xe6, 0xa3, 0xe7,
+ 0xa3, 0xe8, 0xa3, 0xe9, 0xa3, 0xea, 0xa3, 0xeb, 0xa3, 0xec, 0xa3, 0xed, 0xa3,
+ 0xee, 0xa3, 0xef, 0xa3, 0xf0, 0xa3, 0xf1, 0xa3, 0xf2, 0xa3, 0xf3, 0xa3, 0xf4,
+ 0xa3, 0xf5, 0xa3, 0xf6, 0xa3, 0xf7, 0xa3, 0xf8, 0xa3, 0xf9, 0xa3, 0xfa, 0xa6,
+ 0xa1, 0xa6, 0xa2, 0xa6, 0xa3, 0xa6, 0xa4, 0xa6, 0xa5, 0xa6, 0xa6, 0xa6, 0xa7,
+ 0xa6, 0xa8, 0xa6, 0xa9, 0xa6, 0xaa, 0xa1, 0xc4, 0xa6, 0xac, 0xa6, 0xad, 0xa6,
+ 0xae, 0xa6, 0xaf, 0xa1, 0xc7, 0xa6, 0xb1, 0xa1, 0xc6, 0xa6, 0xb3, 0xa6, 0xb4,
+ 0xa6, 0xb5, 0xa6, 0xb6, 0xa6, 0xb7, 0xa6, 0xb8, 0xa6, 0xc1, 0xa6, 0xc2, 0xa6,
+ 0xc3, 0xa6, 0xc4, 0xa6, 0xc5, 0xa6, 0xc6, 0xa6, 0xc7, 0xa6, 0xc8, 0xa6, 0xc9,
+ 0xa6, 0xca, 0xa6, 0xcb, 0xa6, 0xcc, 0xa6, 0xcd, 0xa6, 0xce, 0xa6, 0xcf, 0xa6,
+ 0xd0, 0xa6, 0xd1, 0xa6, 0xd2, 0xa6, 0xd3, 0xa6, 0xd4, 0xa6, 0xd5, 0xa6, 0xd6,
+ 0xa6, 0xd7, 0xa6, 0xd8, 0xa8, 0xc5, 0xa8, 0xc6, 0xa8, 0xc7, 0xa8, 0xc8, 0xa8,
+ 0xc9, 0xa8, 0xca, 0xa8, 0xcb, 0xa8, 0xcc, 0xa8, 0xcd, 0xa8, 0xce, 0xa8, 0xcf,
+ 0xa8, 0xd0, 0xa8, 0xd1, 0xa8, 0xd2, 0xa8, 0xd3, 0xa8, 0xd4, 0xa8, 0xd5, 0xa8,
+ 0xd6, 0xa8, 0xd7, 0xa8, 0xd8, 0xa8, 0xd9, 0xa8, 0xda, 0xa8, 0xdb, 0xa8, 0xdc,
+ 0xa8, 0xdd, 0xa8, 0xde, 0xa8, 0xdf, 0xa8, 0xe0, 0xa8, 0xe1, 0xa8, 0xe2, 0xa8,
+ 0xe3, 0xa8, 0xe4, 0xa8, 0xe5, 0xa8, 0xe6, 0xa8, 0xe7, 0xa8, 0xe8, 0xa8, 0xe9,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd2, 0xbb, 0xd2, 0xd2, 0xb6, 0xa1, 0xc6,
+ 0xdf, 0xc4, 0xcb, 0xbe, 0xc5, 0xc1, 0xcb, 0xb6, 0xfe, 0xc8, 0xcb, 0xb6, 0xf9,
+ 0xc8, 0xeb, 0xb0, 0xcb, 0xbc, 0xb8, 0xb5, 0xb6, 0xb5, 0xf3, 0xc1, 0xa6, 0xd8,
+ 0xb0, 0xca, 0xae, 0xb2, 0xb7, 0xd3, 0xd6, 0xc8, 0xfd, 0xcf, 0xc2, 0xd5, 0xc9,
+ 0xc9, 0xcf, 0xd1, 0xbe, 0xcd, 0xe8, 0xb7, 0xb2, 0xbe, 0xc3, 0xc3, 0xb4, 0xd2,
+ 0xb2, 0xc6, 0xf2, 0xd3, 0xda, 0xcd, 0xf6, 0xd8, 0xa3, 0xc8, 0xd0, 0xc9, 0xd7,
+ 0xc7, 0xa7, 0xb2, 0xe6, 0xbf, 0xda, 0xcd, 0xc1, 0xca, 0xbf, 0xcf, 0xa6, 0xb4,
+ 0xf3, 0xc5, 0xae, 0xd7, 0xd3, 0xe6, 0xdd, 0xe6, 0xde, 0xb4, 0xe7, 0xd0, 0xa1,
+ 0xde, 0xcc, 0xca, 0xac, 0xc9, 0xbd, 0xb4, 0xa8, 0xb9, 0xa4, 0xbc, 0xba, 0xd2,
+ 0xd1, 0xcb, 0xc8, 0xbd, 0xed, 0xb8, 0xc9, 0xde, 0xc3, 0xdf, 0xae, 0xb9, 0xad,
+ 0xb2, 0xc5, 0xb3, 0xf3, 0xd8, 0xa4, 0xb2, 0xbb, 0xd6, 0xd0, 0xb7, 0xe1, 0xb5,
+ 0xa4, 0xd6, 0xae, 0xd2, 0xfc, 0xd3, 0xe8, 0xd4, 0xc6, 0xbe, 0xae, 0xbb, 0xa5,
+ 0xce, 0xe5, 0xbf, 0xba, 0xc8, 0xca, 0xca, 0xb2, 0xd8, 0xea, 0xc6, 0xcd, 0xb3,
+ 0xf0, 0xc8, 0xd4, 0xbd, 0xf1, 0xbd, 0xe9, 0xd8, 0xc6, 0xd4, 0xaa, 0xd4, 0xca,
+ 0xc4, 0xda, 0xc1, 0xf9, 0xd9, 0xe2, 0xb9, 0xab, 0xc8, 0xdf, 0xd0, 0xd7, 0xb7,
+ 0xd6, 0xc7, 0xd0, 0xd8, 0xd7, 0xd4, 0xc8, 0xb9, 0xb4, 0xce, 0xf0, 0xbb, 0xaf,
+ 0xc6, 0xa5, 0xce, 0xe7, 0xc9, 0xfd, 0xd8, 0xa6, 0xb1, 0xe5, 0xb6, 0xf2, 0xd3,
+ 0xd1, 0xbc, 0xb0, 0xb7, 0xb4, 0xc8, 0xc9, 0xcc, 0xec, 0xb7, 0xf2, 0xcc, 0xab,
+ 0xd8, 0xb2, 0xbf, 0xd7, 0xc9, 0xd9, 0xd3, 0xc8, 0xb3, 0xdf, 0xcd, 0xcd, 0xb0,
+ 0xcd, 0xbb, 0xc3, 0xd8, 0xa5, 0xb5, 0xf5, 0xd2, 0xfd, 0xd0, 0xc4, 0xb8, 0xea,
+ 0xbb, 0xa7, 0xca, 0xd6, 0xd4, 0xfa, 0xd6, 0xa7, 0xce, 0xc4, 0xb6, 0xb7, 0xbd,
+ 0xef, 0xb7, 0xbd, 0xc8, 0xd5, 0xd4, 0xbb, 0xd4, 0xc2, 0xc4, 0xbe, 0xc7, 0xb7,
+ 0xd6, 0xb9, 0xb4, 0xf5, 0xce, 0xe3, 0xb1, 0xc8, 0xc3, 0xab, 0xca, 0xcf, 0xcb,
+ 0xae, 0xbb, 0xf0, 0xd7, 0xa6, 0xb8, 0xb8, 0xd8, 0xb3, 0xc6, 0xac, 0xd1, 0xc0,
+ 0xc5, 0xa3, 0xc8, 0xae, 0xcd, 0xf5, 0xb1, 0xfb, 0xca, 0xc0, 0xd8, 0xa7, 0xc7,
+ 0xd2, 0xc7, 0xf0, 0xd6, 0xf7, 0xd5, 0xa7, 0xb7, 0xa6, 0xba, 0xf5, 0xd2, 0xd4,
+ 0xb8, 0xb6, 0xd7, 0xd0, 0xca, 0xcb, 0xcb, 0xfb, 0xd5, 0xcc, 0xb4, 0xfa, 0xc1,
+ 0xee, 0xcf, 0xc9, 0xd8, 0xf0, 0xb3, 0xe4, 0xd0, 0xd6, 0xc8, 0xbd, 0xb2, 0xe1,
+ 0xb6, 0xac, 0xb0, 0xbc, 0xb3, 0xf6, 0xcd, 0xb9, 0xbf, 0xaf, 0xbc, 0xd3, 0xb9,
+ 0xa6, 0xb0, 0xfc, 0xb4, 0xd2, 0xb1, 0xb1, 0xd4, 0xd1, 0xc7, 0xaa, 0xb0, 0xeb,
+ 0xbb, 0xdc, 0xbf, 0xa8, 0xd5, 0xbc, 0xc3, 0xae, 0xd8, 0xb4, 0xc8, 0xa5, 0xbf,
+ 0xc9, 0xb9, 0xc5, 0xd3, 0xd2, 0xd5, 0xd9, 0xb6, 0xa3, 0xdf, 0xb5, 0xdf, 0xb6,
+ 0xb5, 0xf0, 0xcb, 0xbe, 0xd8, 0xcf, 0xbd, 0xd0, 0xc1, 0xed, 0xd6, 0xbb, 0xca,
+ 0xb7, 0xdf, 0xb3, 0xcc, 0xa8, 0xbe, 0xe4, 0xb0, 0xc8, 0xdf, 0xb7, 0xcb, 0xc4,
+ 0xc7, 0xf4, 0xcd, 0xe2, 0xd1, 0xeb, 0xca, 0xa7, 0xc5, 0xab, 0xc4, 0xcc, 0xd4,
+ 0xd0, 0xcb, 0xfc, 0xc4, 0xe1, 0xbe, 0xde, 0xc7, 0xc9, 0xd7, 0xf3, 0xca, 0xd0,
+ 0xb2, 0xbc, 0xc6, 0xbd, 0xd3, 0xd7, 0xdb, 0xcd, 0xba, 0xeb, 0xb8, 0xa5, 0xb1,
+ 0xd8, 0xce, 0xec, 0xb4, 0xf2, 0xc8, 0xd3, 0xb0, 0xc7, 0xc6, 0xcb, 0xb3, 0xe2,
+ 0xb5, 0xa9, 0xca, 0xf5, 0xb1, 0xbe, 0xce, 0xb4, 0xc4, 0xa9, 0xd4, 0xfd, 0xd5,
+ 0xfd, 0xc4, 0xb8, 0xc3, 0xf1, 0xd8, 0xb5, 0xd3, 0xc0, 0xd6, 0xad, 0xcd, 0xa1,
+ 0xb7, 0xba, 0xb7, 0xb8, 0xd0, 0xfe, 0xd3, 0xf1, 0xb9, 0xcf, 0xcd, 0xdf, 0xb8,
+ 0xca, 0xc9, 0xfa, 0xd3, 0xc3, 0xcb, 0xa6, 0xcc, 0xef, 0xd3, 0xc9, 0xbc, 0xd7,
+ 0xc9, 0xea, 0xf1, 0xe2, 0xb0, 0xd7, 0xc6, 0xa4, 0xc3, 0xf3, 0xc4, 0xbf, 0xc3,
+ 0xac, 0xca, 0xb8, 0xca, 0xaf, 0xca, 0xbe, 0xba, 0xcc, 0xd1, 0xa8, 0xc1, 0xa2,
+ 0xd8, 0xa9, 0xb6, 0xaa, 0xc6, 0xb9, 0xc5, 0xd2, 0xd8, 0xc0, 0xd8, 0xa8, 0xbd,
+ 0xbb, 0xd2, 0xe0, 0xba, 0xa5, 0xb7, 0xc2, 0xd8, 0xf8, 0xbb, 0xef, 0xd2, 0xc1,
+ 0xb7, 0xf2, 0xce, 0xe9, 0xb7, 0xa5, 0xd0, 0xdd, 0xb7, 0xfc, 0xd6, 0xd9, 0xbc,
+ 0xfe, 0xc8, 0xce, 0xd1, 0xf6, 0xd8, 0xf2, 0xb7, 0xdd, 0xc6, 0xf3, 0xa1, 0xf5,
+ 0xb9, 0xe2, 0xd0, 0xd7, 0xd5, 0xd7, 0xcf, 0xc8, 0xc8, 0xab, 0xb9, 0xb2, 0xd4,
+ 0xd9, 0xb1, 0xf9, 0xc1, 0xd0, 0xd0, 0xcc, 0xbb, 0xae, 0xd8, 0xd8, 0xeb, 0xbe,
+ 0xc1, 0xd3, 0xd0, 0xd9, 0xbf, 0xef, 0xbd, 0xb3, 0xd3, 0xa1, 0xce, 0xa3, 0xbc,
+ 0xaa, 0xc0, 0xf4, 0xcd, 0xac, 0xb5, 0xf5, 0xcd, 0xc2, 0xd3, 0xf5, 0xb4, 0xe7,
+ 0xb8, 0xf7, 0xcf, 0xf2, 0xc3, 0xfb, 0xba, 0xcf, 0xb3, 0xd4, 0xba, 0xf3, 0xdf,
+ 0xba, 0xdf, 0xb8, 0xd2, 0xf2, 0xbb, 0xd8, 0xe0, 0xee, 0xdb, 0xda, 0xb5, 0xd8,
+ 0xd4, 0xda, 0xb9, 0xe7, 0xdb, 0xd8, 0xdb, 0xdd, 0xdb, 0xd7, 0xd9, 0xed, 0xb6,
+ 0xe0, 0xd2, 0xc4, 0xbf, 0xe4, 0xcd, 0xfd, 0xbc, 0xe9, 0xe5, 0xfa, 0xba, 0xc3,
+ 0xcb, 0xfd, 0xc8, 0xe7, 0xe5, 0xf9, 0xd7, 0xd6, 0xb4, 0xe6, 0xd3, 0xee, 0xca,
+ 0xd8, 0xd5, 0xac, 0xb0, 0xb2, 0xcb, 0xc2, 0xbc, 0xe2, 0xd2, 0xd9, 0xd6, 0xdd,
+ 0xb7, 0xab, 0xb2, 0xa2, 0xc4, 0xea, 0xca, 0xbd, 0xb3, 0xda, 0xc3, 0xa6, 0xe2,
+ 0xe2, 0xc8, 0xd6, 0xd0, 0xe7, 0xca, 0xf9, 0xb3, 0xc9, 0xbf, 0xdb, 0xbf, 0xb8,
+ 0xcd, 0xd0, 0xca, 0xd5, 0xd4, 0xe7, 0xd6, 0xbc, 0xd1, 0xae, 0xd0, 0xf1, 0xc7,
+ 0xfa, 0xd2, 0xb7, 0xd3, 0xd0, 0xd0, 0xe0, 0xc6, 0xd3, 0xd6, 0xec, 0xb6, 0xe4,
+ 0xb4, 0xce, 0xb4, 0xcb, 0xcb, 0xc0, 0xc4, 0xca, 0xc8, 0xea, 0xba, 0xb9, 0xce,
+ 0xdb, 0xbd, 0xad, 0xb3, 0xd8, 0xcf, 0xab, 0xc9, 0xc7, 0xce, 0xdb, 0xd1, 0xb4,
+ 0xa1, 0xf5, 0xb7, 0xba, 0xbb, 0xd2, 0xc4, 0xb2, 0xea, 0xf2, 0xb0, 0xd9, 0xd6,
+ 0xf1, 0xc3, 0xd7, 0xf4, 0xe9, 0xf3, 0xbe, 0xd1, 0xf2, 0xd3, 0xf0, 0xc0, 0xcf,
+ 0xbf, 0xbc, 0xb6, 0xf8, 0xf1, 0xe7, 0xb6, 0xfa, 0xed, 0xb2, 0xc8, 0xe2, 0xc0,
+ 0xdf, 0xbc, 0xa1, 0xb3, 0xbc, 0xd7, 0xd4, 0xd6, 0xc1, 0xbe, 0xca, 0xc9, 0xe0,
+ 0xe2, 0xb6, 0xd6, 0xdb, 0xf4, 0xde, 0xc9, 0xab, 0xb0, 0xac, 0xb3, 0xe6, 0xd1,
+ 0xaa, 0xd0, 0xd0, 0xd2, 0xc2, 0xce, 0xf7, 0xda, 0xe4, 0xb4, 0xae, 0xba, 0xe0,
+ 0xce, 0xbb, 0xd7, 0xa1, 0xd8, 0xf9, 0xd9, 0xa2, 0xd8, 0xfa, 0xb0, 0xe9, 0xb7,
+ 0xf0, 0xba, 0xce, 0xb9, 0xc0, 0xd7, 0xf4, 0xd3, 0xd3, 0xd9, 0xa4, 0xcb, 0xc5,
+ 0xc9, 0xec, 0xb5, 0xe8, 0xd5, 0xbc, 0xcb, 0xc6, 0xb5, 0xab, 0xd3, 0xb6, 0xd7,
+ 0xf7, 0xc4, 0xe3, 0xb2, 0xae, 0xb5, 0xcd, 0xc1, 0xe6, 0xd3, 0xe0, 0xd8, 0xfe,
+ 0xb2, 0xbc, 0xd8, 0xfd, 0xb6, 0xd2, 0xbf, 0xcb, 0xc3, 0xe2, 0xb1, 0xf8, 0xd2,
+ 0xb1, 0xc0, 0xe4, 0xb1, 0xf0, 0xc5, 0xd0, 0xc0, 0xfb, 0xc9, 0xbe, 0xc5, 0xd9,
+ 0xbd, 0xd9, 0xd6, 0xfa, 0xc5, 0xac, 0xdb, 0xbe, 0xcf, 0xbb, 0xbc, 0xb4, 0xc2,
+ 0xd1, 0xc1, 0xdf, 0xbf, 0xd4, 0xcd, 0xcc, 0xce, 0xe1, 0xb7, 0xf1, 0xb3, 0xdf,
+ 0xb0, 0xc9, 0xb4, 0xf4, 0xdf, 0xc0, 0xce, 0xe2, 0xb3, 0xca, 0xc2, 0xc0, 0xbe,
+ 0xfd, 0xb7, 0xd4, 0xb8, 0xe6, 0xb4, 0xb5, 0xce, 0xc7, 0xce, 0xfc, 0xcb, 0xb1,
+ 0xb3, 0xb3, 0xc4, 0xc5, 0xb7, 0xcd, 0xba, 0xf0, 0xd1, 0xbd, 0xd6, 0xa8, 0xba,
+ 0xac, 0xd2, 0xf7, 0xcc, 0xfd, 0xb4, 0xd1, 0xc0, 0xa7, 0xb6, 0xda, 0xe0, 0xf1,
+ 0xb7, 0xbb, 0xbf, 0xd3, 0xd6, 0xb7, 0xcc, 0xae, 0xbe, 0xf9, 0xbf, 0xb2, 0xbb,
+ 0xf8, 0xd7, 0xf8, 0xbb, 0xb5, 0xdb, 0xdf, 0xd7, 0xb3, 0xbc, 0xd0, 0xd7, 0xb1,
+ 0xb6, 0xca, 0xb7, 0xc1, 0xe6, 0xa4, 0xe5, 0xfe, 0xc3, 0xee, 0xd1, 0xfd, 0xe5,
+ 0xfb, 0xe6, 0xa5, 0xbc, 0xcb, 0xc8, 0xd1, 0xcd, 0xd7, 0xd0, 0xa2, 0xd7, 0xce,
+ 0xe6, 0xda, 0xd8, 0xc3, 0xcd, 0xea, 0xcb, 0xce, 0xba, 0xea, 0xde, 0xce, 0xbe,
+ 0xd6, 0xc6, 0xa8, 0xc4, 0xf2, 0xce, 0xb2, 0xe1, 0xaa, 0xe1, 0xaf, 0xb2, 0xed,
+ 0xe1, 0xa7, 0xce, 0xd7, 0xcf, 0xa3, 0xd0, 0xf2, 0xb1, 0xd3, 0xb4, 0xb2, 0xcd,
+ 0xa2, 0xc5, 0xaa, 0xb5, 0xdc, 0xcd, 0xae, 0xd0, 0xce, 0xe1, 0xdd, 0xd2, 0xdb,
+ 0xcd, 0xfc, 0xbc, 0xc9, 0xd6, 0xbe, 0xc8, 0xcc, 0xb3, 0xc0, 0xbf, 0xec, 0xe2,
+ 0xee, 0xe2, 0xec, 0xbd, 0xe4, 0xce, 0xd2, 0xb3, 0xad, 0xbf, 0xb9, 0xb6, 0xb6,
+ 0xbc, 0xbc, 0xb7, 0xf6, 0xbe, 0xf1, 0xc5, 0xa4, 0xb0, 0xd1, 0xb6, 0xf3, 0xd5,
+ 0xd2, 0xc5, 0xfa, 0xb0, 0xe2, 0xca, 0xe3, 0xb3, 0xb6, 0xd5, 0xdb, 0xb0, 0xe7,
+ 0xcd, 0xb6, 0xd7, 0xa5, 0xd2, 0xd6, 0xa1, 0xf5, 0xb8, 0xc4, 0xb9, 0xa5, 0xd8,
+ 0xfc, 0xba, 0xb5, 0xb8, 0xfc, 0xca, 0xf8, 0xc0, 0xee, 0xd0, 0xd3, 0xb2, 0xc4,
+ 0xb4, 0xe5, 0xb6, 0xc5, 0xd5, 0xc8, 0xe8, 0xbd, 0xc9, 0xbc, 0xb8, 0xcb, 0xb8,
+ 0xdc, 0xe8, 0xbc, 0xa1, 0xf5, 0xb2, 0xbd, 0xc3, 0xbf, 0xc7, 0xf3, 0xb9, 0xaf,
+ 0xc9, 0xb3, 0xc7, 0xdf, 0xc9, 0xf2, 0xb3, 0xc1, 0xe3, 0xe4, 0xc5, 0xe6, 0xcd,
+ 0xf4, 0xbe, 0xf6, 0xe3, 0xe5, 0xcc, 0xad, 0xe3, 0xe7, 0xe3, 0xe8, 0xb3, 0xe5,
+ 0xc3, 0xbb, 0xc6, 0xfb, 0xce, 0xd6, 0xbc, 0xb3, 0xb7, 0xda, 0xe3, 0xea, 0xe3,
+ 0xec, 0xe3, 0xeb, 0xa1, 0xf5, 0xe3, 0xe6, 0xa1, 0xf5, 0xd2, 0xca, 0xd4, 0xee,
+ 0xd7, 0xc6, 0xd4, 0xd6, 0xbe, 0xc4, 0xc0, 0xce, 0xc4, 0xb5, 0xcb, 0xfc, 0xb5,
+ 0xd2, 0xbf, 0xf1, 0xbe, 0xc1, 0xf0, 0xae, 0xb8, 0xa6, 0xc4, 0xd0, 0xb5, 0xe9,
+ 0xd4, 0xed, 0xb6, 0xa2, 0xd2, 0xd3, 0xcb, 0xbd, 0xd0, 0xe3, 0xcd, 0xba, 0xbe,
+ 0xbf, 0xcf, 0xb5, 0xba, 0xb1, 0xd0, 0xa4, 0xeb, 0xc1, 0xb8, 0xce, 0xd6, 0xe2,
+ 0xb8, 0xd8, 0xb6, 0xc7, 0xd3, 0xfd, 0xc1, 0xbc, 0xc3, 0xa2, 0xd3, 0xf3, 0xc9,
+ 0xd6, 0xbc, 0xfb, 0xbd, 0xc7, 0xd1, 0xd4, 0xb9, 0xc8, 0xb6, 0xb9, 0xf5, 0xb9,
+ 0xb1, 0xb4, 0xb3, 0xe0, 0xd7, 0xdf, 0xd7, 0xe3, 0xc9, 0xed, 0xb3, 0xb5, 0xd0,
+ 0xc1, 0xb3, 0xbd, 0xd3, 0xd8, 0xe5, 0xc6, 0xd1, 0xb8, 0xc6, 0xf9, 0xd1, 0xb2,
+ 0xd2, 0xd8, 0xd0, 0xcf, 0xd0, 0xb0, 0xb0, 0xee, 0xc4, 0xc7, 0xd3, 0xcf, 0xb2,
+ 0xc9, 0xc0, 0xef, 0xb7, 0xc0, 0xc8, 0xee, 0xda, 0xe5, 0xda, 0xe6, 0xa1, 0xf5,
+ 0xb2, 0xa2, 0xb9, 0xd4, 0xc8, 0xe9, 0xca, 0xc2, 0xd0, 0xa9, 0xd1, 0xc7, 0xcf,
+ 0xed, 0xbe, 0xa9, 0xd1, 0xf0, 0xd2, 0xc0, 0xca, 0xcc, 0xbc, 0xd1, 0xca, 0xb9,
+ 0xc0, 0xd0, 0xb9, 0xa9, 0xc0, 0xfd, 0xc0, 0xb4, 0xd9, 0xa9, 0xb0, 0xdb, 0xb2,
+ 0xa2, 0xb3, 0xde, 0xc5, 0xe5, 0xd9, 0xac, 0xc2, 0xd8, 0xd9, 0xab, 0xd9, 0xaa,
+ 0xd9, 0xa7, 0xa1, 0xf5, 0xcd, 0xc3, 0xb6, 0xf9, 0xd9, 0xee, 0xc1, 0xbd, 0xbe,
+ 0xdf, 0xc6, 0xe4, 0xb5, 0xe4, 0xd9, 0xfd, 0xba, 0xaf, 0xbf, 0xcc, 0xc8, 0xaf,
+ 0xcb, 0xa2, 0xb4, 0xcc, 0xb5, 0xbd, 0xb9, 0xce, 0xd6, 0xc6, 0xb6, 0xe7, 0xdb,
+ 0xc0, 0xa1, 0xf5, 0xd7, 0xe4, 0xd0, 0xad, 0xd7, 0xbf, 0xb1, 0xb0, 0xd8, 0xd4,
+ 0xbe, 0xed, 0xd0, 0xb6, 0xd0, 0xf4, 0xc8, 0xa1, 0xca, 0xe5, 0xca, 0xdc, 0xce,
+ 0xb6, 0xba, 0xc7, 0xbf, 0xa7, 0xc5, 0xde, 0xb9, 0xbe, 0xbe, 0xd7, 0xc9, 0xeb,
+ 0xdf, 0xc8, 0xdf, 0xcd, 0xd6, 0xe4, 0xc5, 0xd8, 0xba, 0xf4, 0xb8, 0xc0, 0xdf,
+ 0xc9, 0xdf, 0xce, 0xba, 0xcd, 0xdf, 0xcb, 0xc4, 0xd8, 0xd6, 0xdc, 0xd5, 0xa6,
+ 0xc3, 0xfc, 0xbe, 0xcc, 0xb9, 0xcc, 0xc0, 0xac, 0xbf, 0xc0, 0xc6, 0xba, 0xdb,
+ 0xe1, 0xc6, 0xc2, 0xcc, 0xb9, 0xc0, 0xa4, 0xdb, 0xe5, 0xd2, 0xb9, 0xb7, 0xee,
+ 0xc6, 0xe6, 0xc4, 0xce, 0xd1, 0xd9, 0xb1, 0xbc, 0xe6, 0xaa, 0xc6, 0xde, 0xce,
+ 0xaf, 0xc3, 0xc3, 0xc4, 0xdd, 0xb9, 0xc3, 0xc4, 0xb7, 0xbd, 0xe3, 0xe6, 0xa9,
+ 0xca, 0xbc, 0xd0, 0xd5, 0xe6, 0xa2, 0xe6, 0xa8, 0xc4, 0xe3, 0xe6, 0xa6, 0xa1,
+ 0xf5, 0xc3, 0xcf, 0xb9, 0xc2, 0xbc, 0xbe, 0xd7, 0xda, 0xb6, 0xa8, 0xb9, 0xd9,
+ 0xd2, 0xcb, 0xd6, 0xe6, 0xcd, 0xf0, 0xc9, 0xd0, 0xc7, 0xfc, 0xbe, 0xd3, 0xbd,
+ 0xec, 0xe1, 0xba, 0xb8, 0xd4, 0xb0, 0xb6, 0xd1, 0xd2, 0xe1, 0xb6, 0xe1, 0xb7,
+ 0xd4, 0xc0, 0xc1, 0xb1, 0xd6, 0xe3, 0xcc, 0xfb, 0xc5, 0xc1, 0xb2, 0xaf, 0xe0,
+ 0xfb, 0xd0, 0xd2, 0xb8, 0xfd, 0xb5, 0xea, 0xb8, 0xae, 0xb5, 0xd7, 0xe2, 0xd2,
+ 0xd1, 0xd3, 0xcf, 0xd2, 0xbb, 0xa1, 0xe5, 0xf3, 0xcd, 0xf9, 0xd5, 0xf7, 0xb7,
+ 0xf0, 0xb1, 0xcb, 0xe3, 0xc3, 0xd6, 0xd2, 0xba, 0xf6, 0xc4, 0xee, 0xb7, 0xde,
+ 0xe2, 0xf3, 0xd5, 0xfa, 0xc7, 0xd3, 0xe2, 0xf0, 0xb2, 0xc0, 0xb9, 0xd6, 0xc5,
+ 0xc2, 0xe2, 0xf9, 0xd0, 0xd4, 0xe2, 0xf5, 0xe2, 0xf6, 0xe2, 0xf2, 0xbb, 0xf2,
+ 0xe3, 0xde, 0xb7, 0xbf, 0xec, 0xe5, 0xcb, 0xf9, 0xb3, 0xd0, 0xc0, 0xad, 0xb0,
+ 0xe8, 0xd6, 0xf4, 0xc3, 0xf2, 0xb7, 0xf7, 0xc4, 0xa8, 0xbe, 0xdc, 0xd5, 0xd0,
+ 0xc5, 0xfb, 0xcd, 0xd8, 0xb0, 0xce, 0xc5, 0xd7, 0xc4, 0xe9, 0xc5, 0xea, 0xb3,
+ 0xe9, 0xd1, 0xba, 0xb9, 0xd5, 0xd7, 0xbe, 0xc4, 0xb4, 0xc5, 0xc4, 0xb5, 0xd6,
+ 0xde, 0xd5, 0xb1, 0xa7, 0xbe, 0xd0, 0xcd, 0xcf, 0xde, 0xd6, 0xb2, 0xf0, 0xcc,
+ 0xa7, 0xc1, 0xe0, 0xb7, 0xc5, 0xb8, 0xab, 0xd3, 0xda, 0xcd, 0xfa, 0xce, 0xf4,
+ 0xd2, 0xd7, 0xb2, 0xfd, 0xc0, 0xa5, 0xb0, 0xba, 0xc3, 0xf7, 0xea, 0xc0, 0xbb,
+ 0xe8, 0xea, 0xbf, 0xea, 0xbb, 0xc9, 0xfd, 0xb7, 0xfe, 0xc5, 0xf3, 0xba, 0xbc,
+ 0xe8, 0xca, 0xd5, 0xed, 0xb6, 0xab, 0xb9, 0xfb, 0xe8, 0xc3, 0xe8, 0xcb, 0xe8,
+ 0xc1, 0xd6, 0xa6, 0xc1, 0xd6, 0xb1, 0xad, 0xbd, 0xdc, 0xb0, 0xe5, 0xcd, 0xf7,
+ 0xcb, 0xc9, 0xce, 0xf6, 0xe8, 0xc6, 0xc3, 0xb6, 0xa1, 0xf5, 0xe8, 0xcc, 0xe8,
+ 0xc2, 0xea, 0xbd, 0xd0, 0xc0, 0xce, 0xe4, 0xc6, 0xe7, 0xe9, 0xe2, 0xc3, 0xa5,
+ 0xb7, 0xd5, 0xc6, 0xfc, 0xd7, 0xa2, 0xd3, 0xbe, 0xe3, 0xfb, 0xc3, 0xda, 0xc4,
+ 0xe0, 0xba, 0xd3, 0xb9, 0xc1, 0xd5, 0xb4, 0xd5, 0xd3, 0xb2, 0xa8, 0xc4, 0xad,
+ 0xb7, 0xa8, 0xe3, 0xfc, 0xb7, 0xd0, 0xd0, 0xb9, 0xd3, 0xcd, 0xbf, 0xf6, 0xbe,
+ 0xda, 0xe3, 0xf4, 0xc7, 0xf6, 0xe3, 0xf3, 0xd1, 0xd8, 0xd6, 0xce, 0xc5, 0xdd,
+ 0xb7, 0xba, 0xb2, 0xb4, 0xa1, 0xf5, 0xe3, 0xfd, 0xa1, 0xf5, 0xe3, 0xf7, 0xe3,
+ 0xf6, 0xbf, 0xbb, 0xd1, 0xd7, 0xb3, 0xb4, 0xb4, 0xb6, 0xd6, 0xcb, 0xc5, 0xc0,
+ 0xd5, 0xf9, 0xb0, 0xd6, 0xb0, 0xe6, 0xc4, 0xc1, 0xce, 0xef, 0xd7, 0xb4, 0xe1,
+ 0xf2, 0xbe, 0xd1, 0xb9, 0xb7, 0xba, 0xfc, 0xcd, 0xe6, 0xe7, 0xe5, 0xe7, 0xe4,
+ 0xc3, 0xb5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xde, 0xb8, 0xed, 0xbe, 0xce, 0xb5,
+ 0xc4, 0xd3, 0xdb, 0xc3, 0xa4, 0xd6, 0xb1, 0xd6, 0xaa, 0xce, 0xf9, 0xc9, 0xe7,
+ 0xec, 0xeb, 0xc6, 0xee, 0xb1, 0xfc, 0xf4, 0xcc, 0xbf, 0xd5, 0xf1, 0xb7, 0xf3,
+ 0xc3, 0xbe, 0xc0, 0xd8, 0xe8, 0xc7, 0xbc, 0xd8, 0xc2, 0xd5, 0xdf, 0xb7, 0xce,
+ 0xb7, 0xca, 0xd6, 0xab, 0xeb, 0xc5, 0xb9, 0xc9, 0xeb, 0xc6, 0xbc, 0xe7, 0xeb,
+ 0xc8, 0xb7, 0xbe, 0xbf, 0xcf, 0xce, 0xd4, 0xf4, 0xa7, 0xc9, 0xe1, 0xb7, 0xbc,
+ 0xd6, 0xa5, 0xdc, 0xbd, 0xb0, 0xc5, 0xd1, 0xbf, 0xdc, 0xcf, 0xc7, 0xdb, 0xbb,
+ 0xa8, 0xb7, 0xd2, 0xbd, 0xe6, 0xd0, 0xbe, 0xdc, 0xbf, 0xa1, 0xf5, 0xdc, 0xc1,
+ 0xdc, 0xc0, 0xdc, 0xc6, 0xbb, 0xa2, 0xca, 0xad, 0xb3, 0xf5, 0xb1, 0xed, 0xd4,
+ 0xfe, 0xd3, 0xad, 0xb7, 0xb5, 0xbd, 0xfc, 0xc9, 0xdb, 0xdb, 0xa1, 0xc7, 0xf1,
+ 0xda, 0xfd, 0xb2, 0xc9, 0xbd, 0xf0, 0xb3, 0xa4, 0xc3, 0xc5, 0xb8, 0xb7, 0xcd,
+ 0xd3, 0xb0, 0xa2, 0xd7, 0xe8, 0xb8, 0xbd, 0xda, 0xe9, 0xf6, 0xbf, 0xd3, 0xea,
+ 0xc7, 0xe0, 0xb7, 0xc7, 0xd8, 0xbd, 0xcd, 0xa4, 0xc1, 0xc1, 0xd0, 0xc5, 0xc7,
+ 0xd6, 0xba, 0xee, 0xb1, 0xe3, 0xcf, 0xc0, 0xd9, 0xb8, 0xc7, 0xce, 0xb1, 0xa3,
+ 0xb4, 0xd9, 0xc2, 0xc2, 0xb7, 0xfd, 0xd9, 0xb9, 0xbf, 0xa1, 0xcb, 0xd7, 0xce,
+ 0xea, 0xc0, 0xfe, 0xb6, 0xed, 0xcf, 0xb5, 0xd9, 0xb5, 0xd9, 0xde, 0xd3, 0xe1,
+ 0xbe, 0xd6, 0xd9, 0xf0, 0xc3, 0xb0, 0xeb, 0xd0, 0xb9, 0xda, 0xc9, 0xb2, 0xcc,
+ 0xea, 0xcf, 0xf7, 0xc7, 0xb0, 0xd8, 0xdd, 0xbf, 0xcb, 0xd4, 0xf2, 0xd3, 0xc2,
+ 0xc3, 0xe3, 0xb2, 0xaa, 0xbe, 0xa2, 0xd9, 0xe9, 0xc4, 0xcf, 0xc8, 0xb4, 0xba,
+ 0xf1, 0xc5, 0xd1, 0xd2, 0xa7, 0xb0, 0xa7, 0xd7, 0xc9, 0xb0, 0xa5, 0xd4, 0xd5,
+ 0xcf, 0xcc, 0xdf, 0xd7, 0xbf, 0xc8, 0xcd, 0xdb, 0xdf, 0xd3, 0xd1, 0xca, 0xdf,
+ 0xe4, 0xc6, 0xb7, 0xba, 0xe5, 0xb9, 0xfe, 0xbf, 0xa9, 0xe5, 0xeb, 0xd4, 0xdb,
+ 0xdf, 0xdd, 0xdf, 0xe3, 0xdf, 0xd6, 0xdf, 0xde, 0xe0, 0xf3, 0xb4, 0xb9, 0xd0,
+ 0xcd, 0xdb, 0xf3, 0xd4, 0xab, 0xb9, 0xb8, 0xb3, 0xc7, 0xbf, 0xe5, 0xdb, 0xf2,
+ 0xde, 0xc8, 0xc6, 0xf5, 0xd7, 0xe0, 0xbf, 0xfc, 0xdb, 0xbc, 0xbd, 0xaa, 0xe6,
+ 0xb0, 0xd7, 0xcb, 0xe6, 0xaf, 0xd2, 0xcc, 0xcd, 0xde, 0xc0, 0xd1, 0xd6, 0xb6,
+ 0xd2, 0xa6, 0xbc, 0xe9, 0xcd, 0xfe, 0xd2, 0xf6, 0xba, 0xa2, 0xd0, 0xfb, 0xbb,
+ 0xc2, 0xca, 0xd2, 0xbf, 0xcd, 0xe5, 0xb6, 0xb7, 0xe2, 0xca, 0xba, 0xc6, 0xc1,
+ 0xca, 0xac, 0xce, 0xdd, 0xd6, 0xc5, 0xe1, 0xbc, 0xcf, 0xef, 0xb5, 0xdb, 0xcb,
+ 0xa7, 0xa1, 0xf5, 0xd3, 0xc4, 0xe2, 0xd4, 0xb6, 0xc8, 0xbd, 0xa8, 0xde, 0xc4,
+ 0xe5, 0xf4, 0xd1, 0xe5, 0xba, 0xdc, 0xb4, 0xfd, 0xbb, 0xb2, 0xc2, 0xc9, 0xe1,
+ 0xdf, 0xba, 0xf3, 0xe1, 0xe0, 0xc5, 0xad, 0xcb, 0xbc, 0xb5, 0xa1, 0xbc, 0xb1,
+ 0xd4, 0xf5, 0xd4, 0xb9, 0xbb, 0xd0, 0xc7, 0xa1, 0xba, 0xde, 0xbb, 0xd6, 0xba,
+ 0xe3, 0xca, 0xd1, 0xcc, 0xf1, 0xb6, 0xb2, 0xe3, 0xa1, 0xd0, 0xf4, 0xb1, 0xe2,
+ 0xb0, 0xdd, 0xcd, 0xda, 0xb0, 0xb4, 0xc6, 0xb4, 0xca, 0xc3, 0xb3, 0xd6, 0xde,
+ 0xd7, 0xd7, 0xa7, 0xd6, 0xb8, 0xb9, 0xb0, 0xbf, 0xbd, 0xd5, 0xfc, 0xc0, 0xa8,
+ 0xca, 0xb0, 0xcb, 0xa9, 0xcc, 0xf4, 0xb9, 0xd2, 0xd5, 0xfe, 0xb9, 0xca, 0xed,
+ 0xbd, 0xca, 0xa9, 0xbc, 0xc8, 0xb4, 0xba, 0xd5, 0xd1, 0xd3, 0xb3, 0xc3, 0xc1,
+ 0xca, 0xc7, 0xd0, 0xc7, 0xd7, 0xf2, 0xea, 0xc5, 0xa1, 0xf5, 0xea, 0xc2, 0xca,
+ 0xc1, 0xc8, 0xbe, 0xd6, 0xf9, 0xc8, 0xe1, 0xc4, 0xb3, 0xbc, 0xed, 0xbc, 0xdc,
+ 0xbf, 0xdd, 0xd5, 0xa4, 0xe8, 0xd1, 0xbf, 0xc2, 0xb1, 0xfa, 0xb8, 0xcc, 0xb9,
+ 0xd5, 0xe8, 0xd6, 0xb2, 0xe9, 0xe8, 0xdb, 0xb0, 0xd8, 0xd7, 0xf5, 0xc1, 0xf8,
+ 0xe8, 0xd2, 0xe8, 0xd4, 0xe8, 0xdc, 0xe8, 0xd8, 0xc6, 0xe2, 0xcd, 0xe1, 0xd1,
+ 0xea, 0xb4, 0xf9, 0xb6, 0xce, 0xb6, 0xbe, 0xc5, 0xfe, 0xb7, 0xfa, 0xc8, 0xaa,
+ 0xd1, 0xf3, 0xd6, 0xde, 0xba, 0xe9, 0xc1, 0xf7, 0xbd, 0xf2, 0xe4, 0xa3, 0xb6,
+ 0xfd, 0xb6, 0xb4, 0xcf, 0xb4, 0xbb, 0xee, 0xc7, 0xa2, 0xc5, 0xc9, 0xd0, 0xda,
+ 0xc2, 0xe5, 0xb1, 0xc3, 0xe4, 0xa1, 0xe4, 0xa2, 0xa1, 0xf5, 0xd0, 0xb9, 0xe4,
+ 0xac, 0xe4, 0xad, 0xe4, 0xa9, 0xe4, 0xaa, 0xec, 0xc5, 0xce, 0xaa, 0xb1, 0xfe,
+ 0xbe, 0xe6, 0xbe, 0xbc, 0xcc, 0xbf, 0xd5, 0xa8, 0xc5, 0xda, 0xa1, 0xf5, 0xeb,
+ 0xbc, 0xc9, 0xfc, 0xea, 0xf4, 0xb5, 0xd6, 0xe1, 0xf7, 0xba, 0xdd, 0xbd, 0xc6,
+ 0xe7, 0xe8, 0xc9, 0xba, 0xb2, 0xa3, 0xc1, 0xe1, 0xd5, 0xe4, 0xe7, 0xea, 0xe7,
+ 0xe9, 0xc9, 0xf5, 0xb1, 0xc2, 0xce, 0xb7, 0xbd, 0xe7, 0xee, 0xb0, 0xee, 0xb1,
+ 0xd2, 0xdf, 0xb0, 0xcc, 0xbd, 0xea, 0xa1, 0xf5, 0xf0, 0xe0, 0xb9, 0xef, 0xbd,
+ 0xd4, 0xbb, 0xca, 0xf0, 0xa7, 0xd3, 0xaf, 0xc5, 0xe8, 0xb1, 0xad, 0xd6, 0xd1,
+ 0xca, 0xa1, 0xed, 0xef, 0xcf, 0xe0, 0xc3, 0xbc, 0xbf, 0xb4, 0xb6, 0xdc, 0xc5,
+ 0xce, 0xed, 0xf0, 0xf1, 0xe6, 0xc9, 0xb0, 0xd1, 0xd0, 0xc6, 0xf6, 0xbf, 0xb3,
+ 0xec, 0xec, 0xec, 0xed, 0xc6, 0xed, 0xa1, 0xf5, 0xd3, 0xed, 0xd8, 0xae, 0xbf,
+ 0xc6, 0xc3, 0xeb, 0xc7, 0xef, 0xb4, 0xa9, 0xcd, 0xbb, 0xb8, 0xcd, 0xf3, 0xc4,
+ 0xd7, 0xd1, 0xe6, 0xfb, 0xba, 0xec, 0xbc, 0xcd, 0xc8, 0xd2, 0xe6, 0xfc, 0xd4,
+ 0xbc, 0xe6, 0xfa, 0xb8, 0xd7, 0xc3, 0xc0, 0xf4, 0xe0, 0xeb, 0xa3, 0xc4, 0xcd,
+ 0xcb, 0xa3, 0xd7, 0xa8, 0xd2, 0xae, 0xc5, 0xd6, 0xf1, 0xe3, 0xc5, 0xdf, 0xce,
+ 0xb8, 0xeb, 0xd0, 0xb1, 0xb3, 0xba, 0xfa, 0xeb, 0xce, 0xcc, 0xa5, 0xb0, 0xfb,
+ 0xd8, 0xb7, 0xeb, 0xd5, 0xd6, 0xc2, 0xf4, 0xae, 0xdc, 0xd1, 0xb7, 0xb6, 0xc3,
+ 0xa9, 0xdc, 0xc4, 0xbf, 0xc1, 0xbf, 0xe0, 0xc7, 0xd1, 0xc8, 0xf4, 0xc3, 0xaf,
+ 0xdc, 0xd4, 0xdc, 0xdb, 0xc3, 0xe7, 0xd3, 0xa2, 0xd7, 0xc2, 0xdc, 0xd9, 0xcc,
+ 0xa6, 0xd4, 0xb7, 0xb0, 0xfa, 0xdc, 0xdf, 0xb9, 0xb6, 0xb1, 0xbd, 0xdc, 0xe2,
+ 0xc5, 0xb0, 0xba, 0xe7, 0xf2, 0xb5, 0xf2, 0xb3, 0xd1, 0xdc, 0xc9, 0xc0, 0xd2,
+ 0xaa, 0xbd, 0xee, 0xbc, 0xc6, 0xb6, 0xa9, 0xb8, 0xbc, 0xd5, 0xea, 0xb8, 0xba,
+ 0xb8, 0xb0, 0xf4, 0xf1, 0xc5, 0xbf, 0xbe, 0xfc, 0xb9, 0xec, 0xca, 0xf6, 0xe5,
+ 0xc8, 0xcc, 0xf6, 0xb5, 0xcf, 0xe5, 0xc4, 0xb5, 0xfc, 0xc6, 0xc8, 0xe5, 0xc6,
+ 0xe5, 0xca, 0xbd, 0xbc, 0xc0, 0xc9, 0xd3, 0xf4, 0xa1, 0xf5, 0xc7, 0xf5, 0xf4,
+ 0xfa, 0xd6, 0xd8, 0xe3, 0xc5, 0xcf, 0xde, 0xc2, 0xaa, 0xc4, 0xb0, 0xbd, 0xb5,
+ 0xc3, 0xe6, 0xb8, 0xef, 0xce, 0xa4, 0xbe, 0xc2, 0xd2, 0xf4, 0xd2, 0xb3, 0xb7,
+ 0xe7, 0xb7, 0xc9, 0xca, 0xb3, 0xca, 0xd7, 0xcf, 0xe3, 0xb3, 0xcb, 0xd9, 0xf1,
+ 0xd9, 0xc4, 0xb1, 0xb6, 0xb7, 0xc2, 0xb8, 0xa9, 0xbe, 0xeb, 0xd9, 0xc5, 0xd9,
+ 0xba, 0xd9, 0xbb, 0xd0, 0xd2, 0xc1, 0xa9, 0xd6, 0xb5, 0xbd, 0xe8, 0xd2, 0xd0,
+ 0xb5, 0xb9, 0xc3, 0xc7, 0xb0, 0xb3, 0xd8, 0xf6, 0xbe, 0xf3, 0xd9, 0xc6, 0xbe,
+ 0xe3, 0xb3, 0xab, 0xb8, 0xf6, 0xba, 0xf2, 0xcc, 0xc8, 0xd9, 0xbd, 0xd0, 0xde,
+ 0xd9, 0xc1, 0xc4, 0xdf, 0xd9, 0xc2, 0xc2, 0xd7, 0xb2, 0xd6, 0xbc, 0xe6, 0xd4,
+ 0xa9, 0xda, 0xa4, 0xda, 0xa3, 0xb6, 0xb3, 0xc1, 0xe8, 0xd7, 0xbc, 0xb5, 0xf2,
+ 0xc6, 0xca, 0xd8, 0xe0, 0xcc, 0xde, 0xb8, 0xd5, 0xb0, 0xfe, 0xb7, 0xcb, 0xc7,
+ 0xe4, 0xd4, 0xad, 0xd8, 0xc8, 0xdb, 0xc5, 0xc9, 0xda, 0xcc, 0xc6, 0xd1, 0xe4,
+ 0xe0, 0xa1, 0xba, 0xdf, 0xb8, 0xe7, 0xd5, 0xdc, 0xcb, 0xf4, 0xb2, 0xb8, 0xdf,
+ 0xed, 0xc1, 0xa8, 0xbf, 0xde, 0xd4, 0xb1, 0xb0, 0xa6, 0xcf, 0xf8, 0xc4, 0xc4,
+ 0xc5, 0xb6, 0xdf, 0xf3, 0xb4, 0xbd, 0xdf, 0xec, 0xdf, 0xf1, 0xc6, 0xd4, 0xe0,
+ 0xf4, 0xb9, 0xa1, 0xc6, 0xd2, 0xc2, 0xf1, 0xb0, 0xa3, 0xa1, 0xf5, 0xcf, 0xc4,
+ 0xcc, 0xd7, 0xde, 0xca, 0xde, 0xc9, 0xe6, 0xb6, 0xc4, 0xef, 0xc4, 0xc8, 0xbe,
+ 0xea, 0xd3, 0xe9, 0xe6, 0xb8, 0xbc, 0xa7, 0xc9, 0xef, 0xe6, 0xb7, 0xc3, 0xe4,
+ 0xb6, 0xf0, 0xe6, 0xb2, 0xe6, 0xb3, 0xcb, 0xef, 0xa1, 0xf5, 0xd4, 0xd7, 0xba,
+ 0xa6, 0xbc, 0xd2, 0xd1, 0xe7, 0xb9, 0xac, 0xcf, 0xfc, 0xc8, 0xdd, 0xe5, 0xb7,
+ 0xc9, 0xe4, 0xd0, 0xbc, 0xd5, 0xb9, 0xe5, 0xec, 0xc7, 0xcd, 0xcf, 0xbf, 0xbe,
+ 0xfe, 0xd3, 0xf8, 0xb6, 0xeb, 0xb7, 0xe5, 0xb5, 0xba, 0xa1, 0xf5, 0xe1, 0xad,
+ 0xb2, 0xee, 0xcf, 0xaf, 0xca, 0xa6, 0xbf, 0xe2, 0xcd, 0xa5, 0xd7, 0xf9, 0xc8,
+ 0xf5, 0xcd, 0xbd, 0xbe, 0xb6, 0xd0, 0xec, 0xed, 0xa6, 0xed, 0xa7, 0xb3, 0xdc,
+ 0xbf, 0xd6, 0xcb, 0xa1, 0xb9, 0xa7, 0xb6, 0xf7, 0xcf, 0xa2, 0xc7, 0xc4, 0xce,
+ 0xf2, 0xe3, 0xa4, 0xba, 0xb7, 0xbb, 0xda, 0xe3, 0xa9, 0xd4, 0xc3, 0xe3, 0xa3,
+ 0xc9, 0xc8, 0xc8, 0xad, 0xea, 0xfc, 0xc4, 0xc3, 0xc9, 0xd3, 0xd0, 0xae, 0xd5,
+ 0xf1, 0xb2, 0xb6, 0xce, 0xe6, 0xc0, 0xa6, 0xc4, 0xf3, 0xd7, 0xbd, 0xcd, 0xa6,
+ 0xbe, 0xe8, 0xcd, 0xec, 0xc5, 0xb2, 0xb4, 0xec, 0xb0, 0xa4, 0xba, 0xb4, 0xb0,
+ 0xc6, 0xd0, 0xa7, 0xf4, 0xcd, 0xc1, 0xcf, 0xc5, 0xd4, 0xc2, 0xc3, 0xca, 0xb1,
+ 0xbd, 0xfa, 0xea, 0xcc, 0xbb, 0xce, 0xc9, 0xb9, 0xc9, 0xce, 0xa1, 0xf5, 0xea,
+ 0xcb, 0xca, 0xe9, 0xcb, 0xb7, 0xeb, 0xde, 0xc0, 0xca, 0xd0, 0xa3, 0xba, 0xcb,
+ 0xb0, 0xb8, 0xbf, 0xf2, 0xbb, 0xb8, 0xb8, 0xf9, 0xb9, 0xf0, 0xbd, 0xdb, 0xe8,
+ 0xf2, 0xca, 0xe1, 0xc0, 0xf5, 0xd7, 0xc0, 0xc9, 0xa3, 0xd4, 0xd4, 0xb2, 0xf1,
+ 0xcd, 0xa9, 0xe8, 0xee, 0xb8, 0xf1, 0xcc, 0xd2, 0xd6, 0xea, 0xce, 0xa6, 0xcb,
+ 0xa8, 0xa1, 0xf5, 0xe8, 0xec, 0xca, 0xe2, 0xd1, 0xb3, 0xd2, 0xf3, 0xc6, 0xf8,
+ 0xd1, 0xf5, 0xb0, 0xb1, 0xba, 0xa4, 0xeb, 0xb3, 0xcc, 0xa9, 0xc0, 0xcb, 0xcc,
+ 0xe9, 0xcf, 0xfb, 0xe3, 0xfe, 0xc6, 0xd6, 0xbd, 0xfe, 0xba, 0xa3, 0xd5, 0xe3,
+ 0xe4, 0xb8, 0xc0, 0xef, 0xc9, 0xe6, 0xb8, 0xa1, 0xbf, 0xa3, 0xd4, 0xa1, 0xba,
+ 0xc6, 0xd3, 0xbf, 0xa1, 0xf5, 0xe4, 0xa4, 0xc4, 0xf9, 0xa1, 0xf5, 0xe4, 0xb9,
+ 0xec, 0xc8, 0xba, 0xe6, 0xbf, 0xbe, 0xc0, 0xd3, 0xc1, 0xd2, 0xce, 0xda, 0xb5,
+ 0xf9, 0xcc, 0xd8, 0xc0, 0xc7, 0xcf, 0xc1, 0xb1, 0xb7, 0xc0, 0xea, 0xe1, 0xfa,
+ 0xd7, 0xc8, 0xb0, 0xe0, 0xc1, 0xf0, 0xc5, 0xe5, 0xd6, 0xe9, 0xb9, 0xe7, 0xe7,
+ 0xf3, 0xc5, 0xcf, 0xc4, 0xb6, 0xd0, 0xf3, 0xdb, 0xce, 0xc1, 0xf4, 0xbc, 0xb2,
+ 0xb2, 0xa1, 0xd6, 0xa2, 0xc6, 0xa3, 0xf0, 0xe1, 0xbe, 0xd2, 0xcc, 0xdb, 0xd5,
+ 0xee, 0xf0, 0xe8, 0xf0, 0xe3, 0xb8, 0xde, 0xf0, 0xe5, 0xd2, 0xe6, 0xee, 0xc1,
+ 0xb0, 0xbb, 0xd1, 0xa3, 0xd5, 0xe6, 0xc3, 0xdf, 0xd5, 0xa3, 0xbe, 0xd8, 0xc5,
+ 0xe9, 0xd5, 0xe8, 0xd4, 0xd2, 0xed, 0xc0, 0xc6, 0xc6, 0xc9, 0xe9, 0xed, 0xc6,
+ 0xed, 0xbe, 0xa1, 0xf5, 0xed, 0xc4, 0xc5, 0xda, 0xc3, 0xd8, 0xd3, 0xd3, 0xec,
+ 0xf4, 0xcb, 0xee, 0xd7, 0xe6, 0xc9, 0xf1, 0xd7, 0xa3, 0xec, 0xf3, 0xec, 0xf1,
+ 0xb3, 0xd3, 0xef, 0xf7, 0xd1, 0xed, 0xd7, 0xe2, 0xc7, 0xd8, 0xd6, 0xc8, 0xc3,
+ 0xd8, 0xd5, 0xad, 0xf1, 0xba, 0xd5, 0xbe, 0xb0, 0xca, 0xd0, 0xa6, 0xb7, 0xdb,
+ 0xb7, 0xc4, 0xc9, 0xb4, 0xce, 0xc6, 0xce, 0xc9, 0xcb, 0xd8, 0xcb, 0xf7, 0xb4,
+ 0xbf, 0xc5, 0xa6, 0xe7, 0xa2, 0xbc, 0xb6, 0xe7, 0xa1, 0xc4, 0xc9, 0xd6, 0xbd,
+ 0xb7, 0xd7, 0xc8, 0xb1, 0xee, 0xb9, 0xb8, 0xe1, 0xb3, 0xe1, 0xce, 0xcc, 0xea,
+ 0xc8, 0xd4, 0xc5, 0xb8, 0xfb, 0xb0, 0xd2, 0xba, 0xc4, 0xb5, 0xa2, 0xb9, 0xa2,
+ 0xeb, 0xd7, 0xd6, 0xac, 0xd2, 0xc8, 0xd0, 0xb2, 0xeb, 0xd9, 0xeb, 0xd8, 0xb4,
+ 0xe0, 0xd0, 0xd8, 0xb8, 0xec, 0xc2, 0xf6, 0xc4, 0xdc, 0xbc, 0xb9, 0xeb, 0xdd,
+ 0xbf, 0xe8, 0xb3, 0xf4, 0xf4, 0xab, 0xd2, 0xa8, 0xf3, 0xc2, 0xba, 0xbd, 0xf4,
+ 0xb3, 0xf4, 0xb2, 0xb0, 0xe3, 0xdb, 0xbb, 0xc3, 0xa3, 0xbb, 0xc4, 0xc0, 0xf3,
+ 0xbe, 0xa3, 0xc8, 0xd7, 0xbc, 0xf6, 0xb2, 0xdd, 0xd2, 0xf0, 0xdc, 0xee, 0xdc,
+ 0xf3, 0xd7, 0xc8, 0xc8, 0xe3, 0xb2, 0xe8, 0xdc, 0xf8, 0xdc, 0xf7, 0xdc, 0xef,
+ 0xb4, 0xc4, 0xdc, 0xf5, 0xf2, 0xaf, 0xce, 0xc3, 0xf2, 0xbd, 0xf2, 0xbe, 0xd4,
+ 0xe9, 0xf2, 0xbf, 0xb0, 0xf6, 0xf2, 0xbc, 0xd1, 0xc1, 0xcb, 0xa5, 0xd6, 0xd4,
+ 0xd4, 0xac, 0xf1, 0xc7, 0xf1, 0xc5, 0xd6, 0xbb, 0xbc, 0xc7, 0xda, 0xa6, 0xcc,
+ 0xd6, 0xda, 0xa7, 0xda, 0xa8, 0xd1, 0xb6, 0xcd, 0xd0, 0xd1, 0xb5, 0xc6, 0xfd,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xc6, 0xf1, 0xb2, 0xf2, 0xb1, 0xaa, 0xb2, 0xc6, 0xb9,
+ 0xb1, 0xc6, 0xf0, 0xb9, 0xaa, 0xd0, 0xf9, 0xe9, 0xed, 0xa1, 0xf5, 0xc8, 0xe8,
+ 0xcb, 0xcd, 0xc4, 0xe6, 0xc3, 0xd4, 0xcd, 0xcb, 0xc4, 0xcb, 0xbb, 0xd8, 0xcc,
+ 0xd3, 0xd7, 0xb7, 0xe5, 0xcb, 0xb1, 0xc5, 0xe7, 0xdf, 0xbf, 0xa4, 0xba, 0xc2,
+ 0xdb, 0xab, 0xbe, 0xc6, 0xc5, 0xe4, 0xd7, 0xc3, 0xb6, 0xa4, 0xd5, 0xeb, 0xee,
+ 0xc8, 0xb8, 0xaa, 0xee, 0xc7, 0xc9, 0xc1, 0xd4, 0xba, 0xd5, 0xf3, 0xb6, 0xb8,
+ 0xb1, 0xdd, 0xc9, 0xc2, 0xb3, 0xfd, 0xda, 0xea, 0xc9, 0xfd, 0xd6, 0xbb, 0xbc,
+ 0xa2, 0xc2, 0xed, 0xb9, 0xc7, 0xb8, 0xdf, 0xb6, 0xb7, 0xd8, 0xaa, 0xb9, 0xed,
+ 0xc7, 0xac, 0xa1, 0xf5, 0xce, 0xb1, 0xcd, 0xa3, 0xbc, 0xd9, 0xd9, 0xc8, 0xd9,
+ 0xbc, 0xd7, 0xf6, 0xce, 0xb0, 0xbd, 0xa1, 0xc5, 0xbc, 0xd9, 0xcb, 0xd9, 0xc9,
+ 0xd5, 0xec, 0xb2, 0xe0, 0xcd, 0xb5, 0xc6, 0xab, 0xd9, 0xbf, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xb6, 0xb5, 0xc3, 0xe1, 0xbb, 0xcb, 0xbc, 0xf4, 0xb8, 0xb1, 0xc0, 0xd5,
+ 0xce, 0xf1, 0xbf, 0xb1, 0xb6, 0xaf, 0xd9, 0xeb, 0xde, 0xcb, 0xb3, 0xd7, 0xc4,
+ 0xe4, 0xc7, 0xf8, 0xd8, 0xd2, 0xb2, 0xce, 0xc2, 0xfc, 0xc9, 0xcc, 0xc5, 0xbe,
+ 0xc0, 0xb2, 0xd7, 0xc4, 0xd1, 0xc6, 0xb7, 0xc8, 0xbf, 0xd0, 0xb0, 0xa1, 0xb3,
+ 0xaa, 0xe0, 0xa2, 0xce, 0xca, 0xdf, 0xfb, 0xce, 0xa8, 0xc6, 0xa1, 0xc4, 0xee,
+ 0xca, 0xdb, 0xe0, 0xa8, 0xbb, 0xa3, 0xcf, 0xce, 0xe0, 0xa6, 0xdf, 0xfa, 0xa1,
+ 0xf5, 0xc8, 0xa6, 0xb9, 0xfa, 0xe0, 0xf6, 0xd3, 0xf2, 0xbc, 0xe1, 0xdb, 0xd1,
+ 0xb6, 0xd1, 0xb2, 0xba, 0xdb, 0xfd, 0xbb, 0xf9, 0xcc, 0xc3, 0xb6, 0xc2, 0xd6,
+ 0xb4, 0xc5, 0xe0, 0xb9, 0xbb, 0xc9, 0xdd, 0xc8, 0xa2, 0xc2, 0xa6, 0xcd, 0xf1,
+ 0xb8, 0xbe, 0xc0, 0xb7, 0xe6, 0xb9, 0xe6, 0xbd, 0xe6, 0xbe, 0xbb, 0xe9, 0xc6,
+ 0xc5, 0xe6, 0xbb, 0xca, 0xeb, 0xbf, 0xdc, 0xd2, 0xfa, 0xbc, 0xc4, 0xbc, 0xc5,
+ 0xcb, 0xde, 0xc3, 0xdc, 0xce, 0xbe, 0xd7, 0xa8, 0xbd, 0xab, 0xcd, 0xc0, 0xcc,
+ 0xeb, 0xa1, 0xf5, 0xb3, 0xe7, 0xe1, 0xc7, 0xc6, 0xe9, 0xe1, 0xc8, 0xd1, 0xc2,
+ 0xe1, 0xbf, 0xc0, 0xa5, 0xb1, 0xc0, 0xb4, 0xde, 0xc2, 0xd8, 0xe1, 0xc5, 0xe1,
+ 0xc2, 0xb8, 0xda, 0xb3, 0xb2, 0xb3, 0xa3, 0xb4, 0xf8, 0xd5, 0xca, 0xe1, 0xa1,
+ 0xbf, 0xb5, 0xd3, 0xb9, 0xca, 0xfc, 0xe2, 0xd6, 0xe2, 0xd7, 0xd5, 0xc5, 0xc7,
+ 0xbf, 0xe5, 0xe7, 0xb1, 0xf2, 0xb2, 0xca, 0xb5, 0xf1, 0xb5, 0xc3, 0xe1, 0xe3,
+ 0xb4, 0xd3, 0xc5, 0xc7, 0xd3, 0xf9, 0xe1, 0xe2, 0xe1, 0xe4, 0xd3, 0xc1, 0xbb,
+ 0xbc, 0xcf, 0xa4, 0xd3, 0xc6, 0xc4, 0xfa, 0xcd, 0xef, 0xe3, 0xb2, 0xb5, 0xeb,
+ 0xc6, 0xe0, 0xc7, 0xe9, 0xe3, 0xac, 0xe2, 0xea, 0xcf, 0xa7, 0xb5, 0xbf, 0xe3,
+ 0xaf, 0xcc, 0xe8, 0xe3, 0xb0, 0xce, 0xa9, 0xbc, 0xc2, 0xe3, 0xb1, 0xb6, 0xd8,
+ 0xc6, 0xdd, 0xea, 0xa9, 0xec, 0xe8, 0xc2, 0xd3, 0xbf, 0xd8, 0xbe, 0xed, 0xd2,
+ 0xb4, 0xcc, 0xbd, 0xbd, 0xd3, 0xbd, 0xdd, 0xc5, 0xf5, 0xbe, 0xf2, 0xb4, 0xeb,
+ 0xde, 0xdf, 0xd1, 0xda, 0xb5, 0xf4, 0xc9, 0xa8, 0xb9, 0xd2, 0xde, 0xd1, 0xcd,
+ 0xc6, 0xc2, 0xd5, 0xca, 0xda, 0xd5, 0xf5, 0xb2, 0xc9, 0xde, 0xe4, 0xc5, 0xc5,
+ 0xcc, 0xcd, 0xcf, 0xc6, 0xc4, 0xed, 0xde, 0xe6, 0xc9, 0xe1, 0xde, 0xe0, 0xb1,
+ 0xd6, 0xb0, 0xbd, 0xbe, 0xc8, 0xbd, 0xcc, 0xb0, 0xdc, 0xc6, 0xf4, 0xc3, 0xf4,
+ 0xd0, 0xf0, 0xeb, 0xb7, 0xa1, 0xf5, 0xd0, 0xb1, 0xf5, 0xfa, 0xd5, 0xb6, 0xd7,
+ 0xe5, 0xd0, 0xfd, 0xec, 0xba, 0xec, 0xbb, 0xd6, 0xe7, 0xcd, 0xed, 0xce, 0xee,
+ 0xb3, 0xbf, 0xbb, 0xde, 0xa1, 0xf5, 0xb2, 0xdc, 0xa1, 0xf5, 0xcd, 0xfb, 0xc1,
+ 0xba, 0xcc, 0xdd, 0xc9, 0xd2, 0xe8, 0xf7, 0xe8, 0xf3, 0xb8, 0xcb, 0xcd, 0xb0,
+ 0xc0, 0xa6, 0xce, 0xe0, 0xb9, 0xa3, 0xd0, 0xb5, 0xe8, 0xe8, 0xc6, 0xfa, 0xcb,
+ 0xf3, 0xb0, 0xf0, 0xc3, 0xb7, 0xe8, 0xd9, 0xcc, 0xf5, 0xc0, 0xe6, 0xe8, 0xc9,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xd3, 0xfb, 0xc9, 0xb1, 0xba, 0xc1, 0xc7, 0xf2, 0xc7,
+ 0xe2, 0xcf, 0xd1, 0xc1, 0xb9, 0xb4, 0xbe, 0xe4, 0xc8, 0xd2, 0xba, 0xb5, 0xad,
+ 0xcc, 0xca, 0xd3, 0xd9, 0xcc, 0xed, 0xc7, 0xb3, 0xc7, 0xe5, 0xe4, 0xbf, 0xc1,
+ 0xdc, 0xd1, 0xc4, 0xca, 0xe7, 0xe4, 0xcc, 0xe4, 0xc1, 0xd1, 0xcd, 0xba, 0xd4,
+ 0xbb, 0xec, 0xd4, 0xa8, 0xe4, 0xc0, 0xc6, 0xe0, 0xe4, 0xbe, 0xba, 0xad, 0xc0,
+ 0xe1, 0xd2, 0xf9, 0xcc, 0xd4, 0xc2, 0xd9, 0xc9, 0xee, 0xbb, 0xb4, 0xbe, 0xbb,
+ 0xcf, 0xfd, 0xd7, 0xcd, 0xb8, 0xa2, 0xb4, 0xe3, 0xe4, 0xc3, 0xe4, 0xc6, 0xc5,
+ 0xeb, 0xd1, 0xc9, 0xba, 0xb8, 0xb7, 0xe9, 0xcf, 0xa9, 0xcb, 0xac, 0xc7, 0xa3,
+ 0xc0, 0xe7, 0xb2, 0xc2, 0xc3, 0xcd, 0xb2, 0xfe, 0xe2, 0xa3, 0xd5, 0xf8, 0xc2,
+ 0xca, 0xc0, 0xc5, 0xe7, 0xf0, 0xc7, 0xf2, 0xc0, 0xed, 0xcf, 0xd6, 0xa1, 0xf5,
+ 0xf0, 0xad, 0xc6, 0xbf, 0xb4, 0xc9, 0xcc, 0xf0, 0xb2, 0xfa, 0xc2, 0xd4, 0xc6,
+ 0xe8, 0xb1, 0xcf, 0xd2, 0xec, 0xca, 0xe8, 0xd6, 0xcc, 0xba, 0xdb, 0xb4, 0xc3,
+ 0xc8, 0xac, 0xf0, 0xea, 0xf0, 0xa8, 0xbf, 0xf8, 0xba, 0xd0, 0xca, 0xa2, 0xbe,
+ 0xec, 0xd6, 0xda, 0xd1, 0xdb, 0xbf, 0xf4, 0xed, 0xf8, 0xcc, 0xf7, 0xc1, 0xf2,
+ 0xd6, 0xec, 0xed, 0xca, 0xcf, 0xe9, 0xc6, 0xb1, 0xbc, 0xc0, 0xd2, 0xc6, 0xd6,
+ 0xcf, 0xf1, 0xbb, 0xf3, 0xd2, 0xb1, 0xbf, 0xb5, 0xd1, 0xb5, 0xda, 0xb7, 0xfb,
+ 0xf3, 0xcf, 0xf3, 0xd7, 0xf3, 0xd0, 0xc1, 0xa3, 0xb4, 0xd6, 0xc6, 0xc9, 0xb0,
+ 0xed, 0xcf, 0xd2, 0xcd, 0xb3, 0xd4, 0xfa, 0xc9, 0xdc, 0xe7, 0xa8, 0xe7, 0xa9,
+ 0xcf, 0xb8, 0xc9, 0xf0, 0xd7, 0xe9, 0xc0, 0xdb, 0xd6, 0xd5, 0xe7, 0xa5, 0xe7,
+ 0xa6, 0xb2, 0xa7, 0xd0, 0xdf, 0xc1, 0xe7, 0xd2, 0xee, 0xf4, 0xe1, 0xcf, 0xb0,
+ 0xf1, 0xea, 0xc1, 0xc4, 0xf1, 0xf6, 0xb8, 0xac, 0xb2, 0xb1, 0xb4, 0xbd, 0xcd,
+ 0xd1, 0xd0, 0xde, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xa9, 0xb6, 0xe6, 0xcf, 0xcf,
+ 0xb2, 0xb0, 0xb4, 0xac, 0xc9, 0xaf, 0xdd, 0xb8, 0xdd, 0xb7, 0xdd, 0xa9, 0xbc,
+ 0xd4, 0xbe, 0xa5, 0xc3, 0xa7, 0xc4, 0xaa, 0xdc, 0xec, 0xd7, 0xaf, 0xdd, 0xae,
+ 0xc0, 0xf2, 0xdd, 0xac, 0xba, 0xc9, 0xdd, 0xb6, 0xdd, 0xb1, 0xc6, 0xce, 0xdc,
+ 0xc8, 0xb4, 0xa6, 0xb1, 0xeb, 0xc9, 0xdf, 0xd6, 0xfb, 0xf2, 0xc0, 0xf2, 0xc1,
+ 0xf2, 0xc2, 0xc7, 0xf9, 0xb5, 0xb0, 0xf2, 0xc6, 0xf2, 0xc7, 0xf2, 0xc8, 0xca,
+ 0xf5, 0xd9, 0xf2, 0xf4, 0xc2, 0xb1, 0xbb, 0xcc, 0xbb, 0xd0, 0xe4, 0xc5, 0xdb,
+ 0xb4, 0xfc, 0xc3, 0xd9, 0xb9, 0xe6, 0xb7, 0xc3, 0xd1, 0xc8, 0xbe, 0xf7, 0xda,
+ 0xab, 0xd0, 0xed, 0xc9, 0xe8, 0xcb, 0xcf, 0xb6, 0xef, 0xd0, 0xc0, 0xf4, 0xf9,
+ 0xeb, 0xe0, 0xb7, 0xb7, 0xd4, 0xf0, 0xb9, 0xe1, 0xbb, 0xf5, 0xcc, 0xb0, 0xc6,
+ 0xb6, 0xf4, 0xf6, 0xc9, 0xe2, 0xd6, 0xba, 0xf5, 0xc3, 0xe9, 0xee, 0xc8, 0xed,
+ 0xd5, 0xe2, 0xe5, 0xd0, 0xcd, 0xa8, 0xb6, 0xba, 0xc1, 0xac, 0xcb, 0xd9, 0xca,
+ 0xc5, 0xd6, 0xf0, 0xe5, 0xc9, 0xb3, 0xd1, 0xd4, 0xec, 0xcd, 0xb8, 0xb7, 0xea,
+ 0xe5, 0xd1, 0xb9, 0xe4, 0xcd, 0xbe, 0xb2, 0xbf, 0xb9, 0xf9, 0xb6, 0xbc, 0xd0,
+ 0xef, 0xd2, 0xb0, 0xee, 0xce, 0xbf, 0xdb, 0xb5, 0xf6, 0xee, 0xcb, 0xa1, 0xf5,
+ 0xb7, 0xb0, 0xb1, 0xd5, 0xc5, 0xe3, 0xc1, 0xea, 0xb3, 0xc2, 0xc2, 0xbd, 0xd2,
+ 0xf5, 0xda, 0xf0, 0xcc, 0xd5, 0xcf, 0xdd, 0xda, 0xee, 0xc8, 0xb8, 0xd1, 0xa9,
+ 0xf6, 0xa7, 0xd5, 0xc2, 0xbe, 0xb9, 0xb6, 0xa5, 0xc7, 0xea, 0xd3, 0xe3, 0xc4,
+ 0xf1, 0xc2, 0xb1, 0xc2, 0xb9, 0xc2, 0xf3, 0xc2, 0xe9, 0xbc, 0xd2, 0xb0, 0xf8,
+ 0xb8, 0xb5, 0xb1, 0xb8, 0xbd, 0xdc, 0xbf, 0xfe, 0xd8, 0xf7, 0xc9, 0xa1, 0xd0,
+ 0xa7, 0xd7, 0xee, 0xbf, 0xad, 0xb8, 0xee, 0xd8, 0xdc, 0xb4, 0xb4, 0xca, 0xa3,
+ 0xc0, 0xcd, 0xca, 0xa4, 0xd1, 0xab, 0xb2, 0xa9, 0xd8, 0xca, 0xe0, 0xb4, 0xbf,
+ 0xa6, 0xd0, 0xfa, 0xcc, 0xe4, 0xba, 0xb0, 0xba, 0xc8, 0xb4, 0xad, 0xce, 0xb9,
+ 0xcf, 0xb2, 0xc9, 0xa5, 0xe0, 0xb8, 0xc0, 0xae, 0xe0, 0xa9, 0xe0, 0xab, 0xd4,
+ 0xfb, 0xb5, 0xa5, 0xe0, 0xb0, 0xcd, 0xd9, 0xd3, 0xb4, 0xbb, 0xbd, 0xd3, 0xf7,
+ 0xc7, 0xc7, 0xe0, 0xac, 0xe0, 0xb1, 0xba, 0xed, 0xa1, 0xf5, 0xe0, 0xb9, 0xce,
+ 0xa7, 0xd2, 0xa2, 0xbf, 0xb0, 0xb3, 0xa1, 0xb5, 0xcc, 0xd1, 0xdf, 0xb1, 0xa8,
+ 0xb1, 0xa4, 0xdb, 0xf6, 0xdc, 0xa9, 0xd2, 0xbc, 0xba, 0xf8, 0xb5, 0xec, 0xe6,
+ 0xc3, 0xc3, 0xc4, 0xd0, 0xf6, 0xc3, 0xbd, 0xe6, 0xc2, 0xe6, 0xb4, 0xe6, 0xdc,
+ 0xe5, 0xee, 0xba, 0xae, 0xb8, 0xbb, 0xd4, 0xa2, 0xc3, 0xc2, 0xd7, 0xf0, 0xd1,
+ 0xb0, 0xbe, 0xcd, 0xc7, 0xb6, 0xe1, 0xb0, 0xe1, 0xcb, 0xef, 0xfa, 0xd9, 0xe3,
+ 0xb7, 0xf9, 0xc3, 0xb1, 0xd6, 0xa1, 0xe0, 0xf8, 0xbc, 0xb8, 0xc0, 0xc8, 0xb2,
+ 0xde, 0xcf, 0xe1, 0xbe, 0xc7, 0xe5, 0xf6, 0xc5, 0xed, 0xb8, 0xb4, 0xd1, 0xad,
+ 0xe1, 0xe5, 0xbb, 0xf3, 0xb6, 0xf1, 0xb1, 0xaf, 0xc3, 0xc6, 0xbb, 0xdd, 0xe3,
+ 0xab, 0xe3, 0xb6, 0xd0, 0xca, 0xe3, 0xb5, 0xb6, 0xe8, 0xe2, 0xfc, 0xe3, 0xb7,
+ 0xbf, 0xae, 0xc4, 0xd5, 0xe3, 0xb9, 0xbb, 0xcc, 0xd3, 0xe4, 0xe3, 0xb8, 0xa1,
+ 0xf5, 0xea, 0xaa, 0xec, 0xe9, 0xb3, 0xb8, 0xd5, 0xc6, 0xc3, 0xe8, 0xbc, 0xf0,
+ 0xbf, 0xab, 0xc8, 0xe0, 0xde, 0xf1, 0xd7, 0xe1, 0xb2, 0xe5, 0xb4, 0xa7, 0xcc,
+ 0xe1, 0xce, 0xd5, 0xd2, 0xbe, 0xbd, 0xd2, 0xbb, 0xd3, 0xb4, 0xb7, 0xd4, 0xae,
+ 0xbe, 0xbe, 0xbb, 0xbb, 0xde, 0xf0, 0xd1, 0xef, 0xb1, 0xb3, 0xb3, 0xa8, 0xb6,
+ 0xd8, 0xb8, 0xd2, 0xc9, 0xa2, 0xb0, 0xdf, 0xec, 0xb3, 0xcb, 0xb9, 0xc6, 0xd5,
+ 0xce, 0xfa, 0xc7, 0xe7, 0xbe, 0xa7, 0xbe, 0xb0, 0xca, 0xee, 0xd6, 0xc7, 0xc1,
+ 0xc0, 0xea, 0xd0, 0xd4, 0xf8, 0xcc, 0xe6, 0xc6, 0xda, 0xb3, 0xaf, 0xb9, 0xd7,
+ 0xd7, 0xd8, 0xcc, 0xc4, 0xbc, 0xac, 0xd4, 0xe6, 0xd2, 0xce, 0xb6, 0xb0, 0xbf,
+ 0xc3, 0xc9, 0xad, 0xd5, 0xbb, 0xe8, 0xfe, 0xb0, 0xf4, 0xc6, 0xdc, 0xe9, 0xa6,
+ 0xc6, 0xe5, 0xb9, 0xf7, 0xd6, 0xb2, 0xbd, 0xb7, 0xd7, 0xb5, 0xc3, 0xde, 0xc5,
+ 0xef, 0xe8, 0xfa, 0xa1, 0xf5, 0xbf, 0xee, 0xc6, 0xdb, 0xc7, 0xd5, 0xb2, 0xd0,
+ 0xd6, 0xb3, 0xbf, 0xc7, 0xcc, 0xba, 0xb5, 0xaa, 0xc2, 0xc8, 0xeb, 0xb2, 0xb8,
+ 0xdb, 0xd3, 0xce, 0xe4, 0xd5, 0xb6, 0xc9, 0xe4, 0xd6, 0xd3, 0xbf, 0xb4, 0xd5,
+ 0xc7, 0xfe, 0xe4, 0xd7, 0xd4, 0xfc, 0xbc, 0xf5, 0xd5, 0xbf, 0xcf, 0xe6, 0xb2,
+ 0xb3, 0xba, 0xfe, 0xe4, 0xce, 0xce, 0xbc, 0xce, 0xd0, 0xcc, 0xc0, 0xbf, 0xca,
+ 0xcd, 0xc4, 0xc3, 0xec, 0xb2, 0xe2, 0xc5, 0xc8, 0xd3, 0xe5, 0xbb, 0xeb, 0xd7,
+ 0xcc, 0xb8, 0xc8, 0xbb, 0xc1, 0xe4, 0xcf, 0xe3, 0xfd, 0xe4, 0xd8, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe4, 0xd2, 0xb1, 0xba, 0xb7, 0xd9, 0xbd, 0xb9, 0xd1, 0xe6, 0xce,
+ 0xde, 0xc8, 0xbb, 0xd6, 0xf3, 0xa1, 0xf5, 0xc5, 0xc6, 0xea, 0xf7, 0xcf, 0xac,
+ 0xd3, 0xcc, 0xe2, 0xab, 0xba, 0xef, 0xd0, 0xc9, 0xb7, 0xa9, 0xe7, 0xf7, 0xc1,
+ 0xd5, 0xd7, 0xc1, 0xe7, 0xfa, 0xc5, 0xfd, 0xc5, 0xc3, 0xc7, 0xd9, 0xa1, 0xf5,
+ 0xe8, 0xa1, 0xe7, 0xf9, 0xe7, 0xfb, 0xc9, 0xfb, 0xcb, 0xd5, 0xbb, 0xad, 0xb7,
+ 0xac, 0xc1, 0xa1, 0xcd, 0xb4, 0xf0, 0xeb, 0xbe, 0xb7, 0xb6, 0xbb, 0xc6, 0xa6,
+ 0xa1, 0xf5, 0xb5, 0xc7, 0xb7, 0xa2, 0xcd, 0xee, 0xf0, 0xa9, 0xf1, 0xe5, 0xb5,
+ 0xc1, 0xc0, 0xa7, 0xb6, 0xcc, 0xcf, 0xf5, 0xd3, 0xb2, 0xd1, 0xe2, 0xc9, 0xd4,
+ 0xb8, 0xd1, 0xb3, 0xcc, 0xcb, 0xb0, 0xcf, 0xa1, 0xbe, 0xbd, 0xb4, 0xb0, 0xbd,
+ 0xd1, 0xcd, 0xaf, 0xbf, 0xa2, 0xb5, 0xc8, 0xb2, 0xdf, 0xb1, 0xca, 0xbf, 0xf0,
+ 0xcd, 0xb2, 0xb4, 0xf0, 0xcb, 0xf1, 0xbd, 0xee, 0xb7, 0xa4, 0xd6, 0xfe, 0xcb,
+ 0xda, 0xd6, 0xe0, 0xbd, 0xca, 0xbd, 0xe1, 0xc8, 0xde, 0xbe, 0xf8, 0xd7, 0xcf,
+ 0xd0, 0xf5, 0xcb, 0xbf, 0xc2, 0xe7, 0xb8, 0xf8, 0xd1, 0xa4, 0xa1, 0xf5, 0xe7,
+ 0xad, 0xc9, 0xc6, 0xcf, 0xe8, 0xf4, 0xe2, 0xf1, 0xf3, 0xf1, 0xf8, 0xcb, 0xe0,
+ 0xcd, 0xf3, 0xc7, 0xbb, 0xd2, 0xb8, 0xb8, 0xad, 0xc9, 0xf6, 0xd5, 0xcd, 0xcc,
+ 0xf3, 0xc6, 0xa2, 0xeb, 0xe7, 0xeb, 0xe8, 0xeb, 0xe9, 0xca, 0xe6, 0xcb, 0xb4,
+ 0xc6, 0xd0, 0xdd, 0xcd, 0xdd, 0xce, 0xc6, 0xbc, 0xb2, 0xa4, 0xdd, 0xd1, 0xdd,
+ 0xc2, 0xdd, 0xbc, 0xbb, 0xaa, 0xc1, 0xe2, 0xa1, 0xf5, 0xd6, 0xf8, 0xc0, 0xb3,
+ 0xdd, 0xd4, 0xc3, 0xc8, 0xbe, 0xfa, 0xdd, 0xc4, 0xb7, 0xc6, 0xbe, 0xd5, 0xdd,
+ 0xc7, 0xce, 0xae, 0xcc, 0xd1, 0xb2, 0xcb, 0xdc, 0xc9, 0xdd, 0xca, 0xdd, 0xcb,
+ 0xd0, 0xe9, 0xf2, 0xd4, 0xcd, 0xdc, 0xf2, 0xce, 0xbb, 0xd7, 0xd6, 0xeb, 0xb8,
+ 0xf2, 0xf2, 0xd0, 0xf2, 0xd2, 0xbd, 0xd6, 0xb2, 0xc3, 0xc1, 0xd1, 0xb8, 0xa4,
+ 0xf1, 0xfb, 0xca, 0xd3, 0xd7, 0xa2, 0xd3, 0xbd, 0xc6, 0xc0, 0xb4, 0xca, 0xd6,
+ 0xa4, 0xda, 0xac, 0xda, 0xb0, 0xd7, 0xe7, 0xd5, 0xa9, 0xda, 0xae, 0xcb, 0xdf,
+ 0xd5, 0xef, 0xda, 0xad, 0xa1, 0xf5, 0xcf, 0xf3, 0xf5, 0xf5, 0xd6, 0xfc, 0xcc,
+ 0xf9, 0xb7, 0xa1, 0xea, 0xdd, 0xea, 0xda, 0xb7, 0xd1, 0xba, 0xd8, 0xb9, 0xf3,
+ 0xc2, 0xf2, 0xb1, 0xe1, 0xc3, 0xb3, 0xb4, 0xfb, 0xd4, 0xbd, 0xb3, 0xac, 0xb3,
+ 0xc3, 0xf5, 0xc9, 0xbe, 0xe0, 0xb0, 0xcf, 0xf5, 0xc7, 0xc5, 0xdc, 0xb5, 0xf8,
+ 0xf5, 0xcb, 0xf5, 0xcc, 0xe9, 0xf0, 0xd6, 0xe1, 0xe9, 0xf3, 0xb9, 0xbc, 0xb4,
+ 0xfe, 0xe5, 0xd3, 0xd6, 0xdc, 0xd2, 0xdd, 0xbd, 0xf8, 0xe5, 0xd4, 0xb6, 0xf5,
+ 0xd3, 0xca, 0xcf, 0xe7, 0xdb, 0xb1, 0xba, 0xa8, 0xcb, 0xd6, 0xc1, 0xbf, 0xb3,
+ 0xae, 0xc5, 0xa5, 0xb8, 0xc6, 0xc4, 0xc6, 0xbe, 0xfb, 0xb6, 0xdb, 0xee, 0xd4,
+ 0xa1, 0xf5, 0xee, 0xd3, 0xe3, 0xc9, 0xc8, 0xf2, 0xbf, 0xaa, 0xcf, 0xd0, 0xbc,
+ 0xe4, 0xcf, 0xd0, 0xe3, 0xc8, 0xb6, 0xd3, 0xbd, 0xd7, 0xcb, 0xe5, 0xd1, 0xf4,
+ 0xd3, 0xe7, 0xc2, 0xa1, 0xda, 0xf2, 0xda, 0xef, 0xb5, 0xcc, 0xd1, 0xe3, 0xd1,
+ 0xc5, 0xd0, 0xdb, 0xbc, 0xaf, 0xb9, 0xcd, 0xf6, 0xa9, 0xd4, 0xc6, 0xc8, 0xcd,
+ 0xcf, 0xee, 0xcb, 0xb3, 0xd0, 0xeb, 0xe2, 0xb8, 0xe2, 0xbf, 0xb7, 0xb9, 0xe2,
+ 0xbd, 0xd2, 0xfb, 0xe2, 0xc1, 0xb7, 0xeb, 0xd4, 0xa6, 0xbb, 0xc6, 0xca, 0xf2,
+ 0xba, 0xda, 0xc2, 0xd2, 0xd3, 0xb6, 0xd5, 0xae, 0xb0, 0xc1, 0xb4, 0xab, 0xbd,
+ 0xf6, 0xc7, 0xe3, 0xb4, 0xdf, 0xc9, 0xcb, 0xc9, 0xb5, 0xd9, 0xcc, 0xa1, 0xf5,
+ 0xbd, 0xcb, 0xb2, 0xf9, 0xd8, 0xe2, 0xc4, 0xbc, 0xbd, 0xcb, 0xc7, 0xda, 0xca,
+ 0xc6, 0xbc, 0xa8, 0xbb, 0xe3, 0xe0, 0xb5, 0xe0, 0xcb, 0xc9, 0xa4, 0xe0, 0xc2,
+ 0xc2, 0xf0, 0xca, 0xc8, 0xd8, 0xc4, 0xe0, 0xbe, 0xcb, 0xc3, 0xe0, 0xcd, 0xe0,
+ 0xc5, 0xce, 0xd8, 0xce, 0xcb, 0xd0, 0xe1, 0xc7, 0xba, 0xe0, 0xc6, 0xe0, 0xbc,
+ 0xd4, 0xb0, 0xd4, 0xb2, 0xc8, 0xfb, 0xcb, 0xdc, 0xcc, 0xc1, 0xcd, 0xbf, 0xda,
+ 0xa3, 0xcb, 0xfe, 0xcc, 0xee, 0xcb, 0xfa, 0xce, 0xc1, 0xbf, 0xe9, 0xce, 0xeb,
+ 0xdb, 0xf5, 0xdc, 0xe3, 0xb0, 0xc2, 0xbc, 0xde, 0xbc, 0xb5, 0xcf, 0xd3, 0xe6,
+ 0xc5, 0xc2, 0xe8, 0xe6, 0xc1, 0xcf, 0xb1, 0xc9, 0xa9, 0xe6, 0xc7, 0xe1, 0xd4,
+ 0xe1, 0xcf, 0xbb, 0xcf, 0xb8, 0xc9, 0xc1, 0xae, 0xcf, 0xc3, 0xdf, 0xb1, 0xbb,
+ 0xe3, 0xc5, 0xd4, 0xce, 0xa2, 0xd3, 0xde, 0xd2, 0xe2, 0xb4, 0xc8, 0xb8, 0xd0,
+ 0xcf, 0xeb, 0xb0, 0xae, 0xc8, 0xc7, 0xb3, 0xee, 0xd3, 0xfa, 0xc9, 0xf7, 0xbb,
+ 0xc5, 0xc0, 0xf5, 0xe3, 0xb3, 0xe2, 0xe9, 0xe2, 0xeb, 0xc0, 0xa2, 0xed, 0xaa,
+ 0xed, 0xa9, 0xe2, 0xfd, 0xea, 0xac, 0xea, 0xab, 0xb4, 0xea, 0xd5, 0xa5, 0xb8,
+ 0xe3, 0xcc, 0xc2, 0xb4, 0xee, 0xb2, 0xeb, 0xb0, 0xe1, 0xb2, 0xab, 0xcb, 0xd1,
+ 0xc9, 0xa6, 0xcb, 0xf0, 0xc7, 0xc0, 0xd2, 0xa1, 0xb5, 0xb7, 0xb9, 0xb9, 0xbe,
+ 0xb4, 0xd5, 0xe5, 0xd0, 0xc2, 0xb0, 0xb5, 0xea, 0xcd, 0xcf, 0xbe, 0xd4, 0xce,
+ 0xc5, 0xaf, 0xea, 0xd1, 0xa1, 0xf5, 0xa1, 0xf5, 0xbb, 0xe1, 0xc0, 0xc6, 0xd2,
+ 0xb5, 0xb3, 0xfe, 0xbf, 0xac, 0xe9, 0xaa, 0xd0, 0xa8, 0xbc, 0xab, 0xd2, 0xac,
+ 0xb8, 0xc5, 0xd1, 0xee, 0xe8, 0xe5, 0xe9, 0xae, 0xc0, 0xe3, 0xb7, 0xe3, 0xe9,
+ 0xba, 0xd3, 0xdc, 0xe9, 0xac, 0xe9, 0xb9, 0xa1, 0xf5, 0xd0, 0xaa, 0xcb, 0xea,
+ 0xbb, 0xd9, 0xb5, 0xee, 0xd8, 0xb9, 0xeb, 0xa6, 0xd2, 0xe7, 0xcb, 0xdd, 0xd7,
+ 0xd2, 0xc8, 0xdc, 0xe4, 0xe8, 0xd4, 0xb4, 0xb9, 0xb5, 0xb5, 0xe1, 0xc3, 0xf0,
+ 0xe4, 0xdf, 0xe4, 0xdb, 0xca, 0xaa, 0xc4, 0xe7, 0xce, 0xc2, 0xbb, 0xac, 0xd7,
+ 0xbc, 0xc1, 0xef, 0xb2, 0xd7, 0xcc, 0xcf, 0xcf, 0xaa, 0xe4, 0xe0, 0xe4, 0xe5,
+ 0xbc, 0xe5, 0xd1, 0xcc, 0xb7, 0xb3, 0xc3, 0xba, 0xc1, 0xb6, 0xd5, 0xd5, 0xec,
+ 0xcf, 0xec, 0xbe, 0xec, 0xe3, 0xbb, 0xcd, 0xbb, 0xc0, 0xc9, 0xb7, 0xcf, 0xba,
+ 0xec, 0xd0, 0xa1, 0xf5, 0xd2, 0xaf, 0xeb, 0xba, 0xe9, 0xe0, 0xca, 0xa8, 0xd4,
+ 0xb3, 0xbb, 0xab, 0xc0, 0xc5, 0xba, 0xf7, 0xe8, 0xa6, 0xc9, 0xaa, 0xc8, 0xf0,
+ 0xe8, 0xa3, 0xe7, 0xf5, 0xe8, 0xa7, 0xe7, 0xf8, 0xe8, 0xa4, 0xb5, 0xb1, 0xbb,
+ 0xfb, 0xf0, 0xf6, 0xcc, 0xb5, 0xb4, 0xe1, 0xc2, 0xe9, 0xf0, 0xf2, 0xb1, 0xd4,
+ 0xf0, 0xf4, 0xb3, 0xd5, 0xc2, 0xe9, 0xd5, 0xb5, 0xc3, 0xcb, 0xbe, 0xa6, 0xbd,
+ 0xde, 0xc4, 0xc0, 0xed, 0xf9, 0xb6, 0xbd, 0xb6, 0xc3, 0xd8, 0xba, 0xb2, 0xc7,
+ 0xd5, 0xf6, 0xee, 0xa2, 0xed, 0xfe, 0xee, 0xa1, 0xb0, 0xab, 0xcb, 0xe9, 0xc5,
+ 0xf6, 0xcd, 0xeb, 0xb5, 0xe2, 0xc2, 0xb5, 0xb5, 0xef, 0xc5, 0xf0, 0xb1, 0xae,
+ 0xed, 0xd4, 0xa1, 0xf5, 0xec, 0xf7, 0xc2, 0xbb, 0xbd, 0xfb, 0xcd, 0xf2, 0xc7,
+ 0xdd, 0xc0, 0xe2, 0xd6, 0xc9, 0xb3, 0xed, 0xef, 0xfe, 0xd9, 0xf7, 0xef, 0xfd,
+ 0xbf, 0xdf, 0xf1, 0xbd, 0xbf, 0xea, 0xbd, 0xda, 0xf3, 0xde, 0xf3, 0xdf, 0xf3,
+ 0xc8, 0xc1, 0xbb, 0xbe, 0xac, 0xd4, 0xc1, 0xbe, 0xad, 0xbe, 0xee, 0xc0, 0xa7,
+ 0xb0, 0xf3, 0xcb, 0xe7, 0xcc, 0xd0, 0xd6, 0xc3, 0xd5, 0xd6, 0xd7, 0xef, 0xca,
+ 0xf0, 0xd2, 0xe5, 0xcf, 0xdb, 0xc8, 0xba, 0xca, 0xa5, 0xc6, 0xb8, 0xcb, 0xc1,
+ 0xd2, 0xde, 0xeb, 0xec, 0xd1, 0xfc, 0xb3, 0xa6, 0xd0, 0xc8, 0xc8, 0xf9, 0xbd,
+ 0xc5, 0xd6, 0xd7, 0xb8, 0xb9, 0xcf, 0xd9, 0xc4, 0xd4, 0xbe, 0xcb, 0xcd, 0xa7,
+ 0xb5, 0xd9, 0xbb, 0xe7, 0xc2, 0xe4, 0xdd, 0xe6, 0xbf, 0xfb, 0xce, 0xad, 0xba,
+ 0xf9, 0xd2, 0xb6, 0xd4, 0xe1, 0xb8, 0xf0, 0xdd, 0xe0, 0xdd, 0xab, 0xc6, 0xcf,
+ 0xb6, 0xad, 0xdd, 0xe2, 0xdd, 0xe7, 0xdd, 0xe1, 0xd3, 0xdd, 0xc2, 0xb2, 0xba,
+ 0xc5, 0xd3, 0xbc, 0xf2, 0xd1, 0xf2, 0xda, 0xf2, 0xd8, 0xca, 0xf1, 0xb6, 0xea,
+ 0xcd, 0xc9, 0xb7, 0xe4, 0xf2, 0xd7, 0xf2, 0xb9, 0xf2, 0xdb, 0xd1, 0xc3, 0xf4,
+ 0xc4, 0xd2, 0xe1, 0xc8, 0xb9, 0xb2, 0xb9, 0xf4, 0xc3, 0xd7, 0xb0, 0xc0, 0xef,
+ 0xf4, 0xc1, 0xd4, 0xa3, 0xd9, 0xf6, 0xa1, 0xf5, 0xbd, 0xe2, 0xb2, 0xef, 0xb8,
+ 0xc3, 0xcf, 0xea, 0xca, 0xd4, 0xca, 0xab, 0xda, 0xb5, 0xbf, 0xe4, 0xda, 0xb6,
+ 0xd2, 0xe8, 0xb3, 0xcf, 0xbb, 0xb0, 0xd6, 0xef, 0xb9, 0xee, 0xd1, 0xaf, 0xda,
+ 0xb9, 0xda, 0xb8, 0xd5, 0xb2, 0xa1, 0xf5, 0xf6, 0xa4, 0xa1, 0xf5, 0xbb, 0xbf,
+ 0xf5, 0xf6, 0xba, 0xd1, 0xd4, 0xf4, 0xd7, 0xca, 0xbc, 0xd6, 0xbb, 0xdf, 0xea,
+ 0xdf, 0xc1, 0xde, 0xc2, 0xb8, 0xea, 0xe0, 0xbc, 0xa3, 0xb8, 0xfa, 0xbf, 0xe7,
+ 0xc2, 0xb7, 0xcc, 0xf8, 0xb6, 0xe5, 0xb9, 0xf2, 0xf5, 0xd3, 0xa1, 0xf5, 0xb6,
+ 0xe3, 0xbd, 0xcf, 0xd4, 0xd8, 0xe9, 0xf8, 0xe9, 0xf9, 0xb1, 0xd9, 0xc5, 0xa9,
+ 0xd4, 0xcb, 0xd3, 0xce, 0xb5, 0xc0, 0xcb, 0xec, 0xb4, 0xef, 0xb1, 0xc6, 0xce,
+ 0xa5, 0xe5, 0xda, 0xd3, 0xf6, 0xb6, 0xf4, 0xb9, 0xfd, 0xb1, 0xe9, 0xe5, 0xd8,
+ 0xd3, 0xe2, 0xb6, 0xdd, 0xd7, 0xde, 0xa1, 0xf5, 0xb3, 0xea, 0xc0, 0xd2, 0xf5,
+ 0xa4, 0xd3, 0xd4, 0xee, 0xdc, 0xc7, 0xaf, 0xee, 0xe0, 0xee, 0xdf, 0xbc, 0xd8,
+ 0xd3, 0xcb, 0xc7, 0xa6, 0xc5, 0xd9, 0xb9, 0xb3, 0xb2, 0xac, 0xc1, 0xe5, 0xee,
+ 0xe7, 0xee, 0xe9, 0xee, 0xd2, 0xee, 0xeb, 0xee, 0xe4, 0xc3, 0xad, 0xd5, 0xa2,
+ 0xb0, 0xaf, 0xb8, 0xf4, 0xd4, 0xc9, 0xd3, 0xba, 0xf6, 0xc1, 0xef, 0xf4, 0xa1,
+ 0xf5, 0xc0, 0xd7, 0xb5, 0xe7, 0xb1, 0xa2, 0xc1, 0xe3, 0xbe, 0xb8, 0xd1, 0xa5,
+ 0xb0, 0xd0, 0xd4, 0xa4, 0xcd, 0xe7, 0xb6, 0xd9, 0xe7, 0xef, 0xb0, 0xe4, 0xcb,
+ 0xcc, 0xcb, 0xc7, 0xe2, 0xc2, 0xb1, 0xa5, 0xca, 0xce, 0xb3, 0xdb, 0xcd, 0xd4,
+ 0xd1, 0xb1, 0xf7, 0xd5, 0xf0, 0xaf, 0xf7, 0xe4, 0xb6, 0xa6, 0xb9, 0xc4, 0xca,
+ 0xf3, 0xc9, 0xae, 0xd9, 0xd7, 0xbd, 0xc4, 0xd9, 0xd2, 0xd9, 0xd4, 0xc1, 0xc5,
+ 0xc6, 0xcd, 0xcf, 0xf1, 0xc7, 0xc8, 0xb9, 0xcd, 0xa1, 0xf5, 0xa1, 0xf5, 0xbe,
+ 0xa4, 0xb5, 0xca, 0xbb, 0xae, 0xd8, 0xe3, 0xd8, 0xd1, 0xd1, 0xe1, 0xe0, 0xd5,
+ 0xe0, 0xd6, 0xc2, 0xef, 0xb3, 0xa2, 0xcb, 0xd4, 0xc5, 0xbb, 0xcc, 0xbe, 0xbc,
+ 0xce, 0xe0, 0xb6, 0xb8, 0xc2, 0xe0, 0xbb, 0xdf, 0xf5, 0xe0, 0xbd, 0xe0, 0xd0,
+ 0xa1, 0xf5, 0xdf, 0xd9, 0xcd, 0xc5, 0xcd, 0xbc, 0xb3, 0xbe, 0xdb, 0xd3, 0xbe,
+ 0xb3, 0xc4, 0xb9, 0xb5, 0xe6, 0xc7, 0xb5, 0xca, 0xfb, 0xa1, 0xf5, 0xca, 0xd9,
+ 0xe2, 0xb7, 0xc3, 0xce, 0xe2, 0xb9, 0xb6, 0xe1, 0xde, 0xc6, 0xb5, 0xd5, 0xe6,
+ 0xcf, 0xc4, 0xdb, 0xe5, 0xfd, 0xe6, 0xce, 0xe6, 0xd0, 0xe6, 0xcc, 0xb7, 0xf5,
+ 0xc4, 0xaf, 0xc4, 0xfe, 0xb9, 0xd1, 0xc1, 0xc8, 0xca, 0xb5, 0xd5, 0xaf, 0xc7,
+ 0xde, 0xe5, 0xbb, 0xb2, 0xec, 0xb6, 0xd4, 0xc2, 0xc5, 0xd5, 0xb8, 0xe1, 0xab,
+ 0xe1, 0xa4, 0xb1, 0xd2, 0xc4, 0xbb, 0xe0, 0xfe, 0xe1, 0xa3, 0xc0, 0xaa, 0xc1,
+ 0xce, 0xb1, 0xd7, 0xb1, 0xf0, 0xd5, 0xc3, 0xb3, 0xb9, 0xd2, 0xf3, 0xd4, 0xb8,
+ 0xcc, 0xac, 0xbf, 0xb6, 0xc2, 0xfd, 0xb9, 0xdf, 0xe2, 0xfa, 0xb2, 0xd1, 0xb2,
+ 0xd2, 0xe3, 0xbc, 0xbd, 0xd8, 0xc6, 0xb2, 0xd5, 0xaa, 0xcb, 0xa4, 0xb3, 0xb7,
+ 0xc3, 0xfe, 0xc2, 0xa7, 0xdf, 0xa1, 0xde, 0xe2, 0xb4, 0xdd, 0xe5, 0xba, 0xde,
+ 0xfd, 0xb2, 0xf4, 0xc7, 0xc3, 0xce, 0xd3, 0xc6, 0xec, 0xec, 0xbd, 0xb3, 0xa9,
+ 0xf4, 0xdf, 0xea, 0xd4, 0xb0, 0xf1, 0xd5, 0xa5, 0xe9, 0xc5, 0xe9, 0xc2, 0xc8,
+ 0xd9, 0xb8, 0xdc, 0xb9, 0xb9, 0xe9, 0xbb, 0xc8, 0xb6, 0xe9, 0xbd, 0xe9, 0xbe,
+ 0xc1, 0xf1, 0xbb, 0xb1, 0xc7, 0xb9, 0xe9, 0xbf, 0xe9, 0xb3, 0xa1, 0xf5, 0xc5,
+ 0xcc, 0xa1, 0xf5, 0xc7, 0xb8, 0xb8, 0xe8, 0xeb, 0xb5, 0xd5, 0xc4, 0xd1, 0xdd,
+ 0xb9, 0xf6, 0xc0, 0xec, 0xb5, 0xce, 0xe4, 0xf6, 0xd1, 0xfa, 0xc4, 0xae, 0xd7,
+ 0xd5, 0xc2, 0xa9, 0xc6, 0xaf, 0xba, 0xba, 0xc2, 0xfa, 0xd6, 0xcd, 0xc6, 0xe1,
+ 0xca, 0xfe, 0xbd, 0xa5, 0xd5, 0xc7, 0xc1, 0xb0, 0xe4, 0xee, 0xc2, 0xfe, 0xe4,
+ 0xf0, 0xb3, 0xba, 0xe4, 0xf4, 0xbb, 0xa6, 0xd3, 0xe6, 0xc9, 0xf8, 0xb5, 0xd3,
+ 0xc2, 0xb1, 0xc8, 0xdb, 0xce, 0xf5, 0xc9, 0xbf, 0xd0, 0xdc, 0xcf, 0xa8, 0xd3,
+ 0xab, 0xb6, 0xfb, 0xea, 0xfb, 0xdc, 0xfd, 0xd3, 0xfc, 0xe2, 0xaf, 0xd1, 0xfe,
+ 0xcb, 0xf6, 0xc2, 0xea, 0xb9, 0xe5, 0xe8, 0xa9, 0xd5, 0xe7, 0xd2, 0xc9, 0xc5,
+ 0xb1, 0xd1, 0xf1, 0xb7, 0xe8, 0xd3, 0xfa, 0xbb, 0xbe, 0xbe, 0xa1, 0xbc, 0xe0,
+ 0xc3, 0xe9, 0xee, 0xa5, 0xee, 0xa3, 0xcb, 0xaf, 0xb4, 0xc5, 0xb5, 0xfa, 0xb1,
+ 0xcc, 0xcc, 0xbc, 0xcb, 0xb6, 0xed, 0xd9, 0xec, 0xf5, 0xb8, 0xa3, 0xbb, 0xf6,
+ 0xd6, 0xd6, 0xb3, 0xc6, 0xcd, 0xdd, 0xce, 0xd1, 0xbd, 0xdf, 0xb6, 0xcb, 0xb9,
+ 0xdc, 0xbb, 0xfe, 0xbc, 0xe3, 0xf3, 0xdb, 0xcb, 0xe3, 0xf3, 0xe9, 0xb2, 0xad,
+ 0xf3, 0xdd, 0xf3, 0xe7, 0xb8, 0xf6, 0xa1, 0xf5, 0xb4, 0xe2, 0xf4, 0xd5, 0xbe,
+ 0xab, 0xd5, 0xc0, 0xe7, 0xba, 0xd7, 0xdb, 0xb4, 0xc2, 0xe7, 0xb1, 0xc2, 0xcc,
+ 0xbd, 0xf4, 0xd7, 0xba, 0xcd, 0xf8, 0xb8, 0xd9, 0xe7, 0xb2, 0xb3, 0xf1, 0xc3,
+ 0xe0, 0xb2, 0xca, 0xc2, 0xda, 0xce, 0xac, 0xd0, 0xf7, 0xe7, 0xbb, 0xe7, 0xb7,
+ 0xb7, 0xa3, 0xb4, 0xe4, 0xf4, 0xe4, 0xb5, 0xd4, 0xce, 0xc5, 0xbe, 0xdb, 0xd5,
+ 0xd8, 0xb8, 0xaf, 0xb0, 0xf2, 0xb8, 0xe0, 0xeb, 0xf5, 0xb2, 0xb2, 0xcd, 0xc8,
+ 0xeb, 0xf6, 0xea, 0xb0, 0xcc, 0xa8, 0xd3, 0xeb, 0xcc, 0xf2, 0xce, 0xe8, 0xf4,
+ 0xbb, 0xc8, 0xd8, 0xdd, 0xef, 0xcf, 0xaf, 0xd0, 0xee, 0xc3, 0xc9, 0xdd, 0xb0,
+ 0xc6, 0xd1, 0xcb, 0xe2, 0xb8, 0xc7, 0xd5, 0xf4, 0xdd, 0xa5, 0xdd, 0xed, 0xa1,
+ 0xf5, 0xb2, 0xd4, 0xcb, 0xf2, 0xdd, 0xee, 0xf2, 0xea, 0xc3, 0xdb, 0xf2, 0xdf,
+ 0xf2, 0xec, 0xf2, 0xe1, 0xf2, 0xe6, 0xd6, 0xa9, 0xca, 0xb4, 0xf2, 0xe9, 0xf2,
+ 0xe8, 0xc9, 0xd1, 0xb9, 0xd3, 0xc5, 0xe1, 0xb9, 0xfc, 0xc2, 0xe3, 0xd6, 0xc6,
+ 0xf1, 0xd4, 0xf1, 0xd2, 0xa1, 0xf5, 0xcb, 0xd0, 0xd6, 0xbe, 0xd3, 0xef, 0xce,
+ 0xdc, 0xc8, 0xcf, 0xbd, 0xeb, 0xca, 0xc4, 0xce, 0xf3, 0xcb, 0xb5, 0xda, 0xbe,
+ 0xbb, 0xe5, 0xd3, 0xd5, 0xda, 0xbf, 0xda, 0xbd, 0xa1, 0xf5, 0xba, 0xc0, 0xc0,
+ 0xea, 0xc3, 0xb2, 0xb1, 0xf6, 0xea, 0xe2, 0xc9, 0xde, 0xba, 0xd5, 0xd5, 0xd4,
+ 0xb8, 0xcf, 0xbe, 0xd6, 0xb8, 0xa8, 0xe9, 0xfc, 0xc7, 0xe1, 0xcd, 0xec, 0xc0,
+ 0xb1, 0xd4, 0xb6, 0xe5, 0xdc, 0xd1, 0xb7, 0xc7, 0xb2, 0xd2, 0xa3, 0xb5, 0xdd,
+ 0xe5, 0xdd, 0xa1, 0xf5, 0xe5, 0xde, 0xb1, 0xc9, 0xa1, 0xf5, 0xdb, 0xb4, 0xbd,
+ 0xcd, 0xcb, 0xe1, 0xbf, 0xe1, 0xf5, 0xa9, 0xbd, 0xc2, 0xd2, 0xf8, 0xcd, 0xad,
+ 0xc3, 0xfa, 0xee, 0xf9, 0xb8, 0xf5, 0xee, 0xfd, 0xcf, 0xce, 0xef, 0xa7, 0xa1,
+ 0xf5, 0xcf, 0xb3, 0xba, 0xd2, 0xb9, 0xeb, 0xc3, 0xf6, 0xb8, 0xf3, 0xb7, 0xa7,
+ 0xb8, 0xf3, 0xcf, 0xb6, 0xd5, 0xcf, 0xbc, 0xca, 0xb4, 0xc6, 0xf6, 0xc3, 0xd0,
+ 0xe8, 0xf7, 0xb0, 0xf7, 0xb1, 0xc9, 0xd8, 0xc6, 0xc4, 0xc1, 0xec, 0xec, 0xaa,
+ 0xcc, 0xa8, 0xbd, 0xc8, 0xb1, 0xfd, 0xb6, 0xfc, 0xe2, 0xc3, 0xb2, 0xb5, 0xb0,
+ 0xb9, 0xf7, 0xbb, 0xf7, 0xd6, 0xbf, 0xfd, 0xbb, 0xea, 0xc3, 0xf9, 0xf0, 0xb0,
+ 0xb7, 0xef, 0xc3, 0xb4, 0xb1, 0xc7, 0xc6, 0xeb, 0xd2, 0xda, 0xd2, 0xc7, 0xc6,
+ 0xa7, 0xbd, 0xa9, 0xbc, 0xdb, 0xd9, 0xaf, 0xbf, 0xeb, 0xbc, 0xf3, 0xa1, 0xf5,
+ 0xc1, 0xdd, 0xbe, 0xe7, 0xc5, 0xfc, 0xc1, 0xf5, 0xbd, 0xa3, 0xb9, 0xf4, 0xdb,
+ 0xc4, 0xc0, 0xf7, 0xdf, 0xeb, 0xce, 0xfb, 0xe0, 0xda, 0xb3, 0xb0, 0xba, 0xd9,
+ 0xd7, 0xec, 0xbb, 0xa9, 0xd0, 0xea, 0xd2, 0xad, 0xe0, 0xdb, 0xc5, 0xe7, 0xcb,
+ 0xbb, 0xd0, 0xa5, 0xdf, 0xb4, 0xdc, 0xaf, 0xd0, 0xe6, 0xd4, 0xf6, 0xb7, 0xd8,
+ 0xd7, 0xb9, 0xb6, 0xe9, 0xb6, 0xd5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xd2, 0xe6,
+ 0xb5, 0xe6, 0xbf, 0xe5, 0xfc, 0xbd, 0xbf, 0xe6, 0xac, 0xe5, 0xbc, 0xbf, 0xed,
+ 0xc9, 0xf3, 0xd0, 0xb4, 0xb2, 0xe3, 0xc2, 0xc4, 0xe1, 0xd8, 0xa1, 0xf5, 0xb4,
+ 0xb1, 0xd6, 0xc4, 0xe1, 0xa6, 0xb7, 0xcf, 0xb3, 0xf8, 0xc3, 0xed, 0xd8, 0xcb,
+ 0xb9, 0xe3, 0xb3, 0xa7, 0xb5, 0xaf, 0xd3, 0xb0, 0xb5, 0xc2, 0xe1, 0xe7, 0xc7,
+ 0xec, 0xbb, 0xdb, 0xc2, 0xc7, 0xed, 0xab, 0xc4, 0xbd, 0xd3, 0xc7, 0xc6, 0xdd,
+ 0xce, 0xbf, 0xcb, 0xcb, 0xd3, 0xfb, 0xe3, 0xbf, 0xc1, 0xaf, 0xc3, 0xf5, 0xd4,
+ 0xf7, 0xe3, 0xbd, 0xb5, 0xac, 0xb7, 0xdf, 0xe3, 0xbe, 0xe2, 0xe4, 0xc2, 0xbe,
+ 0xc4, 0xa6, 0xd6, 0xbf, 0xc4, 0xa1, 0xd7, 0xb2, 0xc6, 0xcb, 0xc0, 0xcc, 0xb3,
+ 0xc5, 0xd7, 0xab, 0xb2, 0xa6, 0xc4, 0xd3, 0xcb, 0xba, 0xc1, 0xc3, 0xc8, 0xf6,
+ 0xb4, 0xe9, 0xb2, 0xa5, 0xb8, 0xa7, 0xc4, 0xed, 0xc7, 0xcb, 0xdf, 0xa4, 0xb5,
+ 0xa7, 0xde, 0xec, 0xb5, 0xd0, 0xb7, 0xf3, 0xca, 0xfd, 0xc4, 0xba, 0xd4, 0xdd,
+ 0xb1, 0xa9, 0xea, 0xc7, 0xd1, 0xf9, 0xd5, 0xc1, 0xe9, 0xa4, 0xd7, 0xae, 0xca,
+ 0xe0, 0xb1, 0xea, 0xb2, 0xdb, 0xc4, 0xa3, 0xc2, 0xa5, 0xb7, 0xae, 0xbd, 0xb0,
+ 0xc0, 0xd6, 0xe8, 0xc8, 0xe9, 0xca, 0xc1, 0xba, 0xc5, 0xb7, 0xcc, 0xbe, 0xe9,
+ 0xe4, 0xd2, 0xe3, 0xc5, 0xb9, 0xbd, 0xac, 0xe4, 0xfc, 0xb3, 0xce, 0xc6, 0xc3,
+ 0xc1, 0xca, 0xbd, 0xe0, 0xbd, 0xbd, 0xcc, 0xb6, 0xc7, 0xb1, 0xe4, 0xfa, 0xb3,
+ 0xb1, 0xc5, 0xec, 0xe4, 0xfd, 0xc0, 0xa3, 0xc8, 0xf3, 0xbd, 0xa7, 0xc5, 0xcb,
+ 0xeb, 0xf8, 0xe4, 0xb1, 0xa1, 0xf5, 0xf4, 0xaa, 0xca, 0xec, 0xb0, 0xbe, 0xc8,
+ 0xc8, 0xec, 0xd9, 0xeb, 0xbb, 0xa1, 0xf5, 0xbd, 0xb1, 0xe2, 0xb1, 0xd3, 0xa8,
+ 0xe8, 0xb0, 0xc1, 0xa7, 0xe8, 0xaa, 0xe8, 0xad, 0xe7, 0xdc, 0xf1, 0xa4, 0xb4,
+ 0xf1, 0xce, 0xc1, 0xc1, 0xf6, 0xca, 0xdd, 0xb4, 0xaf, 0xf1, 0xa3, 0xb0, 0xa8,
+ 0xd6, 0xe5, 0xc5, 0xcc, 0xcf, 0xb9, 0xc3, 0xd0, 0xee, 0xa7, 0xee, 0xa8, 0xa1,
+ 0xf5, 0xb4, 0xe8, 0xb0, 0xf5, 0xc8, 0xb7, 0xc0, 0xda, 0xc4, 0xeb, 0xbf, 0xc4,
+ 0xc2, 0xeb, 0xc5, 0xcd, 0xb8, 0xe5, 0xbc, 0xda, 0xb9, 0xc8, 0xbb, 0xfc, 0xf0,
+ 0xa2, 0xb5, 0xbe, 0xd2, 0xa4, 0xc7, 0xee, 0xbc, 0xfd, 0xcf, 0xe4, 0xb7, 0xb6,
+ 0xf3, 0xf0, 0xd7, 0xad, 0xc6, 0xaa, 0xf3, 0xf2, 0xa1, 0xf5, 0xf3, 0xf3, 0xba,
+ 0xfd, 0xb5, 0xde, 0xc1, 0xb7, 0xce, 0xb3, 0xd6, 0xc2, 0xbc, 0xea, 0xc3, 0xe5,
+ 0xbc, 0xa9, 0xb1, 0xe0, 0xd4, 0xb5, 0xcf, 0xdf, 0xb6, 0xd0, 0xbb, 0xba, 0xe7,
+ 0xb6, 0xe7, 0xbc, 0xe7, 0xbf, 0xe7, 0xbe, 0xc2, 0xee, 0xb0, 0xd5, 0xf4, 0xc9,
+ 0xf4, 0xe6, 0xf1, 0xee, 0xcc, 0xc5, 0xc4, 0xa4, 0xcf, 0xa5, 0xbd, 0xba, 0xb7,
+ 0xf4, 0xb1, 0xec, 0xd5, 0xe1, 0xb1, 0xce, 0xce, 0xb5, 0xc1, 0xab, 0xca, 0xdf,
+ 0xd2, 0xf1, 0xc2, 0xfb, 0xc3, 0xef, 0xbd, 0xaf, 0xb2, 0xcc, 0xb2, 0xb7, 0xc5,
+ 0xee, 0xb4, 0xd0, 0xde, 0xa3, 0xa1, 0xf5, 0xf2, 0xeb, 0xba, 0xfb, 0xb5, 0xfb,
+ 0xf2, 0xf0, 0xcf, 0xba, 0xce, 0xcf, 0xca, 0xad, 0xf2, 0xf9, 0xbb, 0xc8, 0xf2,
+ 0xf2, 0xf2, 0xf5, 0xce, 0xc0, 0xb3, 0xe5, 0xba, 0xd6, 0xb8, 0xb4, 0xb0, 0xfd,
+ 0xf1, 0xd9, 0xa1, 0xf5, 0xf1, 0xdb, 0xd2, 0xea, 0xc1, 0xc2, 0xcc, 0xb8, 0xd7,
+ 0xbb, 0xb5, 0xae, 0xc7, 0xeb, 0xd6, 0xee, 0xbf, 0xce, 0xda, 0xc3, 0xda, 0xc6,
+ 0xb5, 0xf7, 0xcb, 0xad, 0xc2, 0xdb, 0xda, 0xba, 0xda, 0xc7, 0xb7, 0xcc, 0xda,
+ 0xc4, 0xcd, 0xe3, 0xca, 0xfa, 0xd6, 0xed, 0xc5, 0xe2, 0xc9, 0xcd, 0xb8, 0xb3,
+ 0xbc, 0xfa, 0xd5, 0xcb, 0xb6, 0xc4, 0xcf, 0xcd, 0xc2, 0xf4, 0xb4, 0xcd, 0xd6,
+ 0xca, 0xe2, 0xd9, 0xf4, 0xf7, 0xcc, 0xcb, 0xc8, 0xa4, 0xa1, 0xf5, 0xbc, 0xf9,
+ 0xf5, 0xd7, 0xcc, 0xdf, 0xcc, 0xa4, 0xb2, 0xc8, 0xf5, 0xd8, 0xa1, 0xf5, 0xbe,
+ 0xe1, 0xcc, 0xc9, 0xbb, 0xd4, 0xc1, 0xbe, 0xea, 0xa1, 0xb1, 0xb2, 0xe9, 0xfd,
+ 0xc2, 0xd6, 0xea, 0xa2, 0xe9, 0xfe, 0xb9, 0xf5, 0xca, 0xca, 0xd5, 0xda, 0xe5,
+ 0xdb, 0xd4, 0xe2, 0xc7, 0xa8, 0xc1, 0xda, 0xd6, 0xa3, 0xb5, 0xcb, 0xdb, 0xb6,
+ 0xb4, 0xbc, 0xd7, 0xed, 0xb4, 0xd7, 0xeb, 0xe7, 0xd0, 0xbf, 0xcc, 0xe0, 0xcf,
+ 0xfa, 0xc6, 0xcc, 0xee, 0xed, 0xb3, 0xfa, 0xc2, 0xc1, 0xc8, 0xf1, 0xef, 0xb1,
+ 0xb7, 0xe6, 0xb1, 0xb5, 0xef, 0xae, 0xba, 0xb8, 0xe3, 0xcc, 0xd4, 0xc4, 0xcf,
+ 0xf6, 0xf6, 0xaa, 0xd5, 0xf0, 0xc3, 0xb9, 0xbf, 0xbf, 0xb0, 0xb0, 0xd0, 0xac,
+ 0xb9, 0xae, 0xf2, 0xa1, 0xa1, 0xf5, 0xf2, 0xa2, 0xb9, 0xce, 0xd1, 0xf8, 0xb6,
+ 0xf6, 0xc4, 0xd9, 0xe2, 0xc5, 0xcd, 0xd5, 0xd7, 0xa4, 0xe6, 0xe1, 0xca, 0xbb,
+ 0xe6, 0xe5, 0xbc, 0xdd, 0xbe, 0xd4, 0xe6, 0xe2, 0xf7, 0xbc, 0xb7, 0xa2, 0xf7,
+ 0xd7, 0xc4, 0xd6, 0xf7, 0xc8, 0xc6, 0xc7, 0xf6, 0xcf, 0xc2, 0xb3, 0xf0, 0xb2,
+ 0xd1, 0xbb, 0xf5, 0xfb, 0xf4, 0xef, 0xf7, 0xe2, 0xc0, 0xe8, 0xc4, 0xab, 0xb3,
+ 0xdd, 0xc8, 0xe5, 0xbe, 0xa1, 0xd9, 0xb1, 0xd9, 0xcf, 0xd9, 0xad, 0xbc, 0xbd,
+ 0xc3, 0xdd, 0xc4, 0xfd, 0xbc, 0xc1, 0xd8, 0xe6, 0xd1, 0xab, 0xe0, 0xdf, 0xe0,
+ 0xe6, 0xb5, 0xb1, 0xd8, 0xac, 0xe0, 0xe4, 0xb6, 0xd6, 0xd4, 0xeb, 0xc6, 0xf7,
+ 0xdf, 0xe6, 0xe0, 0xe5, 0xe0, 0xc8, 0xca, 0xc9, 0xe0, 0xde, 0xb8, 0xc1, 0xb1,
+ 0xda, 0xbf, 0xd1, 0xcc, 0xb3, 0xdb, 0xd5, 0xb7, 0xdc, 0xa1, 0xf5, 0xd9, 0xf8,
+ 0xd1, 0xa7, 0xe5, 0xbe, 0xb5, 0xbc, 0xc7, 0xbf, 0xcf, 0xdc, 0xc6, 0xbe, 0xed,
+ 0xac, 0xb1, 0xb9, 0xe3, 0xc1, 0xd2, 0xe4, 0xba, 0xb6, 0xb0, 0xc3, 0xd0, 0xb8,
+ 0xd5, 0xbd, 0xc9, 0xc3, 0xd3, 0xb5, 0xb5, 0xb2, 0xcc, 0xa2, 0xba, 0xb3, 0xbe,
+ 0xdd, 0xc2, 0xb0, 0xd4, 0xf1, 0xc0, 0xde, 0xb2, 0xd9, 0xbc, 0xf1, 0xc7, 0xdc,
+ 0xb5, 0xa3, 0xce, 0xce, 0xd5, 0xfb, 0xc0, 0xfa, 0xcf, 0xfe, 0xe5, 0xdf, 0xea,
+ 0xca, 0xea, 0xbc, 0xa1, 0xf5, 0xe9, 0xd7, 0xc6, 0xd3, 0xe8, 0xeb, 0xb3, 0xc8,
+ 0xba, 0xe1, 0xe9, 0xd9, 0xca, 0xf7, 0xe9, 0xcf, 0xcd, 0xd6, 0xcf, 0xf0, 0xc7,
+ 0xc5, 0xc7, 0xc1, 0xe9, 0xd4, 0xbb, 0xfa, 0xe8, 0xe3, 0xec, 0xa8, 0xc0, 0xfa,
+ 0xeb, 0xa9, 0xe5, 0xa5, 0xb5, 0xed, 0xd4, 0xe8, 0xc5, 0xa8, 0xd4, 0xf3, 0xd7,
+ 0xc7, 0xe5, 0xa2, 0xb0, 0xc4, 0xbc, 0xa4, 0xe5, 0xa3, 0xe5, 0xa4, 0xa1, 0xf5,
+ 0xe4, 0xc5, 0xa1, 0xf5, 0xb3, 0xe3, 0xec, 0xc0, 0xc1, 0xd7, 0xc9, 0xd5, 0xb5,
+ 0xc6, 0xd1, 0xe0, 0xec, 0xe4, 0xc1, 0xc7, 0xcc, 0xcc, 0xec, 0xcb, 0xc8, 0xbc,
+ 0xd1, 0xe6, 0xb6, 0xc0, 0xe8, 0xab, 0xe7, 0xe1, 0xa1, 0xf5, 0xa1, 0xf5, 0xe8,
+ 0xb1, 0xc6, 0xb0, 0xea, 0xb1, 0xdd, 0xf9, 0xd5, 0xce, 0xc8, 0xb3, 0xa1, 0xf5,
+ 0xc2, 0xac, 0xee, 0xc2, 0xee, 0xaa, 0xc2, 0xf7, 0xee, 0xa9, 0xc6, 0xb3, 0xc4,
+ 0xa5, 0xd7, 0xa9, 0xed, 0xe0, 0xed, 0xd3, 0xd3, 0xf9, 0xbb, 0xfd, 0xd3, 0xb1,
+ 0xc4, 0xc2, 0xf6, 0xd5, 0xa1, 0xf5, 0xbf, 0xfa, 0xb8, 0xdd, 0xa1, 0xf5, 0xd6,
+ 0xfe, 0xf3, 0xc6, 0xa1, 0xf5, 0xb4, 0xdb, 0xc9, 0xb8, 0xf3, 0xf7, 0xb8, 0xe2,
+ 0xcc, 0xc7, 0xe7, 0xcb, 0xe7, 0xcc, 0xdd, 0xd3, 0xb8, 0xbf, 0xcf, 0xd8, 0xe7,
+ 0xc9, 0xe7, 0xc7, 0xe7, 0xc6, 0xe7, 0xa7, 0xee, 0xbe, 0xf4, 0xcb, 0xba, 0xb2,
+ 0xb0, 0xbf, 0xf4, 0xe7, 0xf1, 0xf1, 0xc9, 0xc5, 0xc4, 0xe5, 0xc5, 0xf2, 0xd5,
+ 0xe9, 0xd0, 0xcb, 0xcb, 0xd2, 0xb2, 0xd5, 0xc8, 0xef, 0xde, 0xa5, 0xde, 0xa6,
+ 0xde, 0xa7, 0xb5, 0xb4, 0xde, 0xac, 0xbd, 0xb6, 0xcf, 0xf4, 0xce, 0xdf, 0xde,
+ 0xa9, 0xf3, 0xa6, 0xc3, 0xf8, 0xc2, 0xec, 0xd3, 0xa9, 0xc8, 0xda, 0xba, 0xe2,
+ 0xcd, 0xca, 0xbf, 0xe3, 0xc8, 0xec, 0xf1, 0xdd, 0xf1, 0xd7, 0xc7, 0xd7, 0xea,
+ 0xec, 0xda, 0xd0, 0xd1, 0xe8, 0xda, 0xc9, 0xbb, 0xe4, 0xc4, 0xb1, 0xb5, 0xfd,
+ 0xd0, 0xb3, 0xda, 0xd1, 0xc5, 0xb5, 0xda, 0xcb, 0xce, 0xbd, 0xb7, 0xed, 0xda,
+ 0xcd, 0xda, 0xcf, 0xda, 0xc8, 0xda, 0xce, 0xd4, 0xa5, 0xa1, 0xf5, 0xc3, 0xa8,
+ 0xc0, 0xb5, 0xcc, 0xe3, 0xf5, 0xe2, 0xd3, 0xbb, 0xf5, 0xe5, 0xf5, 0xdf, 0xf5,
+ 0xe0, 0xb7, 0xf8, 0xbc, 0xad, 0xca, 0xe4, 0xea, 0xa3, 0xb1, 0xe6, 0xb0, 0xec,
+ 0xd7, 0xf1, 0xe5, 0xe0, 0xd1, 0xa1, 0xb3, 0xd9, 0xc1, 0xc9, 0xd2, 0xc5, 0xda,
+ 0xfe, 0xd0, 0xd1, 0xb6, 0xa7, 0xb1, 0xed, 0xbe, 0xe2, 0xc3, 0xcc, 0xb4, 0xed,
+ 0xc7, 0xae, 0xb8, 0xd6, 0xce, 0xfd, 0xc2, 0xbc, 0xef, 0xa3, 0xd7, 0xb6, 0xbd,
+ 0xf5, 0xa1, 0xf5, 0xef, 0xbf, 0xef, 0xc0, 0xef, 0xc5, 0xd1, 0xd6, 0xcb, 0xed,
+ 0xcb, 0xe6, 0xcf, 0xd5, 0xb5, 0xf1, 0xf6, 0xae, 0xd5, 0xb4, 0xc1, 0xd8, 0xbb,
+ 0xf4, 0xc4, 0xde, 0xf6, 0xad, 0xb5, 0xe5, 0xbe, 0xb2, 0xcc, 0xf3, 0xc7, 0xca,
+ 0xbc, 0xd5, 0xbe, 0xb1, 0xc6, 0xb5, 0xf2, 0xa5, 0xcd, 0xb7, 0xcd, 0xc7, 0xd2,
+ 0xc3, 0xb2, 0xcd, 0xb9, 0xdd, 0xbd, 0xa4, 0xe2, 0xc6, 0xcf, 0xda, 0xeb, 0xc8,
+ 0xba, 0xa7, 0xe6, 0xe9, 0xc2, 0xe6, 0xba, 0xa1, 0xf7, 0xc0, 0xf7, 0xd9, 0xf7,
+ 0xda, 0xba, 0xe5, 0xb1, 0xab, 0xcd, 0xd2, 0xf0, 0xb3, 0xd1, 0xec, 0xd1, 0xbc,
+ 0xc1, 0xee, 0xd4, 0xa7, 0xc4, 0xac, 0xc7, 0xad, 0xc1, 0xfa, 0xb9, 0xea, 0xd3,
+ 0xc5, 0xb3, 0xa5, 0xc0, 0xdc, 0xb4, 0xa2, 0xc0, 0xf8, 0xba, 0xbf, 0xdf, 0xcc,
+ 0xb3, 0xa2, 0xe0, 0xe9, 0xcf, 0xc5, 0xcc, 0xe7, 0xba, 0xbe, 0xd1, 0xb9, 0xdb,
+ 0xd6, 0xa1, 0xf5, 0xd3, 0xa4, 0xe6, 0xc9, 0xe6, 0xd6, 0xc8, 0xe6, 0xde, 0xcf,
+ 0xe5, 0xf0, 0xd3, 0xec, 0xc1, 0xeb, 0xd4, 0xc0, 0xe1, 0xc9, 0xb0, 0xef, 0xc3,
+ 0xd6, 0xbb, 0xd5, 0xd3, 0xa6, 0xb6, 0xae, 0xbf, 0xd2, 0xc5, 0xb3, 0xed, 0xae,
+ 0xcf, 0xb7, 0xb4, 0xf7, 0xc7, 0xe6, 0xbb, 0xf7, 0xeb, 0xa2, 0xbc, 0xb7, 0xc5,
+ 0xa1, 0xb2, 0xc1, 0xc4, 0xe2, 0xb8, 0xe9, 0xdf, 0xaa, 0xa1, 0xf5, 0xc1, 0xb2,
+ 0xb1, 0xd0, 0xca, 0xef, 0xea, 0xd3, 0xcc, 0xb4, 0xb5, 0xb5, 0xcf, 0xad, 0xbc,
+ 0xec, 0xe8, 0xed, 0xe8, 0xce, 0xe9, 0xc9, 0xc5, 0xf6, 0xe9, 0xde, 0xe9, 0xdc,
+ 0xe9, 0xd1, 0xa1, 0xf5, 0xe9, 0xe7, 0xa1, 0xf5, 0xd5, 0xb1, 0xc5, 0xa2, 0xb1,
+ 0xf5, 0xbc, 0xc3, 0xe5, 0xa9, 0xc3, 0xc9, 0xcc, 0xce, 0xc0, 0xc4, 0xe5, 0xaa,
+ 0xc9, 0xac, 0xbf, 0xa3, 0xe5, 0xa6, 0xa1, 0xf5, 0xca, 0xaa, 0xe5, 0xa7, 0xce,
+ 0xab, 0xec, 0xdd, 0xd3, 0xaa, 0xdb, 0xc6, 0xb2, 0xd3, 0xd4, 0xef, 0xd6, 0xf2,
+ 0xbb, 0xd9, 0xbb, 0xe2, 0xec, 0xdb, 0xbe, 0xf4, 0xc7, 0xbd, 0xc4, 0xfc, 0xbb,
+ 0xf1, 0xe8, 0xb3, 0xbb, 0xb7, 0xe8, 0xa8, 0xe8, 0xb2, 0xf0, 0xec, 0xc1, 0xc6,
+ 0xb0, 0xa9, 0xb5, 0xb4, 0xcd, 0xab, 0xb5, 0xc9, 0xee, 0xab, 0xcb, 0xb2, 0xc7,
+ 0xc6, 0xc1, 0xcb, 0xbd, 0xc3, 0xc1, 0xd7, 0xbb, 0xc7, 0xed, 0xe3, 0xed, 0xb6,
+ 0xbd, 0xb8, 0xec, 0xfb, 0xec, 0xf8, 0xcb, 0xeb, 0xc1, 0xfe, 0xb4, 0xd8, 0xc2,
+ 0xa8, 0xf3, 0xfa, 0xc5, 0xf1, 0xf3, 0xf9, 0xa1, 0xf5, 0xbf, 0xb7, 0xc3, 0xd3,
+ 0xb7, 0xe0, 0xc4, 0xa3, 0xd4, 0xe3, 0xb2, 0xda, 0xf4, 0xd6, 0xcb, 0xf5, 0xbc,
+ 0xa8, 0xe7, 0xd1, 0xc2, 0xc6, 0xe7, 0xd0, 0xb1, 0xc1, 0xb7, 0xec, 0xd7, 0xdc,
+ 0xd7, 0xdd, 0xe7, 0xd2, 0xb7, 0xb1, 0xcf, 0xcb, 0xe7, 0xce, 0xa1, 0xf5, 0xe7,
+ 0xcf, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xc0, 0xf4, 0xe8, 0xd2, 0xed, 0xf1, 0xfa,
+ 0xc9, 0xf9, 0xb4, 0xcf, 0xc1, 0xaa, 0xcb, 0xca, 0xd2, 0xdc, 0xd3, 0xb7, 0xe2,
+ 0xdf, 0xb1, 0xdb, 0xcd, 0xce, 0xc5, 0xa7, 0xb5, 0xa8, 0xc1, 0xb3, 0xeb, 0xda,
+ 0xc1, 0xd9, 0xbe, 0xd9, 0xbc, 0xe8, 0xd0, 0xbd, 0xb1, 0xa1, 0xc0, 0xd9, 0xde,
+ 0xb5, 0xbd, 0xaa, 0xc7, 0xbe, 0xca, 0xed, 0xd1, 0xa6, 0xde, 0xb1, 0xde, 0xb0,
+ 0xbc, 0xbb, 0xbf, 0xf7, 0xf3, 0xb0, 0xf3, 0xaf, 0xf3, 0xab, 0xf2, 0xfe, 0xf3,
+ 0xa1, 0xf3, 0xa7, 0xf2, 0xf7, 0xc2, 0xdd, 0xf2, 0xe5, 0xf3, 0xac, 0xd9, 0xf4,
+ 0xf1, 0xde, 0xcf, 0xe5, 0xf1, 0xda, 0xa1, 0xf5, 0xea, 0xe9, 0xc3, 0xd5, 0xb0,
+ 0xf9, 0xc7, 0xab, 0xbd, 0xb2, 0xbb, 0xd1, 0xd2, 0xa5, 0xd0, 0xbb, 0xcc, 0xdc,
+ 0xda, 0xd7, 0xbb, 0xed, 0xcf, 0xaa, 0xe1, 0xd9, 0xd7, 0xac, 0xc8, 0xfc, 0xb9,
+ 0xba, 0xa1, 0xf5, 0xea, 0xe7, 0xc7, 0xf7, 0xf5, 0xe3, 0xcc, 0xa3, 0xb5, 0xb8,
+ 0xf5, 0xe8, 0xcf, 0xbd, 0xd5, 0xb7, 0xec, 0xb1, 0xd4, 0xaf, 0xd3, 0xdf, 0xb1,
+ 0xdc, 0xe5, 0xe1, 0xbb, 0xb9, 0xc2, 0xf5, 0xe5, 0xe2, 0xd1, 0xfb, 0xdb, 0xb8,
+ 0xf5, 0xb1, 0xd4, 0xcd, 0xb3, 0xf3, 0xb6, 0xc6, 0xc3, 0xbe, 0xc3, 0xaa, 0xbc,
+ 0xfc, 0xc1, 0xb4, 0xef, 0xc6, 0xb9, 0xf8, 0xb4, 0xb8, 0xef, 0xf1, 0xc7, 0xc2,
+ 0xb6, 0xcd, 0xef, 0xcc, 0xa1, 0xf5, 0xef, 0xc9, 0xc0, 0xab, 0xe3, 0xd7, 0xc0,
+ 0xbb, 0xe3, 0xc7, 0xb0, 0xe5, 0xd2, 0xfe, 0xc1, 0xa5, 0xcb, 0xe4, 0xcb, 0xaa,
+ 0xcf, 0xbc, 0xbe, 0xcf, 0xba, 0xab, 0xbf, 0xc5, 0xec, 0xab, 0xce, 0xb9, 0xb3,
+ 0xd2, 0xbf, 0xa5, 0xcf, 0xca, 0xf6, 0xde, 0xf6, 0xdb, 0xf6, 0xd9, 0xba, 0xe8,
+ 0xb8, 0xeb, 0xf7, 0xe7, 0xf0, 0xa4, 0xb5, 0xe3, 0xf7, 0xed, 0xf7, 0xee, 0xf7,
+ 0xec, 0xf7, 0xfd, 0xd5, 0xab, 0xb4, 0xd4, 0xe0, 0xe0, 0xcf, 0xf2, 0xdb, 0xdb,
+ 0xc0, 0xdd, 0xc9, 0xf4, 0xd2, 0xcd, 0xed, 0xaf, 0xb4, 0xc1, 0xc0, 0xa9, 0xd6,
+ 0xc0, 0xc8, 0xc5, 0xc4, 0xec, 0xb0, 0xda, 0xcb, 0xd3, 0xdf, 0xa2, 0xb6, 0xcf,
+ 0xea, 0xd7, 0xeb, 0xfc, 0xe9, 0xc4, 0xc3, 0xca, 0xb9, 0xf1, 0xbc, 0xf7, 0xc4,
+ 0xfb, 0xe8, 0xfe, 0xa1, 0xf5, 0xcc, 0xa8, 0xec, 0xa3, 0xb9, 0xe9, 0xe9, 0xeb,
+ 0xd0, 0xba, 0xe4, 0xc9, 0xc2, 0xcb, 0xe4, 0xc2, 0xbd, 0xa6, 0xc6, 0xd9, 0xe4,
+ 0xaf, 0xd1, 0xac, 0xbd, 0xfd, 0xec, 0xe2, 0xa1, 0xf5, 0xe1, 0xee, 0xc1, 0xd4,
+ 0xe8, 0xb5, 0xa1, 0xf5, 0xce, 0xcd, 0xf1, 0xb1, 0xf0, 0xdd, 0xd3, 0xfa, 0xee,
+ 0xad, 0xf6, 0xc4, 0xd5, 0xb0, 0xed, 0xfa, 0xb4, 0xa1, 0xc0, 0xf1, 0xf0, 0xa3,
+ 0xbb, 0xe0, 0xa1, 0xf5, 0xb4, 0xdc, 0xc7, 0xcf, 0xf3, 0xef, 0xbb, 0xc9, 0xf4,
+ 0xa2, 0xf3, 0xec, 0xf3, 0xf1, 0xbc, 0xf2, 0xc1, 0xb8, 0xd6, 0xaf, 0xc9, 0xc9,
+ 0xc8, 0xc6, 0xe7, 0xd4, 0xd0, 0xe5, 0xe7, 0xd5, 0xa1, 0xf5, 0xcc, 0xb3, 0xc7,
+ 0xcc, 0xb7, 0xad, 0xd6, 0xb0, 0xc4, 0xf4, 0xc6, 0xea, 0xeb, 0xf7, 0xbe, 0xc9,
+ 0xb2, 0xd8, 0xc8, 0xf8, 0xc0, 0xb6, 0xc3, 0xea, 0xbd, 0xe5, 0xde, 0xb9, 0xdc,
+ 0xf9, 0xde, 0xb7, 0xbc, 0xf6, 0xf2, 0xcd, 0xb2, 0xf5, 0xb3, 0xe6, 0xf3, 0xb4,
+ 0xb8, 0xb2, 0xea, 0xee, 0xf5, 0xfc, 0xda, 0xd3, 0xbd, 0xf7, 0xc3, 0xfd, 0xda,
+ 0xd8, 0xb7, 0xe1, 0xd7, 0xb8, 0xf5, 0xbe, 0xf5, 0xe7, 0xb1, 0xc4, 0xd7, 0xd9,
+ 0xbc, 0xa3, 0xf5, 0xcf, 0xc7, 0xfb, 0xd7, 0xaa, 0xd5, 0xde, 0xe5, 0xc7, 0xe5,
+ 0xe4, 0xe5, 0xe3, 0xd2, 0xbd, 0xbd, 0xb4, 0xc0, 0xe5, 0xc8, 0xdb, 0xb0, 0xf7,
+ 0xcb, 0xf8, 0xce, 0xd9, 0xc4, 0xf8, 0xd5, 0xf2, 0xb8, 0xe4, 0xef, 0xd7, 0xef,
+ 0xd3, 0xb4, 0xb8, 0xc7, 0xb9, 0xe3, 0xd8, 0xb4, 0xb3, 0xe3, 0xd9, 0xe3, 0xda,
+ 0xc0, 0xeb, 0xd4, 0xd3, 0xcb, 0xab, 0xb3, 0xfb, 0xbc, 0xa6, 0xa1, 0xf5, 0xf7,
+ 0xb7, 0xc7, 0xef, 0xb1, 0xde, 0xa1, 0xf5, 0xb6, 0xee, 0xd1, 0xd5, 0xcc, 0xe2,
+ 0xf2, 0xa6, 0xf2, 0xa7, 0xa1, 0xf5, 0xc1, 0xf3, 0xe2, 0xc8, 0xc0, 0xa1, 0xf7,
+ 0xd1, 0xf0, 0xa5, 0xc6, 0xef, 0xf7, 0xc1, 0xd7, 0xd7, 0xcb, 0xc9, 0xce, 0xba,
+ 0xf7, 0xcb, 0xf7, 0xcd, 0xf6, 0xe8, 0xc0, 0xf0, 0xf6, 0xea, 0xa1, 0xf5, 0xf6,
+ 0xe7, 0xbe, 0xe9, 0xb6, 0xec, 0xf0, 0xc0, 0xf7, 0xef, 0xa1, 0xf5, 0xf7, 0xf8,
+ 0xb2, 0xf6, 0xd1, 0xca, 0xbb, 0xb5, 0xc2, 0xa2, 0xdb, 0xde, 0xb3, 0xe8, 0xc5,
+ 0xd3, 0xc2, 0xae, 0xb3, 0xcd, 0xbb, 0xb3, 0xc0, 0xc1, 0xe3, 0xc2, 0xc5, 0xca,
+ 0xc2, 0xa3, 0xbf, 0xf5, 0xc6, 0xd8, 0xb3, 0xf7, 0xe8, 0xfc, 0xe9, 0xb5, 0xe9,
+ 0xd6, 0xe5, 0xad, 0xe4, 0xec, 0xe4, 0xfe, 0xe5, 0xab, 0xc1, 0xa4, 0xb1, 0xf4,
+ 0xe3, 0xf2, 0xb1, 0xac, 0xcb, 0xb8, 0xeb, 0xb9, 0xb6, 0xbf, 0xca, 0xde, 0xcc,
+ 0xa1, 0xe7, 0xf4, 0xc7, 0xed, 0xb0, 0xea, 0xb3, 0xeb, 0xbd, 0xae, 0xb1, 0xf1,
+ 0xb3, 0xd5, 0xc3, 0xc9, 0xb0, 0xad, 0xb5, 0xbb, 0xbb, 0xf1, 0xce, 0xc8, 0xc1,
+ 0xb1, 0xb2, 0xbe, 0xf4, 0xa4, 0xc7, 0xa9, 0xe9, 0xdc, 0xf4, 0xa6, 0xcf, 0xb5,
+ 0xbc, 0xeb, 0xd2, 0xef, 0xc9, 0xfe, 0xbb, 0xe6, 0xc2, 0xde, 0xbd, 0xc9, 0xeb,
+ 0xfe, 0xb8, 0xfe, 0xd9, 0xfa, 0xc0, 0xb0, 0xb7, 0xaa, 0xd2, 0xd5, 0xde, 0xb4,
+ 0xc5, 0xba, 0xcc, 0xd9, 0xd2, 0xa9, 0xa1, 0xf5, 0xd2, 0xcf, 0xd3, 0xac, 0xd0,
+ 0xab, 0xd0, 0xb7, 0xf3, 0xb8, 0xf1, 0xc9, 0xbd, 0xf3, 0xb0, 0xc0, 0xf4, 0xc5,
+ 0xbb, 0xa9, 0xc6, 0xd7, 0xca, 0xb6, 0xd6, 0xa4, 0xcc, 0xb7, 0xda, 0xdc, 0xbc,
+ 0xa5, 0xa1, 0xf5, 0xda, 0xdb, 0xd4, 0xf9, 0xd4, 0xde, 0xf5, 0xeb, 0xb6, 0xd7,
+ 0xb3, 0xf9, 0xf5, 0xea, 0xb5, 0xc5, 0xf5, 0xce, 0xf5, 0xed, 0xea, 0xa5, 0xbd,
+ 0xce, 0xb4, 0xc7, 0xb1, 0xdf, 0xe5, 0xe5, 0xc6, 0xc9, 0xf5, 0xb4, 0xbe, 0xb5,
+ 0xef, 0xe1, 0xb2, 0xf9, 0xef, 0xdf, 0xc1, 0xb4, 0xef, 0xdb, 0xef, 0xdc, 0xf7,
+ 0xe9, 0xef, 0xda, 0xef, 0xdd, 0xef, 0xcf, 0xef, 0xce, 0xef, 0xac, 0xf6, 0xc9,
+ 0xb9, 0xd8, 0xc2, 0xa4, 0xc4, 0xd1, 0xf6, 0xaf, 0xce, 0xed, 0xc3, 0xd2, 0xe8,
+ 0xba, 0xd4, 0xcf, 0xc0, 0xe0, 0xd4, 0xb8, 0xb5, 0xdf, 0xec, 0xac, 0xc2, 0xf8,
+ 0xe2, 0xcb, 0xe6, 0xf0, 0xc6, 0xad, 0xba, 0xfa, 0xbe, 0xa8, 0xf6, 0xf0, 0xf6,
+ 0xeb, 0xf6, 0xf4, 0xf0, 0xc8, 0xf0, 0xc4, 0xc8, 0xb5, 0xf0, 0xc6, 0xc5, 0xf4,
+ 0xf7, 0xe8, 0xc0, 0xf6, 0xc2, 0xb4, 0xf4, 0xf0, 0xc8, 0xb0, 0xc1, 0xfc, 0xc8,
+ 0xc2, 0xe0, 0xd3, 0xd1, 0xcf, 0xbd, 0xc0, 0xc8, 0xc0, 0xe6, 0xd7, 0xc4, 0xef,
+ 0xc4, 0xf5, 0xb1, 0xa6, 0xa1, 0xf5, 0xd0, 0xfc, 0xe2, 0xe3, 0xc8, 0xc1, 0xc0,
+ 0xb9, 0xb2, 0xf3, 0xea, 0xd8, 0xeb, 0xca, 0xe9, 0xb4, 0xc0, 0xbd, 0xc3, 0xd6,
+ 0xe4, 0xf2, 0xc2, 0xaf, 0xcf, 0xd7, 0xe7, 0xe7, 0xd1, 0xf7, 0xd5, 0xf7, 0xbf,
+ 0xf3, 0xed, 0xc2, 0xb7, 0xaf, 0xc0, 0xf9, 0xf1, 0xbc, 0xbe, 0xba, 0xb3, 0xef,
+ 0xc0, 0xba, 0xbc, 0xae, 0xc5, 0xb4, 0xcd, 0xc5, 0xb1, 0xe8, 0xe7, 0xcd, 0xbc,
+ 0xcc, 0xd7, 0xeb, 0xf3, 0xbf, 0xd2, 0xab, 0xeb, 0xcd, 0xbd, 0xa2, 0xd4, 0xe5,
+ 0xb0, 0xaa, 0xc4, 0xa2, 0xdd, 0xfe, 0xc2, 0xab, 0xc6, 0xbb, 0xcb, 0xd5, 0xd4,
+ 0xcc, 0xf2, 0xba, 0xc8, 0xe4, 0xf1, 0xdc, 0xbe, 0xf5, 0xb4, 0xa5, 0xd2, 0xe9,
+ 0xc6, 0xa9, 0xbe, 0xaf, 0xd2, 0xeb, 0xd4, 0xeb, 0xda, 0xde, 0xd3, 0xae, 0xc9,
+ 0xc4, 0xf5, 0xbb, 0xd4, 0xea, 0xf5, 0xee, 0xcc, 0xa4, 0xf5, 0xb7, 0xca, 0xcd,
+ 0xd6, 0xd3, 0xee, 0xf3, 0xd0, 0xe2, 0xb2, 0xfb, 0xf6, 0xb1, 0xc6, 0xae, 0xc8,
+ 0xc4, 0xbc, 0xa2, 0xdc, 0xb0, 0xe5, 0xb9, 0xcc, 0xda, 0xc9, 0xa7, 0xa1, 0xf5,
+ 0xc8, 0xfa, 0xf6, 0xfa, 0xcf, 0xcc, 0xc3, 0xe6, 0xb5, 0xb3, 0xf7, 0xf9, 0xf6,
+ 0xb4, 0xb3, 0xf6, 0xc1, 0xe4, 0xd9, 0xb3, 0xa1, 0xf5, 0xe0, 0xbf, 0xdf, 0xf9,
+ 0xcf, 0xf9, 0xd9, 0xe7, 0xca, 0xf4, 0xce, 0xa1, 0xbe, 0xe5, 0xc9, 0xe5, 0xc9,
+ 0xe3, 0xd0, 0xaf, 0xec, 0xb5, 0xea, 0xd9, 0xd3, 0xa3, 0xc0, 0xb8, 0xe8, 0xf9,
+ 0xbc, 0xdf, 0xb9, 0xe0, 0xc0, 0xc3, 0xce, 0xfe, 0xa1, 0xf5, 0xe8, 0xac, 0xf1,
+ 0xae, 0xeb, 0xca, 0xcc, 0xd9, 0xb2, 0xf8, 0xd0, 0xf8, 0xe5, 0xf1, 0xde, 0xc1,
+ 0xc0, 0xbc, 0xde, 0xba, 0xf2, 0xc3, 0xb4, 0xc0, 0xf3, 0xbb, 0xc0, 0xaf, 0xcd,
+ 0xe0, 0xa1, 0xf5, 0xc0, 0xc0, 0xc7, 0xb4, 0xbb, 0xa4, 0xd3, 0xfe, 0xd4, 0xdf,
+ 0xb3, 0xec, 0xd4, 0xbe, 0xf5, 0xd2, 0xba, 0xe4, 0xb1, 0xe7, 0xf5, 0xb8, 0xc1,
+ 0xad, 0xc0, 0xd8, 0xcc, 0xfa, 0xee, 0xf5, 0xee, 0xec, 0xef, 0xed, 0xef, 0xd4,
+ 0xb1, 0xd9, 0xb0, 0xd4, 0xc5, 0xf9, 0xc2, 0xb6, 0xcf, 0xec, 0xb9, 0xcb, 0xf2,
+ 0xab, 0xf7, 0xcf, 0xc7, 0xfd, 0xe6, 0xf4, 0xdd, 0xeb, 0xc2, 0xe2, 0xf7, 0xc3,
+ 0xc4, 0xa7, 0xf7, 0xce, 0xf7, 0xa2, 0xf7, 0xa4, 0xdd, 0xba, 0xba, 0xd7, 0xf0,
+ 0xce, 0xc8, 0xf5, 0xf7, 0xea, 0xf7, 0xf6, 0xdc, 0xb1, 0xf6, 0xb7, 0xf6, 0xb8,
+ 0xc4, 0xf6, 0xd9, 0xb2, 0xd9, 0xce, 0xdf, 0xbd, 0xc4, 0xd2, 0xc2, 0xde, 0xc2,
+ 0xcf, 0xe1, 0xdb, 0xc2, 0xcd, 0xcd, 0xe4, 0xdc, 0xb2, 0xcc, 0xaf, 0xc8, 0xa8,
+ 0xbb, 0xb6, 0xc8, 0xf7, 0xcc, 0xb2, 0xe2, 0xa4, 0xc8, 0xbf, 0xb5, 0xfe, 0xf1,
+ 0xab, 0xd1, 0xa2, 0xec, 0xfc, 0xc1, 0xfd, 0xf4, 0xa5, 0xc1, 0xfb, 0xcc, 0xfd,
+ 0xd4, 0xe0, 0xcf, 0xae, 0xb3, 0xc4, 0xa1, 0xf5, 0xb6, 0xc1, 0xca, 0xea, 0xd8,
+ 0xcd, 0xf5, 0xdc, 0xf5, 0xd9, 0xe0, 0xce, 0xdb, 0xaa, 0xd6, 0xfd, 0xbc, 0xf8,
+ 0xbc, 0xf8, 0xf6, 0xab, 0xf6, 0xb2, 0xf7, 0xb2, 0xe7, 0xd6, 0xb2, 0xfc, 0xf7,
+ 0xd2, 0xbd, 0xbe, 0xe6, 0xe7, 0xd4, 0xe0, 0xd0, 0xeb, 0xb1, 0xee, 0xf6, 0xe3,
+ 0xf7, 0xa7, 0xf7, 0xa9, 0xf0, 0xd1, 0xc5, 0xb8, 0xf7, 0xfa, 0xf6, 0xb9, 0xf6,
+ 0xba, 0xb9, 0xa8, 0xcb, 0xd5, 0xd1, 0xd2, 0xc1, 0xb5, 0xc2, 0xce, 0xbe, 0xf0,
+ 0xbd, 0xc1, 0xc9, 0xb9, 0xa1, 0xf5, 0xe8, 0xb6, 0xc7, 0xd4, 0xc7, 0xa9, 0xa1,
+ 0xf5, 0xd9, 0xdf, 0xd3, 0xa7, 0xcf, 0xcb, 0xa1, 0xf5, 0xa1, 0xf5, 0xd5, 0xba,
+ 0xc2, 0xdc, 0xb9, 0xc6, 0xb1, 0xe4, 0xe5, 0xce, 0xc2, 0xdf, 0xef, 0xf0, 0xee,
+ 0xe5, 0xa1, 0xf5, 0xd8, 0xcc, 0xcf, 0xd4, 0xf7, 0xd0, 0xbe, 0xaa, 0xe6, 0xe4,
+ 0xd1, 0xe9, 0xcb, 0xe8, 0xcc, 0xe5, 0xf7, 0xc7, 0xf7, 0xad, 0xc1, 0xdb, 0xf7,
+ 0xac, 0xf0, 0xb8, 0xf7, 0xeb, 0xc3, 0xb9, 0xd6, 0xf6, 0xb0, 0xd3, 0xc0, 0xbf,
+ 0xe5, 0xb1, 0xcc, 0xb1, 0xf1, 0xb2, 0xb4, 0xa3, 0xb9, 0xde, 0xee, 0xbf, 0xb2,
+ 0xcf, 0xf3, 0xbc, 0xe1, 0xe9, 0xc8, 0xc3, 0xb2, 0xf7, 0xda, 0xdf, 0xd1, 0xde,
+ 0xb8, 0xd3, 0xc4, 0xf0, 0xa1, 0xf5, 0xf6, 0xa8, 0xc1, 0xe9, 0xf6, 0xb0, 0xc7,
+ 0xa7, 0xf2, 0xad, 0xd6, 0xe8, 0xf7, 0xde, 0xf7, 0xca, 0xf6, 0xd7, 0xd3, 0xa5,
+ 0xf0, 0xd8, 0xbc, 0xee, 0xd1, 0xce, 0xf2, 0xfc, 0xf6, 0xbb, 0xc8, 0xa3, 0xcc,
+ 0xfc, 0xe9, 0xad, 0xcd, 0xe5, 0xc0, 0xe9, 0xc2, 0xe1, 0xc2, 0xf9, 0xb9, 0xdb,
+ 0xf5, 0xe6, 0xd0, 0xc6, 0xcf, 0xe2, 0xd4, 0xbf, 0xc2, 0xad, 0xb2, 0xf6, 0xf7,
+ 0xc5, 0xf7, 0xe0, 0xd9, 0xe4, 0xc2, 0xd0, 0xd6, 0xf5, 0xd4, 0xde, 0xc4, 0xf7,
+ 0xf7, 0xb5, 0xc2, 0xbf, 0xe6, 0xf7, 0xc0, 0xc2, 0xda, 0xd4, 0xf5, 0xef, 0xf5,
+ 0xa6, 0xd7, 0xea, 0xf6, 0xc7, 0xc2, 0xe0, 0xf6, 0xf9, 0xf6, 0xd4, 0xf7, 0xf2,
+ 0xd1, 0xde, 0xd4, 0xe4, 0xf0, 0xd0, 0xec, 0xe0, 0xe6, 0xea, 0xd3, 0xf4, 0xf0,
+ 0xd9, 0xf0, 0xbd, 0xd3, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xd8, 0xbf, 0xdb, 0xc9, 0xd8, 0xce, 0xb3, 0xa7, 0xcd,
+ 0xf2, 0xd8, 0xa2, 0xd8, 0xb1, 0xd8, 0xa1, 0xe0, 0xed, 0xd8, 0xa3, 0xe5, 0xf8,
+ 0xe1, 0xdc, 0xa1, 0xf5, 0xa1, 0xf5, 0xd3, 0xeb, 0xa1, 0xf5, 0xd8, 0xc1, 0xd8,
+ 0xec, 0xd8, 0xeb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb0, 0xba, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xec,
+ 0xaf, 0xa1, 0xf5, 0xc6, 0xf8, 0xe3, 0xdd, 0xa1, 0xf5, 0xa1, 0xf5, 0xd8, 0xed,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xd8, 0xee, 0xd9, 0xda, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xca, 0xa5, 0xa1, 0xf5, 0xba, 0xbb, 0xc4, 0xfe,
+ 0xe5, 0xb3, 0xa1, 0xf5, 0xe5, 0xea, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2,
+ 0xcf, 0xa1, 0xf5, 0xe2, 0xe1, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xad, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xec, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xbc, 0xbf, 0xd3, 0xc5, 0xa1, 0xf5, 0xd8, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xbc, 0xdb, 0xd0, 0xc4, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xd8, 0xf3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xd9, 0xfc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xcd, 0xf2, 0xa1, 0xf5, 0xa1, 0xf5, 0xe0, 0xef, 0xd8, 0xb6, 0xdb, 0xdc,
+ 0xdb, 0xd9, 0xa1, 0xf5, 0xde, 0xc5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xd8, 0xde, 0xcd,
+ 0xa1, 0xf5, 0xe1, 0xa8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xbf, 0xaa, 0xd7,
+ 0xaf, 0xd2, 0xec, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xe3,
+ 0xa1, 0xf5, 0xba, 0xb4, 0xa1, 0xf5, 0xa1, 0xf5, 0xc7, 0xa4, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xb9, 0xea, 0xb8, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xbb, 0xfa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xeb, 0xae, 0xd9, 0xdb, 0xa1, 0xf5, 0xe3, 0xe1, 0xa1, 0xf5, 0xe3, 0xe2,
+ 0xe3, 0xe0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xed, 0xa1,
+ 0xf5, 0xe7, 0xe0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xcd, 0xf8, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xdc, 0xb4, 0xdc, 0xb5, 0xf2, 0xae, 0xa1, 0xf5, 0xda,
+ 0xf8, 0xda, 0xf5, 0xa1, 0xf5, 0xda, 0xf6, 0xa1, 0xf5, 0xda, 0xe3, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xcc,
+ 0xe5, 0xd8, 0xf4, 0xa1, 0xf5, 0xd8, 0xfb, 0xa1, 0xf5, 0xd9, 0xa1, 0xa1, 0xf5,
+ 0xd9, 0xdc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdb, 0xbf, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xd8, 0xd5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xdf, 0xbe, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb6, 0xd6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdb, 0xd0, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe6, 0xa1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xa9, 0xa1,
+ 0xf5, 0xe1, 0xac, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xd1, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xdf, 0xaf, 0xec, 0xfd, 0xec, 0xfe, 0xe2, 0xed, 0xa1, 0xf5, 0xe2,
+ 0xe5, 0xa1, 0xf5, 0xe2, 0xe7, 0xe2, 0xe8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xd0, 0xda, 0xd0, 0xc3, 0xbb, 0xb3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xbc, 0xab, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xc8, 0xc5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xbf, 0xbc, 0xea, 0xba, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe8, 0xbb, 0xe8,
+ 0xbe, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xaf,
+ 0xeb, 0xb0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc6,
+ 0xe3, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xe9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xf0,
+ 0xa1, 0xf5, 0xe1, 0xf1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xae, 0xa1, 0xf5, 0xf0, 0xdb, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xeb, 0xc0, 0xa1, 0xf5, 0xdc, 0xb6, 0xa1, 0xf5, 0xdc, 0xba, 0xdc, 0xbb,
+ 0xa1, 0xf5, 0xdc, 0xb7, 0xa1, 0xf5, 0xdc, 0xb9, 0xf5, 0xf4, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xda, 0xfa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd9,
+ 0xae, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd9, 0xa5, 0xd9, 0xa6,
+ 0xd9, 0xa8, 0xd6, 0xb6, 0xa1, 0xf5, 0xa1, 0xf5, 0xb6, 0xb1, 0xa1, 0xf5, 0xe1,
+ 0xdf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd9, 0xb0,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xd9, 0xfe, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd8, 0xda, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xcc, 0xd5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdf, 0xc6, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdf,
+ 0xcf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xdf, 0xca, 0xa1, 0xf5, 0xe0, 0xf2, 0xc5, 0xf7, 0xa1, 0xf5, 0xdb,
+ 0xe8, 0xdb, 0xe3, 0xa1, 0xf5, 0xa1, 0xf5, 0xdb, 0xe9, 0xa1, 0xf5, 0xc7, 0xf0,
+ 0xdb, 0xe6, 0xdb, 0xea, 0xa1, 0xf5, 0xa1, 0xf5, 0xdb, 0xe7, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc4, 0xa9, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xa7,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xdf,
+ 0xe6, 0xdb, 0xe5, 0xb5, 0xe5, 0xb4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xe1, 0xb2, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xb5, 0xa1, 0xf5,
+ 0xe1, 0xb8, 0xc1, 0xeb, 0xe1, 0xb3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe0, 0xfa, 0xe0, 0xf9,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xde, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xf1, 0xe2, 0xef,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xf7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xf4, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc1, 0xaf, 0xea, 0xa7, 0xec,
+ 0xe6, 0xa1, 0xf5, 0xa1, 0xf5, 0xc7, 0xaf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xde, 0xd4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xd3, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xbe, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xc3,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe8,
+ 0xc4, 0xa1, 0xf5, 0xb9, 0xb9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xbc, 0xab, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xed, 0xb3, 0xa1, 0xf5, 0xe3, 0xf9, 0xe3, 0xfa, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe3, 0xef, 0xe3, 0xf0, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xee, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc5, 0xa2, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xc8, 0xb2, 0xa1, 0xf5, 0xea, 0xc1, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xc0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xf4,
+ 0xa1, 0xf5, 0xb5, 0xa9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xe7, 0xe3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xaf, 0xe7, 0xde, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xed, 0xec, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xb7, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xcb, 0xfb, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf1, 0xb6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xf4,
+ 0xa1, 0xf5, 0xb0, 0xb9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xc7, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdc, 0xbe, 0xa1, 0xf5, 0xdc, 0xc5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xdc, 0xc7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdc,
+ 0xcc, 0xdc, 0xb8, 0xdc, 0xcd, 0xdc, 0xcb, 0xa1, 0xf5, 0xdc, 0xd2, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xb0, 0xa1, 0xf5, 0xf2, 0xb1, 0xd8,
+ 0xa1, 0xa1, 0xf5, 0xa1, 0xf5, 0xe5, 0xc2, 0xa1, 0xf5, 0xa1, 0xf5, 0xe5, 0xc3,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xfb, 0xba, 0xaa, 0xda, 0xfc, 0xdb, 0xa2, 0xa1,
+ 0xf5, 0xda, 0xe7, 0xda, 0xe8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd9, 0xb4,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd9, 0xb6, 0xa1, 0xf5, 0xd9,
+ 0xb7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd8, 0xd9, 0xef, 0xb1, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd8, 0xc7,
+ 0xc0, 0xe5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdf, 0xd2, 0xa1, 0xf5, 0xdf, 0xe7, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xdf, 0xfb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xb6, 0xdf, 0xa1, 0xf5, 0xa1, 0xf5, 0xdf, 0xc3, 0xa1, 0xf5, 0xa1, 0xf5, 0xdf,
+ 0xda, 0xdf, 0xe8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdb, 0xec,
+ 0xdb, 0xed, 0xa1, 0xf5, 0xa1, 0xf5, 0xb6, 0xe2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb8, 0xb4,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6,
+ 0xad, 0xcf, 0xb3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xbe, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xbf, 0xc6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xe1, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xb4, 0xc3, 0xa1, 0xf5, 0xe2, 0xd3, 0xa1, 0xf5, 0xa1, 0xf5, 0xe5,
+ 0xe8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe2, 0xfe, 0xd0, 0xda, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xe7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xbf, 0xe6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb8, 0xf1,
+ 0xa1, 0xf5, 0xde, 0xd9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xea, 0xc6, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xc7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xc3, 0xea, 0xc4, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xd4, 0xe8, 0xde, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xb9, 0xf1, 0xa1, 0xf5, 0xa1, 0xf5, 0xe8, 0xcf, 0xa1, 0xf5, 0xbc, 0xcf,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe8, 0xd5, 0xa1, 0xf5, 0xe8,
+ 0xd7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe8, 0xcd, 0xa1, 0xf5, 0xa1, 0xf5, 0xc0, 0xad, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe8, 0xda, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xe3, 0xe9,
+ 0xe5, 0xa1, 0xf5, 0xb1, 0xd1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xb1,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xcd, 0xdd, 0xa1, 0xf5, 0xc8,
+ 0xf7, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xb2, 0xe4, 0xa7, 0xe4, 0xa8, 0xa1, 0xf5,
+ 0xe4, 0xae, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xbd, 0xe0, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xa6, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xc4, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xec, 0xc6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xea, 0xf0, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xe6, 0xe7,
+ 0xec, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xce, 0xcd, 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xb2, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xf1, 0xa1, 0xf5, 0xed, 0xed, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xef, 0xf2, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xed, 0xbc, 0xc5, 0xf8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xed, 0xb9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xef, 0xf5, 0xd6, 0xd6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf1, 0xb8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6,
+ 0xfd, 0xa1, 0xf5, 0xee, 0xb7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xe8, 0xde, 0xc7, 0xa1, 0xf5, 0xdb, 0xcf, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xcf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xeb, 0xd1, 0xca, 0xa4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb,
+ 0xd3, 0xa1, 0xf5, 0xeb, 0xd2, 0xa1, 0xf5, 0xf4, 0xad, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xc6, 0xbb, 0xdc, 0xd8, 0xa1, 0xf5, 0xa1, 0xf5, 0xdc, 0xe6, 0xdc,
+ 0xfb, 0xc9, 0xbb, 0xa1, 0xf5, 0xdc, 0xda, 0xa1, 0xf5, 0xdc, 0xd3, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xdc, 0xdd, 0xdc, 0xde, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdc,
+ 0xd6, 0xdc, 0xe5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf2, 0xb4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1,
+ 0xc3, 0xa1, 0xf5, 0xa1, 0xf5, 0xd9, 0xea, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xe5, 0xc5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdb,
+ 0xa4, 0xdb, 0xa5, 0xdb, 0xa8, 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xc6, 0xee, 0xc5,
+ 0xda, 0xeb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xb1, 0xed, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd9, 0xbe, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xd9, 0xc3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xb5, 0xb3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc6,
+ 0xe0, 0xb9, 0xcc, 0xbe, 0xbb, 0xa1, 0xf5, 0xd8, 0xdf, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xd8, 0xde, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc7, 0xe6, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdf, 0xea, 0xdf, 0xee,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xdb, 0xc1, 0xdf, 0xc2, 0xa1, 0xf5, 0xa1, 0xf5, 0xdf,
+ 0xf2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xdb, 0xf4, 0xdb, 0xf8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xdb, 0xf9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xd8, 0xab, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe5, 0xf2, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xa2, 0xed, 0xa3, 0xed,
+ 0xa4, 0xed, 0xa5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xa8, 0xa1, 0xf5,
+ 0xe3, 0xa6, 0xe3, 0xa7, 0xa1, 0xf5, 0xe3, 0xaa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xcd, 0xb1, 0xa1, 0xf5, 0xde, 0xdc, 0xa1, 0xf5, 0xde,
+ 0xda, 0xde, 0xdb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xec, 0xb7, 0xec, 0xb9, 0xec, 0xb8, 0xa1, 0xf5, 0xa1, 0xf5, 0xea,
+ 0xc9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xe8, 0xf1, 0xe8, 0xe0, 0xe8, 0xe1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc6,
+ 0xdc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xe8, 0xe4, 0xe8, 0xe6, 0xa1, 0xf5, 0xe8, 0xe9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xbd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xb4,
+ 0xe4, 0xb3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xb7, 0xa1,
+ 0xf5, 0xe4, 0xbb, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xbc, 0xa1, 0xf5, 0xcd, 0xbf,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xfe, 0xe1, 0xf9,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xfc, 0xe2, 0xa1, 0xe1, 0xfb, 0xa1, 0xf5, 0xe7,
+ 0xee, 0xe7, 0xed, 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xf2, 0xa1, 0xf5, 0xe7, 0xf1,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xac, 0xa1, 0xf5, 0xea, 0xb2, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xee, 0xb3, 0xa1, 0xf5, 0xf0, 0xe6, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0,
+ 0xe4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xed, 0xf4, 0xed, 0xf2, 0xed, 0xf3, 0xa1, 0xf5, 0xed, 0xc8,
+ 0xed, 0xc7, 0xa1, 0xf5, 0xb2, 0xa7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xed, 0xc9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xec, 0xee, 0xa1, 0xf5, 0xec, 0xef, 0xec, 0xf0, 0xa1, 0xf5, 0xa1, 0xf5, 0xef,
+ 0xf8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xef, 0xf6, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xb9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xc7, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf3, 0xcb, 0xf3, 0xc5, 0xf3, 0xc9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf4, 0xce, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe7, 0xa3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xee, 0xb8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xe9, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xb0, 0xb7, 0xeb, 0xdc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf4, 0xa8, 0xf4, 0xb1, 0xa1, 0xf5, 0xdc, 0xfc, 0xdc, 0xfa, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xdc, 0xe8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xdc, 0xe7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xa2, 0xa1, 0xf5,
+ 0xdc, 0xeb, 0xdc, 0xed, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xdc, 0xf2, 0xa1, 0xf5, 0xdc, 0xf4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xb2, 0xe7, 0xa1, 0xf5, 0xbc, 0xeb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf2, 0xb6, 0xa1, 0xf5, 0xf2, 0xb7, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xb8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xbb, 0xb2, 0xcf, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf2, 0xba, 0xa1, 0xf5, 0xa1, 0xf5, 0xb1, 0xad, 0xf4, 0xac, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf1, 0xc4, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xc6, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf4, 0xc0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xf8, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb8, 0xcf, 0xa1, 0xf5, 0xf5, 0xc0,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xca,
+ 0xca, 0xa1, 0xf5, 0xa1, 0xf5, 0xe5, 0xcc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdb, 0xa3, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xdb, 0xae, 0xdb, 0xad, 0xdb, 0xac, 0xa1, 0xf5, 0xf4, 0xfb, 0xf4, 0xfc,
+ 0xf4, 0xfd, 0xee, 0xc9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xec, 0xf6,
+ 0xc0, 0xa1, 0xf5, 0xf7, 0xd4, 0xdb, 0xcb, 0xa1, 0xf5, 0xa1, 0xf5, 0xb1, 0xc6,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xd9, 0xca, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb9, 0xd0, 0xdb, 0xc3, 0xa1,
+ 0xf5, 0xd8, 0xd0, 0xa1, 0xf5, 0xe0, 0xa3, 0xe0, 0xa4, 0xdf, 0xfe, 0xa1, 0xf5,
+ 0xdf, 0xfd, 0xa1, 0xf5, 0xdf, 0xf4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe0, 0xa7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc9, 0xb6,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe0, 0xf5, 0xe0, 0xf0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xdb, 0xfa, 0xdc, 0xa5, 0xdc, 0xa4, 0xdc, 0xa3, 0xa1, 0xf5, 0xdb,
+ 0xfc, 0xdc, 0xa1, 0xa1, 0xf5, 0xdb, 0xef, 0xdd, 0xc0, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdb, 0xeb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xdc, 0xa2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xbc, 0xe6,
+ 0xba, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xab, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe5, 0xed, 0xe1, 0xc6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xc1, 0xe1, 0xc3, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xc4, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xd5, 0xa1, 0xf5, 0xe2, 0xd8, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xae, 0xa1, 0xf5, 0xe3, 0xad, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xbe, 0xaa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xfd,
+ 0xa1, 0xf5, 0xde, 0xe5, 0xb5, 0xe0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xde,
+ 0xdd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xe1, 0xa1, 0xf5, 0xb6, 0xde,
+ 0xc6, 0xfe, 0xbe, 0xdd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xe3, 0xde,
+ 0xe7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xea, 0xce, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xb2, 0xce, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe8, 0xf5, 0xa1, 0xf5, 0xe8, 0xf4, 0xe8, 0xf6, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe8, 0xf8, 0xd8, 0xc3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xb1, 0xb4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xec, 0xa4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xe8, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xeb, 0xb4, 0xb5, 0xed, 0xe4, 0xca, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xba, 0xe9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xb5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xc4, 0xa1, 0xf5, 0xc4, 0xd7, 0xa1, 0xf5,
+ 0xe4, 0xcb, 0xa1, 0xf5, 0xe4, 0xc7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xcd, 0xe9, 0xbe, 0xd6,
+ 0xcc, 0xfe, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xc9, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xca, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea,
+ 0xf6, 0xe2, 0xa7, 0xe2, 0xa2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xa5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xa6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd1, 0xf7, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xc3, 0xd0, 0xed, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xed, 0xf6, 0xa1, 0xf5, 0xed, 0xf7, 0xa1, 0xf5, 0xce, 0xf8, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xd1, 0xed, 0xce, 0xb9, 0xe8, 0xed, 0xcf,
+ 0xa1, 0xf5, 0xec, 0xf6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xc0, 0xeb, 0xa1, 0xf5, 0xbd, 0xd5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xcc, 0xa1, 0xf5, 0xf3, 0xd3, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf3, 0xd4, 0xf3, 0xd5, 0xa1, 0xf5, 0xf3, 0xce, 0xa1, 0xf5,
+ 0xf3, 0xd1, 0xf3, 0xca, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xcd, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd5, 0xb3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xa4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xaa, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xc6, 0xa1, 0xf5, 0xf1,
+ 0xb4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xf5, 0xa1,
+ 0xf5, 0xeb, 0xe4, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xd6, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xeb, 0xe3, 0xeb, 0xe2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf4, 0xb4, 0xf4, 0xb6, 0xa1, 0xf5, 0xf4, 0xb7, 0xa1, 0xf5,
+ 0xe5, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xb9, 0xa1, 0xf5, 0xa1, 0xf5, 0xb6,
+ 0xb9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xb3, 0xdd, 0xb4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xdc, 0xf0, 0xdd, 0xad, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xa8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xc5, 0xf2, 0xc4, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xca, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xc5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf1, 0xc8, 0xec, 0xee, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd9, 0xf3, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xfb, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf5, 0xc2, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xc1, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe5, 0xcd, 0xe5, 0xcf, 0xa1, 0xf5, 0xa1, 0xf5, 0xe5, 0xd2, 0xdb,
+ 0xb0, 0xa1, 0xf5, 0xa1, 0xf5, 0xb3, 0xbb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xdb, 0xaf, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xb2, 0xa1, 0xf5, 0xb7, 0xd3, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xee, 0xcc, 0xee, 0xcf, 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xca, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xe3, 0xc6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd8,
+ 0xb8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb4, 0xf6,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe0, 0xb3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe0,
+ 0xa5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe0, 0xae, 0xdf, 0xf6, 0xdf, 0xf7,
+ 0xe0, 0xaf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xdc, 0xa7, 0xdc, 0xa6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xe6, 0xa3, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xc4, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe1, 0xd1, 0xa1, 0xf5, 0xe1, 0xd2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xce, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xcc, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xa2, 0xa1, 0xf5, 0xe5,
+ 0xe9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xa2, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xfe, 0xde, 0xef,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xde, 0xeb, 0xde, 0xde, 0xa1, 0xf5, 0xde, 0xe9, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xde, 0xf2, 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xed, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb1, 0xf3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xec, 0xbc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xc4, 0xf6, 0xa1, 0xf5, 0xa1, 0xf5, 0xc0, 0xe2, 0xe8,
+ 0xe2, 0xe8, 0xc7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xe9, 0xa7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xb1, 0xb0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe8, 0xfb, 0xa1, 0xf5, 0xe9, 0xa3, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xec, 0xa5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xc8, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xa5, 0xc7,
+ 0xe8, 0xed, 0xb5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xed,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xcd, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xa5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xd0,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xd4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xcc, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xec, 0xcd, 0xa1, 0xf5, 0xcd, 0xe9, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xf8, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe2, 0xa9, 0xe2, 0xae, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xfd, 0xe7, 0xfe,
+ 0xe7, 0xfc, 0xa1, 0xf5, 0xa1, 0xf5, 0xe8, 0xa2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe5, 0xb8, 0xa1, 0xf5, 0xee, 0xb4, 0xf0, 0xf0, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf0, 0xed, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xee, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xfb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xef, 0xf3,
+ 0xa1, 0xf5, 0xed, 0xcc, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xcb, 0xa1, 0xf5, 0xed,
+ 0xd2, 0xc8, 0xb7, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xba, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xef, 0xfc, 0xa1, 0xf5, 0xef,
+ 0xfb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xb5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xdc, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3,
+ 0xd8, 0xf3, 0xda, 0xf4, 0xd2, 0xf4, 0xd1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xac, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xcf, 0xdb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc0, 0xb0, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xaa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xba, 0xca, 0xdd, 0xcf, 0xa1, 0xf5, 0xdd, 0xd2,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xc0, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xbd,
+ 0xdd, 0xc3, 0xdd, 0xbe, 0xdd, 0xbf, 0xa1, 0xf5, 0xdd, 0xd5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xdd, 0xc5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xcc, 0xa1, 0xf5,
+ 0xdd, 0xc8, 0xdd, 0xc9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb9,
+ 0xbd, 0xa1, 0xf5, 0xdd, 0xd0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf2, 0xd5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xcb, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf2, 0xd6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1,
+ 0xcb, 0xf1, 0xca, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xcc, 0xa1, 0xf5,
+ 0xea, 0xe8, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xfd, 0xa1, 0xf5, 0xda, 0xaa, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xaf, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xda, 0xb1, 0xee, 0xba, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xdc, 0xa1, 0xf5, 0xea, 0xdb,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xf2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xc5, 0xa1, 0xf5, 0xf5, 0xca, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xc6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9,
+ 0xf7, 0xe9, 0xf2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xf4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe5, 0xd5, 0xa1, 0xf5, 0xe5, 0xd6, 0xdb, 0xa9, 0xa1, 0xf5, 0xdb, 0xb2,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xa2, 0xf4, 0xfe, 0xa1, 0xf5,
+ 0xf5, 0xa1, 0xa1, 0xf5, 0xee, 0xd5, 0xa1, 0xf5, 0xee, 0xd8, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xee, 0xd1, 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xd9, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xd7, 0xee, 0xd6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xe3, 0xca, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xf1, 0xda, 0xed, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xfc, 0xa1, 0xf5, 0xe2, 0xc0, 0xa1,
+ 0xf5, 0xed, 0xe9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xcf, 0xc9, 0xd8, 0xf1, 0xa1, 0xf5, 0xd9,
+ 0xcd, 0xa1, 0xf5, 0xa1, 0xf5, 0xd9, 0xd1, 0xa1, 0xf5, 0xa1, 0xf5, 0xd9, 0xdd,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe0, 0xc9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xe0, 0xc3, 0xa1, 0xf5, 0xe0, 0xc1, 0xe0, 0xc4, 0xdf, 0xef, 0xa1, 0xf5, 0xe0,
+ 0xaa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe0, 0xb2, 0xa1, 0xf5,
+ 0xe0, 0xc7, 0xe0, 0xca, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xdb, 0xf7, 0xdb, 0xee, 0xeb, 0xf3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdc, 0xaa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xba, 0xf8, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xc1, 0xa1, 0xf5,
+ 0xe6, 0xca, 0xa1, 0xf5, 0xeb, 0xf4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xd3, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xe1, 0xcd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdb, 0xcf, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xb0, 0xa1, 0xf5, 0xe1, 0xe6, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xe3, 0xbb, 0xe3, 0xba, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xad, 0xea, 0xae, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xb4, 0xa4, 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xf7, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xf8, 0xde, 0xf9, 0xa1, 0xf5, 0xa1, 0xf5, 0xde,
+ 0xf4, 0xa1, 0xf5, 0xcc, 0xcd, 0xa1, 0xf5, 0xa1, 0xf5, 0xce, 0xe6, 0xb4, 0xb7,
+ 0xa1, 0xf5, 0xde, 0xf5, 0xa1, 0xf5, 0xde, 0xf6, 0xa1, 0xf5, 0xde, 0xfa, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xd2, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe9, 0xb8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xa8,
+ 0xb4, 0xbb, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xa9, 0xe9, 0xab, 0xe9, 0xa5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xb4, 0xaa, 0xa1, 0xf5, 0xe9, 0xa2, 0xe9, 0xb1, 0xe9, 0xb2, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xd8, 0xd2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xa7,
+ 0xa1, 0xf5, 0xec, 0xa6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xea, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xa8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xe7, 0xa1, 0xf5, 0xe4, 0xe9, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xe4, 0xda, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xe1,
+ 0xb3, 0xfc, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xe3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe4, 0xe6, 0xe4, 0xd1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xbf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xdc, 0xe4, 0xec, 0xd2, 0xec, 0xd4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xf9, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xf8, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd5, 0xe8, 0xe7, 0xe2,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe8, 0xa5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xb3,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xb5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf0, 0xf1, 0xa1, 0xf5, 0xf0, 0xe2, 0xf0, 0xf3, 0xb1, 0xd4,
+ 0xa1, 0xf5, 0xf0, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf0, 0xaa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xfd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xd6, 0xed, 0xd5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xd8, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc2, 0xe3, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb0,
+ 0xde, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb2,
+ 0xdf, 0xa1, 0xf5, 0xf3, 0xe2, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xe3, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xd3, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe7, 0xb0, 0xe7, 0xae, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xaf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xee, 0xbb, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xc7, 0xf4, 0xc8, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xd6, 0xfa, 0xa1, 0xf5, 0xeb, 0xed, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xee,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb,
+ 0xf2, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xe1, 0xa1, 0xf5, 0xf4, 0xba, 0xf4, 0xb9,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd,
+ 0xe3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xd7, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xd8, 0xdd,
+ 0xd9, 0xa1, 0xf5, 0xdd, 0xda, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xdd, 0xa1, 0xf5, 0xdd, 0xdf, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xb1, 0xe2, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xa6, 0xd2,
+ 0xa9, 0xa1, 0xf5, 0xdd, 0xe5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xcc,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xd9, 0xa1, 0xf5, 0xf2, 0xdd, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf2, 0xdc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf1, 0xce, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xa1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf5, 0xfe, 0xb4, 0xa5, 0xa1, 0xf5, 0xda, 0xb2, 0xda, 0xb4, 0xda,
+ 0xbc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xb3, 0xda, 0xb7, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb5, 0xc7, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xf7, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xf4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf4, 0xf3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf5, 0xcd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xd0, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xbc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xfb, 0xe9, 0xfa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe5, 0xd9, 0xa1, 0xf5, 0xe5, 0xd7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd4, 0xc7, 0xda, 0xf9, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xcd, 0xaa, 0xf5, 0xa5, 0xee, 0xe8, 0xa1, 0xf5, 0xee, 0xe6, 0xee, 0xda,
+ 0xee, 0xdb, 0xee, 0xdd, 0xa1, 0xf5, 0xee, 0xe1, 0xef, 0xa5, 0xee, 0xea, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xee, 0xe3, 0xee, 0xe2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xda, 0xf3, 0xf6, 0xc2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xbd, 0xf9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xfe, 0xa1,
+ 0xf5, 0xf1, 0xfd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xd9, 0xec, 0xa1, 0xf5, 0xf6, 0xbc, 0xd9, 0xd6, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xd9, 0xc7, 0xc0, 0xfc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xd9, 0xd5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xd8, 0xe4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe0,
+ 0xd7, 0xa1, 0xf5, 0xe0, 0xd1, 0xa1, 0xf5, 0xa1, 0xf5, 0xd8, 0xc5, 0xdf, 0xe9,
+ 0xe0, 0xd2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xdc, 0xad, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xdc, 0xac, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc9,
+ 0xca, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xd1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xc6, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xe6, 0xcb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe5, 0xef, 0xe1, 0xd6,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xd0, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe0, 0xfd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xdb, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xda, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xa8, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xa5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xe2, 0xe6, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xaf, 0xea, 0xa8,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xde,
+ 0xd2, 0xa1, 0xf5, 0xbf, 0xd9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xc1, 0xcc, 0xde, 0xfb, 0xde, 0xe8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xa1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xc1, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe9, 0xb6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xbc, 0xe9, 0xc7, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe8, 0xe7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xc0, 0xa1,
+ 0xf5, 0xe9, 0xc3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe8, 0xbf,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xf8, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xe6,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdc, 0xfe, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xb0, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe4, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc5, 0xbd, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xf1, 0xa1, 0xf5,
+ 0xe4, 0xef, 0xa1, 0xf5, 0xe4, 0xdd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4,
+ 0xd3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd1, 0xac, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xec, 0xc1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xb4, 0xf4, 0xe2, 0xb0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xf8, 0xf0,
+ 0xfd, 0xa1, 0xf5, 0xf0, 0xfa, 0xa1, 0xf5, 0xf1, 0xe4, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xb3, 0xf2, 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xa6, 0xa1, 0xf5, 0xd8, 0xba, 0xa1,
+ 0xf5, 0xed, 0xda, 0xa1, 0xf5, 0xb2, 0xea, 0xed, 0xb8, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xdc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xec, 0xf9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb1, 0xe2, 0xa1, 0xf5, 0xf1, 0xbf, 0xa1, 0xf5,
+ 0xf1, 0xbe, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xed, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3,
+ 0xe4, 0xa1, 0xf5, 0xb9, 0xbf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xeb,
+ 0xa1, 0xf5, 0xd4, 0xfd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf4, 0xd4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xb9,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe7,
+ 0xb5, 0xa1, 0xf5, 0xe7, 0xb3, 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xb8, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xeb, 0xf4, 0xec, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xe3, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe0, 0xbc, 0xeb, 0xf0, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xf5, 0xa1, 0xf5, 0xdd, 0xf2,
+ 0xa1, 0xf5, 0xdd, 0xf0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xdd, 0xf3, 0xdd, 0xf4, 0xdd, 0xe8, 0xdd, 0xe9, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xdd, 0xea, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd,
+ 0xaa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd8, 0xe1, 0xa1, 0xf5,
+ 0xb1, 0xcd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf2, 0xde, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xe2, 0xf2, 0xe0, 0xc0,
+ 0xaf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xe4,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd1,
+ 0xd1, 0xa1, 0xf5, 0xf2, 0xe7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xe3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf1, 0xd1, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xd5, 0xa1, 0xf5, 0xf1, 0xd3,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xd6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea,
+ 0xea, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xa2, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xc0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xea, 0xe4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xd4,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xd5, 0xd3, 0xbb, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf5, 0xbd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdb, 0xb5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdb,
+ 0xb3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf5, 0xa8, 0xf5, 0xaa, 0xa1, 0xf5, 0xd2, 0xbf, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xee, 0xef, 0xee, 0xee, 0xa1, 0xf5, 0xee, 0xf0, 0xa1, 0xf5,
+ 0xee, 0xf7, 0xef, 0xa2, 0xef, 0xa4, 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xfe, 0xef,
+ 0xa8, 0xee, 0xf1, 0xf6, 0xc6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xfb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xa9, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xba, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xd9, 0xd3, 0xd9, 0xd8, 0xa1, 0xf5, 0xa1, 0xf5, 0xd9, 0xd9,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd8, 0xdb, 0xdb, 0xbd, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe0, 0xe1, 0xdf, 0xd8, 0xb6, 0xf1, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe0, 0xd9, 0xd1, 0xb0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe0, 0xdc, 0xa1, 0xf5, 0xdf, 0xbc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xd7, 0xe1, 0xc0,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xbd, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xdc, 0xa1, 0xf5, 0xe2, 0xd0, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xb1, 0xef, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3,
+ 0xb4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xfe, 0xa1, 0xf5, 0xbe, 0xef, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb5, 0xa7, 0xde, 0xd8,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xcb, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc1, 0xac, 0xa1, 0xf5, 0xe9, 0xc8,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9,
+ 0xce, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe8, 0xfd, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe9, 0xcc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xa7, 0xa1, 0xf5, 0xf2, 0xa3, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xc0, 0xd4, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xf8, 0xe4, 0xf7, 0xe4,
+ 0xf9, 0xe4, 0xea, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xb3, 0xce, 0xa1, 0xf5, 0xe4, 0xfb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4,
+ 0xb6, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xe4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xda, 0xa1, 0xf5, 0xa1, 0xf5, 0xec,
+ 0xd8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xd7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9,
+ 0xe1, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xb2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe8, 0xaf, 0xe7, 0xf6, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe8, 0xae, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xfb, 0xf0, 0xf9, 0xf0, 0xfe, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xa1, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xa4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xed, 0xdd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xdf, 0xec, 0xfa, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xa1,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xc1, 0xa1, 0xf5, 0xf3, 0xe6, 0xa1, 0xf5, 0xf3,
+ 0xe8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xdb,
+ 0xf4, 0xda, 0xf4, 0xd8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe7, 0xbd, 0xe7, 0xc5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xc1, 0xe7, 0xc2,
+ 0xe7, 0xc3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4,
+ 0xca, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xe5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xf9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc6, 0xcc, 0xf4, 0xbc, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xa2, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xfd,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc4, 0xe8, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xdd, 0xf8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xa4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdc, 0xea,
+ 0xdd, 0xe4, 0xa1, 0xf5, 0xa1, 0xf5, 0xdc, 0xe0, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd,
+ 0xfb, 0xdc, 0xca, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xbd, 0xa1, 0xf5, 0xf2, 0xf6, 0xf2, 0xf8, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xd0, 0xab, 0xce, 0xb8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf2, 0xf3, 0xa1, 0xf5, 0xf2, 0xfa, 0xa1, 0xf5, 0xf2, 0xef, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xd8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xc1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xda,
+ 0xc2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xc5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd6, 0xdc, 0xa1, 0xf5,
+ 0xea, 0xe3, 0xa1, 0xf5, 0xea, 0xe6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf5, 0xdb, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xda, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5,
+ 0xd6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xdb, 0xb7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb5, 0xa6, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf5, 0xac, 0xd5, 0xb5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xef, 0xb6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xee, 0xf2, 0xef, 0xab, 0xef, 0xb7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xef, 0xb2, 0xee, 0xfa, 0xef, 0xaf, 0xa1, 0xf5, 0xef, 0xb0, 0xa1, 0xf5, 0xf6,
+ 0xc8, 0xa1, 0xf5, 0xef, 0xb8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xcf, 0xe3, 0xcd, 0xa1, 0xf5, 0xd1, 0xd6,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xac, 0xa1, 0xf5, 0xf6,
+ 0xa6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf2, 0xa4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xc4, 0xb2, 0xb8, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6,
+ 0xe0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xe6, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xd8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf7, 0xc9, 0xd0, 0xd0, 0xf6, 0xd0, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xe0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xb1, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xd8, 0xbe, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdf, 0xd5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xdf, 0xdc, 0xa1, 0xf5, 0xa1, 0xf5, 0xdf, 0xe0, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe0, 0xf7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdb, 0xd4, 0xa1, 0xf5, 0xe6, 0xd3, 0xe6, 0xcd,
+ 0xa1, 0xf5, 0xe6, 0xc8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xd4, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe1, 0xbb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xde, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xdd, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xe1, 0xe8, 0xed, 0xad, 0xba, 0xa9, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xf8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xdf, 0xa8, 0xa1, 0xf5, 0xdf, 0xa7, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xd5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe9, 0xd0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xd3, 0xa1,
+ 0xf5, 0xe9, 0xd8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe9, 0xd2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xec, 0xe9,
+ 0xe9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xab, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc2,
+ 0xba, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe4, 0xab, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe5, 0xa1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xec, 0xc7, 0xa1, 0xf5, 0xec, 0xdc, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xb3,
+ 0xa1, 0xf5, 0xe1, 0xfd, 0xe1, 0xf6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf1, 0xa6, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xac, 0xf1, 0xa2, 0xf1, 0xa9, 0xa1,
+ 0xf5, 0xf1, 0xa7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xab, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xd7,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xc0, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xf4, 0xa1,
+ 0xf5, 0xf3, 0xf6, 0xf3, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xf8,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf4, 0xdc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe7, 0xc8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xc4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc5, 0xd5, 0xf1, 0xf0, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xec, 0xa2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc1, 0xcb, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xa1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdc,
+ 0xbf, 0xa1, 0xf5, 0xdc, 0xe9, 0xa1, 0xf5, 0xdd, 0xdb, 0xde, 0xa8, 0xdd, 0xa1,
+ 0xdd, 0xde, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xdc, 0xf1, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xb5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xdc, 0xbc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xa5,
+ 0xf2, 0xfb, 0xa1, 0xf5, 0xf3, 0xa2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xa3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf2, 0xcf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe5, 0xbd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd0,
+ 0xfa, 0xda, 0xbb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xca,
+ 0xda, 0xcc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xd2, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xde,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xe1, 0xf5, 0xe4, 0xd3, 0xe2, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdb, 0xa6, 0xa1, 0xf5, 0xf5, 0xad, 0xf5, 0xaf,
+ 0xf5, 0xae, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xef, 0xc3, 0xef, 0xc4, 0xef,
+ 0xba, 0xa1, 0xf5, 0xd5, 0xe0, 0xef, 0xaa, 0xa1, 0xf5, 0xef, 0xbc, 0xa1, 0xf5,
+ 0xef, 0xb9, 0xef, 0xbe, 0xee, 0xcd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xd5, 0xa1, 0xf5, 0xe3, 0xd0, 0xd1,
+ 0xcb, 0xa1, 0xf5, 0xe3, 0xd1, 0xe3, 0xd3, 0xa1, 0xf5, 0xe3, 0xd4, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7,
+ 0xb4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb2, 0xb5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7,
+ 0xdb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xd6, 0xf6, 0xd8, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xb6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf0, 0xb7, 0xf7, 0xe6, 0xa1, 0xf5, 0xf7, 0xe5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xfc, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xe0, 0xea, 0xdf, 0xe2, 0xa1, 0xf5, 0xe0, 0xe3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xd5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xe1, 0xda, 0xe0, 0xfc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xfb,
+ 0xa1, 0xf5, 0xb1, 0xf7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdf, 0xa9, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe9, 0xdd, 0xa1, 0xf5, 0xe8, 0xdf, 0xbc, 0xd6, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xbd, 0xe2, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xd5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xdb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xbd, 0xa9, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xed, 0xb4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xe5, 0xa8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xe1, 0xfd, 0xe2, 0xb4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xe8, 0xb4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xea, 0xb5, 0xa1, 0xf5, 0xea, 0xb4, 0xa1, 0xf5, 0xf1, 0xaa, 0xa1, 0xf5,
+ 0xf0, 0xf7, 0xf0, 0xef, 0xf0, 0xab, 0xa1, 0xf5, 0xee, 0xac, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xed, 0xcd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xe1, 0xed,
+ 0xe2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xfc, 0xa1, 0xf5, 0xf3, 0xe5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xfe, 0xf3, 0xd9, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xc0, 0xe9, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xdd, 0xe7, 0xca, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf4, 0xed, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xe3, 0xf4, 0xea, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf3, 0xc1, 0xa1, 0xf5, 0xee, 0xc0, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf1, 0xef, 0xeb, 0xfe, 0xa1, 0xf5, 0xeb, 0xfb, 0xeb, 0xfd, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc2, 0xa6, 0xf4, 0xbd, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xb2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xde, 0xae, 0xde, 0xaf, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xf7,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xaa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xcc, 0xea, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xdc, 0xf6, 0xde, 0xb6, 0xde, 0xb3, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xdd, 0xb2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xa4,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xa9, 0xa1, 0xf5, 0xf3, 0xaa, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xfc,
+ 0xd5, 0xdd, 0xf3, 0xb1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3,
+ 0xae, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xcd, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf1, 0xdf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xed, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xec, 0xb2, 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xd5, 0xa1, 0xf5,
+ 0xd6, 0xdf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe5,
+ 0xc0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xd6,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5,
+ 0xf9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf5, 0xc4, 0xe5, 0xbf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xc3, 0xd1, 0xf5, 0xb0, 0xc8, 0xa9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xef, 0xca, 0xa1,
+ 0xf5, 0xef, 0xc7, 0xd5, 0xeb, 0xd5, 0xa1, 0xa1, 0xf5, 0xef, 0xc8, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xcc, 0xa1, 0xf5, 0xf6,
+ 0xca, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xd6,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xf4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xba, 0xfd, 0xa1, 0xf5, 0xe2, 0xbc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xd9, 0xe5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xcc, 0xf6, 0xda, 0xa1, 0xf5, 0xf6, 0xdc, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf0, 0xb9, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xbb, 0xa1, 0xf5, 0xf0, 0xbc,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xed, 0xea, 0xf6, 0xbd, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xf7, 0xf6, 0xb3, 0xd9,
+ 0xdf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xc4, 0xf6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xa1, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xde, 0xf3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xdf, 0xa3, 0xa1, 0xf5, 0xe1, 0xa6, 0xa1, 0xf5, 0xea, 0xd6, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xec, 0xf2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xde, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xf3, 0xe3, 0xf8, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xde, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xb6, 0xf1, 0xb0, 0xf0, 0xdc,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xe4,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xa1,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xa3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xbb, 0xdd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xc0,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xf9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf4, 0xbe, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xdd, 0xa3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xb8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xb2, 0xa1, 0xf5, 0xf3, 0xb3, 0xf3, 0xa8, 0xa1,
+ 0xf5, 0xf6, 0xe0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xad, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf2, 0xb1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xc7, 0xfe, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xd0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xda, 0xa9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xc3, 0xa1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xa5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf5, 0xf8, 0xa1, 0xf5, 0xd8, 0xd3, 0xea, 0xde, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xc5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xd4, 0xe3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5,
+ 0xbf, 0xa1, 0xf5, 0xea, 0xa4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xda, 0xf7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5,
+ 0xb5, 0xf5, 0xb2, 0xef, 0xd8, 0xc1, 0xad, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xf8, 0xa1, 0xf5, 0xef, 0xcb, 0xa1, 0xf5, 0xef,
+ 0xd6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xf6, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xc4, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xb6, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe8, 0xb8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xbe,
+ 0xa1, 0xf5, 0xe6, 0xeb, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xec, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xe6, 0xed, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xc2, 0xa1, 0xf5,
+ 0xf7, 0xdc, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xd2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf6, 0xe9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xe1,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf0, 0xc3, 0xf0, 0xbe, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xc1, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xf0, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xd8, 0xc9, 0xa1, 0xf5, 0xa1, 0xf5, 0xdf, 0xbf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xdb, 0xe4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xdf, 0xab, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xc6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xe8, 0xdd, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xcd, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe9, 0xda, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xaa, 0xa1, 0xf5, 0xe3,
+ 0xf1, 0xe4, 0xeb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe5, 0xac,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xed, 0xe7, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xe6, 0xec, 0xf2, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xd8, 0xa1,
+ 0xf5, 0xe7, 0xd9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xbc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xaf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xde, 0xbc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd9, 0xf9, 0xf2, 0xc9, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xb2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3,
+ 0xb9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xcf, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xef, 0xa1,
+ 0xf5, 0xf6, 0xa3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xda, 0xda, 0xd7, 0xab, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb2,
+ 0xe4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xec, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xb3, 0xef, 0xde, 0xef, 0xe0, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xa5, 0xef, 0xea, 0xa1, 0xf5, 0xef, 0xd2, 0xa1,
+ 0xf5, 0xef, 0xa1, 0xa1, 0xf5, 0xf6, 0xcb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe8,
+ 0xb9, 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xaa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xca, 0xa1, 0xf5, 0xe2, 0xc9, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf7, 0xc4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf6, 0xec, 0xf6, 0xed, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xef, 0xa1,
+ 0xf5, 0xf6, 0xf2, 0xf6, 0xf3, 0xf6, 0xf6, 0xf6, 0xdf, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xee, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xb5, 0xf1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf0, 0xc7, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xb4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xed, 0xeb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe0,
+ 0xb7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xfc, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe8, 0xd0, 0xa1, 0xf5,
+ 0xe8, 0xc0, 0xe8, 0xd3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe5, 0xaf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe5, 0xae, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xa8,
+ 0xe8, 0xb7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xdb, 0xc7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xed, 0xe5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xd7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf1, 0xf7, 0xa1, 0xf5, 0xa1, 0xf5, 0xd0, 0xc6, 0xf4, 0xbf, 0xa1, 0xf5,
+ 0xdc, 0xd7, 0xde, 0xbd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdc,
+ 0xc2, 0xde, 0xad, 0xa1, 0xf5, 0xde, 0xbf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf2, 0xd3, 0xf2, 0xee, 0xa1, 0xf5, 0xf3, 0xb7, 0xf3, 0xb6, 0xa1, 0xf5, 0xf1,
+ 0xe0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xbb, 0xd9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xdb, 0xb9, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xb6, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xef, 0xa6, 0xef, 0xe6, 0xa1, 0xf5, 0xef, 0xe8, 0xa1, 0xf5,
+ 0xef, 0xe2, 0xa1, 0xf5, 0xa1, 0xf5, 0xc1, 0xcd, 0xef, 0xd0, 0xef, 0xeb, 0xa1,
+ 0xf5, 0xee, 0xfc, 0xa1, 0xf5, 0xef, 0xe4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xef, 0xa9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xdb, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf2, 0xa9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xcd, 0xc0, 0xa1, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xe3, 0xa1, 0xf5,
+ 0xe6, 0xf2, 0xe6, 0xf3, 0xe6, 0xef, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xf8, 0xca, 0xc7, 0xa1, 0xf5,
+ 0xf6, 0xfb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf6, 0xfc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf0, 0xc9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xca, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xcd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xf4, 0xa1, 0xf5, 0xf7, 0xf3,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xb6, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf6, 0xb5, 0xa1, 0xf5, 0xd9, 0xd0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xbf, 0xf9, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdf, 0xa5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xe9, 0xb7, 0xa1, 0xf5, 0xe3, 0xe3, 0xe4, 0xdc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xdf, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xb5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xc3, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf4, 0xcf, 0xe6, 0xfe, 0xa1, 0xf5, 0xe7, 0xd3, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xc0, 0xdb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xde, 0xbe, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xc0, 0xdd, 0xfc, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xba, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xc3, 0xef, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xe1,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xdb, 0xba, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xef, 0xee, 0xa1, 0xf5,
+ 0xbb, 0xb7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xcb, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xec, 0xad, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe6, 0xf5, 0xe6, 0xee, 0xe6, 0xf1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xe5, 0xf7, 0xa3, 0xf7,
+ 0xa5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xcf, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7,
+ 0xbd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xbc, 0xb9, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5,
+ 0xba, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xd9, 0xe6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xae,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd4,
+ 0xdc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xac, 0xc0, 0xec, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xa8, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf0, 0xa6, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xea, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xc2, 0xab, 0xd9, 0xe1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf4, 0xb5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xea, 0xeb, 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xd9, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xe9, 0xf5, 0xf0,
+ 0xf5, 0xd1, 0xf5, 0xc8, 0xf5, 0xf1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9,
+ 0xf6, 0xa1, 0xf5, 0xef, 0xd9, 0xa1, 0xf5, 0xef, 0xec, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xd3, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xf6, 0xa1, 0xf5, 0xe6, 0xe8, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe5, 0xf7,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xa8, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6,
+ 0xe4, 0xf7, 0xa6, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xe6, 0xa1, 0xf5, 0xf7, 0xa1,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xd2, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xba,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xe8,
+ 0xba, 0xcd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xdf, 0xac, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe8, 0xef, 0xe9,
+ 0xa1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xd3, 0xb8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xdd, 0xf1, 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xc2, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xc3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd1, 0xe7, 0xf6, 0xc5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xf1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc0, 0xb0, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xdf, 0xa1, 0xf5, 0xf7,
+ 0xae, 0xf6, 0xe0, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xd1, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xd3, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf0, 0xd6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf0, 0xd4, 0xf0, 0xd5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xc2, 0xf0,
+ 0xc2, 0xa1, 0xf5, 0xb7, 0xb2, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xfb, 0xa1, 0xf5, 0xa1, 0xf5, 0xec,
+ 0xb4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc4, 0xf6, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xe5, 0xb0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xfd, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xbd, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xc0, 0xbe, 0xf5, 0xf3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xce, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7,
+ 0xc6, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xaf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xd3, 0xae, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xba, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe0,
+ 0xec, 0xdf, 0xad, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3,
+ 0xd6, 0xa1, 0xf5, 0xf4, 0xd0, 0xa1, 0xf5, 0xe7, 0xda, 0xf4, 0xee, 0xa1, 0xf5,
+ 0xd9, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf1, 0xe1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb4, 0xda,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xef, 0xe7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xc3, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xdd,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf6, 0xbe, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xbd, 0xf4, 0xf5, 0xf5,
+ 0xf2, 0xf5, 0xa7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xdd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf2, 0xa8, 0xc8, 0xa7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xe6, 0xf8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xb5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xed, 0xb0, 0xe8, 0xf9, 0xa1, 0xf5, 0xb1, 0xee, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xce, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf6, 0xe2, 0xf0, 0xbf, 0xe4, 0xd9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd0, 0xe2, 0xc0, 0xef, 0xa1, 0xf5,
+ 0xba, 0xe3, 0xd7, 0xb1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+};
+
+} // namespace FQTerm
diff --git a/src/utilities/fqterm_convert.h b/src/utilities/fqterm_convert.h
new file mode 100644
index 0000000..d7b226c
--- /dev/null
+++ b/src/utilities/fqterm_convert.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_CONVERT_H
+#define FQTERM_CONVERT_H
+
+namespace FQTerm {
+
+class FQTermConvert {
+ public:
+ FQTermConvert();
+ ~FQTermConvert();
+
+ char *G2B(const char *string, int length);
+ char *B2G(const char *string, int length);
+
+ private:
+ void g2b(unsigned char c1, unsigned char c2, char *s);
+ void b2g(unsigned char c1, unsigned char c2, char *s);
+
+ static unsigned char GtoB[];
+ static unsigned char BtoG[];
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_CONVERT_H
diff --git a/src/utilities/fqterm_http.cpp b/src/utilities/fqterm_http.cpp
new file mode 100644
index 0000000..57cde46
--- /dev/null
+++ b/src/utilities/fqterm_http.cpp
@@ -0,0 +1,264 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm.h"
+#include "fqterm_path.h"
+#include "fqterm_http.h"
+#include "fqterm_config.h"
+#include "fqterm_filedialog.h"
+
+namespace FQTerm {
+
+QMap<QString, int> FQTermHttp::downloadMap_;
+QMutex FQTermHttp::mutex_;
+
+FQTermHttp::FQTermHttp(FQTermConfig *config, QWidget *p, const QString &poolDir, int serverEncodingID)
+ : nam_(new QNetworkAccessManager), poolDir_(poolDir) {
+ // m_pDialog = NULL;
+ config_ = config;
+
+ serverEncodingID_ = serverEncodingID;
+
+ }
+
+FQTermHttp::~FQTermHttp() {
+}
+
+void FQTermHttp::cancel() {
+ if(netreply_){
+ netreply_->abort();
+ }
+ if (QFile::exists(cacheFileName_)) {
+ QFile::remove(cacheFileName_);
+ }
+
+ emit done(this);
+}
+
+
+
+void FQTermHttp::getLink(const QString &url, bool preview) {
+ QUrl u(url);
+ getLink(u,preview);
+}
+
+void FQTermHttp::getLink(const QUrl& url, bool preview) {
+ QUrl u=url;
+ isExisting_ = false;
+ isPreview_ = preview;
+ previewEmitted = false;
+ lastPercent_ = 0;
+ if (u.isRelative() || u.scheme() == "file") {
+ emit previewImage(cacheFileName_, false, true);
+ emit done(this);
+ return ;
+ }
+
+ if (QFile::exists(getPath(USER_CONFIG) + "hosts.cfg")) {
+ config_ = new FQTermConfig(getPath(USER_CONFIG) + "hosts.cfg");
+ QString strTmp = config_->getItemValue("hosts", u.host().toLocal8Bit());
+ if (!strTmp.isEmpty()) {
+ QString strUrl = u.toString();
+ strUrl.replace(QRegExp(u.host(), Qt::CaseInsensitive), strTmp);
+ u = strUrl;
+ }
+ }
+ if (!(netreply_ && netreply_->hasRawHeader("Location"))) {
+ cacheFileName_ = QFileInfo(u.path()).fileName();
+ }
+ if(netreply_){
+ netreply_->blockSignals(true);
+ netreply_.take()->deleteLater();
+ }
+
+ netreply_.reset(nam_->get(QNetworkRequest(u)));
+ FQ_VERIFY(connect(netreply_.data(), SIGNAL(finished()), this, SLOT(httpDone())));
+ FQ_VERIFY(connect(netreply_.data(), SIGNAL(downloadProgress(qint64, qint64)),this, SLOT(httpRead(qint64, qint64))));
+ FQ_VERIFY(connect(netreply_.data(), SIGNAL(error( QNetworkReply::NetworkError)), this, SLOT(httpError(QNetworkReply::NetworkError))));
+ FQ_VERIFY(connect(netreply_.data(), SIGNAL(metaDataChanged()), this, SLOT(httpResponse())));
+}
+
+void FQTermHttp::httpResponse() {
+ if (netreply_->hasRawHeader("Location")) {
+ //FIXME: according to RC, this code still could not work
+ //if the server send the relative location.
+ QString realLocation = netreply_->header(QNetworkRequest::LocationHeader).toString();
+ QUrl u = realLocation;
+ if (u.isRelative() ) {
+ u=netreply_->url().resolved(u);
+ }
+ cacheFileName_ = QFileInfo(u.path()).fileName(); // update filename
+ getLink(u,isPreview_);
+ return;
+ }
+
+ QString ValueString;
+ QString filename;
+
+ ValueString = netreply_->header(QNetworkRequest::ContentLengthHeader).toString();
+ int FileLength = ValueString.toInt();
+
+ ValueString = netreply_->rawHeader("Content-Disposition");
+ // ValueString = ValueString.mid(ValueString.find(';') + 1).stripWhiteSpace();
+ // if(ValueString.lower().find("filename") == 0)
+ // m_strHttpFile = ValueString.mid(ValueString.find('=') + 1).stripWhiteSpace();
+ if (ValueString.right(1) != ";") {
+ ValueString += ";";
+ }
+ QRegExp re("filename=.*;", Qt::CaseInsensitive);
+ re.setMinimal(true);
+ //Dont FIXME:this will also split filenames with ';' inside, does anyone really do this?
+ int pos = re.indexIn(ValueString);
+ if (pos != -1) {
+ cacheFileName_ = ValueString.mid(pos + 9, re.matchedLength() - 10);
+ }
+ //cacheFileName_ = encoding2unicode(cacheFileName_.toLatin1(), serverEncodingID_);
+ filename = cacheFileName_;
+
+ if (isPreview_) {
+ cacheFileName_ = poolDir_ + cacheFileName_;
+
+ QFileInfo fi(cacheFileName_);
+
+ int i = 1;
+ QFileInfo fi2 = fi;
+
+ mutex_.lock();
+ if (downloadMap_.find(cacheFileName_) == downloadMap_.end() && !fi2.exists()) {
+ downloadMap_[cacheFileName_] = FileLength;
+ }
+ while (fi2.exists()) {
+
+ QMap<QString, int>::iterator ii;
+ if ((ii = downloadMap_.find(cacheFileName_)) != downloadMap_.end()) {
+ if (ii.value() == FileLength) {
+ mutex_.unlock();
+ netreply_->abort();
+ isExisting_ = true;
+ emit headerReceived(this, filename);
+ emit done(this);
+ return;
+ }
+ }
+
+ if (fi2.size() == FileLength) {
+ mutex_.unlock();
+ isExisting_ = true;
+ emit headerReceived(this, filename);
+ netreply_->abort();
+ return;
+ } else {
+ cacheFileName_ = QString("%1/%2(%3).%4").arg(fi.path())
+ .arg(fi.completeBaseName()).arg(i).arg(fi.suffix());
+ fi2.setFile(cacheFileName_);
+ if (!fi2.exists()) {
+ downloadMap_[cacheFileName_] = FileLength;
+ break;
+ }
+
+ i++;
+ }
+ }
+ mutex_.unlock();
+
+ fi.setFile(cacheFileName_);
+
+ QString strExt = fi.suffix().toLower();
+ if (strExt == "jpg" || strExt == "jpeg" || strExt == "gif" || strExt == "mng"
+ || strExt == "png" || strExt == "bmp") {
+ isPreview_ = true;
+ } else {
+ isPreview_ = false;
+ }
+ } else {
+ //getSaveFileName(cacheFileName_, NULL, strSave);
+ mutex_.lock();
+
+ FQTermFileDialog fileDialog(config_);
+ QString strSave = fileDialog.getSaveName(cacheFileName_, "*");
+ mutex_.unlock();
+ // no filename specified which means the user canceled this download
+ if (strSave.isEmpty()) {
+ netreply_->abort();
+ emit done(this);
+ return ;
+ }
+ cacheFileName_ = strSave;
+ }
+
+ emit headerReceived(this, filename);
+}
+
+
+void FQTermHttp::httpRead(qint64 done, qint64 total) {
+ QByteArray ba = netreply_->readAll();
+ QFile file(cacheFileName_);
+ if (file.open(QIODevice::ReadWrite | QIODevice::Append)) {
+ QDataStream ds(&file);
+ ds.writeRawData(ba, ba.size());
+ file.close();
+ }
+ if (total != 0) {
+ //m_pDialog->setProgress(done,total);
+ int p = done *100 / total;
+ if (p - lastPercent_ >= 10 && isPreview_ && QFileInfo(cacheFileName_).suffix().toLower() == "jpg") {
+ if (!previewEmitted) {
+ emit previewImage(cacheFileName_,true, false);
+ previewEmitted = true;
+ } else {
+ emit previewImage(cacheFileName_,false, false);
+ }
+ lastPercent_ = p;
+ }
+ emit percent(p);
+ }
+}
+
+void FQTermHttp::httpDone() {
+ mutex_.lock();
+ downloadMap_.remove(cacheFileName_);
+ mutex_.unlock();
+ if (isPreview_) {
+ emit previewImage(cacheFileName_, true, true);
+ } else {
+ emit message("Download one file successfully");
+ }
+ emit done(this);
+}
+
+void FQTermHttp::httpError(QNetworkReply::NetworkError code) {
+ switch(code)
+ {
+ case QNetworkReply::OperationCanceledError:
+ break;
+ default:
+ QMessageBox::critical(NULL, tr("Download Error"), tr("Failed to download file\n code=%1").arg(code));
+ //deleteLater(); /*Not needed. http done will be called and this will cause a double free.
+ //return;
+ break;
+ }
+}
+
+void FQTermHttp::setProxy(const QNetworkProxy & proxy) {
+ nam_->setProxy(proxy);
+}
+} // namespace FQTerm
+
+#include "fqterm_http.moc"
diff --git a/src/utilities/fqterm_http.h b/src/utilities/fqterm_http.h
new file mode 100644
index 0000000..4c029d9
--- /dev/null
+++ b/src/utilities/fqterm_http.h
@@ -0,0 +1,83 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_HTTP_H
+#define FQTERM_HTTP_H
+
+#include <QObject>
+#include <QMutex>
+#include <QMap>
+#include <QScopedPointer>
+#include <QNetworkReply>
+
+class QNetworkProxy;
+class QNetworkAccessManager;
+
+namespace FQTerm {
+
+class FQTermConfig;
+class FQTermFileDialog;
+
+class FQTermHttp: public QObject {
+ Q_OBJECT;
+ public:
+ FQTermHttp(FQTermConfig *, QWidget*, const QString &poolDir, int serverEncodingID);
+ ~FQTermHttp();
+
+ void getLink(const QString &, bool);
+ void getLink(const QUrl &, bool);
+ void setProxy (const QNetworkProxy & proxy);
+ signals:
+ void done(QObject*);
+ void message(const QString &);
+ void percent(int);
+ void headerReceived(FQTermHttp *, const QString &filename);
+ void previewImage(const QString &filename, bool raiseViewer, bool done);
+
+ public slots:
+ void cancel();
+
+ protected slots:
+ void httpDone();
+ void httpRead(qint64, qint64);
+ void httpError(QNetworkReply::NetworkError);
+ void httpResponse();
+
+ protected:
+ QScopedPointer<QNetworkAccessManager> nam_;
+ QScopedPointer<QNetworkReply> netreply_;
+ QString cacheFileName_;
+ bool previewEmitted;
+ bool isPreview_;
+ bool isExisting_;
+ int lastPercent_;
+ int serverEncodingID_;
+
+ QString poolDir_;
+
+ static QMap<QString, int> downloadMap_;
+ static QMutex mutex_;
+
+ FQTermConfig *config_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_HTTP_H
diff --git a/src/utilities/fqterm_ip_location.cpp b/src/utilities/fqterm_ip_location.cpp
new file mode 100644
index 0000000..ea5946d
--- /dev/null
+++ b/src/utilities/fqterm_ip_location.cpp
@@ -0,0 +1,265 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QString>
+#include <QRegExp>
+#include <QDir>
+#include <QStringList>
+#include <ctype.h>
+
+#ifdef Q_OS_WIN32
+#include <winsock2.h>
+#else
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif
+
+#include "fqterm_trace.h"
+#include "fqterm_ip_location.h"
+#include "fqterm_path.h"
+#include "fqterm.h"
+
+namespace FQTerm {
+
+FQTermIPLocation* FQTermIPLocation::instance_ = NULL;
+
+FQTermIPLocation::FQTermIPLocation(const QString &pathLib) {
+ ipDatabase_ = new IPDatabase;
+ ipDatabase_->ipfp = NULL;
+
+ isFileExiting_ = true;
+
+ //case-insensitive match
+ QDir dir(pathLib);
+ QStringList files = dir.entryList(QStringList(
+ "[Qq][Qq][Ww][Rr][Yy].[Dd][Aa][Tt]"), QDir::Files);
+ if (!files.isEmpty()) {
+ if ((ipDatabase_->ipfp = fopen((pathLib + (files.at(0))).toLocal8Bit(), "rb")) == NULL) {
+ FQ_TRACE("iplocation", 0) << "Can't open ip database file!";
+ isFileExiting_ = false;
+ }
+ } else {
+ isFileExiting_ = false;
+ }
+
+}
+
+FQTermIPLocation::~FQTermIPLocation() {
+ if (ipDatabase_->ipfp != NULL) {
+ fclose(ipDatabase_->ipfp);
+ }
+ delete ipDatabase_;
+}
+
+uint32 FQTermIPLocation::byteArrayToInt(char *ip, int count) {
+ uint32 tmp, ret = 0L;
+ if (count < 1 || count > 4) {
+ FQ_TRACE("iplocation", 0) << "byteArrayToInt() error!";
+ return 0;
+ }
+ for (int i = 0; i < count; i++) {
+ tmp = ((uint32)ip[i]) &0x000000FF;
+ ret |= (tmp << (8 *i));
+ }
+ return ret;
+}
+
+void FQTermIPLocation::readFrom(FILE *fp, uint32 offset, char *buf, int len) {
+ if (fseek(fp, (long)offset, SEEK_SET) == -1) {
+ FQ_TRACE("iplocation", 0) << "readFrom() error 1";
+ memset(buf, 0, len);
+ return ;
+ }
+ if (fread(buf, sizeof(char), len, fp) == 0) {
+ FQ_TRACE("iplocation", 0) << "readFrom() error 2";
+ memset(buf, 0, len);
+ return ;
+ }
+ return ;
+}
+
+int FQTermIPLocation::readLineFrom(FILE *fp, uint32 offset, QByteArray &ret_str) {
+ char str[512];
+ if (fseek(fp, (long)offset, SEEK_SET) == -1) {
+ FQ_TRACE("iplocation", 0) << "readLineFrom error 1";
+ ret_str = QByteArray();
+ return -1;
+ }
+ if (fgets((char*)str, 512, fp) == NULL) {
+ FQ_TRACE("iplocation", 0) << "readLineFrom error 2";
+ ret_str = QByteArray();
+ return -1;
+ }
+ ret_str = QByteArray(str);
+ return (ret_str.length());
+}
+
+uint32 FQTermIPLocation::getString(FILE *fp, uint32 offset, uint32 lastoffset,
+ QByteArray &ret, unsigned int flag, int maxRecursiveDepth) {
+ if (maxRecursiveDepth <= 0)
+ return 0;
+ unsigned int fg;
+ if (fp == NULL) {
+ return 0;
+ }
+ char buf[3] = {0};
+ readFrom(fp, offset, buf, 1);
+ if (buf[0] == 0x01 || buf[0] == 0x02) {
+ fg = buf[0];
+ readFrom(fp, offset + 1, buf, 3);
+ return getString(fp, byteArrayToInt(buf, 3), offset, ret, fg, maxRecursiveDepth - 1);
+ } else {
+ readLineFrom(fp, offset, ret);
+ }
+ switch (flag) {
+ case 0x01:
+ return 0;
+ case 0x02:
+ return lastoffset + 4;
+ default:
+ return offset + ret.length() + 1;
+ }
+}
+
+
+void FQTermIPLocation::getCountryCity(FILE *fp, uint32 offset, QByteArray &country,
+ QByteArray &city) {
+ uint32 next_offset;
+ if (fp == NULL) {
+ return ;
+ }
+ next_offset = getString(fp, offset, 0L, country, 0);
+ if (next_offset == 0) {
+ city = "";
+ } else {
+ getString(fp, next_offset, 0L, city, 0);
+ }
+ return ;
+}
+
+void FQTermIPLocation::setIpRange(int rec_no, IPDatabase *f) {
+ uint32 offset;
+ if (f == NULL) {
+ return ;
+ }
+ char buf[7] = {0};
+ offset = f->offset_first_start_ip + rec_no * 7;
+ readFrom(f->ipfp, offset, buf, 7);
+ f->cur_start_ip = byteArrayToInt(buf, 4);
+ f->offset_cur_end_ip = byteArrayToInt(buf + 4, 3);
+
+ readFrom(f->ipfp, f->offset_cur_end_ip, buf, 4);
+ f->cur_end_ip = byteArrayToInt(buf, 4);
+
+}
+
+bool FQTermIPLocation::getLocation(QString &url, QString &country, QString &city)
+{
+ QByteArray gbCountry, gbCity;
+ bool result = getLocation(url, gbCountry, gbCity);
+ country = encoding2unicode(gbCountry, FQTERM_ENCODING_GBK);
+ city = encoding2unicode(gbCity, FQTERM_ENCODING_GBK);
+ return result;
+}
+
+bool FQTermIPLocation::getLocation(QString &url, QByteArray &country,
+ QByteArray &city) {
+ int rec, record_count, B, E;
+ uint32 ip;
+#ifdef Q_OS_WIN32
+ uint32 ipValue = inet_addr((const char*)url.toLatin1());
+#else
+ in_addr_t ipValue = inet_addr((const char*)url.toLatin1());
+#endif
+ if ((int)ipValue == -1) {
+ return false;
+ } else {
+ ip = ntohl(ipValue);
+ }
+
+ char buf[4] = {0};
+ readFrom(ipDatabase_->ipfp, 0L, (char*)buf, 4);
+ ipDatabase_->offset_first_start_ip = byteArrayToInt((char*)buf, 4);
+ readFrom(ipDatabase_->ipfp, 4L, (char*)buf, 4);
+ ipDatabase_->offset_last_start_ip = byteArrayToInt((char*)buf, 4);
+
+ record_count = (ipDatabase_->offset_last_start_ip - ipDatabase_->offset_first_start_ip) / 7;
+ if (record_count <= 1) {
+ return FALSE;
+ }
+
+ // search for right range
+ B = 0;
+ E = record_count;
+ while (B < E-1) {
+ rec = (B + E) / 2;
+ setIpRange(rec, ipDatabase_);
+ if (ip == ipDatabase_->cur_start_ip) {
+ B = rec;
+ break;
+ }
+ if (ip > ipDatabase_->cur_start_ip) {
+ B = rec;
+ } else {
+ E = rec;
+ }
+ }
+ setIpRange(B, ipDatabase_);
+
+ if (ipDatabase_->cur_start_ip <= ip && ip <= ipDatabase_->cur_end_ip) {
+ getCountryCity(ipDatabase_->ipfp, ipDatabase_->offset_cur_end_ip + 4, country, city);
+ //country.replace( country.find( "CZ88.NET", 0, FALSE ), 8, "" );
+ if ((rec = country.toUpper().indexOf("CZ88.NET", 0)) >= 0) {
+ country.replace(rec, 8, "********");
+ }
+ if ((rec = city.toUpper().indexOf("CZ88.NET", 0)) >= 0) {
+ city.replace(rec, 8, "********");
+ }
+
+ } else {
+ // not in this range... miss
+ country = "unkown";
+ city = "";
+ }
+ // if ip_start<=ip<=ip_end
+ return TRUE;
+}
+
+FQTermIPLocation* FQTermIPLocation::getInstance() {
+ if (instance_ == NULL) {
+ instance_ = new FQTermIPLocation(getPath(USER_CONFIG));
+ if (instance_->isFileExiting_ == NULL) {
+ delete instance_;
+ instance_ = new FQTermIPLocation(getPath(RESOURCE));
+ if (instance_->isFileExiting_ == NULL) {
+ delete instance_;
+ instance_ = NULL;
+ }
+ }
+ }
+ return instance_;
+}
+
+void FQTermIPLocation::Destroy() {
+ delete instance_;
+ instance_ = NULL;
+}
+
+} // namespace FQTerm
diff --git a/src/utilities/fqterm_ip_location.h b/src/utilities/fqterm_ip_location.h
new file mode 100644
index 0000000..55de36b
--- /dev/null
+++ b/src/utilities/fqterm_ip_location.h
@@ -0,0 +1,73 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_IPLOCATION_H
+#define FQTERM_IPLOCATION_H
+
+#include <stdio.h>
+#include <stdlib.h>
+
+class QString;
+
+namespace FQTerm {
+
+#define MAX_RECURSIVE_IP_DATA_DEPTH 100
+
+typedef unsigned long uint32;
+
+
+class FQTermIPLocation {
+public:
+ static FQTermIPLocation* getInstance();
+ static void Destroy();
+
+ bool getLocation(QString &url, QString &country, QString &city);
+ bool getLocation(QString &url, QByteArray &country, QByteArray &city);
+
+private:
+ struct IPDatabase {
+ uint32 offset_first_start_ip; // first abs offset of start ip
+ uint32 offset_last_start_ip; // last abs offset of start ip
+ uint32 cur_start_ip; // start ip of current search range
+ uint32 cur_end_ip; // end ip of current search range
+ uint32 offset_cur_end_ip; // where is the current end ip saved
+ FILE *ipfp; // IO Channel to read file
+ };
+
+ FQTermIPLocation(const QString &pathLib);
+ ~FQTermIPLocation();
+ uint32 byteArrayToInt(char *ip, int count);
+ void readFrom(FILE *fp, uint32 offset, char *buf, int len);
+ int readLineFrom(FILE *fp, uint32 offset, QByteArray &ret_str);
+ uint32 getString(FILE *fp, uint32 offset, uint32 lastoffset, QByteArray &str,
+ unsigned int flag, int maxRecursiveDepth = MAX_RECURSIVE_IP_DATA_DEPTH);
+ void getCountryCity(FILE *fp, uint32 offset, QByteArray &country, QByteArray &city);
+ void setIpRange(int rec_no, IPDatabase *f);
+
+
+ IPDatabase *ipDatabase_;
+ bool isFileExiting_;
+
+ static FQTermIPLocation* instance_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_IPLOCATION_H
diff --git a/src/utilities/fqwcwidth.cpp b/src/utilities/fqwcwidth.cpp
new file mode 100644
index 0000000..fc980e5
--- /dev/null
+++ b/src/utilities/fqwcwidth.cpp
@@ -0,0 +1,468 @@
+/*
+ * This is an implementation of wcwidth() and wcswidth() (defined in
+ * IEEE Std 1002.1-2001) for Unicode.
+ *
+ * http://www.opengroup.org/onlinepubs/007904975/functions/wcwidth.html
+ * http://www.opengroup.org/onlinepubs/007904975/functions/wcswidth.html
+ *
+ * In fixed-width output devices, Latin characters all occupy a single
+ * "cell" position of equal width, whereas ideographic CJK characters
+ * occupy two such cells. Interoperability between terminal-line
+ * applications and (teletype-style) character terminals using the
+ * UTF-8 encoding requires agreement on which character should advance
+ * the cursor by how many cell positions. No established formal
+ * standards exist at present on which Unicode character shall occupy
+ * how many cell positions on character terminals. These routines are
+ * a first attempt of defining such behavior based on simple rules
+ * applied to data provided by the Unicode Consortium.
+ *
+ * For some graphical characters, the Unicode standard explicitly
+ * defines a character-cell width via the definition of the East Asian
+ * FullWidth (F), Wide (W), Half-width (H), and Narrow (Na) classes.
+ * In all these cases, there is no ambiguity about which width a
+ * terminal shall use. For characters in the East Asian Ambiguous (A)
+ * class, the width choice depends purely on a preference of backward
+ * compatibility with either historic CJK or Western practice.
+ * Choosing single-width for these characters is easy to justify as
+ * the appropriate long-term solution, as the CJK practice of
+ * displaying these characters as double-width comes from historic
+ * implementation simplicity (8-bit encoded characters were displayed
+ * single-width and 16-bit ones double-width, even for Greek,
+ * Cyrillic, etc.) and not any typographic considerations.
+ *
+ * Much less clear is the choice of width for the Not East Asian
+ * (Neutral) class. Existing practice does not dictate a width for any
+ * of these characters. It would nevertheless make sense
+ * typographically to allocate two character cells to characters such
+ * as for instance EM SPACE or VOLUME INTEGRAL, which cannot be
+ * represented adequately with a single-width glyph. The following
+ * routines at present merely assign a single-cell width to all
+ * neutral characters, in the interest of simplicity. This is not
+ * entirely satisfactory and should be reconsidered before
+ * establishing a formal standard in this area. At the moment, the
+ * decision which Not East Asian (Neutral) characters should be
+ * represented by double-width glyphs cannot yet be answered by
+ * applying a simple rule from the Unicode database content. Setting
+ * up a proper standard for the behavior of UTF-8 character terminals
+ * will require a careful analysis not only of each Unicode character,
+ * but also of each presentation form, something the author of these
+ * routines has avoided to do so far.
+ *
+ * http://www.unicode.org/unicode/reports/tr11/
+ *
+ * Markus Kuhn -- 2007-05-26 (Unicode 5.0)
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * for any purpose and without fee is hereby granted. The author
+ * disclaims all warranties with regard to this software.
+ *
+ * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
+ */
+
+/*
+ * For wchar_t may be of 16 bits on some platforms, use uint32_t instead.
+ *
+ */
+
+#include "fqwcwidth.h"
+#include "fqterm_trace.h"
+
+namespace FQTerm {
+
+struct interval {
+ uint32_t first;
+ uint32_t last;
+};
+
+/* auxiliary function for binary search in interval table */
+static int bisearch(uint32_t ucs, const struct interval *table, int max) {
+ int min = 0;
+ int mid;
+
+ if (ucs < table[0].first || ucs > table[max].last)
+ return 0;
+ while (max >= min) {
+ mid = (min + max) / 2;
+ if (ucs > table[mid].last)
+ min = mid + 1;
+ else if (ucs < table[mid].first)
+ max = mid - 1;
+ else
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/* The following two functions define the column width of an ISO 10646
+ * character as follows:
+ *
+ * - The null character (U+0000) has a column width of 0.
+ *
+ * - Other C0/C1 control characters and DEL will lead to a return
+ * value of -1.
+ *
+ * - Non-spacing and enclosing combining characters (general
+ * category code Mn or Me in the Unicode database) have a
+ * column width of 0.
+ *
+ * - SOFT HYPHEN (U+00AD) has a column width of 1.
+ *
+ * - Other format characters (general category code Cf in the Unicode
+ * database) and ZERO WIDTH SPACE (U+200B) have a column width of 0.
+ *
+ * - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF)
+ * have a column width of 0.
+ *
+ * - Spacing characters in the East Asian Wide (W) or East Asian
+ * Full-width (F) category as defined in Unicode Technical
+ * Report #11 have a column width of 2.
+ *
+ * - All remaining characters (including all printable
+ * ISO 8859-1 and WGL4 characters, Unicode control characters,
+ * etc.) have a column width of 1.
+ *
+ * This implementation assumes that uint32_t characters are encoded
+ * in ISO 10646.
+ */
+
+int mk_wcwidth(uint32_t ucs)
+{
+ /* sorted list of non-overlapping intervals of non-spacing characters */
+ /* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */
+ static const struct interval combining[] = {
+ { 0x0300, 0x036F }, { 0x0483, 0x0486 }, { 0x0488, 0x0489 },
+ { 0x0591, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 },
+ { 0x05C4, 0x05C5 }, { 0x05C7, 0x05C7 }, { 0x0600, 0x0603 },
+ { 0x0610, 0x0615 }, { 0x064B, 0x065E }, { 0x0670, 0x0670 },
+ { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED },
+ { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A },
+ { 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, { 0x0901, 0x0902 },
+ { 0x093C, 0x093C }, { 0x0941, 0x0948 }, { 0x094D, 0x094D },
+ { 0x0951, 0x0954 }, { 0x0962, 0x0963 }, { 0x0981, 0x0981 },
+ { 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD },
+ { 0x09E2, 0x09E3 }, { 0x0A01, 0x0A02 }, { 0x0A3C, 0x0A3C },
+ { 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D },
+ { 0x0A70, 0x0A71 }, { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC },
+ { 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD },
+ { 0x0AE2, 0x0AE3 }, { 0x0B01, 0x0B01 }, { 0x0B3C, 0x0B3C },
+ { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, { 0x0B4D, 0x0B4D },
+ { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 },
+ { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 },
+ { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0CBC, 0x0CBC },
+ { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD },
+ { 0x0CE2, 0x0CE3 }, { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D },
+ { 0x0DCA, 0x0DCA }, { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 },
+ { 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E },
+ { 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC },
+ { 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 },
+ { 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E },
+ { 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 },
+ { 0x0F99, 0x0FBC }, { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 },
+ { 0x1032, 0x1032 }, { 0x1036, 0x1037 }, { 0x1039, 0x1039 },
+ { 0x1058, 0x1059 }, { 0x1160, 0x11FF }, { 0x135F, 0x135F },
+ { 0x1712, 0x1714 }, { 0x1732, 0x1734 }, { 0x1752, 0x1753 },
+ { 0x1772, 0x1773 }, { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD },
+ { 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD },
+ { 0x180B, 0x180D }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 },
+ { 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B },
+ { 0x1A17, 0x1A18 }, { 0x1B00, 0x1B03 }, { 0x1B34, 0x1B34 },
+ { 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, { 0x1B42, 0x1B42 },
+ { 0x1B6B, 0x1B73 }, { 0x1DC0, 0x1DCA }, { 0x1DFE, 0x1DFF },
+ { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2063 },
+ { 0x206A, 0x206F }, { 0x20D0, 0x20EF }, { 0x302A, 0x302F },
+ { 0x3099, 0x309A }, { 0xA806, 0xA806 }, { 0xA80B, 0xA80B },
+ { 0xA825, 0xA826 }, { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F },
+ { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB },
+ { 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F },
+ { 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 },
+ { 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD },
+ { 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F },
+ { 0xE0100, 0xE01EF }
+ };
+
+ /* test for 8-bit control characters */
+ if (ucs == 0)
+ return 0;
+ if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))
+ return -1;
+
+ /* binary search in table of non-spacing characters */
+ if (bisearch(ucs, combining,
+ sizeof(combining) / sizeof(struct interval) - 1))
+ return 0;
+
+ /* if we arrive here, ucs is not a combining or C0/C1 control character */
+
+ return 1 +
+ (ucs >= 0x1100 &&
+ (ucs <= 0x115f || /* Hangul Jamo init. consonants */
+ ucs == 0x2329 || ucs == 0x232a ||
+ (ucs >= 0x2e80 && ucs <= 0xa4cf &&
+ ucs != 0x303f) || /* CJK ... Yi */
+ (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */
+ (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */
+ (ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */
+ (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */
+ (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */
+ (ucs >= 0xffe0 && ucs <= 0xffe6) ||
+ (ucs >= 0x20000 && ucs <= 0x2fffd) ||
+ (ucs >= 0x30000 && ucs <= 0x3fffd)));
+}
+
+
+int mk_wcswidth(const uint32_t *pwcs, size_t n)
+{
+ int w, width = 0;
+
+ for (;*pwcs && n-- > 0; pwcs++)
+ if ((w = mk_wcwidth(*pwcs)) < 0)
+ return -1;
+ else
+ width += w;
+
+ return width;
+}
+
+
+int mk_wcswidth(const UTF16 *utf16_str, size_t n)
+{
+ int w, width = 0;
+
+ // FIXME: only BMP is supported here.
+ for (;*utf16_str && n-- > 0; utf16_str++)
+ if ((w = mk_wcwidth(*utf16_str)) < 0)
+ return -1;
+ else
+ width += w;
+
+ return width;
+}
+
+int mk_wcswidth(const UTF16 *utf16_str, size_t n, int max_width, int &element_consumed) {
+ const UTF16 *org = utf16_str;
+ int w, width = 0;
+
+ // FIXME: only BMP is supported here.
+ for (;*utf16_str && n-- > 0 && width < max_width; utf16_str++)
+ if ((w = mk_wcwidth(*utf16_str)) < 0)
+ return -1;
+ else
+ width += w;
+
+ FQ_VERIFY(width <= max_width);
+
+ element_consumed = utf16_str - org;
+
+ return width;
+}
+
+int mk_advance_one_code_point(const UTF16 **p, const UTF16 *end) {
+ FQ_ASSERT(*p < end);
+
+ // TODO_UTF16: FIXME: only support BMP here.
+ *p = *p + 1;
+ return get_str_width(**p);
+}
+
+int mk_advace_at_least_one_cell(const UTF16 **p, const UTF16 *end) {
+ FQ_ASSERT(*p < end);
+
+ // TODO_UTF16: FIXME: only support BMP here.
+ int w = 0;
+ int width = 0;
+ do {
+ w = get_str_width(**p);
+ width += w;
+ *p = *p + 1;
+ } while (w == 0 && *p < end);
+
+ if (w < 0) {
+ return -1;
+ }
+
+ while (*p < end && get_str_width(**p) == 0) {
+ *p = *p + 1;
+ }
+
+ return width;
+}
+
+/*
+ * The following functions are the same as mk_wcwidth() and
+ * mk_wcswidth(), except that spacing characters in the East Asian
+ * Ambiguous (A) category as defined in Unicode Technical Report #11
+ * have a column width of 2. This variant might be useful for users of
+ * CJK legacy encodings who want to migrate to UCS without changing
+ * the traditional terminal character-width behaviour. It is not
+ * otherwise recommended for general use.
+ */
+int mk_wcwidth_cjk(uint32_t ucs)
+{
+ /* sorted list of non-overlapping intervals of East Asian Ambiguous
+ * characters, generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" */
+ static const struct interval ambiguous[] = {
+ { 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 },
+ { 0x00AA, 0x00AA }, { 0x00AE, 0x00AE }, { 0x00B0, 0x00B4 },
+ { 0x00B6, 0x00BA }, { 0x00BC, 0x00BF }, { 0x00C6, 0x00C6 },
+ { 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00E1 },
+ { 0x00E6, 0x00E6 }, { 0x00E8, 0x00EA }, { 0x00EC, 0x00ED },
+ { 0x00F0, 0x00F0 }, { 0x00F2, 0x00F3 }, { 0x00F7, 0x00FA },
+ { 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 },
+ { 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B },
+ { 0x0126, 0x0127 }, { 0x012B, 0x012B }, { 0x0131, 0x0133 },
+ { 0x0138, 0x0138 }, { 0x013F, 0x0142 }, { 0x0144, 0x0144 },
+ { 0x0148, 0x014B }, { 0x014D, 0x014D }, { 0x0152, 0x0153 },
+ { 0x0166, 0x0167 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE },
+ { 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 },
+ { 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA },
+ { 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 },
+ { 0x02C4, 0x02C4 }, { 0x02C7, 0x02C7 }, { 0x02C9, 0x02CB },
+ { 0x02CD, 0x02CD }, { 0x02D0, 0x02D0 }, { 0x02D8, 0x02DB },
+ { 0x02DD, 0x02DD }, { 0x02DF, 0x02DF }, { 0x0391, 0x03A1 },
+ { 0x03A3, 0x03A9 }, { 0x03B1, 0x03C1 }, { 0x03C3, 0x03C9 },
+ { 0x0401, 0x0401 }, { 0x0410, 0x044F }, { 0x0451, 0x0451 },
+ { 0x2010, 0x2010 }, { 0x2013, 0x2016 }, { 0x2018, 0x2019 },
+ { 0x201C, 0x201D }, { 0x2020, 0x2022 }, { 0x2024, 0x2027 },
+ { 0x2030, 0x2030 }, { 0x2032, 0x2033 }, { 0x2035, 0x2035 },
+ { 0x203B, 0x203B }, { 0x203E, 0x203E }, { 0x2074, 0x2074 },
+ { 0x207F, 0x207F }, { 0x2081, 0x2084 }, { 0x20AC, 0x20AC },
+ { 0x2103, 0x2103 }, { 0x2105, 0x2105 }, { 0x2109, 0x2109 },
+ { 0x2113, 0x2113 }, { 0x2116, 0x2116 }, { 0x2121, 0x2122 },
+ { 0x2126, 0x2126 }, { 0x212B, 0x212B }, { 0x2153, 0x2154 },
+ { 0x215B, 0x215E }, { 0x2160, 0x216B }, { 0x2170, 0x2179 },
+ { 0x2190, 0x2199 }, { 0x21B8, 0x21B9 }, { 0x21D2, 0x21D2 },
+ { 0x21D4, 0x21D4 }, { 0x21E7, 0x21E7 }, { 0x2200, 0x2200 },
+ { 0x2202, 0x2203 }, { 0x2207, 0x2208 }, { 0x220B, 0x220B },
+ { 0x220F, 0x220F }, { 0x2211, 0x2211 }, { 0x2215, 0x2215 },
+ { 0x221A, 0x221A }, { 0x221D, 0x2220 }, { 0x2223, 0x2223 },
+ { 0x2225, 0x2225 }, { 0x2227, 0x222C }, { 0x222E, 0x222E },
+ { 0x2234, 0x2237 }, { 0x223C, 0x223D }, { 0x2248, 0x2248 },
+ { 0x224C, 0x224C }, { 0x2252, 0x2252 }, { 0x2260, 0x2261 },
+ { 0x2264, 0x2267 }, { 0x226A, 0x226B }, { 0x226E, 0x226F },
+ { 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 },
+ { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF },
+ { 0x2312, 0x2312 }, { 0x2460, 0x24E9 }, { 0x24EB, 0x254B },
+ { 0x2550, 0x2573 }, { 0x2580, 0x258F }, { 0x2592, 0x2595 },
+ { 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 },
+ { 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 },
+ { 0x25C6, 0x25C8 }, { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 },
+ { 0x25E2, 0x25E5 }, { 0x25EF, 0x25EF }, { 0x2605, 0x2606 },
+ { 0x2609, 0x2609 }, { 0x260E, 0x260F }, { 0x2614, 0x2615 },
+ { 0x261C, 0x261C }, { 0x261E, 0x261E }, { 0x2640, 0x2640 },
+ { 0x2642, 0x2642 }, { 0x2660, 0x2661 }, { 0x2663, 0x2665 },
+ { 0x2667, 0x266A }, { 0x266C, 0x266D }, { 0x266F, 0x266F },
+ { 0x273D, 0x273D }, { 0x2776, 0x277F }, { 0xE000, 0xF8FF },
+ { 0xFFFD, 0xFFFD }, { 0xF0000, 0xFFFFD }, { 0x100000, 0x10FFFD }
+ };
+
+ /* binary search in table of non-spacing characters */
+ if (bisearch(ucs, ambiguous,
+ sizeof(ambiguous) / sizeof(struct interval) - 1))
+ return 2;
+
+ return mk_wcwidth(ucs);
+}
+
+
+int mk_wcswidth_cjk(const uint32_t *pwcs, size_t n)
+{
+ int w, width = 0;
+
+ for (;*pwcs && n-- > 0; pwcs++)
+ if ((w = mk_wcwidth_cjk(*pwcs)) < 0)
+ return -1;
+ else
+ width += w;
+
+ return width;
+}
+
+int mk_wcswidth_cjk(const UTF16 *utf16_str, size_t n)
+{
+ int w, width = 0;
+
+ // FIXME: only BMP is supported here.
+ for (;*utf16_str && n-- > 0; utf16_str++) {
+ if ((w = mk_wcwidth_cjk(*utf16_str)) < 0)
+ return -1;
+ else
+ width += w;
+ }
+
+ return width;
+}
+
+int mk_wcswidth_cjk(const UTF16 *utf16_str, size_t n, int max_width, int &element_consumed) {
+ const UTF16 *org = utf16_str;
+ int w, width = 0;
+
+ // FIXME: only BMP is supported here.
+ for (;*utf16_str && n-- > 0 && width < max_width; utf16_str++) {
+ const UTF16 *bak_str = utf16_str;
+ int bak_width = width;
+
+ if ((w = mk_wcwidth_cjk(*utf16_str)) < 0) {
+ return -1;
+ } else {
+ width += w;
+ }
+
+ if (width > max_width) {
+ utf16_str = bak_str;
+ width = bak_width;
+ if (utf16_str == org) {
+ return -1;
+ } else {
+ break;
+ }
+ }
+ }
+
+ element_consumed = utf16_str - org;
+ return width;
+}
+
+
+#define USE_CJK_WIDTH
+
+
+// TODO_UTF16: if we don't use CJK width, we will get wrong text layout.
+#ifdef USE_CJK_WIDTH
+
+int get_str_width(uint32_t ucs) {
+ return mk_wcwidth_cjk(ucs);
+}
+
+int get_str_width(const uint32_t *pwcs, size_t n) {
+ return mk_wcswidth_cjk(pwcs, n);
+}
+
+int get_str_width(const UTF16 *utf16_str, size_t n) {
+ return mk_wcswidth_cjk(utf16_str, n);
+}
+
+int get_str_width(const UTF16 *utf16_str, size_t n, int max_width, int &element_consumed) {
+ return mk_wcswidth_cjk(utf16_str, n, max_width, element_consumed);
+}
+
+#else
+
+int get_str_width(uint32_t ucs) {
+ return mk_wcwidth(ucs);
+}
+int get_str_width(const uint32_t *pwcs, size_t n) {
+ return mk_wcswidth(pwcs, n);
+}
+int get_str_width(const UTF16 *utf16_str, size_t n) {
+ return mk_wcswidth(utf16_str, n);
+}
+
+int get_str_width(const UTF16 *utf16_str, size_t n, int max_width, int &element_consumed) {
+ return mk_wcswidth(utf16_str, n, max_width, element_consumed);
+}
+
+#endif
+
+} // namespace FQTerm
diff --git a/src/utilities/fqwcwidth.h b/src/utilities/fqwcwidth.h
new file mode 100644
index 0000000..b2007bc
--- /dev/null
+++ b/src/utilities/fqwcwidth.h
@@ -0,0 +1,60 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_FQWCWIDTH_H
+#define FQTERM_FQWCWIDTH_H
+
+#ifdef WIN32
+#define uint32_t unsigned __int32
+#define uint16_t unsigned __int16
+typedef wchar_t UTF16;
+#else // WIN32
+#include <stdio.h>
+#include <stdint.h>
+typedef uint16_t UTF16;
+#endif // WIN32
+
+typedef char Verify_UTF16_Is_Two_Bytes[
+ (sizeof(UTF16) == 2)? 1 : -1];
+
+namespace FQTerm {
+
+//const uint16_t URC = 0xfffd; // the Unicode Replacement Character
+// TODO_UTF16: 0xfffd is of width 2, which is not desired.
+const uint16_t URC = '?'; // use '?' instead of the Unicode Replacement Character
+
+const int MAX_CELLS_PER_CHAR = 2;
+
+int get_str_width(uint32_t ucs);
+int get_str_width(const uint32_t *pwcs, size_t n);
+int get_str_width(const UTF16 *utf16_str, size_t n);
+int get_str_width(const UTF16 *utf16_str, size_t n, int max_width, int &element_consumed);
+
+// Move p to next code point in max_n UTF16 characters.
+// Return the width of the current code point.
+int mk_advance_one_code_point(const UTF16 **p, const UTF16 *end);
+
+// Move p to next code point in max_n UTF16 characters.
+// Return the width.
+int mk_advace_at_least_one_cell(const UTF16 **p, const UTF16 *end);
+
+} // namespace FQTerm
+
+#endif // FQTERM_FQWCWIDTH_H