Merge branch 'master' of https://vcs.maemo.org/git/qwerkisync
authorJamie Thompson <coding@jamie-thompson.co.uk>
Fri, 26 Aug 2011 13:11:29 +0000 (14:11 +0100)
committerJamie Thompson <coding@jamie-thompson.co.uk>
Fri, 26 Aug 2011 13:11:29 +0000 (14:11 +0100)
46 files changed:
.gitignore
DBBackends/AllBackends.cpp [new file with mode: 0644]
DBBackends/AllBackends.h
DBBackends/DBBackends.cpp [deleted file]
DBBackends/Fmms.cpp
DBBackends/Fmms.h
DBBackends/RtcomEventLogger.cpp
DBBackends/RtcomEventLogger.h
DBBackends/RtcomEventLoggerComponents/TriggerDisabler.cpp [new file with mode: 0644]
DBBackends/RtcomEventLoggerComponents/TriggerDisabler.h [new file with mode: 0644]
DBBackends/iDBBackend.h
EventLogReindexer.cpp [deleted file]
EventLogReindexer.h [deleted file]
EventParsers/CSVSymbianEventLogParser.cpp
EventParsers/CSVSymbianEventLogParser.h
EventParsers/Factory.cpp
EventParsers/MMSParser.cpp
EventParsers/VMGEntities/Factory.h
EventParsers/VMGEntities/SMSEntity.cpp
EventParsers/VMGEntities/SMSEntity.h
EventParsers/VMGEntities/VBody.cpp
EventParsers/VMGEntities/VBody.h
EventParsers/VMGEntities/VCalendar.cpp
EventParsers/VMGEntities/VCalendar.h
EventParsers/VMGEntities/VCard.cpp
EventParsers/VMGEntities/VCard.h
EventParsers/VMGEntities/VEnvelope.cpp
EventParsers/VMGEntities/VEnvelope.h
EventParsers/VMGEntities/VMGFactory.cpp
EventParsers/VMGEntities/VMessage.cpp
EventParsers/VMGEntities/VMessage.h
EventParsers/VMGParser.cpp
EventProcessors/Hasher.cpp
EventTypes/EventFromFile.h
EventTypes/PhoneCall.cpp
EventTypes/PhoneCall.h
EventTypes/SMS.cpp
EventTypes/eEventTypes.h [new file with mode: 0644]
NumberToNameLookup.cpp
Settings.cpp
Settings.h
SyncerThread.cpp
Windows/TypesWindow.cpp
main.cpp
qwerkisync.pro
rcc/qrc_Resources1.cpp [deleted file]

index b90ef37..eabe074 100644 (file)
@@ -9,4 +9,6 @@
 /resources/Thumbs.db
 *.deb
 *.changes
-/debian
\ No newline at end of file
+/debian
+/rcc
+*-stamp
diff --git a/DBBackends/AllBackends.cpp b/DBBackends/AllBackends.cpp
new file mode 100644 (file)
index 0000000..1adc783
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2011, Jamie Thompson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "AllBackends.h"
+
+#include "Fmms.h"
+#include "RtcomEventLogger.h"
+
+#include <QList>
+#include <QSharedPointer>
+
+using namespace DBBackends;
+
+AllBackends::AllBackends(const Settings &settings) :
+       m_Settings(settings),
+       m_Backends(QList<QSharedPointer<iDBBackend> >()
+               << QSharedPointer<iDBBackend>(new RtcomEventLogger(CurrentSettings()))
+               << QSharedPointer<iDBBackend>(new Fmms(CurrentSettings())))
+{
+}
+
+void AllBackends::Process(EventProcessors::iEventProcessor &eventProcessor)
+{
+       foreach(QSharedPointer<iDBBackend> backend, Backends())
+               backend->Process(eventProcessor);
+}
+
+void AllBackends::PreInsert()
+{
+       foreach(QSharedPointer<iDBBackend> backend, Backends())
+               backend->PreInsert();
+}
+
+void AllBackends::Insert(EventTypes::iEvent &event, const NumberToNameLookup &numberToNameLookup)
+{
+       foreach(QSharedPointer<iDBBackend> backend, Backends())
+               backend->Insert(event, numberToNameLookup);
+}
+
+void AllBackends::PostInsert()
+{
+       foreach(QSharedPointer<iDBBackend> backend, Backends())
+               backend->PostInsert();
+}
index c9eb4ea..c455c38 100644 (file)
@@ -24,26 +24,30 @@ namespace EventTypes { class iEvent; }
 
 class NumberToNameLookup;
 class Settings;
-template <typename T1> class QList;
+#include <QList>
+template <typename T1> class QSharedPointer;
+
+#include "iDBBackend.h"
 
 namespace DBBackends
 {
-       class iDBBackend;
-
        class AllBackends
        {
        public:
                AllBackends(const Settings &settings);
 
-               const QList<iDBBackend *> & Backends() const;
                void Process(EventProcessors::iEventProcessor &eventProcessor);
+               void PreInsert();
                void Insert(EventTypes::iEvent &event, const NumberToNameLookup &numberToNameLookup);
+               void PostInsert();
 
        public:
                const Settings &CurrentSettings() const { return m_Settings; }
+               const QList<QSharedPointer<iDBBackend> > &Backends() const { return m_Backends; }
 
        private:
                const Settings &m_Settings;
+               const QList<QSharedPointer<iDBBackend> > m_Backends;
        };
 }
 
diff --git a/DBBackends/DBBackends.cpp b/DBBackends/DBBackends.cpp
deleted file mode 100644 (file)
index 05762d2..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2011, Jamie Thompson
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; If not, see
- * <http://www.gnu.org/licenses/>.
- */
-
-#include "AllBackends.h"
-
-#include "Fmms.h"
-#include "RtcomEventLogger.h"
-
-#include <QList>
-
-using namespace DBBackends;
-
-AllBackends::AllBackends(const Settings &settings) :
-       m_Settings(settings)
-{
-}
-
-const QList<iDBBackend *> & AllBackends::Backends() const
-{
-       const static QList<iDBBackend *> availableBackends(QList<iDBBackend *>()
-               << new RtcomEventLogger(CurrentSettings())
-               << new Fmms(CurrentSettings()));
-
-       return availableBackends;
-}
-
-void AllBackends::Process(EventProcessors::iEventProcessor &eventProcessor)
-{
-       foreach(iDBBackend *backend, Backends())
-               backend->Process(eventProcessor);
-}
-
-void AllBackends::Insert(EventTypes::iEvent &event, const NumberToNameLookup &numberToNameLookup)
-{
-       foreach(iDBBackend *backend, Backends())
-               backend->Insert(event, numberToNameLookup);
-}
index 38dbd4f..e2817fa 100644 (file)
@@ -40,7 +40,21 @@ EventTypes::iEvent *const Fmms::CreateEvent(int &fevent, QList<void *> &fattachm
        return 0;
 }
 
+void Fmms::PreInsert()
+{
+}
+
 void Fmms::Insert(EventTypes::iEvent &event, const NumberToNameLookup &numberToNameLookup)
 {
        return;
 }
+
+void Fmms::PostInsert()
+{
+}
+
+void Fmms::ClearInsertedIDs()
+{
+       InsertedIDs().clear();
+}
+
index 12c82e9..f92161b 100644 (file)
@@ -24,7 +24,7 @@
 namespace EventTypes { class iEvent; class FmmsEvent; }
 class Settings;
 
-template <typename T1> class QList;
+#include <QList>
 
 namespace DBBackends
 {
@@ -34,17 +34,28 @@ namespace DBBackends
                Fmms(const Settings &settings);
                Fmms(const Settings &settings, const EventTypes::FmmsEvent &event);
 
+               virtual void PreInsert();
                virtual void Insert(EventTypes::iEvent &event, const NumberToNameLookup &numberToNameLookup);
+               virtual void PostInsert();
                virtual void Process(EventProcessors::iEventProcessor &eventProcessor);
 
        protected:
                const Settings &CurrentSettings() const { return m_Settings; }
 
+       virtual const QList<int> &InsertedIDs() const { return m_InsertedIDs; }
+
+       public:
+               virtual void ClearInsertedIDs();
+
        protected:
                virtual EventTypes::iEvent *const CreateEvent(int &fevent, QList<void*> &fattachments);
 
        private:
+               QList<int> &InsertedIDs() { return m_InsertedIDs; }
+
+       private:
                const Settings &m_Settings;
+               QList<int> m_InsertedIDs;
        };
 }
 
index 2e1ee83..c34a8df 100644 (file)
 #include "RtcomEventLogger.h"
 
 #include "EventProcessors/iEventProcessor.h"
+#include "EventTypes/eEventTypes.h"
 #include "EventTypes/iEvent.h"
+#include "EventTypes/PhoneCall.h"
 #include "EventTypes/SMS.h"
+#include "RtcomEventLoggerComponents/TriggerDisabler.h"
 #include "Settings.h"
 
 #include <QDebug>
+#include <QMutex>
+#include <QWaitCondition>
+
+// For reindexing
+#include <QDir>
+#include <QPair>
+#include <QStringList>
+#include <QtSql/QSqlDatabase>
+#include <QtSql/QSqlQuery>
+#include <QVariant>
 
 #include <uuid/uuid.h>
 
 #include <rtcom-eventlogger/event.h>
 #include <rtcom-eventlogger/eventlogger.h>
 
+#include <stdexcept>
+
 using namespace DBBackends;
+using namespace EventTypes;
 
 QDebug operator<<(QDebug, RTComElEvent &);
 QDebug operator<<(QDebug, RTComElAttachment &);
@@ -44,15 +60,15 @@ RtcomEventLogger::RtcomEventLogger(const Settings &settings) :
        if(NULL != el)
        {
                // Grab the service IDs we want to work with
-               m_ServiceIDs.insert(SERVICE_ID_CALL, rtcom_el_get_service_id(el, "RTCOM_EL_SERVICE_CALL"));
-               m_ServiceIDs.insert(SERVICE_ID_CHAT, rtcom_el_get_service_id(el, "RTCOM_EL_SERVICE_CHAT"));
-               m_ServiceIDs.insert(SERVICE_ID_SMS, rtcom_el_get_service_id(el, "RTCOM_EL_SERVICE_SMS"));
-               m_ServiceIDs.insert(SERVICE_ID_MMS, rtcom_el_get_service_id(el, "RTCOM_EL_SERVICE_MMS"));
+               m_ServiceIDs.insert(EVENT_TYPE_CALL, rtcom_el_get_service_id(el, "RTCOM_EL_SERVICE_CALL"));
+               //m_ServiceIDs.insert(EVENT_TYPE_CHAT, rtcom_el_get_service_id(el, "RTCOM_EL_SERVICE_CHAT"));
+               m_ServiceIDs.insert(EVENT_TYPE_SMS, rtcom_el_get_service_id(el, "RTCOM_EL_SERVICE_SMS"));
+               //m_ServiceIDs.insert(EVENT_TYPE_MMS, rtcom_el_get_service_id(el, "RTCOM_EL_SERVICE_MMS"));
 
                // Remove any service IDs that weren't found
-               foreach(ServiceID serviceID, m_ServiceIDs.keys())
-                       if(m_ServiceIDs.value(serviceID) == -1)
-                               m_ServiceIDs.remove(serviceID);
+               foreach(EventTypes::eEventTypes service, m_ServiceIDs.keys())
+                       if(m_ServiceIDs.value(service) == -1)
+                               m_ServiceIDs.remove(service);
 
                g_object_unref(el);
        }
@@ -71,20 +87,35 @@ void RtcomEventLogger::Process(EventProcessors::iEventProcessor &processor)
        RTComEl *el = rtcom_el_new();
        if(NULL != el)
        {
+               foreach(eEventTypes service, m_ServiceIDs.keys())
+                       ProcessService(processor, service, *el);
+
+               g_object_unref(el);
+       }
+       else
+               qDebug() << "Failed to create event logger.";
+}
+
+void RtcomEventLogger::ProcessService(EventProcessors::iEventProcessor &processor, const EventTypes::eEventTypes service, const RTComEl &el)
+{
+       RTComEl *el_nonconst(const_cast<RTComEl *>(&el));
+
+       bool incoming = CurrentSettings().ShouldProcess( Settings::INCOMING, service);
+       bool outgoing = CurrentSettings().ShouldProcess( Settings::OUTGOING, service);
+
+       if(incoming || outgoing)
+       {
                // Initialise a query
-               RTComElQuery *query = rtcom_el_query_new(el);
+               RTComElQuery *query = rtcom_el_query_new(el_nonconst);
                if(query != NULL)
                {
-                       bool incoming = CurrentSettings().ShouldProcess( Settings::TYPE_RECIEVED, Settings::EVENTTYPE_SMS);
-                       bool outgoing = CurrentSettings().ShouldProcess( Settings::TYPE_SENT, Settings::EVENTTYPE_SMS);
-
                        // Prepare it...
                        bool prepared = false;
                        if(incoming && outgoing)
                        {
                                prepared = rtcom_el_query_prepare(query,
                                        "service-id",
-                                       m_ServiceIDs.value(SERVICE_ID_SMS),
+                                       m_ServiceIDs.value(service),
                                        RTCOM_EL_OP_EQUAL,
 
                                        NULL);
@@ -93,7 +124,7 @@ void RtcomEventLogger::Process(EventProcessors::iEventProcessor &processor)
                        {
                                prepared = rtcom_el_query_prepare(query,
                                        "service-id",
-                                       m_ServiceIDs.value(SERVICE_ID_SMS),
+                                       m_ServiceIDs.value(service),
                                        RTCOM_EL_OP_EQUAL,
 
                                        "outgoing",
@@ -107,7 +138,7 @@ void RtcomEventLogger::Process(EventProcessors::iEventProcessor &processor)
 
                        if(prepared)
                        {
-                               RTComElIter *it = rtcom_el_get_events(el, query);
+                               RTComElIter *it = rtcom_el_get_events(el_nonconst, query);
                                if(it != NULL)
                                {
                                        if(rtcom_el_iter_first(it))
@@ -120,7 +151,7 @@ void RtcomEventLogger::Process(EventProcessors::iEventProcessor &processor)
                                                // Reset the iterator and grab the actual values
                                                qDebug() << "Resetting iterator...";
                                                g_object_unref(it);
-                                               it = rtcom_el_get_events(el, query);
+                                               it = rtcom_el_get_events(el_nonconst, query);
                                                if(it != NULL)
                                                {
                                                        if(rtcom_el_iter_first(it))
@@ -135,26 +166,13 @@ void RtcomEventLogger::Process(EventProcessors::iEventProcessor &processor)
                                                                        RTComElEvent revent;
                                                                        memset(&revent, 0, sizeof(revent));
 
-                                                                       if(rtcom_el_iter_get_values (
-                                                                               it,
-                                                                               "id", &revent.fld_id,
-                                                                               "service-id", &revent.fld_service_id,
-                                                                               "start-time", &revent.fld_start_time,
-                                                                               "end-time", &revent.fld_end_time,
-                                                                               "local-uid", &revent.fld_local_uid,
-                                                                               "local-name", &revent.fld_local_name,
-                                                                               "remote-uid", &revent.fld_remote_uid,
-                                                                               "remote-name", &revent.fld_remote_name,
-                                                                               "is-read", &revent.fld_is_read,
-                                                                               "outgoing", &revent.fld_outgoing,
-                                                                               "free-text", &revent.fld_free_text,
-                                                                               NULL))
+                                                                       if(rtcom_el_iter_get_full(it, &revent))
                                                                        {
                                                                                qDebug() << revent;
 
                                                                                QList<RTComElAttachment *> rattachments;
                                                                                RTComElAttachIter *at_it = rtcom_el_iter_get_attachments(it);
-                                                                               if(it != NULL)
+                                                                               if(at_it != NULL)
                                                                                {
                                                                                        qDebug() << "Attachments OK";
                                                                                        if(rtcom_el_attach_iter_first(at_it))
@@ -200,37 +218,39 @@ void RtcomEventLogger::Process(EventProcessors::iEventProcessor &processor)
                }
                else
                        qDebug() << "Failed to create query.";
-
-               g_object_unref(el);
        }
        else
-               qDebug() << "Failed to create event logger.";
+               qDebug() << "Nothing to do for " << m_ServiceIDs.value(service);
 }
 
 EventTypes::iEvent *const RtcomEventLogger::CreateEvent(RTComElEvent &revent, QList<RTComElAttachment*> &rattachments)
 {
-       //if(m_ServiceIDs.contains(SERVICE_ID_CALL) && revent.fld_service_id == m_ServiceIDs.value(SERVICE_ID_CALL))
-       //      return new EventTypes::Call(CurrentSettings(), revent, rattachments);
+       if(m_ServiceIDs.contains(EVENT_TYPE_CALL) && revent.fld_service_id == m_ServiceIDs.value(EVENT_TYPE_CALL))
+               return new EventTypes::PhoneCall(CurrentSettings(), revent, rattachments);
 
-       //if(m_ServiceIDs.contains(SERVICE_ID_CHAT) && revent.fld_service_id == m_ServiceIDs.value(SERVICE_ID_CHAT))
+       //if(m_ServiceIDs.contains(EVENT_TYPE_CHAT) && revent.fld_service_id == m_ServiceIDs.value(EVENT_TYPE_CHAT))
        //      return new EventTypes::Chat(CurrentSettings(), revent, rattachments);
 
-       if(m_ServiceIDs.contains(SERVICE_ID_SMS) && revent.fld_service_id == m_ServiceIDs.value(SERVICE_ID_SMS))
+       if(m_ServiceIDs.contains(EVENT_TYPE_SMS) && revent.fld_service_id == m_ServiceIDs.value(EVENT_TYPE_SMS))
                return new EventTypes::SMS(CurrentSettings(), revent, rattachments);
 
-       //if(m_ServiceIDs.contains(SERVICE_ID_MMS) && revent.fld_service_id == m_ServiceIDs.value(SERVICE_ID_MMS))
+       //if(m_ServiceIDs.contains(EVENT_TYPE_MMS) && revent.fld_service_id == m_ServiceIDs.value(EVENT_TYPE_MMS))
        //      return new EventTypes::MMS(CurrentSettings(), revent, rattachments);
 
        return NULL;
 }
 
+void RtcomEventLogger::PreInsert()
+{
+       m_TriggerDisabler = new RtcomEventLoggerComponents::TriggerDisabler(CurrentSettings());
+}
+
 void RtcomEventLogger::Insert(EventTypes::iEvent &event, const NumberToNameLookup &numberToNameLookup)
 {
        if(EventTypes::RtcomEvent *rtcomEvent = dynamic_cast<EventTypes::RtcomEvent *>(&event))
        {
                const uint UUID_STR_LEN(36);
 
-               int newEventID(0);
                _RTComEl *el(rtcom_el_new());
                if(NULL != el)
                {
@@ -254,12 +274,41 @@ void RtcomEventLogger::Insert(EventTypes::iEvent &event, const NumberToNameLooku
                        qDebug() << *rattachments;
 
                        // Add the event
-                       newEventID = rtcom_el_add_event_full(el, revent, rheaders, rattachments, &error);
-                       qDebug() << "new id: " << newEventID;
-                       if(error != NULL)
+                       QDateTime startTime(QDateTime::currentDateTimeUtc());
+                       int newEventID(-1);
+                       int currentBackoffInMillisecs(5);
+                       while(((newEventID = rtcom_el_add_event_full(el, revent, rheaders, rattachments, &error)) == -1)
+                                 && startTime.msecsTo(QDateTime::currentDateTimeUtc()) < 10000)
+                       {
+                               if(error != NULL)
+                               {
+                                       qDebug() << "err: " << error->message;
+                                       g_error_free(error);
+                                       error = NULL;
+                               }
+
+                               // Don't hammer the DB when there's an error. Give it literally just a moment before retrying.
+                               QMutex mutex;
+                               mutex.lock();
+
+                               QWaitCondition waitCondition;
+                               waitCondition.wait(&mutex, currentBackoffInMillisecs);
+
+                               mutex.unlock();
+
+                               // Exponential backoff...
+                               currentBackoffInMillisecs *= 2;
+                       }
+
+                       if(-1 == newEventID)
+                       {
+                               qDebug() << "Unable to insert event due to error.";
+                               qDebug() << *revent << "\n";
+                       }
+                       else
                        {
-                               qDebug() << "err: " << error->message;
-                               g_error_free(error);
+                               qDebug() << "new id: " << newEventID;
+                               InsertedIDs().append(newEventID);
                        }
 
                        // Release the attachments
@@ -278,17 +327,231 @@ void RtcomEventLogger::Insert(EventTypes::iEvent &event, const NumberToNameLooku
        return;
 }
 
+void RtcomEventLogger::PostInsert()
+{
+       // Reorder the DB IDs as Nokia are guilty of both premature
+       // optimisation as well as closed source UIs...
+       Reindex();
+
+       delete m_TriggerDisabler;
+}
+
+void RtcomEventLogger::ClearInsertedIDs()
+{
+       InsertedIDs().clear();
+}
+
+// Reorder the DB IDs as Nokia are guilty of both premature
+// optimisation as well as closed source UIs...
+void RtcomEventLogger::Reindex()
+{
+       // Set up the database connection...
+       QSqlDatabase db(QSqlDatabase::addDatabase("QSQLITE"));
+
+       db.setDatabaseName(CurrentSettings().DBPath());
+       if(!db.open())
+       {
+               throw std::runtime_error("Cannot open database: Unable to establish database connection");
+       }
+       else
+       {
+               // Reorder the evnts by their start time
+               uint changesRequired(0);
+               do
+               {
+                       // Note the smallest event ID found, so we have a place to start.
+                       int min(0);
+
+                       // The required ID changes ( current, correct );
+                       QHash<int, int> mapping;
+
+                       // Grab the current records, and determine what changes need to
+                       // happen to get to the sorted results
+                       {
+                               qDebug() << "DB Opened";
+
+                               QSqlQuery * dbq1(new QSqlQuery( db )), * dbq2(new QSqlQuery( db ));
+
+                               dbq1->setForwardOnly( true );
+                               dbq2->setForwardOnly( true );
+
+                               QString s1("SELECT id, event_type_id, start_time, end_time "
+                                                  " FROM Events");
+                               QString s2("SELECT id, event_type_id, start_time, end_time "
+                                                  " FROM Events ORDER BY start_time ASC");
+
+                               if ( dbq1->exec( s1 ) && dbq2->exec( s2 ))
+                               {
+                                       qDebug() << "Query OK, " << dbq1->numRowsAffected() << " & " << dbq2->numRowsAffected() << " rows affected.";
+
+                                       while( dbq1->next() && dbq2->next())
+                                       {
+                                               int one (dbq1->value( 0 ).value< int >());
+                                               int two (dbq2->value( 0 ).value< int >());
+                                               //uint startTime( m_dbq->value( 1 ).value< uint >() );
+                                               //uint endTime( m_dbq->value( 2 ).value< uint >() );
+
+                                               //qDebug() << "Event: " << type << ", " << startTime << ", " << endTime << "";
+                                               //qDebug() << "( " << one << ", " << two << " )";
+
+                                               if(two != one)
+                                               {
+                                                       if(min == 0)
+                                                               min = one;
+
+                                                       //qDebug() << "( " << one << ", " << two << " )";
+                                                       mapping.insert(one, two);
+                                               }
+                                       }
+                               }
+                               else
+                               {
+                                       qDebug() << "SQL EXEC Error: "<< "EXEC query failed";
+                                       qDebug() << "Query1: " << s1;
+                                       qDebug() << "Query2: " << s1;
+                               }
+
+                               // Clear up database connections
+                               if ( dbq1 != NULL )
+                               {
+                                       qDebug() << "Cleaning up connection 1";
+
+                                       dbq1->finish();
+
+                                       delete dbq1;
+                                       dbq1 = NULL;
+                               }
+
+                               if ( dbq2 != NULL )
+                               {
+                                       qDebug() << "Cleaning up connection 2";
+
+                                       dbq2->finish();
+
+                                       delete dbq2;
+                                       dbq2 = NULL;
+                               }
+                       }
+
+                       QList<int> sequence;
+                       int val(min);
+                       sequence.append(0);
+                       sequence.append(val);
+                       //qDebug().nospace() << "val1: " << val << ", ";
+
+                       while((val = mapping[val]) && val != min)
+                       {
+                               sequence.append(val);
+                               //qDebug().nospace() << val << ", ";
+                       }
+                       sequence.append(0);
+
+                       //qDebug().nospace() << "seq: ";
+                       QList<QPair<int,int> > updates;
+                       int last(sequence.first());
+                       foreach(int seq, sequence)
+                       {
+                               if(seq != last)
+                               {
+                                       //qDebug().nospace() << seq << ", " << last << ", ";
+                                       updates.append(QPair<int,int>(seq, last));
+                               }
+
+                               last = seq;
+                       }
+
+                       // Used to keep iterating until no changes are required.
+                       // TODO: Shouldn't be required, but is. One to revisit later.
+                       changesRequired = updates.count();
+
+                       for( QList<QPair<int,int> >::const_iterator it(updates.constBegin()); it != updates.constEnd(); ++it)
+                       {
+                               //qDebug().nospace() << (*it).first << ", " << (*it).second;
+                       }
+
+                       QList<QString> tables = QList<QString>() << "Events" << "Attachments" << "Headers" << "GroupCache";
+                       QString query;
+                       for( QList<QString>::const_iterator currentTable(tables.constBegin()); currentTable != tables.constEnd(); ++currentTable)
+                       {
+                               QString curquery = "UPDATE %3 set %4 = %1 WHERE %4 = %2;";
+                               for( QList<QPair<int,int> >::const_iterator currentUpdate(updates.constBegin()); currentUpdate != updates.constEnd(); ++currentUpdate)
+                               {
+                                       query.append(
+                                               curquery
+                                                       .arg((*currentUpdate).second)
+                                                       .arg((*currentUpdate).first)
+                                                       .arg((*currentTable))
+                                                       .arg((*currentTable) == "Events" ? "id" : "event_id")
+                                               ).append("\n");
+
+                                       //qDebug().nospace() << (*it).first << ", " << (*it).second;
+                               }
+                       }
+
+                       //qDebug() << query;
+
+                       QSqlQuery * UpdateQuery(new QSqlQuery( db ));
+                       if(UpdateQuery != NULL)
+                       {
+                               UpdateQuery->setForwardOnly( true );
+
+                               if(db.transaction())
+                               {
+                                       QStringList statements = query.trimmed().split(";", QString::SkipEmptyParts);
+                                       try
+                                       {
+                                               for( QStringList::const_iterator currentStatement(statements.constBegin()); currentStatement != statements.constEnd(); ++currentStatement)
+                                               {
+                                                       if (!UpdateQuery->exec(*currentStatement))
+                                                       {
+                                                               qDebug() << "Query Failed: " << *currentStatement;
+                                                               throw std::exception();
+                                                       }
+                                               }
+
+                                               qDebug() << "Committing.";
+                                               db.commit();
+                                       }
+                                       catch(...)
+                                       {
+                                               qDebug() << "Rolling back.";
+                                               db.rollback();
+                                       }
+                               }
+                               else
+                                       qDebug() << "Unable to start transaction.";
+                       }
+               }while(changesRequired > 0);
+
+               qDebug() << "Closing.";
+               db.close();
+               QSqlDatabase::removeDatabase( "QSQLITE" );
+       }
+
+       return;
+}
+
 QDebug operator<<(QDebug dbg, RTComElEvent &event)
 {
        dbg.nospace() << "\tid:\t\t" << event.fld_id << "\n";
-       dbg.nospace() << "\tFolder:\t\t" << (event.fld_outgoing ? "Sent" : "Inbox") << "\n";
-       dbg.nospace() << "\tstart-time:\t" << QDateTime::fromTime_t(event.fld_start_time) << "\n";
-       dbg.nospace() << "\tend-time:\t\t" << QDateTime::fromTime_t(event.fld_end_time) << "\n";
-       //dbg.nospace() << "\tlocal-uid:\t" << event.fld_local_uid << "\n";
-       //dbg.nospace() << "\tlocal-name:\t" << event.fld_local_name << "\n";
+       dbg.nospace() << "\tservice_id:\t" << event.fld_service_id << "\n";
+       dbg.nospace() << "\tservice:\t" << event.fld_service << "\n";
+       dbg.nospace() << "\tevt_typ_id:\t" << event.fld_event_type_id << "\n";
+       dbg.nospace() << "\tevt_typ:\t" << event.fld_event_type << "\n";
+       dbg.nospace() << "\tstore-time:\t" << QDateTime::fromTime_t(event.fld_storage_time).toUTC() << "\n";
+       dbg.nospace() << "\tstart-time:\t" << QDateTime::fromTime_t(event.fld_start_time).toUTC() << "\n";
+       dbg.nospace() << "\tend-time:\t" << QDateTime::fromTime_t(event.fld_end_time).toUTC() << "\n";
+       dbg.nospace() << "\tis-read:\t" << (event.fld_is_read ? "true" : "false") << "\n";
+       dbg.nospace() << "\tdirection:\t" << (event.fld_outgoing ? "Outgoing" : "Incoming") << "\n";
+       dbg.nospace() << "\tflags:\t\t" << "0x" << QString::number(event.fld_flags, 16) << "\n";
+       dbg.nospace() << "\tbytes sent:\t" << event.fld_bytes_sent << "\n";
+       dbg.nospace() << "\tbytes recv:\t" << event.fld_bytes_received << "\n";
+       dbg.nospace() << "\tlocal-uid:\t" << event.fld_local_uid << "\n";
+       dbg.nospace() << "\tlocal-name:\t" << event.fld_local_name << "\n";
        dbg.nospace() << "\tremote-uid:\t" << event.fld_remote_uid << "\n";
        dbg.nospace() << "\tremote-name:\t" << event.fld_remote_name << "\n";
-       dbg.nospace() << "\tis-read:\t\t" << (event.fld_is_read ? "true" : "false") << "\n";
+       dbg.nospace() << "\tremote-ebid:\t" << event.fld_remote_ebook_uid << "\n";
+       dbg.nospace() << "\tchannel:\t\t" << event.fld_channel << "\n";
        dbg.nospace() << "\tfree-text:\t" << event.fld_free_text << "\n";
        dbg.nospace() << "\tgroup-uid:\t" << event.fld_group_uid << "\n";
 
index d99d4c4..d82814d 100644 (file)
 #define DBBACKENDS_RTCOMEVENTLOGGER_H
 
 #include "iDBBackend.h"
-
-class Settings;
+#include "Settings.h"
 
 class _RTComElAttachment;
 typedef _RTComElAttachment RTComElAttachment;
 class _RTComElEvent;
 typedef _RTComElEvent RTComElEvent;
+class _RTComEl;
+typedef _RTComEl RTComEl;
 
 template <typename T1> class QList;
+class QString;
 
 #include <QHash>
 
 namespace DBBackends
 {
+       namespace RtcomEventLoggerComponents { class TriggerDisabler; }
+
        class RtcomEventLogger : public iDBBackend
        {
        public:
                RtcomEventLogger(const Settings &settings);
                RtcomEventLogger(const Settings &settings, const EventTypes::RtcomEvent &event);
 
+               virtual void PreInsert();
                virtual void Insert(EventTypes::iEvent &event, const NumberToNameLookup &numberToNameLookup);
+               virtual void PostInsert();
                virtual void Process(EventProcessors::iEventProcessor &eventProcessor);
 
        protected:
@@ -48,20 +54,24 @@ namespace DBBackends
 
        protected:
                virtual EventTypes::iEvent *const CreateEvent(RTComElEvent &revent, QList<RTComElAttachment*> &rattachments);
+               void ProcessService(EventProcessors::iEventProcessor &processor, const EventTypes::eEventTypes service, const RTComEl &el);
+
+               virtual const QList<int> &InsertedIDs() const { return m_InsertedIDs; }
+
+       public:
+               virtual void ClearInsertedIDs();
 
        private:
+               void Reindex();
+
                const Settings &m_Settings;
 
-               enum ServiceID
-               {
-                       SERVICE_ID_CALL,
-                       SERVICE_ID_CHAT,
-                       SERVICE_ID_SMS,
-                       SERVICE_ID_MMS,
-                       SERVICE_ID_SIZE
-               };
+               QHash<EventTypes::eEventTypes, int> m_ServiceIDs;
+
+               QList<int> m_InsertedIDs;
+               QList<int> &InsertedIDs() { return m_InsertedIDs; }
 
-               QHash<ServiceID, int> m_ServiceIDs;
+               RtcomEventLoggerComponents::TriggerDisabler *m_TriggerDisabler;
        };
 }
 
diff --git a/DBBackends/RtcomEventLoggerComponents/TriggerDisabler.cpp b/DBBackends/RtcomEventLoggerComponents/TriggerDisabler.cpp
new file mode 100644 (file)
index 0000000..e7edc8e
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2011, Jamie Thompson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "TriggerDisabler.h"
+
+#include "Settings.h"
+
+#include <QtSql>
+
+#include <sqlite3.h>
+
+#include <stdexcept>
+
+static void _sqlite3ORStep(sqlite3_context *context, int numArgs, sqlite3_value **value);
+static void _sqlite3ORFinal(sqlite3_context *context);
+bool createSQLiteFunctions(const QSqlDatabase &db);
+
+using namespace DBBackends::RtcomEventLoggerComponents;
+
+TriggerDisabler::TriggerDisabler(const Settings &settings)
+       : m_Settings(settings), m_Reenabled(false)
+{
+       // Preserve default cache triggers
+       // Set up the database connection...
+       QSqlDatabase db(QSqlDatabase::addDatabase( "QSQLITE" ));
+
+       db.setDatabaseName(CurrentSettings().DBPath());
+       if ( ! db.open() )
+               throw std::runtime_error("Cannot open database: Unable to establish database connection");
+       else
+       {
+               qDebug() << "DB Opened";
+
+               QSqlQuery dbqGetTriggers(db);
+               dbqGetTriggers.setForwardOnly( true );
+
+               const char * sqlGetTriggers("SELECT name, sql FROM sqlite_master WHERE type = \"trigger\" AND name LIKE \"gc_update_ev_%\"");
+               if(dbqGetTriggers.exec(sqlGetTriggers))
+               {
+                       qDebug() << "Query OK, " << dbqGetTriggers.numRowsAffected() << " rows affected.";
+
+                       while( dbqGetTriggers.next())
+                       {
+                               QString name(dbqGetTriggers.value(0).value<QString>());
+                               QString sqlTrigger(dbqGetTriggers.value(1).value<QString>());
+
+                               qDebug() << "( " << name << ", " << sqlTrigger << " )";
+
+                               Triggers().insert(name, sqlTrigger);
+                       }
+
+                       qDebug() << Triggers().count() << " triggers found.";
+
+                       QSqlQuery dbqRemoveTriggers(db);
+                       dbqRemoveTriggers.setForwardOnly( true );
+
+                       const QString sqlRemoveTriggers("DROP TRIGGER ");
+                       foreach(QString triggerName, Triggers().keys())
+                       {
+                               qDebug() << "Executing: " << sqlRemoveTriggers + triggerName;
+                               if(dbqRemoveTriggers.exec(sqlRemoveTriggers + triggerName))
+                                       qDebug() << "Query OK, " << dbqGetTriggers.numRowsAffected() << " rows affected.";
+                               else
+                                       qDebug() << "Query failed, " << dbqGetTriggers.numRowsAffected() << " rows affected. Error: " << dbqRemoveTriggers.lastError().text();
+                       }
+               }
+               else
+               {
+                       qDebug() << "SQL EXEC Error: " << "EXEC query failed";
+                       qDebug() << "Query: " << sqlGetTriggers;
+               }
+
+               qDebug() << "Closing.";
+               db.close();
+       }
+
+       QSqlDatabase::removeDatabase("QSQLITE");
+
+       return;
+}
+
+TriggerDisabler::~TriggerDisabler()
+{
+       // Restore default cache triggers
+       if(!Reenabled())
+               Reenable();
+}
+
+void TriggerDisabler::Reenable()
+{
+       // Set up the database connection...
+       QSqlDatabase db(QSqlDatabase::addDatabase( "QSQLITE" ));
+
+       db.setDatabaseName(CurrentSettings().DBPath());
+       if (!db.open())
+               throw std::runtime_error("Cannot open database: Unable to establish database connection");
+       else
+       {
+               qDebug() << "DB Opened";
+
+               RestoreTriggers(db);
+
+               UpdateGroupCache(db);
+
+               qDebug() << "Closing DB.";
+               db.close();
+       }
+
+       QSqlDatabase::removeDatabase( "QSQLITE" );
+
+       Reenabled(true);
+}
+
+void TriggerDisabler::RestoreTriggers(QSqlDatabase &db)
+{
+       QSqlQuery dbqRestoreTriggers(db);
+       dbqRestoreTriggers.setForwardOnly( true );
+
+       foreach(QString triggerName, Triggers().keys())
+       {
+               qDebug() << "Restoring trigger " << triggerName;
+               qDebug() << "\tSQL: " << Triggers().value(triggerName);
+               if(dbqRestoreTriggers.exec(Triggers().value(triggerName)))
+                       qDebug() << "Query OK, " << dbqRestoreTriggers.numRowsAffected() << " rows affected.";
+               else
+                       qDebug() << "Query failed, " << dbqRestoreTriggers.numRowsAffected() << " rows affected. Error: " << dbqRestoreTriggers.lastError().text();
+       }
+}
+
+void TriggerDisabler::UpdateGroupCache(QSqlDatabase &db)
+{
+       const char * sqlUpdateGroupCache(
+               "INSERT OR REPLACE INTO groupcache "
+               "SELECT id, service_id, group_uid, total, readcount, mergedflags "
+               "FROM events e, "
+                       "(SELECT max(start_time) as maxdate, group_uid as maxgid, count(group_uid) as total, total(is_read) as readcount, _OR(flags) as mergedflags "
+                       "FROM events "
+                       "GROUP BY maxgid) maxresults "
+               "WHERE group_uid = maxgid AND start_time=maxresults.maxdate "
+               "GROUP BY group_uid");
+
+       QSqlQuery dbqRecalculateGroupCache(db);
+       dbqRecalculateGroupCache.setForwardOnly(true);
+
+       createSQLiteFunctions(db);
+
+       qDebug() << "Updating group cache...";
+       if(dbqRecalculateGroupCache.exec(sqlUpdateGroupCache))
+       {
+               qDebug() << "Query OK, " << dbqRecalculateGroupCache.numRowsAffected() << " rows affected.";
+
+               while(dbqRecalculateGroupCache.next())
+               {
+                       int id(dbqRecalculateGroupCache.value(0).value<int>());
+                       QString group_uid(dbqRecalculateGroupCache.value(1).value<QString>());
+                       int total(dbqRecalculateGroupCache.value(2).value<int>());
+                       int readcount(dbqRecalculateGroupCache.value(3).value<int>());
+                       int flags(dbqRecalculateGroupCache.value(4).value<int>());
+
+                       qDebug() << "( " << id << ", " << group_uid << ", " << total << ", " << readcount << ", " << flags << " )";
+               }
+       }
+       else
+       {
+               qDebug() << "SQL EXEC Error: " << "EXEC query failed. Error: " << dbqRecalculateGroupCache.lastError().text();
+               qDebug() << "Query: " << sqlUpdateGroupCache;
+       }
+}
+
+bool createSQLiteFunctions(const QSqlDatabase &db)
+{
+       // Get handle to the driver and check it is both valid and refers to SQLite3.
+       QVariant v(db.driver()->handle());
+       if (!v.isValid() || qstrcmp(v.typeName(), "sqlite3*") != 0)
+       {
+               qDebug() << "Cannot get a sqlite3 handle to the driver.";
+               return false;
+       }
+
+       // Create a handler and attach functions.
+       sqlite3 *handler(*static_cast<sqlite3**>(v.data()));
+       if (!handler)
+       {
+               qDebug() << "Cannot get a sqlite3 handler.";
+               return false;
+       }
+
+       // Check validity of the state.
+       if (!db.isValid())
+       {
+               qDebug() << "Cannot create SQLite custom functions: db object is not valid.";
+               return false;
+       }
+
+       if (!db.isOpen())
+       {
+               qDebug() << "Cannot create SQLite custom functions: db object is not open.";
+               return false;
+       }
+
+       if (sqlite3_create_function(handler, "_OR", 1, SQLITE_ANY, NULL, NULL, _sqlite3ORStep, _sqlite3ORFinal))
+               qDebug() << "Cannot create SQLite functions: sqlite3_create_function failed.";
+
+       return true;
+}
+
+static void _sqlite3ORStep(sqlite3_context *context, int, sqlite3_value **value)
+{
+       int *result((int *)sqlite3_aggregate_context(context, sizeof(int)));
+       *result |= sqlite3_value_int(*value);
+}
+
+static void _sqlite3ORFinal(sqlite3_context *context)
+{
+       sqlite3_result_int(context, *(int *)sqlite3_aggregate_context(context, sizeof(int)));
+}
diff --git a/DBBackends/RtcomEventLoggerComponents/TriggerDisabler.h b/DBBackends/RtcomEventLoggerComponents/TriggerDisabler.h
new file mode 100644 (file)
index 0000000..fe26af9
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2011, Jamie Thompson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DBBACKENDS_RTCOMEVENTLOGGERCOMPONENTS_TRIGGERDISABLER_H
+#define DBBACKENDS_RTCOMEVENTLOGGERCOMPONENTS_TRIGGERDISABLER_H
+
+class Settings;
+
+#include <QHash>
+class QSqlDatabase;
+#include <QString>
+
+namespace DBBackends
+{
+       namespace RtcomEventLoggerComponents
+       {
+               class TriggerDisabler
+               {
+               public:
+                       TriggerDisabler(const Settings &settings);
+                       ~TriggerDisabler();
+
+                       void Reenable();
+
+               protected:
+                       const Settings &CurrentSettings() const { return m_Settings; }
+
+                       const QHash<QString, QString> &Triggers() const { return m_Triggers; }
+
+                       const bool Reenabled() const { return m_Reenabled; }
+
+                       void RestoreTriggers(QSqlDatabase &db);
+                       void UpdateGroupCache(QSqlDatabase &db);
+
+               private:
+                       const Settings &m_Settings;
+
+                       QHash<QString, QString> &Triggers() { return m_Triggers; }
+                       QHash<QString, QString> m_Triggers;
+
+                       void Reenabled(bool reenabled) { m_Reenabled = reenabled; }
+                       bool m_Reenabled;
+               };
+       }
+}
+
+#endif // DBBACKENDS_RTCOMEVENTLOGGERCOMPONENTS_TRIGGERDISABLER_H
index 841bd94..88c1cc2 100644 (file)
@@ -23,15 +23,27 @@ namespace EventProcessors { class iEventProcessor; }
 namespace EventTypes { class RtcomEvent; class iEvent; }
 class NumberToNameLookup;
 
+template <typename T1> class QList;
+
 namespace DBBackends
 {
        class iDBBackend
        {
        public:
+               virtual ~iDBBackend() {}
+
+               virtual void PreInsert() =0;
                virtual void Insert(EventTypes::iEvent &event, const NumberToNameLookup &numberToNameLookup) =0;
+               virtual void PostInsert() =0;
+
+               virtual void ClearInsertedIDs() =0;
                //virtual uint Remove();
 
                virtual void Process(EventProcessors::iEventProcessor &eventProcessor) =0;
+
+       protected:
+               virtual const QList<int> &InsertedIDs() const =0;
+
        };
 }
 
diff --git a/EventLogReindexer.cpp b/EventLogReindexer.cpp
deleted file mode 100644 (file)
index a2978b3..0000000
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Copyright (C) 2011, Jamie Thompson
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; If not, see
- * <http://www.gnu.org/licenses/>.
- */
-
-#include <QDebug>
-#include <QDir>
-#include <QPair>
-#include <QStringList>
-#include <QtSql/QSqlDatabase>
-#include <QtSql/QSqlQuery>
-#include <QVariant>
-
-#include <stdexcept>
-
-#include "EventLogReindexer.h"
-
-#define DB_LOC "/.rtcom-eventlogger/el-v1.db"
-
-EventLogReindexer::EventLogReindexer()
-{
-}
-
-void EventLogReindexer::Reindex()
-{
-       // Set up the database connection...
-       QSqlDatabase db(QSqlDatabase::addDatabase( "QSQLITE" ));
-
-       db.setDatabaseName( QDir::homePath() + DB_LOC );
-       if ( ! db.open() )
-       {
-               throw std::runtime_error("Cannot open database: Unable to establish database connection");
-       }
-       else
-       {
-               // Reorder the evnts by their start time
-               uint changesRequired(0);
-               do
-               {
-                       // Note the smallest event ID found, so we have a place to start.
-                       int min(0);
-
-                       // The required ID changes ( current, correct );
-                       QHash<int, int> mapping;
-
-                       // Grab the current records, and determine what changes need to
-                       // happen to get to the sorted results
-                       {
-                               qDebug() << "DB Opened";
-
-                               QSqlQuery * dbq1(new QSqlQuery( db )), * dbq2(new QSqlQuery( db ));
-
-                               dbq1->setForwardOnly( true );
-                               dbq2->setForwardOnly( true );
-
-                               QString s1("SELECT id, event_type_id, start_time, end_time "
-                                                  " FROM Events");
-                               QString s2("SELECT id, event_type_id, start_time, end_time "
-                                                  " FROM Events ORDER BY start_time ASC");
-
-                               if ( dbq1->exec( s1 ) && dbq2->exec( s2 ))
-                               {
-                                       qDebug() << "Query OK, " << dbq1->numRowsAffected() << " & " << dbq2->numRowsAffected() << " rows affected.";
-
-                                       while( dbq1->next() && dbq2->next())
-                                       {
-                                               int one (dbq1->value( 0 ).value< int >());
-                                               int two (dbq2->value( 0 ).value< int >());
-                                               //uint startTime( m_dbq->value( 1 ).value< uint >() );
-                                               //uint endTime( m_dbq->value( 2 ).value< uint >() );
-
-                                               //qDebug() << "Event: " << type << ", " << startTime << ", " << endTime << "";
-                                               //qDebug() << "( " << one << ", " << two << " )";
-
-                                               if(two != one)
-                                               {
-                                                       if(min == 0)
-                                                               min = one;
-
-                                                       qDebug() << "( " << one << ", " << two << " )";
-                                                       mapping.insert(one, two);
-                                               }
-                                       }
-                               }
-                               else
-                               {
-                                       qDebug() << "SQL EXEC Error: "<< "EXEC query failed";
-                                       qDebug() << "Query1: " << s1;
-                                       qDebug() << "Query2: " << s1;
-                               }
-
-                               // Clear up database connections
-                               if ( dbq1 != NULL )
-                               {
-                                       qDebug() << "Cleaning up connection 1";
-
-                                       dbq1->finish();
-
-                                       delete dbq1;
-                                       dbq1 = NULL;
-                               }
-
-                               if ( dbq2 != NULL )
-                               {
-                                       qDebug() << "Cleaning up connection 2";
-
-                                       dbq2->finish();
-
-                                       delete dbq2;
-                                       dbq2 = NULL;
-                               }
-                       }
-
-                       QList<int> sequence;
-                       int val(min);
-                       sequence.append(0);
-                       sequence.append(val);
-                       qDebug().nospace() << "val1: " << val << ", ";
-
-                       while((val = mapping[val]) && val != min)
-                       {
-                               sequence.append(val);
-                               qDebug().nospace() << val << ", ";
-                       }
-                       sequence.append(0);
-
-                       qDebug().nospace() << "seq: ";
-                       QList<QPair<int,int> > updates;
-                       int last(sequence.first());
-                       foreach(int seq, sequence)
-                       {
-                               if(seq != last)
-                               {
-                                       qDebug().nospace() << seq << ", " << last << ", ";
-                                       updates.append(QPair<int,int>(seq, last));
-                               }
-
-                               last = seq;
-                       }
-
-                       // Used to keep iterating until no changes are required.
-                       // TODO: Shouldn't be required, but is. One to revisit later.
-                       changesRequired = updates.count();
-
-                       for( QList<QPair<int,int> >::const_iterator it(updates.constBegin()); it != updates.constEnd(); ++it)
-                       {
-                               //qDebug().nospace() << (*it).first << ", " << (*it).second;
-                       }
-
-                       QList<QString> tables = QList<QString>() << "Events" << "Attachments" << "Headers" << "GroupCache";
-                       QString query;
-                       for( QList<QString>::const_iterator currentTable(tables.constBegin()); currentTable != tables.constEnd(); ++currentTable)
-                       {
-                               QString curquery = "UPDATE %3 set %4 = %1 WHERE %4 = %2;";
-                               for( QList<QPair<int,int> >::const_iterator currentUpdate(updates.constBegin()); currentUpdate != updates.constEnd(); ++currentUpdate)
-                               {
-                                       query.append(
-                                               curquery
-                                                       .arg((*currentUpdate).second)
-                                                       .arg((*currentUpdate).first)
-                                                       .arg((*currentTable))
-                                                       .arg((*currentTable) == "Events" ? "id" : "event_id")
-                                               ).append("\n");
-
-                                       //qDebug().nospace() << (*it).first << ", " << (*it).second;
-                               }
-                       }
-
-                       qDebug() << query;
-
-                       QSqlQuery * UpdateQuery(new QSqlQuery( db ));
-                       if(UpdateQuery != NULL)
-                       {
-                               UpdateQuery->setForwardOnly( true );
-
-                               if(db.transaction())
-                               {
-                                       QStringList statements = query.trimmed().split(";", QString::SkipEmptyParts);
-                                       try
-                                       {
-                                               for( QStringList::const_iterator currentStatement(statements.constBegin()); currentStatement != statements.constEnd(); ++currentStatement)
-                                               {
-                                                       if ( UpdateQuery->exec( *currentStatement ))
-                                                               qDebug() << "Query OK, " << UpdateQuery->numRowsAffected() << " rows affected.";
-                                                       else
-                                                       {
-                                                               qDebug() << "Query Failed: " << *currentStatement;
-                                                               throw std::exception();
-                                                       }
-                                               }
-
-                                               qDebug() << "Committing.";
-                                               db.commit();
-                                       }
-                                       catch(...)
-                                       {
-                                               qDebug() << "Rolling back.";
-                                               db.rollback();
-                                       }
-                               }
-                               else
-                                       qDebug() << "Unable to start transaction.";
-                       }
-               }while(changesRequired > 0);
-
-               // Update the group cache so the last events are correct
-               {
-                       qDebug() << "Updating most recent events.";
-
-                       // Grab group UIDs from group cache
-                       QSqlQuery * dbq(new QSqlQuery( db ));
-                       dbq->setForwardOnly( true );
-
-                       const char * groupUIDListSQL("SELECT group_uid FROM GroupCache");
-                       if (dbq->exec(groupUIDListSQL))
-                       {
-                               qDebug() << "Query OK, " << dbq->numRowsAffected() << " rows affected.";
-                               qDebug() << "GroupUIDs:";
-
-                               QSet<QString> groupUIDs;
-                               while( dbq->next() )
-                               {
-                                       QString groupUID(dbq->value(0).value<QString>());
-
-                                       qDebug() << groupUID;
-                                       groupUIDs.insert(groupUID);
-                               }
-
-                               // Iterate over group UIDS
-                               if(groupUIDs.count() > 0)
-                               {
-                                       // Build a batch statement to update every group with
-                                       // the most recent event
-
-                                       // Ignore 'data' failures (i.e. no events but present in the
-                                       // cache)- something else's been monkeying with the DB, and
-                                       // we can't account for everything.
-                                       QString updateGroupCacheWithLatestEventsSQL(
-                                               "UPDATE OR IGNORE GroupCache SET event_id = "
-                                                       "(SELECT id FROM events WHERE group_uid = \"%1\" "
-                                                       " ORDER BY id DESC LIMIT 1)"
-                                               " WHERE group_uid = \"%1\";");
-                                       QString updateGroupCacheWithLatestEventsBatchSQL;
-                                       foreach(QString groupUID, groupUIDs)
-                                       {
-                                               updateGroupCacheWithLatestEventsBatchSQL.append(
-                                                       updateGroupCacheWithLatestEventsSQL
-                                                       .arg(groupUID)
-                                                       ).append("\n");
-                                       }
-
-                                       // Execute the statement in single-statement chunks thanks
-                                       // to QT's inability to call the SQLite function supporting
-                                       // multiple statements
-
-                                       QSqlQuery * setLatestEventInGroupCacheSQL(new QSqlQuery( db ));
-                                       if(NULL != setLatestEventInGroupCacheSQL)
-                                       {
-                                               setLatestEventInGroupCacheSQL->setForwardOnly( true );
-
-                                               if(db.transaction())
-                                               {
-                                                       QStringList statements = updateGroupCacheWithLatestEventsBatchSQL.trimmed().split(";", QString::SkipEmptyParts);
-                                                       try
-                                                       {
-                                                               for( QStringList::const_iterator currentStatement(statements.constBegin()); currentStatement != statements.constEnd(); ++currentStatement)
-                                                               {
-                                                                       if ( setLatestEventInGroupCacheSQL->exec( *currentStatement ))
-                                                                               qDebug() << "Query OK, " << setLatestEventInGroupCacheSQL->numRowsAffected() << " rows affected.";
-                                                                       else
-                                                                       {
-                                                                               qDebug() << "Query Failed: " << *currentStatement;
-                                                                               throw std::exception();
-                                                                       }
-                                                               }
-
-                                                               qDebug() << "Committing.";
-                                                               db.commit();
-                                                       }
-                                                       catch(...)
-                                                       {
-                                                               qDebug() << "Rolling back.";
-                                                               db.rollback();
-                                                       }
-                                               }
-                                               else
-                                                       qDebug() << "Unable to start transaction.";
-                                       }
-                               }
-                       }
-                       else
-                       {
-                               qDebug() << "SQL EXEC Error: "<< "EXEC query failed";
-                               qDebug() << "Query: " << groupUIDListSQL;
-                       }
-               }
-
-               qDebug() << "Closing.";
-               db.close();
-               QSqlDatabase::removeDatabase( "QSQLITE" );
-       }
-
-       return;
-}
diff --git a/EventLogReindexer.h b/EventLogReindexer.h
deleted file mode 100644 (file)
index 18db01b..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2011, Jamie Thompson
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; If not, see
- * <http://www.gnu.org/licenses/>.
- */
-
-#ifndef EVENTLOGREINDEXER_H
-#define EVENTLOGREINDEXER_H
-
-class EventLogReindexer
-{
-public:
-       EventLogReindexer();
-
-       void Reindex();
-};
-
-#endif // EVENTLOGREINDEXER_H
index 8d38ffe..43142f1 100644 (file)
@@ -17,6 +17,8 @@
  */
 
 #include "CSVSymbianEventLogParser.h"
+#include "EventTypes/PhoneCall.h"
+#include "Settings.h"
 
 #include <QDebug>
 
 #include <QString>
 #include <QStringList>
 
+#include <stdexcept>
+
 using namespace EventParsers;
+using EventTypes::PhoneCall;
 
 class SortByValueDesc
 {
 public:
-       inline bool operator()(const QPair<char, uint> &a, const QPair<char, uint> &b) const
+       inline bool operator()(const QPair<QChar, uint> &a, const QPair<QChar, uint> &b) const
        {
                return b.second < a.second;
        }
 };
 
-iEventParser *CSVSymbianEventLogParser::IsValid(QFile &eventFile)
+const QString ExtractString(const QString &originalString)
+{
+       QRegExp content("^[\"\']?(.*)?[\"\']?$");
+       content.indexIn(originalString.trimmed());
+       return content.cap(1);
+}
+
+iEventParser *CSVSymbianEventLogParser::IsValid(const Settings &currentSettings, QFile &eventFile)
 {
        qDebug() << "Checking if a CSV call log file...";
 
-       QByteArray firstLineContent(eventFile.readLine());
+       QTextStream stream(&eventFile);
+
+       QString firstLineContent(stream.readLine());
        eventFile.seek(0);
        if(firstLineContent.length() > 0)
        {
                // Count the non-alphanumeric characters used
-               QHash<char, uint> counts;
-               foreach(char c, firstLineContent)
+               QHash<QChar, uint> counts;
+               foreach(const QChar c, firstLineContent)
                        ++counts[c];
 
-               QList<QPair<char, uint> > orderedCounts;
+               QList<QPair<QChar, uint> > orderedCounts;
                orderedCounts.reserve(counts.size());
-               foreach(char c, counts.keys())
+               foreach(const QChar c, counts.keys())
                        if(!QChar(c).isLetterOrNumber())
-                               orderedCounts.append(QPair<char, uint>(c, counts.value(c)));
+                               orderedCounts.append(QPair<QChar, uint>(c, counts.value(c)));
 
                qSort(orderedCounts.begin(), orderedCounts.end(), SortByValueDesc());
 
                // Work around Q_FOREACH macro limitation when dealing with
                // multi-typed templates (comma issue)
-               typedef QPair<char, uint> bodge;
+               typedef QPair<QChar, uint> bodge;
                foreach(bodge count, orderedCounts)
                        qDebug() << count.first << " = " << count.second;
 
-               char delim;
+               QChar delim;
                // No-one would be mad enough to use quotation marks or apostrophes
                // as their delimiter,but just in case, check the second most
                // frequent character is present thr right number of times for
@@ -80,18 +94,17 @@ iEventParser *CSVSymbianEventLogParser::IsValid(QFile &eventFile)
                // Check we have the essential fields we need, and grab their
                // column ordering
                QStringList requiredHeadings;
-               requiredHeadings << "etype" << "etime" << "remote"
-                                                << "direction" << "duration" << "number";
+               requiredHeadings << "etype" << "etime" << "remote" << "direction"
+                                                << "duration" << "number" << "data";
 
                EventParsers::CSVSymbianEventLogParser::ColumnIndicesHash headingPositions;
                headingPositions.reserve(requiredHeadings.count());
 
-               QStringList headings(QString(firstLineContent).split(delim));
+               QStringList headings(QString(firstLineContent).split(delim, QString::KeepEmptyParts, Qt::CaseSensitive));
+               int numColumnsPerRecord(headings.count());
                for(QStringList::size_type i(0); i < headings.count(); ++i)
                {
-                       QRegExp content("^[\"\']?(\\w*)?[\"\']?$");
-                       content.indexIn(headings.value(i).trimmed());
-                       QString heading(content.cap(1));
+                       QString heading(ExtractString(headings.value(i)));
                        qDebug() << headings.value(i) << " : " << heading;
 
                        // Check over the required headings
@@ -107,20 +120,101 @@ iEventParser *CSVSymbianEventLogParser::IsValid(QFile &eventFile)
 
                // If we found all of the required headings, continue
                if(requiredHeadings.count() == 0)
-               {
-                       return new EventParsers::CSVSymbianEventLogParser(eventFile.fileName(), headingPositions);
-               }
+                       return new EventParsers::CSVSymbianEventLogParser(currentSettings, eventFile.fileName(), delim, numColumnsPerRecord, headingPositions);
        }
 
        return NULL;
 }
 
-CSVSymbianEventLogParser::CSVSymbianEventLogParser(const QString &filename, const ColumnIndicesHash &columns)
+CSVSymbianEventLogParser::CSVSymbianEventLogParser(const Settings &settings, const QString &filename, const QChar delimiter, const int numColumnsPerRecord, const ColumnIndicesHash &headingIndices)
+       : m_Settings(settings), m_Delimiter(delimiter), m_NumColumnsPerRecord(numColumnsPerRecord), m_HeadingIndices(headingIndices)
 {
 }
 
 EventTypes::EventFromFileList CSVSymbianEventLogParser::ParseFile(QFile &eventFile, const QList<uint> &recordsToReturn)
 {
        qDebug() << "CSV Parsing NYI!";
-       return EventTypes::EventFromFileList();
+       EventTypes::EventFromFileList fileEvents;
+       //return fileEvents;
+
+       QSet<uint> recordsToReturnSet(QSet<uint>::fromList(recordsToReturn));
+
+       uint lineNumber(0);
+       uint recordNumber(0);
+       eventFile.seek(0);
+
+       // Read the first line
+       QTextStream stream(&eventFile);
+       QString firstLineContent(stream.readLine());
+       QStringList firstLineValues(QString(firstLineContent).split(m_Delimiter));
+       if(firstLineValues.count() != m_NumColumnsPerRecord)
+               throw new std::runtime_error(QString("Unexpected number of columns (%1, expected %2) on line %3 of %4")
+                       .arg(firstLineValues.count())
+                       .arg(m_NumColumnsPerRecord)
+                       .arg(lineNumber)
+                       .arg(eventFile.fileName()).toStdString());
+       ++lineNumber;
+
+       // Read the main body of the file
+       while(!stream.atEnd())
+       {
+               QStringList lineValues(QString(stream.readLine()).split(m_Delimiter));
+               ++lineNumber;
+               // Make sure we have enough columns (i.e. handle newlines in values)
+               while(lineValues.count() < m_NumColumnsPerRecord)
+               {
+                       lineValues.append(QString(stream.readLine()).split(m_Delimiter));
+                       ++lineNumber;
+               }
+
+               if(recordsToReturnSet.count() == 0 || recordsToReturnSet.contains(recordNumber))
+               {
+                       bool bOK(false);
+                       int eType(lineValues.at(m_HeadingIndices.value("etype")).toUInt(&bOK));
+                       // We're only interested in phone calls
+                       if(bOK && eType == 0)
+                       {
+                               qDebug() << "Parsing event from line #" << lineNumber << ". Values: " << lineValues;
+
+                               QDateTime eTime(QDateTime::fromString(lineValues.at(m_HeadingIndices.value("etime")), "dd/MM/yyyy h:mm:ss ap"));
+                               Settings::eDirection direction(lineValues.at(m_HeadingIndices.value("direction")) == "0"
+                                       ? Settings::INCOMING
+                                       : Settings::OUTGOING);
+
+                               // We only care about the requested directions...
+                               if(CurrentSettings().ShouldProcess(direction, EventTypes::EVENT_TYPE_CALL))
+                               {
+                                       int duration(lineValues.at(m_HeadingIndices.value("duration")).toInt(&bOK));
+                                       if(!bOK)
+                                       {
+                                               qDebug() << QString("Unable to parse '%1' as a duration. Skipping record.")
+                                                                               .arg(lineValues.at(m_HeadingIndices.value("duration")));
+                                               continue;
+                                       }
+                                       QString number(ExtractString(lineValues.at(m_HeadingIndices.value("number"))));
+                                       // TODO: Not currently used...but almost certainly contains SIP call data
+                                       QString data(ExtractString(lineValues.at(m_HeadingIndices.value("data"))));
+
+                                       if(number.trimmed().length() == 0)
+                                       {
+                                               qDebug() << "Empty tel!";
+                                       }
+
+                                       QSharedPointer<EventTypes::iEvent> newEvent(new PhoneCall(
+                                               CurrentSettings(),
+                                               direction,
+                                               eTime,
+                                               number,
+                                               duration));
+                                       fileEvents.append(EventTypes::EventFromFile(newEvent, recordNumber));
+                               }
+                       }
+               }
+
+               ++recordNumber;
+       }
+
+       qDebug() << QString("File pos: %1, bAvail: %2, canReadLine: %3").arg(eventFile.pos()).arg(eventFile.bytesAvailable()).arg(eventFile.canReadLine());
+       qDebug() << fileEvents.count() << " events loaded from file";
+       return fileEvents;
 }
index 4b155fb..102d210 100644 (file)
 #define EVENTPARSERS_CSVSYMBIANEVENTLOGPARSER_H
 
 #include "iEventParser.h"
+class Settings;
 
-template <typename T1, typename T2> class QHash;
+#include <QHash>
+class QChar;
 class QFile;
 class QString;
 
@@ -32,11 +34,20 @@ namespace EventParsers
        public:
                typedef QHash<QString, int> ColumnIndicesHash;
 
-               static iEventParser *IsValid(QFile &eventFile);
+               static iEventParser *IsValid(const Settings &currentSettings, QFile &eventFile);
 
-               CSVSymbianEventLogParser(const QString &filename, const ColumnIndicesHash &columns);
+               CSVSymbianEventLogParser(const Settings &currentSettings, const QString &filename, const QChar delimiter, const int numColumnsPerRecord, const ColumnIndicesHash &columns);
 
                virtual EventTypes::EventFromFileList ParseFile(QFile &eventFile, const QList<unsigned int> &recordsToReturn);
+
+       protected:
+               const Settings &CurrentSettings() const { return m_Settings; }
+
+       private:
+               const Settings &m_Settings;
+               const QChar m_Delimiter;
+               const int m_NumColumnsPerRecord;
+               const ColumnIndicesHash m_HeadingIndices;
        };
 }
 
index 4eb74c0..dc35ddf 100644 (file)
@@ -43,7 +43,7 @@ iEventParser * Factory::CreateParser(const Settings &settings, const QString &fi
                        return parser;
 
                // Check for CSV-format call logs
-               if((parser = CSVSymbianEventLogParser::IsValid(eventFile)))
+               if((parser = CSVSymbianEventLogParser::IsValid(settings, eventFile)))
                        return parser;
 
                // Check for MMS-format MMS messages
index 55109f9..5339983 100644 (file)
@@ -21,6 +21,7 @@
 #include <QDebug>
 
 #include <QFile>
+#include <QSharedPointer>
 #include <QString>
 
 using namespace EventParsers;
index f6ce10b..ecd60ae 100644 (file)
@@ -19,6 +19,8 @@
 #ifndef EVENTPARSERS_VMGEntities_FACTORY_H
 #define EVENTPARSERS_VMGEntities_FACTORY_H
 
+class Settings;
+
 class QString;
 
 namespace EventParsers
@@ -34,7 +36,7 @@ namespace EventParsers
                        Factory() {};
 
                public:
-                       static iReader* Instantiate(QString& lineData, const SMSEntity* parent);
+                       static iReader* Instantiate(const Settings &settings, QString& lineData, const SMSEntity* parent);
                };
        }
 }
index 1a23c6c..b60a00d 100644 (file)
@@ -22,8 +22,8 @@
 
 using namespace EventParsers::VMGEntities;
 
-SMSEntity::SMSEntity(const SMSEntity* parent):
-       m_Parent(parent)
+SMSEntity::SMSEntity(const Settings &settings, const SMSEntity *parent):
+       m_Settings(settings), m_Parent(parent)
 {
 }
 
index 9ed198a..28925af 100644 (file)
@@ -19,6 +19,8 @@
 #ifndef EVENTPARSERS_VMGEntities_SMSENTITY_H
 #define EVENTPARSERS_VMGEntities_SMSENTITY_H
 
+class Settings;
+
 #include <cstddef>
 #include <typeinfo>
 
@@ -31,16 +33,20 @@ namespace EventParsers
                class SMSEntity
                {
                public:
-                       SMSEntity(const SMSEntity* parent);
-                       virtual ~SMSEntity() {};
+                       SMSEntity(const Settings &settings, const SMSEntity* parent);
+                       virtual ~SMSEntity() {}
 
                protected:
                        const bool isAttachment() const;
 
-                       const SMSEntity* m_Parent;
-                       const SMSEntity* getParent() const { return m_Parent; };
+                       const SMSEntity *getParent() const { return m_Parent; }
+
+                       virtual const char *getTagName() const { return "VBODY"; }
+                       const Settings &CurrentSettings() const { return m_Settings; }
 
-                       virtual const char* getTagName() const { return "VBODY"; }
+               private:
+                       const Settings &m_Settings;
+                       const SMSEntity *m_Parent;
                };
        }
 }
index dba3fd7..346d97b 100644 (file)
@@ -30,8 +30,8 @@
 
 using namespace EventParsers::VMGEntities;
 
-VBody::VBody(const SMSEntity* parent) :
-       SMSEntity(parent)
+VBody::VBody(const Settings &settings, const SMSEntity *parent) :
+       SMSEntity(settings, parent)
 {
 }
 
@@ -97,7 +97,7 @@ bool VBody::Read(const QString &initialLine, QTextStream &stream, EventTypes::SM
                }
                else if(lineData.startsWith("BEGIN:"))
                {
-                       iReader* reader = Factory::Instantiate(lineData, this);
+                       iReader* reader = Factory::Instantiate(CurrentSettings(), lineData, this);
                        bool valid(NULL != reader && reader->Read(lineData, stream, event));
                        delete reader;
 
index 5a9bb6c..8eb84c0 100644 (file)
@@ -25,6 +25,8 @@
 #include "iReader.h"
 #include "iWriter.h"
 
+class Settings;
+
 class QString;
 
 namespace EventTypes { class SMS; }
@@ -36,7 +38,7 @@ namespace EventParsers
                class VBody : public SMSEntity, public iWriter, public iReader
                {
                public:
-                       VBody(const SMSEntity *parent);
+                       VBody(const Settings &settings, const SMSEntity *parent);
                        //VBody(QTextStream& stream);
                        ~VBody();
 
index 8b97dab..db7a1b0 100644 (file)
@@ -38,8 +38,8 @@
 
 using namespace EventParsers::VMGEntities;
 
-VCalendar::VCalendar(const SMSEntity* parent) :
-       SMSEntity(parent), m_Version(1.0)
+VCalendar::VCalendar(const Settings &settings, const SMSEntity* parent) :
+       SMSEntity(settings, parent), m_Version(1.0)
 {
 }
 
@@ -47,8 +47,8 @@ VCalendar::VCalendar(const SMSEntity* parent) :
 //{
 //}
 
-VCalendar::VCalendar(const SMSEntity* parent, float version) :
-       SMSEntity(parent), m_Version(version)
+VCalendar::VCalendar(const Settings &settings, const SMSEntity* parent, float version) :
+       SMSEntity(settings, parent), m_Version(version)
 {
 }
 
@@ -134,7 +134,7 @@ bool VCalendar::Read(const QString &initialLine, QTextStream &stream, EventTypes
                        }
                        else if(lineData.startsWith("BEGIN:"))
                        {
-                               iReader* reader = Factory::Instantiate(lineData, this);
+                               iReader* reader = Factory::Instantiate(CurrentSettings(), lineData, this);
                                bool valid(NULL != reader && reader->Read(lineData, stream, event));
                                delete reader;
 
index f64c72d..de6a323 100644 (file)
@@ -34,9 +34,9 @@ namespace EventParsers
                class VCalendar : public SMSEntity, public iWriter, public iReader
                {
                public:
-                       VCalendar (const SMSEntity *parent);
+                       VCalendar (const Settings &settings, const SMSEntity *parent);
                        //VCalendar (QTextStream& stream);
-                       VCalendar (const SMSEntity *parent, float version);
+                       VCalendar (const Settings &settings, const SMSEntity *parent, float version);
                        ~VCalendar ();
 
                        virtual bool Read(const QString &initialLine, QTextStream &stream, EventTypes::SMS &event);
index b6d6b63..e5e0a7d 100644 (file)
@@ -38,8 +38,8 @@
 
 using namespace EventParsers::VMGEntities;
 
-VCard::VCard(const SMSEntity* parent) :
-       SMSEntity(parent), m_Version(2.1), m_Target(VCARD_LOCAL)
+VCard::VCard(const Settings &settings, const SMSEntity* parent) :
+       SMSEntity(settings, parent), m_Version(2.1), m_Target(VCARD_LOCAL)
 {
 }
 
@@ -47,8 +47,8 @@ VCard::VCard(const SMSEntity* parent) :
 //{
 //}
 
-VCard::VCard(const SMSEntity* parent, float version, eTarget target) :
-       SMSEntity(parent), m_Version(version), m_Target(target)
+VCard::VCard(const Settings &settings, const SMSEntity* parent, float version, eTarget target) :
+       SMSEntity(settings, parent), m_Version(version), m_Target(target)
 {
 }
 
@@ -164,7 +164,7 @@ bool VCard::Read(const QString &initialLine, QTextStream &stream, EventTypes::SM
                        }
                        else if(lineData.startsWith("BEGIN:"))
                        {
-                               iReader* reader = Factory::Instantiate(lineData, this);
+                               iReader* reader = Factory::Instantiate(CurrentSettings(), lineData, this);
                                bool valid(NULL != reader && reader->Read(lineData, stream, event));
                                delete reader;
 
index 29d3960..0386c97 100644 (file)
@@ -40,9 +40,9 @@ namespace EventParsers
                                VCARD_REMOTE
                        };
 
-                       VCard(const SMSEntity *parent);
+                       VCard(const Settings &settings, const SMSEntity *parent);
                        //VCard(QTextStream& stream);
-                       VCard(const SMSEntity *parent, float version, eTarget target);
+                       VCard(const Settings &settings, const SMSEntity *parent, float version, eTarget target);
                        ~VCard();
 
                        virtual bool Read(const QString &initialLine, QTextStream &stream, EventTypes::SMS &event);
index 54b8f41..aa8c10c 100644 (file)
@@ -27,8 +27,8 @@
 
 using namespace EventParsers::VMGEntities;
 
-VEnvelope::VEnvelope(const SMSEntity* parent) :
-       SMSEntity(parent)
+VEnvelope::VEnvelope(const Settings &settings, const SMSEntity* parent) :
+       SMSEntity(settings, parent)
 {
 }
 
@@ -75,7 +75,7 @@ bool VEnvelope::Read(const QString &initialLine, QTextStream &stream, EventTypes
        {
                if(lineData.startsWith("BEGIN:"))
                {
-                       iReader* reader = Factory::Instantiate(lineData, this);
+                       iReader* reader = Factory::Instantiate(CurrentSettings(), lineData, this);
                        bool valid(NULL != reader && reader->Read(lineData, stream, event));
                        delete reader;
 
index d399a90..cff710f 100644 (file)
@@ -38,7 +38,7 @@ namespace EventParsers
                class VEnvelope : public SMSEntity, public iWriter, public iReader
                {
                public:
-                       VEnvelope(const SMSEntity* parent);
+                       VEnvelope(const Settings &settings, const SMSEntity* parent);
                        //VEnvelope(QTextStream& stream);
                        ~VEnvelope();
 
index 1959d89..849932b 100644 (file)
 
 using namespace EventParsers::VMGEntities;
 
-iReader *Factory::Instantiate(QString& lineData, const SMSEntity *parent)
+iReader *Factory::Instantiate(const Settings &settings, QString& lineData, const SMSEntity *parent)
 {
        if(lineData.startsWith("BEGIN:"))
        {
                QString item = lineData.mid(lineData.indexOf(":")+1);
 
                if(item == "VMSG")
-                       return new VMessage(parent);
+                       return new VMessage(settings, parent);
                else if(item == "VCARD")
-                       return new VCard(parent);
+                       return new VCard(settings, parent);
                else if(item == "VENV")
-                       return new VEnvelope(parent);
+                       return new VEnvelope(settings, parent);
                else if(item == "VBODY")
-                       return new VBody(parent);
+                       return new VBody(settings, parent);
                else if(item == "VCALENDAR")
-                       return new VCalendar(parent);
+                       return new VCalendar(settings, parent);
        }
 
        qDebug() << "Unrecognised entity '" << lineData <<"'";
index 59097d7..443070e 100644 (file)
 
 #include "EventTypes/SMS.h"
 #include "Factory.h"
+#include "Settings.h"
+#include "VBody.h"
 #include "VCard.h"
 #include "VEnvelope.h"
-#include "VBody.h"
 
 #include <QDateTime>
 #include <QTextStream>
@@ -31,8 +32,8 @@
 
 using namespace EventParsers::VMGEntities;
 
-VMessage::VMessage(const SMSEntity* parent) :
-       SMSEntity(parent), m_Version(1.1)
+VMessage::VMessage(const Settings &settings, const SMSEntity *parent) :
+       SMSEntity(settings, parent), m_Version(1.1)
 {
 }
 
@@ -40,8 +41,8 @@ VMessage::VMessage(const SMSEntity* parent) :
 //{
 //}
 
-VMessage::VMessage(const SMSEntity* parent, float version) :
-       SMSEntity(parent), m_Version(version)
+VMessage::VMessage(const Settings &settings, const SMSEntity *parent, float version) :
+       SMSEntity(settings, parent), m_Version(version)
 {
 }
 
@@ -49,7 +50,7 @@ VMessage::~VMessage()
 {
 }
 
-bool VMessage::Read(const QString & initialLine, QTextStream & stream, EventTypes::SMS & event)
+bool VMessage::Read(const QString &initialLine, QTextStream &stream, EventTypes::SMS &event)
 {
        if(getParent() != NULL)
        {
@@ -88,6 +89,14 @@ bool VMessage::Read(const QString & initialLine, QTextStream & stream, EventType
                {
                        QString box = lineData.mid(lineData.indexOf(":") + 1);
                        bool isOutgoing(box == "SENT");
+
+                       // Early out once we know we're not processing this type of message
+                       if((!isOutgoing && !CurrentSettings().ShouldProcess(Settings::INCOMING, EventTypes::EVENT_TYPE_SMS))
+                               || isOutgoing && !CurrentSettings().ShouldProcess(Settings::OUTGOING, EventTypes::EVENT_TYPE_SMS))
+                       {
+                               return false;
+                       }
+
                        if (isOutgoing == false && box != "INBOX")
                        {
                                qDebug() << "Unexpected box: " << box;
@@ -105,7 +114,7 @@ bool VMessage::Read(const QString & initialLine, QTextStream & stream, EventType
                }
                else if(lineData.startsWith("BEGIN:"))
                {
-                       iReader* reader = Factory::Instantiate(lineData, this);
+                       iReader* reader = Factory::Instantiate(CurrentSettings(), lineData, this);
                        bool valid(NULL != reader && reader->Read(lineData, stream, event));
                        delete reader;
 
@@ -141,24 +150,24 @@ void VMessage::Write(QTextStream &stream, const EventTypes::SMS &event)
        stream << "X-IRMC-BOX:" << ( event.Destination() == EventTypes::SMS::SENT ? "SENT" : "INBOX") << "\n";
        stream << "X-NOK-DT:" << event.Timestamp().toUTC().toString("yyyyMMddThhmmssZ") << "\n";
 
-       VEnvelope msgEnvelope(this);
+       VEnvelope msgEnvelope(CurrentSettings(), this);
 
        // Add in the empty vcard for outgoing messages
        if(event.Destination() == EventTypes::SMS::SENT)
        {
-               VCard(this, 2.1, VCard::VCARD_LOCAL).Write(stream, event);
+               VCard(CurrentSettings(), this, 2.1, VCard::VCARD_LOCAL).Write(stream, event);
 
-               msgEnvelope.getContentWriters().append(new VCard(&msgEnvelope, 2.1, VCard::VCARD_REMOTE));
+               msgEnvelope.getContentWriters().append(new VCard(CurrentSettings(), &msgEnvelope, 2.1, VCard::VCARD_REMOTE));
 
-               VEnvelope *bodyEnvelope = new VEnvelope(this);
-               bodyEnvelope->getContentWriters().append(new VBody(bodyEnvelope));
+               VEnvelope *bodyEnvelope = new VEnvelope(CurrentSettings(), this);
+               bodyEnvelope->getContentWriters().append(new VBody(CurrentSettings(), bodyEnvelope));
                msgEnvelope.getContentWriters().append(bodyEnvelope);
        }
        else
        {
-               VCard(this, 2.1, VCard::VCARD_REMOTE).Write(stream, event);
+               VCard(CurrentSettings(), this, 2.1, VCard::VCARD_REMOTE).Write(stream, event);
 
-               msgEnvelope.getContentWriters().append(new VBody(&msgEnvelope));
+               msgEnvelope.getContentWriters().append(new VBody(CurrentSettings(), &msgEnvelope));
        }
 
        msgEnvelope.Write(stream, event);
index 725b175..b302c5d 100644 (file)
@@ -23,6 +23,8 @@
 #include "iReader.h"
 #include "iWriter.h"
 
+class Settings;
+
 class QString;
 class QTextStream;
 
@@ -38,9 +40,9 @@ namespace EventParsers
                class VMessage : public SMSEntity, public iWriter, public iReader
                {
                public:
-                       VMessage(const SMSEntity* parent);
+                       VMessage(const Settings &settings, const SMSEntity* parent);
                        //VMessage(QTextStream& stream);
-                       VMessage(const SMSEntity* parent, float version);
+                       VMessage(const Settings &settings, const SMSEntity* parent, float version);
                        ~VMessage();
 
                        virtual bool Read(const QString & initialLine, QTextStream& stream, EventTypes::SMS & event);
index dbb82f3..0cfda71 100644 (file)
@@ -81,7 +81,7 @@ EventTypes::EventFromFileList VMGParser::ParseFile(QFile &eventFile, const QList
        // Parse the event
        EventTypes::SMS *event(new EventTypes::SMS(CurrentSettings()));
        QString lineData = eventStream.readLine();
-       EventParsers::VMGEntities::iReader* reader = EventParsers::VMGEntities::Factory::Instantiate(lineData, NULL);
+       EventParsers::VMGEntities::iReader* reader = EventParsers::VMGEntities::Factory::Instantiate(CurrentSettings(), lineData, NULL);
        bool valid(NULL != reader && reader->Read(QString(""), eventStream, *event));
        delete reader;
        if (!valid)
@@ -92,6 +92,6 @@ EventTypes::EventFromFileList VMGParser::ParseFile(QFile &eventFile, const QList
 
        // VMGs only support single events per file, so just create the list
        EventTypes::EventFromFileList retList;
-       retList.append(EventTypes::EventFromFile(event, 0));
+       retList.append(EventTypes::EventFromFile(QSharedPointer<EventTypes::iEvent>(event), 0));
        return retList;
 }
index 19ad9f7..60a4bc9 100644 (file)
@@ -33,7 +33,7 @@ void Hasher::Process(EventTypes::iEvent &event)
 {
        uint hash(event.HashCode());
        m_Hashes.insert(hash);
-       qDebug() << "DB Event hash: " << hash << " @ " << event.Timestamp();
+       qDebug() << "DB Event hash: " << hash << " @ " << event.Timestamp().toUTC();
 }
 
 void Hasher::EmitEventProcessed(int eventsProcessed, int totalEvents)
index ed3ed39..8ed30e3 100644 (file)
@@ -19,6 +19,7 @@
 #ifndef EVENTTYPES_EVENTFROMFILE_H
 #define EVENTTYPES_EVENTFROMFILE_H
 
+template <typename T1> class QSharedPointer;
 template <typename T1> class QList;
 template <typename T1, typename T2> class QPair;
 
@@ -26,7 +27,7 @@ namespace EventTypes
 {
        class iEvent;
 
-       typedef QPair<iEvent *, unsigned int> EventFromFile;
+       typedef QPair<QSharedPointer<EventTypes::iEvent>, unsigned int> EventFromFile;
 }
 
 #endif // EVENTTYPES_EVENTFROMFILE_H
index 9901cfc..7997fc2 100644 (file)
@@ -47,6 +47,7 @@ const DBBackends::iDBBackend &PhoneCall::DB() const
 PhoneCall::PhoneCall(const Settings &settings) :
        m_Settings(settings)
 {
+       qDebug() << "Created new default Phone Call: " << *this;
 }
 
 PhoneCall::~PhoneCall()
@@ -60,19 +61,35 @@ PhoneCall::~PhoneCall()
 PhoneCall::PhoneCall(const Settings &settings, const RTComElEvent &event, const QList<RTComElAttachment*> attachments) :
        m_Settings(settings)
 {
-       setDestination(event.fld_outgoing ? OUTGOING : INCOMING);
+       setDestination(event.fld_outgoing ? Settings::OUTGOING : Settings::INCOMING);
        setTimestamp(QDateTime::fromTime_t(event.fld_start_time).toUTC());
        setDurationInSeconds(QDateTime::fromTime_t(event.fld_start_time).toUTC().secsTo(QDateTime::fromTime_t(event.fld_end_time).toUTC()));
        setTel(event.fld_remote_uid);
        if(Tel().indexOf("0") == 0)
                setTel(QString(Tel()).replace(QRegExp("^0"), "+44"));
 
-       // We directly access the m_Attachments member variable here rather than the
-       // accessor as the accessor is const
        if(attachments.count() > 0)
                foreach(RTComElAttachment *attachment, attachments)
                        Attachments().append(new Attachment(*attachment));
+
+       qDebug() << "Created new Phone Call from RtCom:\n" << *this;
 }
+
+PhoneCall::PhoneCall(const Settings &settings, const Settings::eDirection destination, const QDateTime &timestamp, const QString &tel, int durationInSeconds, const AttachmentCollection &attachments) :
+       m_Settings(settings), m_Destination(destination), m_Timestamp(timestamp), m_Tel(tel),
+       m_DurationInSeconds(durationInSeconds), m_Attachments(attachments)
+{
+       if(Tel().indexOf("0") == 0)
+               setTel(QString(Tel()).replace(QRegExp("^0"), "+44"));
+
+       // TODO: Copy attachments.
+//     if(attachments.count() > 0)
+//             foreach(const QSharedPointer<Attachment *> &attachment, attachments)
+//                     Attachments().append(attachment);
+
+       qDebug() << "Created new Phone Call: " << *this;
+}
+
 #include <QDebug>
 const uint PhoneCall::HashCode() const
 {
@@ -94,6 +111,7 @@ const uint PhoneCall::HashCode() const
 RTComElEvent * PhoneCall::toRTComEvent(const NumberToNameLookup &numberToNameLookup) const
 {
        QList<QString> voiceMailList;
+       voiceMailList << "+447945353070"; // T-Mobile UK Voicemail
 
        QString groupId((Tel().length() < 7 || Tel().indexOf(QRegExp("[:alpha:]+")) > -1)
                ? Tel()
@@ -107,19 +125,18 @@ RTComElEvent * PhoneCall::toRTComEvent(const NumberToNameLookup &numberToNameLoo
                RTCOM_EL_EVENT_SET_FIELD (event, event_type, g_strdup("RTCOM_EL_EVENTTYPE_CALL_VOICEMAIL"));
        else
                RTCOM_EL_EVENT_SET_FIELD (event, event_type, g_strdup("RTCOM_EL_EVENTTYPE_CALL"));
-       RTCOM_EL_EVENT_SET_FIELD (event, storage_time, Timestamp().toUTC().toTime_t());
        RTCOM_EL_EVENT_SET_FIELD (event, start_time, Timestamp().toUTC().toTime_t());
-       RTCOM_EL_EVENT_SET_FIELD (event, end_time, Timestamp().toUTC().toTime_t());
+       RTCOM_EL_EVENT_SET_FIELD (event, end_time, Timestamp().addSecs(DurationInSeconds()).toUTC().toTime_t());
+       RTCOM_EL_EVENT_SET_FIELD (event, storage_time, Timestamp().addSecs(DurationInSeconds()).toUTC().toTime_t());
        //RTCOM_EL_EVENT_SET_FIELD (event, is_read, 0);
-       RTCOM_EL_EVENT_SET_FIELD (event, outgoing, Destination() == PhoneCall::OUTGOING ? 1 : 0);
+       RTCOM_EL_EVENT_SET_FIELD (event, outgoing, Destination() == Settings::OUTGOING ? 1 : 0);
+       //if(local_uid) // Voicemail local_uid transform needed here
        RTCOM_EL_EVENT_SET_FIELD (event, local_uid, g_strdup("ring/tel/ring"));
        //RTCOM_EL_EVENT_SET_FIELD (&event, local_name, g_strdup("<SelfHandle>"));
        RTCOM_EL_EVENT_SET_FIELD (event, remote_uid, g_strdup(Tel().toUtf8()));
        //RTCOM_EL_EVENT_SET_FIELD (&event, remote_name, g_strdup(QString::number(numberToNameLookup.ContactDetails().value(Tel()).second).toUtf8()));
        RTCOM_EL_EVENT_SET_FIELD (event, remote_ebook_uid, g_strdup(QString::number(numberToNameLookup.ContactDetails().value(Tel()).first).toUtf8()));
        RTCOM_EL_EVENT_SET_FIELD (event, group_uid, g_strdup(groupId.toUtf8()));
-       //RTCOM_EL_EVENT_SET_FIELD (event, free_text, g_strdup(Contents().replace(0x2029, "\n").toUtf8()));
-       //RTCOM_EL_EVENT_SET_FIELD (event, free_text, g_strdup(Contents().toUtf8()));
 
        return event;
 }
@@ -158,9 +175,10 @@ void PhoneCall::Export(const QString &baseDirectory) const
 
 QDebug operator<<(QDebug dbg, PhoneCall& event)
 {
-       dbg.nospace() << "\tFolder:\t\t" << (event.Destination() == PhoneCall::OUTGOING ? "Sent" : "Inbox") << "\n";
+       dbg.nospace() << "\tHash:\t\t" << event.HashCode() << "\n";
+       dbg.nospace() << "\tDirection:\t\t" << (event.Destination() == Settings::OUTGOING ? "Made" : "Recieved") << "\n";
        dbg.nospace() << "\tTimestamp:\t" << event.Timestamp().toUTC() << "\n";
-       dbg.nospace() << "\tDuration:\t" << event.DurationInSeconds() << "\n";
+       dbg.nospace() << "\tDuration:\t\t" << event.DurationInSeconds() << " seconds\n";
        dbg.nospace() << "\tRemote-Tel:\t" << event.Tel() << "\n";
        //dbg.nospace() << "\tremote-name:\t" << event.fld_remote_name << "\n";
 
index 88f8b2a..c246258 100644 (file)
@@ -19,6 +19,8 @@
 #ifndef EVENTTYPES_PHONECALL_H
 #define EVENTTYPES_PHONECALL_H
 
+#include "Settings.h"
+
 #include <QDateTime>
 #include <QDebug>
 #include <QList>
@@ -35,22 +37,16 @@ namespace EventTypes
        class PhoneCall : public RtcomEvent
        {
        public:
-               enum eDestination
-               {
-                       INCOMING,
-                       OUTGOING
-               };
-
-       public:
                virtual const DBBackends::iDBBackend &DB() const;
 
                PhoneCall(const Settings &settings);
+               PhoneCall(const Settings &settings, const Settings::eDirection destination, const QDateTime &timestamp, const QString &tel, int durationInSeconds, const AttachmentCollection &attachments = AttachmentCollection());
                ~PhoneCall();
 
                virtual const uint HashCode() const;
 
-               const eDestination Destination() const { return m_Destination; }
-               void setDestination(const eDestination destination) { m_Destination = destination; }
+               const Settings::eDirection Destination() const { return m_Destination; }
+               void setDestination(const Settings::eDirection destination) { m_Destination = destination; }
 
                virtual const QDateTime Timestamp() const { return m_Timestamp; }
                void setTimestamp(const QDateTime timestamp) { m_Timestamp = timestamp; }
@@ -74,7 +70,7 @@ namespace EventTypes
 
        private:
                const Settings &m_Settings;
-               eDestination m_Destination;
+               Settings::eDirection m_Destination;
                QDateTime m_Timestamp;
                QString m_Tel;
                int m_DurationInSeconds;
index 19d4df5..97ee9c5 100644 (file)
@@ -64,7 +64,7 @@ SMS::SMS(const Settings &settings, const RTComElEvent &event, const QList<RTComE
        setIsRead(event.fld_is_read);
        setDestination(event.fld_outgoing ? SENT : INBOX);
        setTimestamp(QDateTime::fromTime_t(event.fld_start_time).toUTC());
-       setTel(event.fld_remote_uid);
+       setTel(QString::fromUtf8(event.fld_remote_uid));
        if(Tel().indexOf("0") == 0)
                setTel(QString(Tel()).replace(QRegExp("^0"), "+44"));
        //setContents(QString(event.fld_free_text).replace("\n", QChar(0x2029)));
@@ -141,7 +141,7 @@ void SMS::Export(const QString &baseDirectory) const
                stream.setAutoDetectUnicode(false);
                stream.setCodec("UTF-16LE");
 
-               EventParsers::VMGEntities::VMessage writer(NULL, 1.1);
+               EventParsers::VMGEntities::VMessage writer(CurrentSettings(), NULL, 1.1);
                writer.Write(stream, *this);
 //stream << "Test";
                //stream.setCodec(oldCodec);
diff --git a/EventTypes/eEventTypes.h b/EventTypes/eEventTypes.h
new file mode 100644 (file)
index 0000000..2c28492
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2011, Jamie Thompson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef EVENT_TYPES_EEVENTTYPES_H
+#define EVENT_TYPES_EEVENTTYPES_H
+
+namespace EventTypes
+{
+       // Options for supported event types
+       enum eEventTypes
+       {
+               EVENT_TYPE_CALL,
+               EVENT_TYPE_CHAT,
+               EVENT_TYPE_SMS,
+               EVENT_TYPE_MMS
+       };
+       static const int kNumEventTypes = EVENT_TYPE_MMS + 1;
+}
+
+#endif // EVENT_TYPES_EEVENTTYPES_H
index 96eb7f9..6fa3b12 100644 (file)
@@ -82,7 +82,7 @@ NumberToNameLookup::NumberToNameLookup()
                                // Now work out the current name for the contact and add it to the lookup
                                EContactName *contactName = (EContactName*)e_contact_get((EContact*)currentContact->data, E_CONTACT_NAME);
                                char *completeName(e_contact_name_to_string(contactName));
-                               qDebug() << completeName;
+                               //qDebug() << completeName;
 
                                // Looking at each number they have...
                                GList * attrs(e_contact_get_attributes(E_CONTACT(currentContact->data), E_CONTACT_FIRST_PHONE_ID));
@@ -102,7 +102,7 @@ NumberToNameLookup::NumberToNameLookup()
 
                                                        m_ContactDetails.insert(QString(number), QPair<uint, QString>(remote_ebook_uid, QString(completeName)));
 
-                                                       qDebug() << "Number: " << number << ", ID: " << remote_ebook_uid << ", completeName: " << completeName;
+                                                       //qDebug() << "Number: " << number << ", ID: " << remote_ebook_uid << ", completeName: " << completeName;
                                                }
                                        }
                                }
@@ -112,7 +112,7 @@ NumberToNameLookup::NumberToNameLookup()
                                e_contact_name_free(contactName);
 
                                // I hate C-style APIs.
-                               g_object_unref(currentContact);
+                               g_object_unref(currentContact->data);
                        }
 
                        // I *really* hate C-style APIs.
index dc462c6..cec9b44 100644 (file)
@@ -18,6 +18,8 @@
 
 #include "Settings.h"
 
+#include <QDir>
+
 Settings::Settings()
 {
        // Default to console
@@ -30,18 +32,21 @@ Settings::Settings()
        setMode(MODE_EXPORT);
 
        // We don't process anything by default
-       setShouldProcess(TYPE_SENT, EVENTTYPE_SMS, false);
-       setShouldProcess(TYPE_SENT, EVENTTYPE_MMS, false);
-       setShouldProcess(TYPE_SENT, EVENTTYPE_CHAT, false);
+       setShouldProcess(OUTGOING, EventTypes::EVENT_TYPE_SMS, false);
+       setShouldProcess(OUTGOING, EventTypes::EVENT_TYPE_MMS, false);
+       setShouldProcess(OUTGOING, EventTypes::EVENT_TYPE_CHAT, false);
 
        // We still don't process anything by default
-       setShouldProcess(TYPE_RECIEVED, EVENTTYPE_SMS, false);
-       setShouldProcess(TYPE_RECIEVED, EVENTTYPE_MMS, false);
-       setShouldProcess(TYPE_RECIEVED, EVENTTYPE_CHAT, false);
+       setShouldProcess(INCOMING, EventTypes::EVENT_TYPE_SMS, false);
+       setShouldProcess(INCOMING, EventTypes::EVENT_TYPE_MMS, false);
+       setShouldProcess(INCOMING, EventTypes::EVENT_TYPE_CHAT, false);
 
        // Default to the UK :)
        setCountryCode(44);
 
        // It's OK to disable the radio by default
        setDisableCellular(true);
+
+       // Where it lives...
+       DBPath(QDir::homePath() + "/.rtcom-eventlogger/el-v1.db");
 }
index da1d08c..b308b6f 100644 (file)
@@ -19,6 +19,8 @@
 #ifndef SETTINGS_H
 #define SETTINGS_H
 
+#include "EventTypes/eEventTypes.h"
+
 #include <QString>
 
 class Settings
@@ -39,21 +41,12 @@ public:
        static const int kNumModes = MODE_EXPORT + 1;
 
        // Options for targets - sent or recieved
-       enum eTargets
-       {
-               TYPE_SENT,
-               TYPE_RECIEVED,
-       };
-       static const int kNumTargets = TYPE_RECIEVED + 1;
-
-       // Options for supported event types
-       enum eEventTypes
+       enum eDirection
        {
-               EVENTTYPE_SMS,
-               EVENTTYPE_MMS,
-               EVENTTYPE_CHAT,
+               OUTGOING,
+               INCOMING,
        };
-       static const int kNumEventTypes = EVENTTYPE_CHAT + 1;
+       static const int kNumTargets = INCOMING + 1;
 
 private:
        // The current UI mode of the application (Console/GUI)
@@ -66,7 +59,7 @@ private:
        eMode m_Mode;
 
        // The current targets & event types being processed
-       bool m_ShouldProcess[kNumTargets][kNumEventTypes];
+       bool m_ShouldProcess[kNumTargets][EventTypes::kNumEventTypes];
 
        // The root directory to import or export from
        QString m_Directory;
@@ -77,6 +70,10 @@ private:
        // Is it OK to disable the cellular radio to prevent calls and messages?
        bool m_DisableCellular;
 
+       // RtcomEventLogger path
+       QString m_DBPath;
+       void DBPath(QString dbPath) { m_DBPath = dbPath; }
+
 public:
        Settings();
 
@@ -89,12 +86,12 @@ public:
        eMode const Mode() const { return m_Mode; }
        eMode const setMode(const eMode mode) { return m_Mode = mode; }
 
-       bool const ShouldProcess(const eTargets target, const eEventTypes eventType) const { return m_ShouldProcess[target][eventType]; }
-       bool const setShouldProcess(const eTargets target, const eEventTypes eventType, const bool shouldProcess = true){ return m_ShouldProcess[target][eventType] = shouldProcess; }
+       bool const ShouldProcess(const eDirection target, const EventTypes::eEventTypes eventType) const { return m_ShouldProcess[target][eventType]; }
+       bool const setShouldProcess(const eDirection target, const EventTypes::eEventTypes eventType, const bool shouldProcess = true){ return m_ShouldProcess[target][eventType] = shouldProcess; }
        bool const anyToProcess()
        {
                for(int targetIndex = 0; targetIndex < kNumTargets; ++targetIndex)
-                       for(int eventTypeIndex = 0; eventTypeIndex < kNumEventTypes; ++eventTypeIndex)
+                       for(int eventTypeIndex = 0; eventTypeIndex < EventTypes::kNumEventTypes; ++eventTypeIndex)
                                if (m_ShouldProcess[targetIndex][eventTypeIndex])
                                        return true;
                return false;
@@ -108,6 +105,8 @@ public:
 
        bool const DisableCellular() const { return m_DisableCellular; }
        bool const setDisableCellular(const bool disableCellular) { return m_DisableCellular = disableCellular; }
+
+       const QString &DBPath() const { return m_DBPath; }
 };
 
 #endif // SETTINGS_H
index 55fce3c..754123b 100644 (file)
@@ -28,7 +28,6 @@
 #include "EventTypes/EventFromFileList.h"
 #include "EventTypes/iEvent.h"
 #include "EventLogBackupManager.h"
-#include "EventLogReindexer.h"
 #include "EventParsers/Factory.h"
 #include "EventParsers/iEventParser.h"
 
@@ -37,6 +36,7 @@
 #include <QFile>
 #include <QFileInfo>
 #include <QProcess>
+#include <QSharedPointer>
 
 #include <stdexcept>
 
@@ -167,7 +167,7 @@ void SyncerThread::run()
                        foreach(iHashable::Hash hash, newHashes)
                                qDebug() << hash << endl;
 
-                       // Now an optimisation: group the new hases by the files they come
+                       // Now an optimisation: group the new hashes by the files they come
                        // from. This enables each file to only be parsed once and return
                        // all the required events from it.
                        QHash<QString, QList<iHashable::Hash> > newHashesByPath;
@@ -187,7 +187,8 @@ void SyncerThread::run()
 
                        qDebug() << "Importing new events";
 
-                       // Re-parse the new events
+                       // Re-parse the new events and insert them
+                       allBackends.PreInsert();
                        {
                                int idx = 0;
                                foreach(QString filename, newHashesByPath.keys())
@@ -196,8 +197,6 @@ void SyncerThread::run()
                                        foreach(iHashable::Hash newHash, newHashesByPath.value(filename))
                                                recordsToReturn.append(pathsByHashes.value(newHash).second);
 
-                                       ++idx;
-
                                        // Repeating an action that caused an exception last time
                                        // shouldn't happen again, but just in case...
                                        try
@@ -213,6 +212,8 @@ void SyncerThread::run()
                                                        {
                                                                qDebug() << "Unable to insert event: " << exception.what();
                                                        }
+
+                                                       emit EventProcessed(++idx, newHashes.count());
                                                }
                                        }
                                        catch(const std::runtime_error &exception)
@@ -220,14 +221,12 @@ void SyncerThread::run()
                                                qDebug() << exception.what() << endl;
                                        }
 
+                                       // Just to make sure the listeners are synced even if the
+                                       // earlier call is skipped due to errors...
                                        emit EventProcessed(idx, newHashes.count());
                                }
                        }
-
-                       // Reorder the DB IDs as Nokia are guilty of both premature
-                       // optimisation as well as closed source UIs...
-                       EventLogReindexer reindexer;
-                       reindexer.Reindex();
+                       allBackends.PostInsert(); // Perform any post-insert cleanup (i.e. reindexing)
 
                        // Need to find a better way of refreshing the conversations view...
                        QProcess::execute("pkill rtcom");
index 6e619f2..b4b86e3 100644 (file)
@@ -105,14 +105,14 @@ void TypesWindow::CreateContents()
                                }
                                {
                                        cbMadeCalls = new QCheckBox();
-                                       cbMadeCalls->setEnabled(false);
+                                       //cbMadeCalls->setEnabled(false);
                                        cbMadeCalls->setSizePolicy(sizePolicyForCheckBoxes);
                                        cbMadeCalls->setMaximumSize(QSize(70, 64));
                                        layout->addWidget(cbMadeCalls, row, 2, 1, 1);
                                }
                                {
                                        cbRecvCalls = new QCheckBox();
-                                       cbRecvCalls->setEnabled(false);
+                                       //cbRecvCalls->setEnabled(false);
                                        cbRecvCalls->setSizePolicy(sizePolicyForCheckBoxes);
                                        cbRecvCalls->setMaximumSize(QSize(70, 64));
                                        layout->addWidget(cbRecvCalls, row, 3, 1, 1);
@@ -236,12 +236,14 @@ void TypesWindow::OrientationChanged()
 
 void TypesWindow::Continue()
 {
-       CurrentSettings().setShouldProcess(Settings::TYPE_SENT, Settings::EVENTTYPE_SMS, cbSentSMS->checkState() == Qt::Checked);
-       CurrentSettings().setShouldProcess(Settings::TYPE_SENT, Settings::EVENTTYPE_MMS, cbSentMMS->checkState() == Qt::Checked);
-       CurrentSettings().setShouldProcess(Settings::TYPE_SENT, Settings::EVENTTYPE_CHAT, cbSentChat->checkState() == Qt::Checked);
-       CurrentSettings().setShouldProcess(Settings::TYPE_RECIEVED, Settings::EVENTTYPE_SMS, cbRecvSMS->checkState() == Qt::Checked);
-       CurrentSettings().setShouldProcess(Settings::TYPE_RECIEVED, Settings::EVENTTYPE_MMS, cbRecvMMS->checkState() == Qt::Checked);
-       CurrentSettings().setShouldProcess(Settings::TYPE_RECIEVED, Settings::EVENTTYPE_CHAT, cbRecvChat->checkState() == Qt::Checked);
+       CurrentSettings().setShouldProcess(Settings::OUTGOING, EventTypes::EVENT_TYPE_CALL, cbMadeCalls->checkState() == Qt::Checked);
+       CurrentSettings().setShouldProcess(Settings::OUTGOING, EventTypes::EVENT_TYPE_SMS, cbSentSMS->checkState() == Qt::Checked);
+       CurrentSettings().setShouldProcess(Settings::OUTGOING, EventTypes::EVENT_TYPE_MMS, cbSentMMS->checkState() == Qt::Checked);
+       CurrentSettings().setShouldProcess(Settings::OUTGOING, EventTypes::EVENT_TYPE_CHAT, cbSentChat->checkState() == Qt::Checked);
+       CurrentSettings().setShouldProcess(Settings::INCOMING, EventTypes::EVENT_TYPE_CALL, cbRecvCalls->checkState() == Qt::Checked);
+       CurrentSettings().setShouldProcess(Settings::INCOMING, EventTypes::EVENT_TYPE_SMS, cbRecvSMS->checkState() == Qt::Checked);
+       CurrentSettings().setShouldProcess(Settings::INCOMING, EventTypes::EVENT_TYPE_MMS, cbRecvMMS->checkState() == Qt::Checked);
+       CurrentSettings().setShouldProcess(Settings::INCOMING, EventTypes::EVENT_TYPE_CHAT, cbRecvChat->checkState() == Qt::Checked);
 
        if(CurrentSettings().anyToProcess())
                Advance();
index c81212e..a19b8dc 100644 (file)
--- a/main.cpp
+++ b/main.cpp
 
 #include "ui_dialog.h"
 
+#include <QDebug>
 #include <QtGui>
 #include <QtGui/QApplication>
 #include <QHash>
 
+#include <glib-2.0/glib.h>
+void g_log_default_handler (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer unused_data)
+{
+       qDebug() << "GLIB: <D>" << log_domain << "<L>" << log_level << "<M>" << message << "\n";
+}
+
 int main(int argc, char *argv[])
 {
+       g_log_set_default_handler(g_log_default_handler, NULL);
+
        QApplication app(argc, argv);
 
        Settings settings;
index 12eba92..f834b8f 100644 (file)
@@ -30,7 +30,6 @@ SOURCES += main.cpp\
        AttachmentCollection.cpp \
        CellularRadio.cpp \
        EventLogBackupManager.cpp \
-       EventLogReindexer.cpp \
        EventParsers/CSVSymbianEventLogParser.cpp \
        EventParsers/Factory.cpp \
        EventParsers/MMSParser.cpp \
@@ -59,8 +58,9 @@ SOURCES += main.cpp\
        DBBackends/Fmms.cpp \
        EventProcessors/Hasher.cpp \
        EventProcessors/Writer.cpp \
-       DBBackends/DBBackends.cpp \
-       EventTypes/PhoneCall.cpp
+       EventTypes/PhoneCall.cpp \
+       DBBackends/AllBackends.cpp \
+       DBBackends/RtcomEventLoggerComponents/TriggerDisabler.cpp
 
 HEADERS  += \
        Windows/ModeWindow.h \
@@ -83,7 +83,6 @@ HEADERS  += \
        AttachmentCollection.h \
        iHashable.h \
        NumberToNameLookup.h \
-       EventLogReindexer.h \
        EventParsers/VMGEntities/VCalendar.h \
        EventPreventer.h \
        EventLogBackupManager.h \
@@ -107,7 +106,9 @@ HEADERS  += \
        EventProcessors/iEventProcessor.h \
        DBBackends/AllBackends.h \
        EventTypes/PhoneCall.h \
-    EventTypes/RtcomEvent.h
+       EventTypes/RtcomEvent.h \
+       EventTypes/eEventTypes.h \
+       DBBackends/RtcomEventLoggerComponents/TriggerDisabler.h
 
 FORMS    += \
        dialog.ui
diff --git a/rcc/qrc_Resources1.cpp b/rcc/qrc_Resources1.cpp
deleted file mode 100644 (file)
index 1f14045..0000000
+++ /dev/null
@@ -1,1131 +0,0 @@
-/****************************************************************************
-** Resource object code
-**
-** Created: Sat 6. Aug 22:47:58 2011
-**      by: The Resource Compiler for Qt version 4.7.0
-**
-** WARNING! All changes made in this file will be lost!
-*****************************************************************************/
-
-#include <QtCore/qglobal.h>
-
-static const unsigned char qt_resource_data[] = {
-  // D:/CODING/Projects/Maemo/qwerkisync/resources/sphone.png
-  0x0,0x0,0x6,0x5c,
-  0x89,
-  0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,
-  0x0,0x0,0x20,0x0,0x0,0x0,0x20,0x8,0x6,0x0,0x0,0x0,0x73,0x7a,0x7a,0xf4,
-  0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xda,0xc,0x17,0x14,0x30,0x19,0xd7,
-  0x4d,0x82,0x51,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xa,0xf0,0x0,
-  0x0,0xa,0xf0,0x1,0x42,0xac,0x34,0x98,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,
-  0x0,0x0,0xb1,0x8f,0xb,0xfc,0x61,0x5,0x0,0x0,0x5,0xeb,0x49,0x44,0x41,0x54,
-  0x78,0xda,0xed,0x57,0x4d,0x68,0x5c,0x55,0x14,0x3e,0xef,0xbe,0xf7,0xe6,0x27,0x33,
-  0x93,0x99,0x49,0x34,0x69,0x9a,0xa6,0xa6,0x16,0x51,0x4c,0x8c,0x52,0x23,0xe2,0xa2,
-  0x16,0x77,0x52,0x84,0x4a,0x5b,0x45,0x97,0xda,0x90,0x95,0x50,0xba,0x10,0x41,0x5a,
-  0x62,0x77,0x22,0x88,0x74,0x63,0xb5,0x60,0xc1,0xea,0xc2,0x45,0x4a,0x5d,0xa8,0x48,
-  0xab,0x84,0xaa,0x60,0x17,0x5a,0xad,0x54,0x10,0x91,0xb6,0x36,0xda,0x64,0xa6,0xc9,
-  0x64,0x32,0xf3,0xe6,0xfd,0xbf,0x77,0xfd,0xce,0x9d,0x4c,0x9a,0x46,0xdb,0xa4,0xa1,
-  0xb,0x41,0xf,0x9c,0x79,0xef,0xfe,0x9c,0x7b,0xbe,0xf3,0x7b,0xdf,0x10,0xfd,0x4f,
-  0xff,0x75,0xd2,0x96,0x8f,0x77,0xef,0xde,0xbd,0xb7,0xa3,0xd0,0xb1,0x2d,0xa6,0x18,
-  0x43,0x1,0x8e,0x17,0x1f,0x4b,0x49,0x8,0x41,0x95,0x4a,0xe5,0xf4,0xf8,0xf8,0xf8,
-  0x21,0xc,0xe5,0x5a,0x1,0x18,0xcb,0xc6,0xd9,0xce,0xce,0xce,0x37,0xb6,0x6c,0xd9,
-  0x62,0x6,0x41,0x40,0xd9,0x6c,0x56,0x29,0x2a,0x95,0x4a,0xa4,0x69,0x1a,0xa5,0x52,
-  0xa9,0x6b,0x82,0x86,0x41,0x67,0xcf,0xfe,0xf0,0x14,0x5e,0xdf,0x3,0xd7,0x6f,0x17,
-  0x80,0x8d,0x85,0x42,0x41,0xcb,0xe5,0x72,0xf4,0x8b,0x95,0xa2,0xa8,0xad,0x5d,0x4d,
-  0x36,0x8a,0x79,0x28,0xd4,0x69,0xb2,0xda,0xd4,0x63,0x8,0x8d,0x86,0xf3,0x92,0xf2,
-  0x79,0xb5,0xbe,0x11,0xfc,0xf3,0x6d,0x1,0xa0,0xeb,0xfa,0xfa,0x42,0xbe,0xa0,0xf9,
-  0xb1,0x46,0xe5,0xee,0x47,0xa9,0x66,0xea,0x54,0x71,0x22,0xca,0x74,0x9,0xba,0x3c,
-  0x1f,0x50,0x50,0x90,0x2a,0x6a,0x32,0xe,0x69,0x28,0x3a,0x43,0xc5,0x62,0x41,0x63,
-  0x99,0x28,0x8a,0xd6,0xc,0x40,0x2c,0x1d,0xc,0xc,0xc,0xf4,0x48,0x92,0x3a,0x99,
-  0x69,0xd2,0xa0,0xcb,0xf3,0x63,0x72,0xbc,0x98,0x2c,0x37,0x22,0x17,0xef,0x51,0x24,
-  0xc1,0xc8,0x8e,0x8,0x5e,0x9,0x59,0x54,0xd3,0x59,0x46,0x9,0xbf,0x2b,0x4d,0x3a,
-  0x2c,0xb7,0xd3,0x9b,0x32,0xbd,0x66,0x0,0xeb,0x41,0x71,0x1c,0x93,0x4,0x80,0xc0,
-  0x8f,0x68,0xba,0xea,0x51,0x56,0x97,0xea,0x19,0xf9,0xe1,0x22,0x87,0x41,0x48,0x36,
-  0x0,0x84,0x61,0xa8,0x64,0xa0,0xfc,0x9,0x88,0x1f,0xc7,0x69,0x7b,0x29,0x45,0xf7,
-  0xac,0x35,0x4,0x5a,0x5b,0x5b,0xdb,0x6,0x4e,0x2e,0x37,0xd2,0xa9,0xe1,0x4,0xe4,
-  0xc3,0xfa,0x1a,0xcc,0x75,0x9c,0xf0,0x3a,0x21,0x29,0x25,0xd9,0xc8,0x9,0x4e,0xd0,
-  0x99,0xfb,0x76,0xee,0x6b,0x4e,0xd2,0x55,0x44,0x67,0x1a,0xfc,0x20,0x1d,0x91,0x75,
-  0x80,0x1,0x6a,0xf2,0x49,0xc7,0x73,0x92,0x2,0x1a,0x0,0x3f,0xab,0x45,0x37,0x3,
-  0x20,0x12,0x89,0xc4,0x3a,0xc4,0x94,0x1a,0x81,0x46,0xa5,0x39,0x97,0xee,0xc8,0x98,
-  0x74,0x65,0xce,0xa3,0x10,0xae,0xbf,0xae,0xce,0x30,0x68,0x20,0x3f,0xf2,0x0,0x90,
-  0xd2,0xa3,0x4e,0xcc,0xcc,0x29,0x6f,0x4a,0xa8,0xd3,0xe9,0x49,0x94,0xec,0x20,0xf8,
-  0xf,0xcc,0xfd,0x49,0x21,0x4d,0x51,0x37,0x95,0xb0,0x63,0x16,0xc8,0x6b,0x28,0x27,
-  0x79,0x23,0x0,0x5a,0x14,0xc7,0x1b,0x94,0x55,0xd,0xc4,0x19,0xae,0x9e,0x97,0xc8,
-  0x81,0x46,0x48,0x4b,0xcb,0x5c,0xaa,0xd6,0x21,0xa9,0x91,0x14,0x54,0x40,0x69,0x26,
-  0xad,0x12,0xb2,0x52,0x85,0x52,0x57,0x1c,0x83,0x5,0x98,0xc1,0x68,0x6a,0x2c,0x14,
-  0x23,0xad,0xe8,0xb5,0x5,0xe1,0x1b,0x0,0xd0,0x4d,0xc3,0xe8,0x4e,0x24,0x4c,0x2a,
-  0x23,0xe3,0x53,0x0,0x5a,0xae,0x38,0x14,0x44,0x72,0x51,0x6a,0xa9,0xb4,0x95,0xd4,
-  0xc8,0x34,0x4d,0xca,0x85,0xa5,0x96,0x5b,0x5,0x36,0x30,0x10,0x1f,0x7c,0x58,0x85,
-  0x80,0xdd,0x1f,0x62,0x6c,0x83,0xaf,0x22,0x4,0x7,0xb5,0x65,0xed,0xec,0x7a,0x0,
-  0x6,0x92,0x6a,0x9d,0x10,0x3a,0x94,0x6a,0x34,0x6f,0xb9,0x64,0xc3,0xfa,0x56,0xab,
-  0x5c,0xde,0xea,0xea,0x0,0x90,0xec,0x48,0x52,0xa2,0x7e,0x25,0xa2,0x4b,0xdf,0x6f,
-  0xa7,0xfe,0x87,0x47,0xb1,0xe9,0x7e,0x8,0x64,0xb0,0x3c,0x45,0xa3,0x9a,0x7d,0xab,
-  0x49,0xd8,0x9d,0x4e,0xa7,0x4d,0xee,0x7e,0xfd,0x26,0x8c,0xd1,0x1d,0x8a,0x72,0x2d,
-  0xb5,0xcb,0x61,0x68,0x74,0xa7,0x19,0x13,0x37,0x2c,0x74,0x47,0x93,0x5e,0x1f,0xbe,
-  0x8a,0xc9,0x3d,0x48,0xbe,0x87,0xb0,0x65,0x17,0x6c,0xe5,0xe,0x75,0xcb,0x0,0x7a,
-  0xe1,0x52,0xe9,0xba,0x2e,0xdd,0x9d,0x9c,0xa2,0xbb,0x8a,0xd1,0x8a,0xc2,0x8e,0xe3,
-  0x13,0x12,0x97,0x51,0xf5,0x82,0x2f,0x8c,0x3d,0xf3,0xf4,0x25,0x53,0xa4,0xcf,0xec,
-  0x6f,0xff,0xa8,0x44,0x2f,0xad,0x46,0xfd,0x12,0x0,0x7d,0x7d,0x7d,0x3d,0x50,0x6e,
-  0x4c,0x4c,0x4c,0xd0,0xd0,0xd0,0x90,0x2a,0x35,0xb6,0xdb,0x1,0xa0,0xd6,0x1d,0xc0,
-  0xe0,0xe0,0x25,0xb5,0x26,0x90,0x80,0x3f,0x9e,0x3b,0xc7,0x79,0x60,0xb0,0xec,0xe4,
-  0xe4,0x24,0x1a,0x94,0x71,0xaf,0x30,0xc4,0x27,0x87,0x82,0x17,0x7e,0x8a,0xdd,0x78,
-  0x6c,0x5f,0xea,0xfd,0x8f,0x57,0xd,0x60,0xf3,0xe6,0xcd,0x3d,0x8d,0x46,0x3,0xfd,
-  0x3d,0x4f,0x99,0x4c,0xa6,0x9,0x0,0x4a,0xf2,0x85,0xc2,0xe2,0x66,0x6,0x14,0x86,
-  0x11,0xc5,0xa8,0xe,0xb1,0x70,0x39,0xd5,0x6a,0x35,0x25,0xcb,0x0,0xec,0x64,0x7c,
-  0x51,0xf,0x3,0xd2,0x85,0x18,0x8a,0xa5,0x3c,0xb1,0x7f,0x76,0xe7,0x77,0x95,0x9a,
-  0x3d,0xf6,0xf6,0xa6,0xcf,0x3f,0x5b,0x9,0x0,0xf7,0xf4,0x3e,0xdb,0xb6,0x69,0x53,
-  0x7f,0x3f,0x75,0x75,0x75,0xa9,0x49,0xb8,0x97,0xca,0xe5,0xb2,0x2,0xd3,0xa2,0xd,
-  0x7d,0xbd,0xe4,0x79,0xbe,0x7a,0x2f,0x16,0x8b,0x34,0x3d,0x5d,0x22,0xf3,0x1,0xb9,
-  0x6b,0xc7,0x5b,0x8f,0x14,0x2b,0x57,0xaa,0x14,0x67,0x33,0xb1,0x17,0x84,0x82,0x65,
-  0x1c,0xdf,0x1f,0x76,0x2,0xef,0xd3,0x1d,0x67,0x87,0xbf,0x9d,0xb5,0x6a,0x7,0xbe,
-  0x79,0xfc,0xd7,0x2f,0x6f,0x8,0x0,0xae,0x5d,0xe7,0x38,0xe,0xf9,0xb0,0x60,0x76,
-  0x76,0xb6,0xb9,0x88,0xa6,0x54,0xad,0x56,0x55,0xb2,0x31,0xd5,0xeb,0x75,0xe5,0x15,
-  0x5c,0x3e,0x6a,0x1c,0xe2,0xca,0x66,0x36,0xf3,0x62,0xab,0xeb,0xf9,0x5b,0x2d,0xdd,
-  0x25,0x6e,0x59,0x9,0x74,0x53,0xc6,0xec,0xe1,0x2c,0xb,0x61,0xb3,0x5c,0xef,0x31,
-  0xdb,0xd,0xbe,0xd8,0x74,0xa2,0xeb,0xf4,0x9c,0x5b,0x3b,0x50,0x7d,0xde,0xfd,0x7a,
-  0x39,0x0,0xe1,0xda,0x76,0x6f,0x88,0x83,0x4d,0xc3,0x54,0xbd,0x5e,0xe5,0xbc,0x94,
-  0x4a,0x99,0x1a,0x6b,0xb,0xef,0xe8,0xff,0x51,0x18,0xaa,0x78,0x18,0xe8,0x3,0x61,
-  0x84,0x71,0x39,0x24,0x7,0xde,0x43,0x23,0x63,0xab,0xc9,0xd4,0x75,0x55,0x2f,0x3e,
-  0xf6,0x39,0x9e,0x47,0x75,0x5,0x2,0x65,0xed,0xfb,0xdb,0x2,0x4f,0x7e,0x25,0x8e,
-  0xd0,0x48,0x3c,0xaa,0xbe,0x23,0xae,0x1,0xd0,0x84,0xe8,0x9,0xb1,0x19,0xf7,0x1,
-  0xd9,0x4e,0xb3,0x82,0x38,0xe1,0x98,0x5a,0x63,0xee,0x92,0x3e,0x14,0x78,0xd8,0xc7,
-  0xc4,0x7b,0x19,0x90,0x59,0x87,0xa7,0x90,0x3f,0xac,0x30,0x9,0xeb,0xb9,0x9d,0xb3,
-  0xb,0x2,0x0,0x76,0xe1,0x21,0x1b,0xfb,0x1b,0xc,0xc0,0xf5,0xa4,0x17,0x86,0x47,
-  0x63,0x49,0xe3,0xcb,0x3d,0xa0,0x3,0x7d,0x37,0x5b,0x88,0x4,0x52,0x8a,0x98,0xf8,
-  0x66,0xe4,0xc3,0xd8,0xed,0x2d,0x0,0x2a,0x39,0xf1,0xd4,0xf0,0xe4,0x35,0x96,0x31,
-  0xe7,0xd,0x5,0x80,0x95,0xb1,0xf5,0x7c,0x6,0x7b,0x80,0xaf,0x6e,0xe,0x29,0xcf,
-  0x83,0x7f,0xf7,0x3,0x7f,0x34,0x1c,0x89,0x4e,0xfe,0x53,0xe,0x14,0x70,0x70,0x8e,
-  0x15,0xe6,0xda,0xdb,0xa9,0xbd,0xbd,0x7d,0xa1,0xce,0x1d,0xe5,0x85,0x96,0x27,0xd8,
-  0x72,0xb6,0xb8,0x3,0xc9,0xa7,0x0,0x41,0x19,0xcb,0x68,0x8e,0x88,0x4a,0xcf,0xcd,
-  0xf7,0x61,0x6a,0xaa,0xe3,0xc3,0xec,0x4e,0x5d,0x17,0xc7,0x79,0x9d,0x43,0x82,0xb0,
-  0x4a,0xf0,0x3b,0x76,0xe4,0xbf,0x42,0x23,0x7f,0xff,0x74,0x6b,0x1,0xe8,0x45,0x49,
-  0x49,0xcb,0xb2,0x68,0x76,0x66,0x46,0x7d,0x3,0x32,0xa1,0xc4,0x91,0x88,0x26,0x7a,
-  0x81,0xb3,0x18,0x12,0x1f,0x20,0xf8,0x60,0xe5,0xb6,0x5,0x0,0x69,0xc8,0x52,0xb3,
-  0x19,0x4d,0xd5,0x5d,0xef,0xa2,0xd0,0x9a,0xb7,0x27,0x8c,0xba,0x80,0x9d,0x23,0xd1,
-  0x48,0x34,0xb1,0x52,0x19,0x3a,0xb0,0xc,0xb9,0x15,0x1a,0x27,0x4f,0x9d,0x5a,0xa9,
-  0x77,0x2c,0x92,0x6c,0x66,0x2a,0x5,0xdc,0x1c,0x70,0x6,0xf,0xf1,0xe1,0xf6,0x1b,
-  0x7e,0xaa,0x48,0xd2,0x63,0x54,0xa3,0x57,0xe9,0x65,0x6a,0xdc,0xec,0x8c,0x16,0x80,
-  0xb,0xa8,0xf7,0xf,0x66,0x66,0x66,0xf6,0x0,0xb5,0xc6,0x8d,0x28,0x9b,0xcb,0x52,
-  0x36,0x93,0x55,0x56,0xf3,0xad,0xa7,0xe,0x47,0x2c,0x39,0x2c,0x56,0xc3,0x22,0xab,
-  0x6e,0x11,0x37,0x2e,0xe4,0x7,0x44,0xe4,0x31,0x3e,0x43,0x6d,0x62,0x37,0x8f,0x51,
-  0x27,0x1d,0xa4,0x98,0x56,0x41,0xda,0x92,0xe7,0xc6,0xc1,0xc1,0xc1,0xa3,0x8,0xc3,
-  0x36,0x43,0x37,0xf4,0x44,0x32,0xa1,0x1a,0x91,0xd1,0xca,0x6a,0x95,0x54,0xcd,0x32,
-  0xe4,0x4a,0xf0,0x7d,0xce,0x87,0x28,0xc2,0xe5,0x75,0xfa,0xfc,0xf9,0xf3,0x2f,0x62,
-  0xf9,0x32,0xad,0xe1,0xff,0xc1,0xd2,0x3f,0x26,0xac,0xa5,0x3,0xdc,0xb9,0xf0,0xbe,
-  0x1a,0x62,0xd7,0x73,0xd7,0xaa,0x2c,0xbc,0xdf,0x32,0x69,0xab,0x9c,0xbb,0x19,0xad,
-  0xf9,0x5f,0xd1,0xbf,0x82,0xfe,0x2,0x92,0x85,0x12,0x9,0xe1,0x19,0x84,0x3a,0x0,
-  0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82,
-    // D:/CODING/Projects/Maemo/qwerkisync/resources/phone.png
-  0x0,0x0,0x3b,0x35,
-  0x89,
-  0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,
-  0x0,0x0,0x80,0x0,0x0,0x0,0x80,0x8,0x6,0x0,0x0,0x0,0xc3,0x3e,0x61,0xcb,
-  0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,
-  0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0xa,0x4d,0x69,0x43,0x43,0x50,0x50,0x68,0x6f,
-  0x74,0x6f,0x73,0x68,0x6f,0x70,0x20,0x49,0x43,0x43,0x20,0x70,0x72,0x6f,0x66,0x69,
-  0x6c,0x65,0x0,0x0,0x78,0xda,0x9d,0x53,0x77,0x58,0x93,0xf7,0x16,0x3e,0xdf,0xf7,
-  0x65,0xf,0x56,0x42,0xd8,0xf0,0xb1,0x97,0x6c,0x81,0x0,0x22,0x23,0xac,0x8,0xc8,
-  0x10,0x59,0xa2,0x10,0x92,0x0,0x61,0x84,0x10,0x12,0x40,0xc5,0x85,0x88,0xa,0x56,
-  0x14,0x15,0x11,0x9c,0x48,0x55,0xc4,0x82,0xd5,0xa,0x48,0x9d,0x88,0xe2,0xa0,0x28,
-  0xb8,0x67,0x41,0x8a,0x88,0x5a,0x8b,0x55,0x5c,0x38,0xee,0x1f,0xdc,0xa7,0xb5,0x7d,
-  0x7a,0xef,0xed,0xed,0xfb,0xd7,0xfb,0xbc,0xe7,0x9c,0xe7,0xfc,0xce,0x79,0xcf,0xf,
-  0x80,0x11,0x12,0x26,0x91,0xe6,0xa2,0x6a,0x0,0x39,0x52,0x85,0x3c,0x3a,0xd8,0x1f,
-  0x8f,0x4f,0x48,0xc4,0xc9,0xbd,0x80,0x2,0x15,0x48,0xe0,0x4,0x20,0x10,0xe6,0xcb,
-  0xc2,0x67,0x5,0xc5,0x0,0x0,0xf0,0x3,0x79,0x78,0x7e,0x74,0xb0,0x3f,0xfc,0x1,
-  0xaf,0x6f,0x0,0x2,0x0,0x70,0xd5,0x2e,0x24,0x12,0xc7,0xe1,0xff,0x83,0xba,0x50,
-  0x26,0x57,0x0,0x20,0x91,0x0,0xe0,0x22,0x12,0xe7,0xb,0x1,0x90,0x52,0x0,0xc8,
-  0x2e,0x54,0xc8,0x14,0x0,0xc8,0x18,0x0,0xb0,0x53,0xb3,0x64,0xa,0x0,0x94,0x0,
-  0x0,0x6c,0x79,0x7c,0x42,0x22,0x0,0xaa,0xd,0x0,0xec,0xf4,0x49,0x3e,0x5,0x0,
-  0xd8,0xa9,0x93,0xdc,0x17,0x0,0xd8,0xa2,0x1c,0xa9,0x8,0x0,0x8d,0x1,0x0,0x99,
-  0x28,0x47,0x24,0x2,0x40,0xbb,0x0,0x60,0x55,0x81,0x52,0x2c,0x2,0xc0,0xc2,0x0,
-  0xa0,0xac,0x40,0x22,0x2e,0x4,0xc0,0xae,0x1,0x80,0x59,0xb6,0x32,0x47,0x2,0x80,
-  0xbd,0x5,0x0,0x76,0x8e,0x58,0x90,0xf,0x40,0x60,0x0,0x80,0x99,0x42,0x2c,0xcc,
-  0x0,0x20,0x38,0x2,0x0,0x43,0x1e,0x13,0xcd,0x3,0x20,0x4c,0x3,0xa0,0x30,0xd2,
-  0xbf,0xe0,0xa9,0x5f,0x70,0x85,0xb8,0x48,0x1,0x0,0xc0,0xcb,0x95,0xcd,0x97,0x4b,
-  0xd2,0x33,0x14,0xb8,0x95,0xd0,0x1a,0x77,0xf2,0xf0,0xe0,0xe2,0x21,0xe2,0xc2,0x6c,
-  0xb1,0x42,0x61,0x17,0x29,0x10,0x66,0x9,0xe4,0x22,0x9c,0x97,0x9b,0x23,0x13,0x48,
-  0xe7,0x3,0x4c,0xce,0xc,0x0,0x0,0x1a,0xf9,0xd1,0xc1,0xfe,0x38,0x3f,0x90,0xe7,
-  0xe6,0xe4,0xe1,0xe6,0x66,0xe7,0x6c,0xef,0xf4,0xc5,0xa2,0xfe,0x6b,0xf0,0x6f,0x22,
-  0x3e,0x21,0xf1,0xdf,0xfe,0xbc,0x8c,0x2,0x4,0x0,0x10,0x4e,0xcf,0xef,0xda,0x5f,
-  0xe5,0xe5,0xd6,0x3,0x70,0xc7,0x1,0xb0,0x75,0xbf,0x6b,0xa9,0x5b,0x0,0xda,0x56,
-  0x0,0x68,0xdf,0xf9,0x5d,0x33,0xdb,0x9,0xa0,0x5a,0xa,0xd0,0x7a,0xf9,0x8b,0x79,
-  0x38,0xfc,0x40,0x1e,0x9e,0xa1,0x50,0xc8,0x3c,0x1d,0x1c,0xa,0xb,0xb,0xed,0x25,
-  0x62,0xa1,0xbd,0x30,0xe3,0x8b,0x3e,0xff,0x33,0xe1,0x6f,0xe0,0x8b,0x7e,0xf6,0xfc,
-  0x40,0x1e,0xfe,0xdb,0x7a,0xf0,0x0,0x71,0x9a,0x40,0x99,0xad,0xc0,0xa3,0x83,0xfd,
-  0x71,0x61,0x6e,0x76,0xae,0x52,0x8e,0xe7,0xcb,0x4,0x42,0x31,0x6e,0xf7,0xe7,0x23,
-  0xfe,0xc7,0x85,0x7f,0xfd,0x8e,0x29,0xd1,0xe2,0x34,0xb1,0x5c,0x2c,0x15,0x8a,0xf1,
-  0x58,0x89,0xb8,0x50,0x22,0x4d,0xc7,0x79,0xb9,0x52,0x91,0x44,0x21,0xc9,0x95,0xe2,
-  0x12,0xe9,0x7f,0x32,0xf1,0x1f,0x96,0xfd,0x9,0x93,0x77,0xd,0x0,0xac,0x86,0x4f,
-  0xc0,0x4e,0xb6,0x7,0xb5,0xcb,0x6c,0xc0,0x7e,0xee,0x1,0x2,0x8b,0xe,0x58,0xd2,
-  0x76,0x0,0x40,0x7e,0xf3,0x2d,0x8c,0x1a,0xb,0x91,0x0,0x10,0x67,0x34,0x32,0x79,
-  0xf7,0x0,0x0,0x93,0xbf,0xf9,0x8f,0x40,0x2b,0x1,0x0,0xcd,0x97,0xa4,0xe3,0x0,
-  0x0,0xbc,0xe8,0x18,0x5c,0xa8,0x94,0x17,0x4c,0xc6,0x8,0x0,0x0,0x44,0xa0,0x81,
-  0x2a,0xb0,0x41,0x7,0xc,0xc1,0x14,0xac,0xc0,0xe,0x9c,0xc1,0x1d,0xbc,0xc0,0x17,
-  0x2,0x61,0x6,0x44,0x40,0xc,0x24,0xc0,0x3c,0x10,0x42,0x6,0xe4,0x80,0x1c,0xa,
-  0xa1,0x18,0x96,0x41,0x19,0x54,0xc0,0x3a,0xd8,0x4,0xb5,0xb0,0x3,0x1a,0xa0,0x11,
-  0x9a,0xe1,0x10,0xb4,0xc1,0x31,0x38,0xd,0xe7,0xe0,0x12,0x5c,0x81,0xeb,0x70,0x17,
-  0x6,0x60,0x18,0x9e,0xc2,0x18,0xbc,0x86,0x9,0x4,0x41,0xc8,0x8,0x13,0x61,0x21,
-  0x3a,0x88,0x11,0x62,0x8e,0xd8,0x22,0xce,0x8,0x17,0x99,0x8e,0x4,0x22,0x61,0x48,
-  0x34,0x92,0x80,0xa4,0x20,0xe9,0x88,0x14,0x51,0x22,0xc5,0xc8,0x72,0xa4,0x2,0xa9,
-  0x42,0x6a,0x91,0x5d,0x48,0x23,0xf2,0x2d,0x72,0x14,0x39,0x8d,0x5c,0x40,0xfa,0x90,
-  0xdb,0xc8,0x20,0x32,0x8a,0xfc,0x8a,0xbc,0x47,0x31,0x94,0x81,0xb2,0x51,0x3,0xd4,
-  0x2,0x75,0x40,0xb9,0xa8,0x1f,0x1a,0x8a,0xc6,0xa0,0x73,0xd1,0x74,0x34,0xf,0x5d,
-  0x80,0x96,0xa2,0x6b,0xd1,0x1a,0xb4,0x1e,0x3d,0x80,0xb6,0xa2,0xa7,0xd1,0x4b,0xe8,
-  0x75,0x74,0x0,0x7d,0x8a,0x8e,0x63,0x80,0xd1,0x31,0xe,0x66,0x8c,0xd9,0x61,0x5c,
-  0x8c,0x87,0x45,0x60,0x89,0x58,0x1a,0x26,0xc7,0x16,0x63,0xe5,0x58,0x35,0x56,0x8f,
-  0x35,0x63,0x1d,0x58,0x37,0x76,0x15,0x1b,0xc0,0x9e,0x61,0xef,0x8,0x24,0x2,0x8b,
-  0x80,0x13,0xec,0x8,0x5e,0x84,0x10,0xc2,0x6c,0x82,0x90,0x90,0x47,0x58,0x4c,0x58,
-  0x43,0xa8,0x25,0xec,0x23,0xb4,0x12,0xba,0x8,0x57,0x9,0x83,0x84,0x31,0xc2,0x27,
-  0x22,0x93,0xa8,0x4f,0xb4,0x25,0x7a,0x12,0xf9,0xc4,0x78,0x62,0x3a,0xb1,0x90,0x58,
-  0x46,0xac,0x26,0xee,0x21,0x1e,0x21,0x9e,0x25,0x5e,0x27,0xe,0x13,0x5f,0x93,0x48,
-  0x24,0xe,0xc9,0x92,0xe4,0x4e,0xa,0x21,0x25,0x90,0x32,0x49,0xb,0x49,0x6b,0x48,
-  0xdb,0x48,0x2d,0xa4,0x53,0xa4,0x3e,0xd2,0x10,0x69,0x9c,0x4c,0x26,0xeb,0x90,0x6d,
-  0xc9,0xde,0xe4,0x8,0xb2,0x80,0xac,0x20,0x97,0x91,0xb7,0x90,0xf,0x90,0x4f,0x92,
-  0xfb,0xc9,0xc3,0xe4,0xb7,0x14,0x3a,0xc5,0x88,0xe2,0x4c,0x9,0xa2,0x24,0x52,0xa4,
-  0x94,0x12,0x4a,0x35,0x65,0x3f,0xe5,0x4,0xa5,0x9f,0x32,0x42,0x99,0xa0,0xaa,0x51,
-  0xcd,0xa9,0x9e,0xd4,0x8,0xaa,0x88,0x3a,0x9f,0x5a,0x49,0x6d,0xa0,0x76,0x50,0x2f,
-  0x53,0x87,0xa9,0x13,0x34,0x75,0x9a,0x25,0xcd,0x9b,0x16,0x43,0xcb,0xa4,0x2d,0xa3,
-  0xd5,0xd0,0x9a,0x69,0x67,0x69,0xf7,0x68,0x2f,0xe9,0x74,0xba,0x9,0xdd,0x83,0x1e,
-  0x45,0x97,0xd0,0x97,0xd2,0x6b,0xe8,0x7,0xe9,0xe7,0xe9,0x83,0xf4,0x77,0xc,0xd,
-  0x86,0xd,0x83,0xc7,0x48,0x62,0x28,0x19,0x6b,0x19,0x7b,0x19,0xa7,0x18,0xb7,0x19,
-  0x2f,0x99,0x4c,0xa6,0x5,0xd3,0x97,0x99,0xc8,0x54,0x30,0xd7,0x32,0x1b,0x99,0x67,
-  0x98,0xf,0x98,0x6f,0x55,0x58,0x2a,0xf6,0x2a,0x7c,0x15,0x91,0xca,0x12,0x95,0x3a,
-  0x95,0x56,0x95,0x7e,0x95,0xe7,0xaa,0x54,0x55,0x73,0x55,0x3f,0xd5,0x79,0xaa,0xb,
-  0x54,0xab,0x55,0xf,0xab,0x5e,0x56,0x7d,0xa6,0x46,0x55,0xb3,0x50,0xe3,0xa9,0x9,
-  0xd4,0x16,0xab,0xd5,0xa9,0x1d,0x55,0xbb,0xa9,0x36,0xae,0xce,0x52,0x77,0x52,0x8f,
-  0x50,0xcf,0x51,0x5f,0xa3,0xbe,0x5f,0xfd,0x82,0xfa,0x63,0xd,0xb2,0x86,0x85,0x46,
-  0xa0,0x86,0x48,0xa3,0x54,0x63,0xb7,0xc6,0x19,0x8d,0x21,0x16,0xc6,0x32,0x65,0xf1,
-  0x58,0x42,0xd6,0x72,0x56,0x3,0xeb,0x2c,0x6b,0x98,0x4d,0x62,0x5b,0xb2,0xf9,0xec,
-  0x4c,0x76,0x5,0xfb,0x1b,0x76,0x2f,0x7b,0x4c,0x53,0x43,0x73,0xaa,0x66,0xac,0x66,
-  0x91,0x66,0x9d,0xe6,0x71,0xcd,0x1,0xe,0xc6,0xb1,0xe0,0xf0,0x39,0xd9,0x9c,0x4a,
-  0xce,0x21,0xce,0xd,0xce,0x7b,0x2d,0x3,0x2d,0x3f,0x2d,0xb1,0xd6,0x6a,0xad,0x66,
-  0xad,0x7e,0xad,0x37,0xda,0x7a,0xda,0xbe,0xda,0x62,0xed,0x72,0xed,0x16,0xed,0xeb,
-  0xda,0xef,0x75,0x70,0x9d,0x40,0x9d,0x2c,0x9d,0xf5,0x3a,0x6d,0x3a,0xf7,0x75,0x9,
-  0xba,0x36,0xba,0x51,0xba,0x85,0xba,0xdb,0x75,0xcf,0xea,0x3e,0xd3,0x63,0xeb,0x79,
-  0xe9,0x9,0xf5,0xca,0xf5,0xe,0xe9,0xdd,0xd1,0x47,0xf5,0x6d,0xf4,0xa3,0xf5,0x17,
-  0xea,0xef,0xd6,0xef,0xd1,0x1f,0x37,0x30,0x34,0x8,0x36,0x90,0x19,0x6c,0x31,0x38,
-  0x63,0xf0,0xcc,0x90,0x63,0xe8,0x6b,0x98,0x69,0xb8,0xd1,0xf0,0x84,0xe1,0xa8,0x11,
-  0xcb,0x68,0xba,0x91,0xc4,0x68,0xa3,0xd1,0x49,0xa3,0x27,0xb8,0x26,0xee,0x87,0x67,
-  0xe3,0x35,0x78,0x17,0x3e,0x66,0xac,0x6f,0x1c,0x62,0xac,0x34,0xde,0x65,0xdc,0x6b,
-  0x3c,0x61,0x62,0x69,0x32,0xdb,0xa4,0xc4,0xa4,0xc5,0xe4,0xbe,0x29,0xcd,0x94,0x6b,
-  0x9a,0x66,0xba,0xd1,0xb4,0xd3,0x74,0xcc,0xcc,0xc8,0x2c,0xdc,0xac,0xd8,0xac,0xc9,
-  0xec,0x8e,0x39,0xd5,0x9c,0x6b,0x9e,0x61,0xbe,0xd9,0xbc,0xdb,0xfc,0x8d,0x85,0xa5,
-  0x45,0x9c,0xc5,0x4a,0x8b,0x36,0x8b,0xc7,0x96,0xda,0x96,0x7c,0xcb,0x5,0x96,0x4d,
-  0x96,0xf7,0xac,0x98,0x56,0x3e,0x56,0x79,0x56,0xf5,0x56,0xd7,0xac,0x49,0xd6,0x5c,
-  0xeb,0x2c,0xeb,0x6d,0xd6,0x57,0x6c,0x50,0x1b,0x57,0x9b,0xc,0x9b,0x3a,0x9b,0xcb,
-  0xb6,0xa8,0xad,0x9b,0xad,0xc4,0x76,0x9b,0x6d,0xdf,0x14,0xe2,0x14,0x8f,0x29,0xd2,
-  0x29,0xf5,0x53,0x6e,0xda,0x31,0xec,0xfc,0xec,0xa,0xec,0x9a,0xec,0x6,0xed,0x39,
-  0xf6,0x61,0xf6,0x25,0xf6,0x6d,0xf6,0xcf,0x1d,0xcc,0x1c,0x12,0x1d,0xd6,0x3b,0x74,
-  0x3b,0x7c,0x72,0x74,0x75,0xcc,0x76,0x6c,0x70,0xbc,0xeb,0xa4,0xe1,0x34,0xc3,0xa9,
-  0xc4,0xa9,0xc3,0xe9,0x57,0x67,0x1b,0x67,0xa1,0x73,0x9d,0xf3,0x35,0x17,0xa6,0x4b,
-  0x90,0xcb,0x12,0x97,0x76,0x97,0x17,0x53,0x6d,0xa7,0x8a,0xa7,0x6e,0x9f,0x7a,0xcb,
-  0x95,0xe5,0x1a,0xee,0xba,0xd2,0xb5,0xd3,0xf5,0xa3,0x9b,0xbb,0x9b,0xdc,0xad,0xd9,
-  0x6d,0xd4,0xdd,0xcc,0x3d,0xc5,0x7d,0xab,0xfb,0x4d,0x2e,0x9b,0x1b,0xc9,0x5d,0xc3,
-  0x3d,0xef,0x41,0xf4,0xf0,0xf7,0x58,0xe2,0x71,0xcc,0xe3,0x9d,0xa7,0x9b,0xa7,0xc2,
-  0xf3,0x90,0xe7,0x2f,0x5e,0x76,0x5e,0x59,0x5e,0xfb,0xbd,0x1e,0x4f,0xb3,0x9c,0x26,
-  0x9e,0xd6,0x30,0x6d,0xc8,0xdb,0xc4,0x5b,0xe0,0xbd,0xcb,0x7b,0x60,0x3a,0x3e,0x3d,
-  0x65,0xfa,0xce,0xe9,0x3,0x3e,0xc6,0x3e,0x2,0x9f,0x7a,0x9f,0x87,0xbe,0xa6,0xbe,
-  0x22,0xdf,0x3d,0xbe,0x23,0x7e,0xd6,0x7e,0x99,0x7e,0x7,0xfc,0x9e,0xfb,0x3b,0xfa,
-  0xcb,0xfd,0x8f,0xf8,0xbf,0xe1,0x79,0xf2,0x16,0xf1,0x4e,0x5,0x60,0x1,0xc1,0x1,
-  0xe5,0x1,0xbd,0x81,0x1a,0x81,0xb3,0x3,0x6b,0x3,0x1f,0x4,0x99,0x4,0xa5,0x7,
-  0x35,0x5,0x8d,0x5,0xbb,0x6,0x2f,0xc,0x3e,0x15,0x42,0xc,0x9,0xd,0x59,0x1f,
-  0x72,0x93,0x6f,0xc0,0x17,0xf2,0x1b,0xf9,0x63,0x33,0xdc,0x67,0x2c,0x9a,0xd1,0x15,
-  0xca,0x8,0x9d,0x15,0x5a,0x1b,0xfa,0x30,0xcc,0x26,0x4c,0x1e,0xd6,0x11,0x8e,0x86,
-  0xcf,0x8,0xdf,0x10,0x7e,0x6f,0xa6,0xf9,0x4c,0xe9,0xcc,0xb6,0x8,0x88,0xe0,0x47,
-  0x6c,0x88,0xb8,0x1f,0x69,0x19,0x99,0x17,0xf9,0x7d,0x14,0x29,0x2a,0x32,0xaa,0x2e,
-  0xea,0x51,0xb4,0x53,0x74,0x71,0x74,0xf7,0x2c,0xd6,0xac,0xe4,0x59,0xfb,0x67,0xbd,
-  0x8e,0xf1,0x8f,0xa9,0x8c,0xb9,0x3b,0xdb,0x6a,0xb6,0x72,0x76,0x67,0xac,0x6a,0x6c,
-  0x52,0x6c,0x63,0xec,0x9b,0xb8,0x80,0xb8,0xaa,0xb8,0x81,0x78,0x87,0xf8,0x45,0xf1,
-  0x97,0x12,0x74,0x13,0x24,0x9,0xed,0x89,0xe4,0xc4,0xd8,0xc4,0x3d,0x89,0xe3,0x73,
-  0x2,0xe7,0x6c,0x9a,0x33,0x9c,0xe4,0x9a,0x54,0x96,0x74,0x63,0xae,0xe5,0xdc,0xa2,
-  0xb9,0x17,0xe6,0xe9,0xce,0xcb,0x9e,0x77,0x3c,0x59,0x35,0x59,0x90,0x7c,0x38,0x85,
-  0x98,0x12,0x97,0xb2,0x3f,0xe5,0x83,0x20,0x42,0x50,0x2f,0x18,0x4f,0xe5,0xa7,0x6e,
-  0x4d,0x1d,0x13,0xf2,0x84,0x9b,0x85,0x4f,0x45,0xbe,0xa2,0x8d,0xa2,0x51,0xb1,0xb7,
-  0xb8,0x4a,0x3c,0x92,0xe6,0x9d,0x56,0x95,0xf6,0x38,0xdd,0x3b,0x7d,0x43,0xfa,0x68,
-  0x86,0x4f,0x46,0x75,0xc6,0x33,0x9,0x4f,0x52,0x2b,0x79,0x91,0x19,0x92,0xb9,0x23,
-  0xf3,0x4d,0x56,0x44,0xd6,0xde,0xac,0xcf,0xd9,0x71,0xd9,0x2d,0x39,0x94,0x9c,0x94,
-  0x9c,0xa3,0x52,0xd,0x69,0x96,0xb4,0x2b,0xd7,0x30,0xb7,0x28,0xb7,0x4f,0x66,0x2b,
-  0x2b,0x93,0xd,0xe4,0x79,0xe6,0x6d,0xca,0x1b,0x93,0x87,0xca,0xf7,0xe4,0x23,0xf9,
-  0x73,0xf3,0xdb,0x15,0x6c,0x85,0x4c,0xd1,0xa3,0xb4,0x52,0xae,0x50,0xe,0x16,0x4c,
-  0x2f,0xa8,0x2b,0x78,0x5b,0x18,0x5b,0x78,0xb8,0x48,0xbd,0x48,0x5a,0xd4,0x33,0xdf,
-  0x66,0xfe,0xea,0xf9,0x23,0xb,0x82,0x16,0x7c,0xbd,0x90,0xb0,0x50,0xb8,0xb0,0xb3,
-  0xd8,0xb8,0x78,0x59,0xf1,0xe0,0x22,0xbf,0x45,0xbb,0x16,0x23,0x8b,0x53,0x17,0x77,
-  0x2e,0x31,0x5d,0x52,0xba,0x64,0x78,0x69,0xf0,0xd2,0x7d,0xcb,0x68,0xcb,0xb2,0x96,
-  0xfd,0x50,0xe2,0x58,0x52,0x55,0xf2,0x6a,0x79,0xdc,0xf2,0x8e,0x52,0x83,0xd2,0xa5,
-  0xa5,0x43,0x2b,0x82,0x57,0x34,0x95,0xa9,0x94,0xc9,0xcb,0x6e,0xae,0xf4,0x5a,0xb9,
-  0x63,0x15,0x61,0x95,0x64,0x55,0xef,0x6a,0x97,0xd5,0x5b,0x56,0x7f,0x2a,0x17,0x95,
-  0x5f,0xac,0x70,0xac,0xa8,0xae,0xf8,0xb0,0x46,0xb8,0xe6,0xe2,0x57,0x4e,0x5f,0xd5,
-  0x7c,0xf5,0x79,0x6d,0xda,0xda,0xde,0x4a,0xb7,0xca,0xed,0xeb,0x48,0xeb,0xa4,0xeb,
-  0x6e,0xac,0xf7,0x59,0xbf,0xaf,0x4a,0xbd,0x6a,0x41,0xd5,0xd0,0x86,0xf0,0xd,0xad,
-  0x1b,0xf1,0x8d,0xe5,0x1b,0x5f,0x6d,0x4a,0xde,0x74,0xa1,0x7a,0x6a,0xf5,0x8e,0xcd,
-  0xb4,0xcd,0xca,0xcd,0x3,0x35,0x61,0x35,0xed,0x5b,0xcc,0xb6,0xac,0xdb,0xf2,0xa1,
-  0x36,0xa3,0xf6,0x7a,0x9d,0x7f,0x5d,0xcb,0x56,0xfd,0xad,0xab,0xb7,0xbe,0xd9,0x26,
-  0xda,0xd6,0xbf,0xdd,0x77,0x7b,0xf3,0xe,0x83,0x1d,0x15,0x3b,0xde,0xef,0x94,0xec,
-  0xbc,0xb5,0x2b,0x78,0x57,0x6b,0xbd,0x45,0x7d,0xf5,0x6e,0xd2,0xee,0x82,0xdd,0x8f,
-  0x1a,0x62,0x1b,0xba,0xbf,0xe6,0x7e,0xdd,0xb8,0x47,0x77,0x4f,0xc5,0x9e,0x8f,0x7b,
-  0xa5,0x7b,0x7,0xf6,0x45,0xef,0xeb,0x6a,0x74,0x6f,0x6c,0xdc,0xaf,0xbf,0xbf,0xb2,
-  0x9,0x6d,0x52,0x36,0x8d,0x1e,0x48,0x3a,0x70,0xe5,0x9b,0x80,0x6f,0xda,0x9b,0xed,
-  0x9a,0x77,0xb5,0x70,0x5a,0x2a,0xe,0xc2,0x41,0xe5,0xc1,0x27,0xdf,0xa6,0x7c,0x7b,
-  0xe3,0x50,0xe8,0xa1,0xce,0xc3,0xdc,0xc3,0xcd,0xdf,0x99,0x7f,0xb7,0xf5,0x8,0xeb,
-  0x48,0x79,0x2b,0xd2,0x3a,0xbf,0x75,0xac,0x2d,0xa3,0x6d,0xa0,0x3d,0xa1,0xbd,0xef,
-  0xe8,0x8c,0xa3,0x9d,0x1d,0x5e,0x1d,0x47,0xbe,0xb7,0xff,0x7e,0xef,0x31,0xe3,0x63,
-  0x75,0xc7,0x35,0x8f,0x57,0x9e,0xa0,0x9d,0x28,0x3d,0xf1,0xf9,0xe4,0x82,0x93,0xe3,
-  0xa7,0x64,0xa7,0x9e,0x9d,0x4e,0x3f,0x3d,0xd4,0x99,0xdc,0x79,0xf7,0x4c,0xfc,0x99,
-  0x6b,0x5d,0x51,0x5d,0xbd,0x67,0x43,0xcf,0x9e,0x3f,0x17,0x74,0xee,0x4c,0xb7,0x5f,
-  0xf7,0xc9,0xf3,0xde,0xe7,0x8f,0x5d,0xf0,0xbc,0x70,0xf4,0x22,0xf7,0x62,0xdb,0x25,
-  0xb7,0x4b,0xad,0x3d,0xae,0x3d,0x47,0x7e,0x70,0xfd,0xe1,0x48,0xaf,0x5b,0x6f,0xeb,
-  0x65,0xf7,0xcb,0xed,0x57,0x3c,0xae,0x74,0xf4,0x4d,0xeb,0x3b,0xd1,0xef,0xd3,0x7f,
-  0xfa,0x6a,0xc0,0xd5,0x73,0xd7,0xf8,0xd7,0x2e,0x5d,0x9f,0x79,0xbd,0xef,0xc6,0xec,
-  0x1b,0xb7,0x6e,0x26,0xdd,0x1c,0xb8,0x25,0xba,0xf5,0xf8,0x76,0xf6,0xed,0x17,0x77,
-  0xa,0xee,0x4c,0xdc,0x5d,0x7a,0x8f,0x78,0xaf,0xfc,0xbe,0xda,0xfd,0xea,0x7,0xfa,
-  0xf,0xea,0x7f,0xb4,0xfe,0xb1,0x65,0xc0,0x6d,0xe0,0xf8,0x60,0xc0,0x60,0xcf,0xc3,
-  0x59,0xf,0xef,0xe,0x9,0x87,0x9e,0xfe,0x94,0xff,0xd3,0x87,0xe1,0xd2,0x47,0xcc,
-  0x47,0xd5,0x23,0x46,0x23,0x8d,0x8f,0x9d,0x1f,0x1f,0x1b,0xd,0x1a,0xbd,0xf2,0x64,
-  0xce,0x93,0xe1,0xa7,0xb2,0xa7,0x13,0xcf,0xca,0x7e,0x56,0xff,0x79,0xeb,0x73,0xab,
-  0xe7,0xdf,0xfd,0xe2,0xfb,0x4b,0xcf,0x58,0xfc,0xd8,0xf0,0xb,0xf9,0x8b,0xcf,0xbf,
-  0xae,0x79,0xa9,0xf3,0x72,0xef,0xab,0xa9,0xaf,0x3a,0xc7,0x23,0xc7,0x1f,0xbc,0xce,
-  0x79,0x3d,0xf1,0xa6,0xfc,0xad,0xce,0xdb,0x7d,0xef,0xb8,0xef,0xba,0xdf,0xc7,0xbd,
-  0x1f,0x99,0x28,0xfc,0x40,0xfe,0x50,0xf3,0xd1,0xfa,0x63,0xc7,0xa7,0xd0,0x4f,0xf7,
-  0x3e,0xe7,0x7c,0xfe,0xfc,0x2f,0xf7,0x84,0xf3,0xfb,0x25,0xd2,0x9f,0x33,0x0,0x0,
-  0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a,0x25,0x0,0x0,0x80,0x83,0x0,0x0,
-  0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75,0x30,0x0,0x0,0xea,0x60,0x0,0x0,
-  0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5,0x46,0x0,0x0,0x30,0x62,0x49,0x44,
-  0x41,0x54,0x78,0xda,0xec,0x7d,0x79,0x90,0x65,0x57,0x79,0xdf,0xef,0x9c,0x7b,0xef,
-  0x5b,0x7b,0x7f,0xdd,0xaf,0xb7,0x11,0x2,0xb4,0x8c,0x91,0x20,0xc6,0x44,0x98,0x18,
-  0x3,0xae,0x48,0x36,0x56,0xaa,0x12,0x1c,0x6f,0xc2,0x2c,0x5e,0xa8,0xd8,0x26,0x2c,
-  0x65,0x6c,0x1c,0xa5,0x48,0x9,0xca,0x71,0x90,0x5c,0xb6,0x9c,0x10,0x3,0x4e,0x2a,
-  0x96,0x8b,0x80,0xe3,0x2,0x2c,0x33,0x36,0x65,0xca,0x6,0x59,0x96,0x48,0x4,0x16,
-  0x60,0x1,0x65,0x4b,0xa3,0x85,0x91,0xe4,0x19,0x4f,0x8b,0x61,0x96,0x9e,0xe9,0xee,
-  0xe9,0xee,0xf7,0xee,0x7a,0xbe,0x2f,0x7f,0x9c,0xe5,0x9e,0xfb,0x5e,0x4f,0x4f,0xf7,
-  0x68,0x0,0x69,0xd4,0x67,0xea,0x4e,0xbf,0xed,0xbe,0xe5,0x9e,0xef,0x7c,0xcb,0xef,
-  0xfb,0x7d,0xdf,0x11,0xcc,0x8c,0xbd,0xf1,0xdc,0x1d,0x72,0xef,0x12,0xec,0x9,0xc0,
-  0xde,0xd8,0x13,0x80,0xbd,0xb1,0x27,0x0,0x7b,0x63,0x4f,0x0,0xf6,0xc6,0x9e,0x0,
-  0xec,0x8d,0x3d,0x1,0xd8,0x1b,0x7b,0x2,0xb0,0x37,0xf6,0x4,0x60,0x6f,0xec,0x9,
-  0xc0,0xde,0xd8,0x13,0x80,0xbd,0xb1,0x27,0x0,0x7b,0x63,0x4f,0x0,0xf6,0xc6,0x9e,
-  0x0,0xec,0x8d,0x3d,0x1,0xd8,0x1b,0x97,0xe2,0x8,0x9f,0xce,0xc9,0x42,0x8,0xe1,
-  0xdf,0x35,0x7,0xbc,0xbf,0xcf,0xb4,0xc1,0xde,0x5f,0xde,0xe2,0xf1,0x9d,0xbf,0xd1,
-  0x25,0xc2,0xa3,0x8,0x9f,0xe6,0xe4,0xdb,0x43,0x2,0x78,0x1d,0x80,0xb7,0x2,0x98,
-  0x7e,0x86,0xb,0xc0,0x69,0x0,0x7f,0x0,0xe0,0x33,0x0,0xc8,0x4e,0xfe,0xfb,0xde,
-  0xf7,0x3e,0x76,0x92,0xc0,0xc,0x2d,0xda,0x2,0x6c,0xfe,0x7f,0xff,0xfb,0x6f,0xbd,
-  0x24,0x35,0x80,0xb8,0x10,0x49,0xf6,0x26,0x5f,0x2,0x8,0x0,0xfc,0xfe,0xab,0x5f,
-  0xfd,0xea,0xd7,0xbf,0xe9,0x8d,0x6f,0xcc,0x6b,0xf5,0x3a,0x98,0xbc,0x77,0x15,0x46,
-  0x1a,0x18,0x60,0x73,0x9b,0x19,0xb0,0xba,0x83,0xd9,0x3c,0x26,0xf4,0xb,0x84,0xe0,
-  0xaa,0x12,0xd1,0x33,0xa0,0x57,0x9c,0x10,0x43,0x92,0x65,0x67,0x4d,0xd8,0xd7,0x98,
-  0xf,0x14,0xf6,0xf3,0x58,0xbf,0xb7,0x80,0x80,0x10,0x42,0xa4,0x59,0x8a,0x4f,0x7c,
-  0xfc,0x13,0xd1,0x17,0xbf,0xf8,0xc5,0x3b,0x1,0xbc,0x13,0x80,0xb2,0x82,0xf0,0xbe,
-  0xf7,0xbd,0x8f,0xe1,0xde,0x83,0xc1,0xde,0xa7,0xdd,0xfa,0xfe,0xf7,0xef,0x69,0x80,
-  0x41,0x39,0x30,0x93,0xff,0xee,0x9f,0xfa,0xa9,0x9f,0xba,0xe9,0x8d,0x6f,0x7c,0xe3,
-  0xe8,0x3f,0xfd,0xd3,0x51,0xac,0xad,0x9d,0x5,0xb9,0x15,0x4,0xb0,0x9d,0x41,0x6f,
-  0x3d,0xd9,0x89,0x77,0x92,0xa1,0x67,0xd8,0x48,0x85,0xbe,0x2f,0xe0,0x9,0x88,0x28,
-  0x95,0xb4,0x9e,0x54,0x6,0xb,0x31,0x2c,0x9,0xc2,0x57,0x3d,0xf6,0x7d,0x7d,0xc3,
-  0x24,0xd0,0xa8,0xd7,0xf1,0x6b,0xbf,0xf6,0x6b,0x98,0x9d,0x9d,0xbd,0xe9,0xc0,0x81,
-  0x3,0x87,0x1,0x7c,0xc0,0x9a,0x4,0x86,0xff,0xbd,0x8d,0x60,0x5e,0x98,0x85,0xb8,
-  0xe4,0x5,0xc0,0x4e,0x7e,0x4,0xe0,0x97,0x6e,0xba,0xe9,0x26,0x1c,0x3a,0xf4,0x38,
-  0x56,0xd7,0x56,0xb0,0xba,0xb2,0x8a,0xd5,0xd5,0xd5,0xb,0x5a,0x21,0x93,0x93,0x93,
-  0x98,0x9f,0x9f,0x77,0x13,0xc8,0x5c,0xae,0x66,0x3b,0x89,0xc7,0x8f,0x1f,0xc7,0xea,
-  0xea,0xea,0x85,0x68,0x2d,0x4c,0x4e,0x4e,0x61,0xba,0xd3,0x41,0x92,0xa6,0xb8,0xe9,
-  0xa6,0x9b,0x70,0xe0,0xc0,0x81,0x5f,0x2,0xf0,0xe1,0xd2,0x27,0x10,0x46,0xd1,0xb0,
-  0xe7,0xcc,0x98,0xef,0xb1,0x27,0x0,0x43,0x2,0x20,0x1,0x34,0xa5,0x94,0xcf,0xf,
-  0x82,0x80,0x93,0xb8,0x8f,0xd5,0x95,0x55,0xfc,0xd0,0xf,0xfd,0x10,0x5e,0xf0,0xfc,
-  0xe7,0x23,0x2f,0x8a,0x73,0xa,0x41,0xa3,0xd1,0x40,0xa3,0xd1,0xa8,0x3c,0x36,0x3a,
-  0x3a,0x8a,0x8f,0x7e,0xf4,0xa3,0x8,0x82,0xc0,0x13,0x82,0xea,0x38,0x7e,0xfc,0x38,
-  0x66,0x66,0x66,0xf0,0x8e,0x77,0xbc,0x3,0x6b,0x6b,0x6b,0xbb,0x9a,0xfc,0x5a,0xad,
-  0x86,0xc7,0x1e,0x7b,0xc,0xf,0x3c,0xf0,0x0,0x6a,0xb5,0x8,0x41,0x10,0x8e,0x48,
-  0x29,0x47,0x89,0xa8,0x9,0xa0,0xd0,0x73,0xcd,0xa5,0x76,0xda,0xd2,0x77,0xdc,0x13,
-  0x80,0x41,0xd,0x70,0x59,0xb7,0xdb,0xcd,0xb3,0x3c,0xab,0x15,0x4a,0x61,0x75,0x75,
-  0x15,0x57,0x5c,0x71,0x5,0xe,0x1f,0x3e,0x8c,0x3c,0xcf,0xb7,0x3c,0x31,0x8,0x2,
-  0x74,0x3a,0x1d,0x48,0x59,0x8d,0x40,0xd7,0xd7,0xd7,0xf1,0x9a,0xd7,0xbc,0x6,0x77,
-  0xdc,0x71,0x7,0xe,0x1e,0x3c,0x78,0xce,0xf,0xfe,0x85,0x5f,0xf8,0x5,0x3c,0xf1,
-  0xc4,0x13,0xe8,0xf7,0xfb,0xbb,0xfa,0xc2,0xf5,0x7a,0x1d,0x57,0x5d,0x75,0x15,0xee,
-  0xbe,0xfb,0x6e,0x4c,0x4f,0x4f,0x23,0xcf,0x33,0xd9,0xe9,0x74,0xf2,0xe5,0xe5,0xe5,
-  0x45,0x0,0x4f,0x0,0x28,0xe0,0xf9,0xd,0xd6,0x3c,0xf9,0xfe,0xca,0x9e,0x0,0x54,
-  0x1d,0xc0,0x0,0xc0,0xc2,0xf4,0xf4,0xb4,0xca,0xd2,0xc,0xc,0x46,0x18,0x86,0xc8,
-  0xf3,0xfc,0x9c,0x93,0xf,0x0,0x23,0x23,0x23,0x10,0x42,0x38,0xed,0x60,0x23,0xc9,
-  0x24,0x49,0xd0,0x6c,0x36,0x71,0xcb,0x2d,0xb7,0x20,0x8,0x2,0x6c,0x6c,0x6c,0x38,
-  0xcd,0x60,0x85,0xa5,0xd7,0xeb,0xe1,0xd8,0xb1,0x63,0x48,0x92,0x64,0xd7,0x3f,0x34,
-  0xcb,0x32,0x0,0x80,0x52,0xca,0xdd,0x9f,0x9d,0x9d,0x2d,0x96,0x97,0x97,0xf7,0x1,
-  0x38,0xc,0x40,0xdc,0x7a,0xdb,0xad,0xe2,0x96,0x5b,0x6e,0x61,0xb6,0x3e,0x9,0xc4,
-  0x9e,0x9,0x38,0x9f,0x6,0x58,0x58,0x58,0x50,0x79,0x96,0x23,0xcf,0xb,0x8c,0x8e,
-  0x8e,0xba,0xb,0xbc,0xd5,0x88,0xa2,0x68,0x48,0xf5,0x33,0xb3,0x13,0x88,0x7e,0xbf,
-  0x8f,0x7e,0xbf,0x8f,0xb3,0x67,0xcf,0x22,0x8e,0x63,0xb4,0xdb,0x6d,0xf4,0x7a,0x3d,
-  0xf7,0xda,0x53,0xa7,0x4e,0x6d,0xfb,0xfe,0x3b,0x89,0xdb,0x9b,0xcd,0x26,0x94,0x2a,
-  0x90,0xa5,0x29,0x16,0x16,0x16,0xd4,0xc3,0xf,0x3f,0x7c,0x99,0xf9,0x2d,0xa5,0x4b,
-  0x6a,0x4d,0x1,0x48,0xdf,0xdf,0xd3,0x0,0x5b,0x22,0x88,0x12,0xc0,0xc2,0xfc,0xdc,
-  0x1c,0x65,0x79,0x6,0x55,0x14,0x68,0xb5,0x5a,0xdb,0x4e,0xd0,0xd8,0xd8,0xd8,0xb6,
-  0x93,0x23,0x84,0x40,0x9e,0xe7,0x88,0xe3,0x18,0x42,0x8,0x8c,0x8c,0x8c,0xb8,0xd7,
-  0xf4,0xfb,0xfd,0xb,0x9e,0x7c,0x3b,0x94,0x52,0x68,0xb5,0x5a,0x28,0xa,0x85,0x2c,
-  0xcf,0x31,0x37,0x37,0x47,0x0,0x16,0xbc,0xdf,0x63,0x62,0x81,0x4b,0x13,0xf4,0xb9,
-  0x58,0x2,0xe0,0x63,0x0,0x73,0x33,0xdd,0x2e,0x65,0x59,0xe6,0x2e,0x2e,0x11,0x55,
-  0x5e,0xfc,0xe0,0x7a,0xb,0x8f,0x9e,0xce,0x31,0xd5,0xae,0xa1,0x9b,0x86,0x7e,0x44,
-  0x56,0x89,0xf7,0xed,0xfd,0x7f,0x3c,0xbe,0x89,0x5e,0x22,0x30,0x3b,0x39,0x82,0xf9,
-  0xbc,0xf4,0x13,0x1e,0x7b,0xaa,0x87,0x34,0x17,0x3b,0xfe,0x86,0x41,0x10,0xe1,0x9f,
-  0xcd,0x4,0xb8,0x76,0x34,0x1e,0x12,0x0,0x52,0x84,0x2c,0xcb,0xd0,0xed,0x76,0x9,
-  0xc0,0x9c,0xf9,0x2d,0x2,0x6,0x36,0x70,0x5e,0xa0,0x89,0x3f,0x5,0xf6,0x4c,0xc0,
-  0xb9,0x84,0x60,0x6e,0x6a,0x6a,0x4a,0x65,0x79,0x29,0x0,0x83,0xab,0xf4,0x41,0xb5,
-  0x8,0x8c,0x2b,0xb4,0xa7,0xea,0x48,0x3,0xe9,0x43,0x3c,0x6e,0xd2,0xed,0x5,0x5e,
-  0xed,0x67,0x38,0x1d,0x6,0x8,0xc6,0x4,0xc6,0xe7,0xc6,0x91,0x98,0x17,0xac,0xf6,
-  0x32,0xac,0xd5,0x25,0x50,0xdf,0x85,0x8a,0xa,0x6b,0x78,0x48,0x49,0x5c,0x8b,0x7f,
-  0x1c,0x12,0x80,0x8d,0x8d,0xd,0xe4,0x79,0x8e,0xa9,0xa9,0x29,0x65,0x4,0x40,0x54,
-  0x1,0xa,0xf,0x61,0x2,0xe3,0x52,0x2e,0x9e,0x7b,0xba,0x1a,0x60,0x76,0x7c,0x7c,
-  0x9c,0x57,0x57,0x57,0xa1,0xa,0x85,0x91,0x91,0x91,0x8a,0x0,0x28,0x48,0xc8,0xd1,
-  0x69,0xec,0x1b,0x6f,0xa2,0xdd,0xa,0x87,0xd6,0x91,0x1c,0x0,0x5d,0xd6,0x39,0x45,
-  0x6b,0x9e,0xb1,0x30,0x1a,0xa2,0xd9,0x8e,0x1c,0x70,0x74,0x96,0x12,0xb4,0xe6,0x2d,
-  0x30,0xc3,0x15,0x21,0x62,0x8,0xf7,0xbf,0xaf,0xb2,0x99,0x19,0x44,0x19,0xe0,0x9,
-  0x0,0x11,0x61,0x64,0x64,0x4,0x6b,0x6b,0x6b,0xc8,0xd2,0x14,0x93,0x93,0x93,0xc,
-  0x60,0xb6,0xaa,0x1,0xd8,0xcb,0x18,0x78,0xd0,0xe5,0x9e,0x0,0xc,0x9,0x80,0x0,
-  0x30,0x3b,0x3a,0x3a,0x12,0x9d,0x3c,0x79,0x12,0x85,0x2a,0xd0,0x6e,0xb7,0x2b,0x26,
-  0xa0,0xc7,0x35,0xb4,0xa2,0x10,0xe3,0xed,0x1a,0x84,0x90,0xbe,0x56,0xad,0x38,0x56,
-  0x2,0xc0,0xe9,0xbe,0x42,0x86,0x8,0x51,0x24,0xd0,0x19,0x89,0x4c,0x74,0xc0,0x58,
-  0x4d,0x8,0x39,0x42,0xc8,0x50,0x7b,0xe6,0xc2,0x88,0x5,0x50,0xcd,0x3e,0xb9,0xc9,
-  0x17,0xc,0xc1,0x2,0x42,0x15,0x50,0xcc,0x48,0x38,0x42,0x43,0xe4,0x4e,0x3,0xb4,
-  0xdb,0x6d,0x14,0x45,0x81,0x34,0xcf,0xd0,0x1e,0x19,0x89,0x8c,0x0,0x94,0xbf,0x89,
-  0xd8,0x84,0x82,0x2,0x10,0x4,0x10,0xf6,0x34,0xc0,0x36,0x40,0xd0,0x6c,0xbd,0xd6,
-  0x90,0x45,0x9e,0x83,0x88,0x50,0xab,0xd5,0x2a,0x1a,0x20,0xe3,0x10,0xb3,0x23,0x11,
-  0x98,0x18,0x90,0x3e,0xc8,0x22,0x9c,0xa7,0x2d,0x5,0x90,0x11,0x70,0xaa,0x57,0x0,
-  0xc,0xcc,0xb4,0x3,0x8,0x0,0x44,0xfa,0xf9,0x53,0x1b,0x85,0x3e,0xc7,0x3a,0x8a,
-  0x6,0xae,0x65,0xbb,0x50,0x9d,0x40,0xf9,0xf,0x1a,0x0,0x9a,0x81,0x14,0x21,0x1a,
-  0xc8,0x2b,0x26,0x40,0x29,0x85,0x22,0x2f,0xd0,0x68,0x34,0x5a,0x0,0x1a,0x9e,0x6,
-  0x0,0x41,0xb,0x10,0x83,0x75,0x86,0xc0,0x28,0x82,0x4b,0x75,0xc8,0xa7,0xa1,0x1,
-  0x66,0x26,0x26,0x26,0x82,0x82,0x8a,0x48,0x11,0xa1,0x28,0xa,0x13,0x62,0x95,0x2,
-  0x20,0x1a,0xa3,0xa8,0x5,0xfa,0x62,0x32,0xb1,0x99,0x20,0x7d,0x58,0xad,0xaa,0x18,
-  0x58,0xde,0x54,0x20,0x5,0x44,0x12,0x98,0xaa,0x4b,0x30,0xe9,0x29,0x5c,0x8d,0xb,
-  0xa4,0x5,0x19,0x95,0xae,0x55,0x3b,0x31,0xf4,0x7b,0x59,0x69,0x22,0xe3,0xb9,0x13,
-  0x3b,0x41,0x71,0x2,0xc3,0x8c,0x84,0x6b,0x15,0x1f,0xa0,0xd1,0x68,0x40,0x29,0xa5,
-  0x85,0xa0,0x28,0xa2,0x89,0x89,0x89,0x0,0xc0,0x8c,0xfb,0x5d,0xe6,0x73,0x74,0x34,
-  0xa0,0xff,0x9,0xde,0xd3,0x0,0x83,0x20,0x90,0x4,0x30,0xdb,0xe9,0x74,0x8a,0x3c,
-  0xcb,0x43,0x62,0x86,0x52,0xa,0xf5,0x7a,0x1d,0x69,0x9a,0xba,0x90,0xae,0xde,0x6a,
-  0xeb,0xc9,0x23,0x6b,0x4e,0x4b,0x70,0xc5,0x1a,0xff,0xa4,0x20,0xac,0xf6,0x73,0x30,
-  0x4,0x66,0x5a,0xa1,0x59,0xc4,0x5a,0xef,0x2e,0x6f,0x9a,0xd5,0x5f,0x49,0xc9,0x18,
-  0xd8,0x9e,0xcb,0x74,0x8d,0x46,0xeb,0xc8,0x93,0x4f,0x72,0xca,0x20,0xe6,0xb0,0xe2,
-  0x3,0xd4,0xeb,0x75,0x28,0x45,0x20,0x62,0x64,0x59,0x86,0x4e,0xa7,0x53,0xac,0xad,
-  0xad,0xcd,0x2,0xf8,0x27,0x0,0xe2,0xf6,0xdb,0x6f,0x17,0x37,0xdf,0xfc,0x1f,0xb9,
-  0x9a,0x4,0x62,0xe0,0xf,0xaa,0x52,0x20,0xee,0x78,0x66,0x4c,0x20,0xff,0xf2,0x77,
-  0x5e,0x3,0xd8,0xab,0xbc,0xb8,0xb8,0xb8,0xa8,0xd2,0x34,0x5,0x88,0x41,0x44,0x88,
-  0xa2,0xc8,0xf9,0x0,0xed,0x76,0x1b,0x39,0x42,0x93,0x66,0xe3,0xea,0x2a,0x26,0x76,
-  0xab,0xf9,0xe4,0x66,0x1,0x22,0xa0,0x2e,0x18,0x63,0x75,0x9,0x66,0x3d,0x79,0xab,
-  0xb1,0x42,0x52,0x90,0x59,0xd9,0xec,0x56,0xa5,0x30,0xcf,0x97,0xab,0xdd,0x78,0xea,
-  0xf6,0x33,0x88,0x2a,0x9f,0xd7,0xe7,0xa8,0xa2,0x1,0xf4,0x77,0xd4,0x19,0xe0,0x2c,
-  0xcb,0xb0,0xb8,0xb8,0xa8,0x0,0x2c,0x56,0xdc,0x9,0xae,0xf2,0x45,0xce,0xa1,0x0,
-  0x6a,0xcf,0x75,0x27,0x70,0x7e,0x6e,0x6e,0x8e,0xb2,0x2c,0x5,0x83,0xdd,0xc5,0x55,
-  0x4a,0x21,0x8,0x2,0xd4,0xeb,0x75,0xc4,0xb9,0x16,0x0,0x22,0x40,0x48,0xbb,0x52,
-  0x85,0x5b,0xc4,0x9b,0x99,0xc2,0x46,0xaa,0x5,0xa6,0x63,0x7c,0x5,0x36,0x78,0xdc,
-  0xb2,0xb1,0xfd,0xc2,0x2c,0x65,0x36,0x19,0x3a,0xf2,0x75,0x81,0x9f,0xb3,0xb5,0x21,
-  0xa5,0x67,0x69,0x0,0x20,0xa1,0xa0,0x22,0x0,0x5a,0x3,0x28,0x30,0x69,0x38,0x78,
-  0x66,0x66,0x86,0x0,0x74,0x7d,0x9f,0xd2,0x45,0x2,0x26,0x11,0x30,0x20,0x0,0x63,
-  0x0,0x7e,0x11,0xc0,0xf5,0x0,0x8e,0x1,0xf8,0x6d,0x0,0x47,0x9e,0x2b,0x3e,0x40,
-  0x5,0x4,0xd2,0x2,0x90,0x9b,0x55,0xad,0xd5,0x2b,0x11,0xa1,0xdd,0x6e,0x6b,0x27,
-  0x90,0x2,0xb7,0xda,0x99,0x8c,0xc9,0x76,0xab,0x9f,0x71,0x62,0x23,0x7,0x88,0x51,
-  0xf,0x80,0xd1,0x48,0x98,0xd7,0x31,0xce,0x7a,0xab,0x9f,0xcc,0x6b,0x99,0x8c,0xe6,
-  0xb0,0xbe,0x84,0x79,0x1f,0xb8,0xf7,0x67,0xe7,0x3b,0x38,0x1b,0x4e,0x40,0x32,0xa0,
-  0x1,0xac,0xa3,0xca,0x60,0xab,0x1,0xc8,0x68,0x80,0x32,0x14,0xb4,0x1a,0x4,0xa5,
-  0x3f,0x60,0x9e,0xff,0x9,0x0,0x7f,0x2,0xe0,0x5f,0x59,0x3f,0x8,0xc0,0x8f,0x3d,
-  0x17,0x35,0x80,0x4,0x30,0x37,0x39,0x39,0xa9,0xd2,0x34,0x5,0x11,0x41,0x8,0x1,
-  0x29,0x25,0xc2,0x30,0x44,0x18,0x86,0x60,0x66,0xa4,0x2c,0xc1,0xd0,0x13,0x28,0x98,
-  0x21,0x24,0xdc,0x2a,0x3e,0x1b,0x2b,0x64,0x85,0xc6,0xda,0x3b,0xcd,0x10,0xc4,0xc,
-  0xc9,0x2,0x2c,0x18,0xcb,0x9b,0x5a,0xa8,0x7c,0xbe,0x88,0x5,0xe5,0xd9,0xa4,0xec,
-  0x5c,0xe,0xc1,0xa7,0x9c,0x30,0x83,0x84,0xaf,0xc5,0x9,0xb1,0xa,0x2a,0x3e,0x40,
-  0x18,0x86,0xda,0x4c,0x31,0x5b,0x2c,0x40,0xd,0xa0,0x81,0xee,0xb3,0xed,0xca,0xff,
-  0xc0,0xfe,0xff,0xf6,0xbd,0x0,0xde,0x3,0xe0,0x5,0x0,0x32,0x73,0xd8,0x6b,0xf1,
-  0xfc,0xe7,0x92,0x0,0x8,0xef,0x42,0x2d,0x4c,0x4e,0x4e,0xd2,0xda,0xea,0x6a,0x25,
-  0xbc,0x6a,0xb5,0x5a,0xee,0xc5,0x29,0x5,0x20,0x30,0x24,0x18,0x2c,0x18,0xd2,0xc4,
-  0xd4,0x8a,0x59,0x3b,0x78,0xc4,0x68,0x44,0x12,0xed,0x9a,0x70,0x61,0xdf,0x7a,0xa2,
-  0x10,0xe7,0x5a,0x60,0x48,0x94,0x2a,0x1d,0x26,0x49,0xc3,0x70,0x70,0x8d,0xa1,0x93,
-  0x31,0x78,0xc0,0x5f,0x73,0xf8,0x3d,0x31,0x62,0x11,0x56,0x0,0x22,0x21,0x84,0x36,
-  0x55,0x44,0x48,0xb3,0xc,0xe3,0xe3,0xe3,0x34,0x80,0x6,0xa,0x9b,0xf,0xf8,0xc0,
-  0xf7,0x7c,0x60,0x6,0xc0,0xaf,0x3,0xf8,0x37,0xde,0xc4,0x8b,0x1,0x6d,0x38,0x6b,
-  0xae,0x63,0xf1,0x5c,0xd3,0x0,0x33,0xcd,0x66,0x53,0xda,0xc,0xdd,0xe8,0xe8,0x28,
-  0x82,0x20,0xa8,0xe4,0xf9,0xfb,0x24,0xf5,0x44,0x9,0x86,0x0,0x83,0x4c,0x40,0x7d,
-  0xa6,0x57,0xa0,0x50,0x5a,0x1a,0xa6,0x5b,0x3a,0xec,0x33,0xbe,0x3b,0x96,0x37,0xb5,
-  0x59,0x60,0x13,0x80,0x93,0x87,0xfc,0x11,0x4a,0xae,0x9f,0x9d,0xed,0xea,0xbc,0x97,
-  0xf8,0xa0,0x75,0x10,0x13,0x8a,0x86,0x12,0x42,0x23,0x23,0x23,0x28,0x54,0x81,0x2c,
-  0xcb,0x30,0x3a,0x3a,0x12,0x78,0x68,0xa0,0x84,0x9e,0xf8,0x0,0xc0,0x5b,0x0,0xbc,
-  0xcb,0xe0,0x4,0x59,0x25,0x71,0x51,0xc5,0xa0,0xec,0xf9,0xc7,0x9e,0x2b,0x1a,0xc0,
-  0xa,0xc0,0xfc,0xc8,0xc8,0x48,0x98,0x65,0xa9,0xbb,0xa8,0x41,0x10,0x54,0x32,0x7b,
-  0xa9,0xa,0xb4,0xf3,0x47,0xe5,0xaa,0x2d,0x98,0xb0,0xda,0xd7,0xe,0x5e,0xbb,0x26,
-  0xd1,0xc,0x5,0x88,0x8,0x12,0x2,0xeb,0xa9,0x42,0x9c,0x53,0x9,0xc4,0x40,0xd3,
-  0xb3,0xb4,0x4f,0x26,0x50,0x71,0xd0,0x2c,0xac,0x38,0xb8,0xfc,0x85,0xd3,0xf7,0x3a,
-  0xa,0xf0,0x9c,0x40,0x1f,0xc,0xca,0xf2,0xc,0x69,0x9a,0xa2,0xd5,0x6a,0x37,0x1,
-  0xcc,0x3b,0xcd,0xf6,0xa1,0x8d,0x1f,0x4,0x70,0x1b,0x80,0x2b,0x0,0xe4,0xde,0xaa,
-  0x17,0x5b,0x20,0xa1,0xf6,0xb1,0xcb,0x9e,0xad,0x2,0x70,0xa1,0x4e,0x60,0xb3,0x5e,
-  0xaf,0xb7,0x98,0xb9,0x51,0xe4,0x5,0x88,0x14,0x5a,0xed,0x6a,0x26,0x30,0x51,0x12,
-  0x44,0x25,0x1,0x9f,0x4c,0x88,0x76,0x72,0x3d,0x37,0x8e,0x20,0x30,0xd5,0xc,0xb4,
-  0x53,0x67,0xc2,0xc8,0xd3,0x9b,0x39,0xa0,0x18,0xc4,0x64,0x9c,0x2f,0x2,0x2b,0x13,
-  0x3e,0x12,0x99,0x10,0xd1,0xb,0x23,0xbd,0xc7,0xdc,0xa1,0x50,0x9e,0x3,0x81,0x94,
-  0x24,0xc8,0x8b,0xf0,0x2c,0x1c,0x4c,0x85,0x42,0xa1,0x14,0x98,0xa9,0x51,0xaf,0xd7,
-  0x5b,0xb8,0xfe,0x57,0x2e,0xc7,0xef,0xc7,0xff,0x3,0xf5,0x91,0xbf,0x0,0xf0,0x3d,
-  0x3,0xbf,0xf9,0x5c,0x13,0xef,0x9b,0x81,0x4b,0xdb,0x7,0xf0,0x8a,0x40,0x4,0x80,
-  0x7d,0x73,0x73,0x73,0x79,0x9c,0xc4,0x75,0x62,0x82,0x52,0x84,0x76,0xab,0x6d,0x26,
-  0x84,0xd,0xc,0x1c,0x38,0xaf,0xdf,0x6,0x52,0x49,0x4e,0xd8,0x4c,0x14,0x4,0x80,
-  0x76,0x4d,0xa0,0x16,0x0,0x64,0x8c,0xf9,0x66,0x46,0x48,0x32,0xaa,0xda,0x71,0x4b,
-  0x16,0x36,0x2c,0x60,0xe1,0x70,0x7a,0x7d,0x9e,0x33,0xb,0x9e,0x19,0x10,0xa2,0xa4,
-  0x71,0xd9,0x88,0xa1,0xa7,0x22,0x8c,0x6,0x59,0x25,0x21,0x74,0xea,0xd4,0x29,0x30,
-  0x11,0x92,0x24,0xc5,0xec,0xc2,0x22,0x2d,0xbd,0xe6,0x97,0x3f,0x8b,0xb0,0x1e,0x99,
-  0x55,0xf,0x6c,0x5d,0xe8,0x72,0xae,0xc7,0xf6,0x3d,0x97,0xc2,0x40,0x9,0x60,0xa1,
-  0xdb,0xed,0xaa,0x2c,0x4d,0x41,0x5c,0xda,0x55,0x1f,0x6,0x8e,0x95,0xe,0x1,0xc9,
-  0x86,0x72,0x54,0xda,0x77,0x30,0xbb,0xd5,0x4f,0xa4,0x51,0xb9,0xe5,0x8d,0xdc,0x69,
-  0x89,0x32,0xac,0x63,0x7,0xf3,0x42,0x11,0x88,0x19,0x50,0xe5,0xe3,0xc4,0x65,0x8,
-  0x68,0x43,0x44,0x52,0xde,0x39,0xc4,0x20,0x2,0x12,0xe,0x86,0x4c,0x80,0x15,0xd6,
-  0x34,0x4d,0x31,0x33,0x7f,0x59,0x88,0xb5,0xe3,0xed,0x2d,0x56,0x3d,0xb6,0x58,0xf5,
-  0x5b,0x69,0x83,0x7d,0x97,0xbc,0x6,0xd8,0x2,0x4,0x52,0x59,0x96,0x3,0x4c,0x20,
-  0x22,0x34,0x9b,0xcd,0x8a,0x9,0x88,0x49,0x82,0x0,0x48,0x33,0x69,0x9b,0xa9,0x42,
-  0x9c,0x11,0x4,0x3,0xed,0x46,0x80,0xc8,0xac,0x7e,0xc1,0xc0,0x46,0xaa,0x90,0xe6,
-  0x66,0xe2,0x85,0xcd,0xfa,0x79,0x45,0x23,0x16,0xa4,0x27,0xa1,0x23,0x3,0xcb,0xde,
-  0xe4,0xad,0x93,0x35,0x36,0x55,0x0,0x13,0xee,0xf5,0x55,0x4,0x84,0xb1,0xd3,0x0,
-  0x36,0x62,0x61,0x66,0x64,0x59,0x8a,0xee,0xdc,0x3c,0xb0,0x76,0xc,0xdb,0xd8,0xfa,
-  0xed,0x4c,0x0,0x4c,0x28,0xf8,0x31,0x0,0xe9,0xe,0x8e,0x6c,0x8b,0xdb,0x99,0x77,
-  0xe4,0xde,0x5f,0x7b,0x14,0x5b,0x1c,0xdf,0x71,0x1,0x18,0x4,0x81,0x38,0x4d,0x53,
-  0xa3,0xe6,0xa9,0x44,0xd8,0x4c,0xa8,0x15,0xab,0x10,0x4c,0x4,0x82,0x4,0x4,0xe3,
-  0xcc,0x66,0x61,0xf5,0x3d,0xa6,0x9a,0x91,0x31,0xd,0xda,0xf3,0x3f,0xbd,0xa9,0xb3,
-  0x89,0x2,0xa2,0x12,0x83,0xf3,0x0,0xc,0xa0,0x73,0x4,0xce,0xcb,0x2b,0x33,0xb,
-  0x5c,0xfd,0x92,0x16,0x19,0xb0,0x18,0x8e,0x8f,0x5,0x58,0x34,0xd0,0xd7,0x0,0xb3,
-  0xb3,0x73,0xc0,0xf1,0x63,0xe2,0x1c,0x1a,0x60,0x3b,0x13,0xb0,0x9d,0x80,0x9c,0xeb,
-  0xc0,0x2e,0x4,0xeb,0x5c,0xdf,0x45,0xe0,0x22,0x65,0xa9,0x2f,0x54,0x3,0xcc,0x75,
-  0x3a,0x1d,0x95,0xa6,0x29,0x98,0x34,0xc,0xec,0x6b,0x0,0x66,0x46,0xac,0x24,0x88,
-  0x4,0x24,0x80,0xd5,0x24,0x47,0x66,0xcc,0xc3,0x58,0x3d,0x84,0x84,0xb6,0xcf,0xc,
-  0xa0,0x97,0x29,0xa4,0x99,0xf2,0x7e,0x52,0x95,0xf2,0x51,0xe1,0xe4,0x98,0xd7,0xe8,
-  0xa,0x1e,0xe1,0x12,0x47,0x96,0x51,0x64,0xcb,0xcb,0x4a,0x8d,0xa1,0x4d,0x41,0x7f,
-  0x40,0x0,0xec,0x77,0x65,0x62,0xa4,0x69,0x86,0x89,0x4e,0x7,0x78,0xec,0x5b,0xe7,
-  0xba,0xd0,0x62,0x1b,0xb3,0x80,0x8b,0x20,0x4,0xe7,0x7b,0xaf,0x73,0x99,0xa1,0xef,
-  0xae,0x6,0x98,0x98,0x98,0x50,0xeb,0x1b,0x1b,0xe,0x7a,0xb5,0x1a,0xa0,0x8c,0x2,
-  0x2,0x10,0x11,0x14,0x9,0x9c,0xed,0x17,0xe,0x5b,0x1f,0x6f,0x48,0x87,0xf9,0xb,
-  0xc1,0x38,0xbd,0x91,0x83,0xa9,0xc4,0xf9,0x5d,0xd8,0xe7,0xa,0xa,0x2b,0x9e,0x28,
-  0x2c,0x43,0x83,0xbd,0xe2,0x3f,0x1b,0x1a,0xa,0x0,0x24,0x4a,0xbb,0x60,0x23,0x83,
-  0x5e,0x71,0xe,0xd,0x60,0xe0,0xe0,0xb1,0x89,0x39,0x60,0xed,0xeb,0x30,0x6a,0x43,
-  0x42,0x88,0xed,0x84,0xe1,0x7c,0x93,0x88,0x1d,0xa,0x6,0x76,0x20,0x60,0xe2,0x99,
-  0xaa,0x1,0x16,0x46,0x47,0x47,0xe5,0xf2,0xf2,0xb2,0xb,0xc7,0x6a,0xb5,0x1a,0x36,
-  0x37,0x37,0x4b,0x14,0x50,0x49,0x80,0x18,0x67,0xe2,0x1c,0xaa,0xd0,0xdf,0x75,0xac,
-  0x19,0x20,0x14,0x26,0x32,0x10,0xc0,0x66,0xea,0xad,0x7e,0x58,0x1c,0x7f,0xd0,0x90,
-  0xf,0xfe,0x5c,0x57,0x4d,0xa,0xd,0x30,0xa0,0x9a,0xb5,0x13,0x1e,0x12,0x68,0xfc,
-  0x8f,0x94,0xe4,0x96,0x70,0xb0,0x73,0x2,0x5b,0x2d,0x60,0xed,0xd8,0xf9,0x26,0x7d,
-  0xa7,0xe6,0x40,0xec,0x50,0x85,0xef,0xf4,0xfc,0xf3,0x69,0xa3,0xef,0x8a,0x6,0xe8,
-  0x36,0x9b,0xcd,0x5a,0x96,0x65,0xce,0x93,0xaf,0xd7,0xeb,0x58,0x5f,0x5f,0x77,0x61,
-  0x60,0xaf,0x10,0x48,0x32,0x85,0xcd,0x98,0x0,0x21,0x21,0x5,0x30,0xd6,0x90,0x50,
-  0xc6,0xf,0x10,0x2c,0x70,0xa6,0xa7,0x57,0xbf,0x57,0x87,0xe1,0x21,0x7c,0x62,0x80,
-  0x88,0x61,0x42,0x41,0x94,0xa6,0xa2,0x8c,0xf7,0xbc,0x73,0xa9,0x5a,0x7a,0xcc,0xcc,
-  0xd8,0xc8,0xaa,0x1a,0xa0,0xd1,0x68,0x38,0x13,0x90,0xa4,0x29,0x46,0x9b,0x11,0xb0,
-  0xf2,0xd4,0x85,0xaa,0xe4,0x8b,0xe5,0x3,0x6c,0x87,0x3b,0x3c,0x63,0xa2,0x0,0x9,
-  0xa0,0x1e,0x45,0x51,0x7,0x0,0x67,0x59,0xae,0x29,0x54,0x42,0x38,0x13,0x60,0xb5,
-  0x67,0x5c,0x48,0x9c,0xd9,0x2c,0xcc,0x22,0x15,0x18,0x69,0x6,0x10,0x64,0xed,0x39,
-  0xa3,0x97,0x15,0x7a,0xf5,0x43,0xb8,0x60,0xde,0x92,0x3f,0x4,0xf4,0xea,0x66,0x93,
-  0xec,0x11,0xa6,0xca,0x97,0x5,0xd,0x93,0x40,0x69,0x90,0x1a,0x66,0xb3,0x81,0x46,
-  0x48,0x48,0x9b,0x23,0x5f,0x0,0xa2,0x28,0x32,0xd9,0x3e,0x46,0x91,0xe5,0xa8,0xb,
-  0x5,0xd9,0x5b,0xd6,0x3c,0x1,0x19,0x60,0x1b,0x47,0x6c,0xb7,0xe,0xdd,0x4e,0x7d,
-  0x0,0x9c,0x67,0x85,0x6f,0xa7,0x51,0xbe,0x63,0x38,0x80,0x43,0xbd,0xa6,0xa6,0xa6,
-  0xf2,0x2c,0xcb,0x24,0x91,0x2,0x29,0xaa,0x50,0xc1,0xac,0x6,0x58,0xe9,0x11,0x92,
-  0x54,0x93,0x3d,0x4,0x8,0xa3,0xd,0x9d,0x19,0x54,0xa4,0x8f,0x15,0x93,0xc,0xb2,
-  0x68,0x1e,0x11,0xe9,0xb0,0xcd,0x62,0x3,0x86,0xfa,0xc5,0x4a,0x63,0x3,0xc4,0xfa,
-  0x39,0x28,0x32,0x58,0x0,0xcc,0xa1,0xcf,0xd7,0x69,0x61,0x2a,0xcf,0x31,0x44,0x4,
-  0x22,0x46,0xaf,0x90,0x43,0x9,0x21,0x6b,0x6,0xa,0x52,0xc8,0xd3,0x14,0x33,0x73,
-  0xb,0xc0,0xda,0x37,0x77,0x32,0x29,0x3b,0x79,0x6c,0x37,0x42,0x80,0xb,0x14,0x10,
-  0xf1,0x1d,0xd3,0x0,0x3,0xdd,0x40,0xe6,0x67,0x67,0x67,0x55,0x92,0xa6,0x6,0xe0,
-  0x19,0x2e,0x8,0x29,0x8,0x38,0xb1,0x49,0x60,0x84,0x0,0x31,0xda,0x8d,0xd0,0x4c,
-  0x90,0x5e,0x95,0x7d,0xb3,0xfa,0x19,0x55,0x34,0x8f,0x7c,0x6b,0xce,0x65,0xb1,0x3f,
-  0x79,0x54,0xfd,0x32,0x58,0xe0,0x8a,0xf1,0xe7,0xc1,0x4a,0x7e,0x8f,0x81,0xd4,0xcf,
-  0xe4,0x96,0x9,0x21,0x52,0x4,0x19,0x8,0x24,0x69,0x82,0xce,0xcc,0x2c,0x4e,0x9e,
-  0x3d,0x21,0x30,0x75,0xf9,0x85,0x82,0x41,0x3b,0x9d,0x14,0xb1,0x3,0x9f,0x61,0x3b,
-  0x3f,0xe2,0xbb,0xaa,0x1,0xa4,0x15,0x80,0x2c,0x49,0x34,0x1a,0x47,0x84,0xd1,0xd1,
-  0x51,0x14,0x45,0x89,0x4d,0xac,0xc7,0x5,0xf2,0x5c,0x19,0x67,0x4f,0x60,0xa4,0x2e,
-  0x8c,0xb0,0xe8,0x95,0xbe,0xba,0x59,0x94,0xc8,0x1d,0x69,0xbc,0xdf,0xda,0x64,0x77,
-  0x78,0xaf,0x2f,0x1f,0x27,0x77,0x9e,0xbd,0xcf,0x6a,0xe0,0x3c,0xa3,0x31,0x98,0xc8,
-  0x9,0x40,0xc1,0x40,0xe2,0x39,0x82,0x2e,0x7d,0xed,0x39,0x82,0x73,0xb,0xfb,0x80,
-  0x95,0xa5,0x9d,0xae,0xc2,0x9d,0xac,0xe2,0xdd,0xf8,0x0,0xbb,0xd1,0x2c,0xdf,0xf5,
-  0x30,0x70,0x7e,0x6e,0x6e,0x8e,0xd2,0xb4,0x74,0x0,0x7d,0x68,0x15,0x0,0xce,0xf4,
-  0x95,0xe3,0xec,0x8d,0xd4,0x84,0x56,0xeb,0x60,0x8,0x21,0xf5,0xea,0xcf,0x55,0xa5,
-  0xf3,0x7,0x8b,0xd2,0x66,0x8b,0x8a,0x1b,0x58,0xa5,0x83,0x96,0xbe,0x81,0xad,0x26,
-  0xe2,0x4a,0x31,0xa7,0xef,0x1f,0x9a,0x98,0xce,0x8,0x81,0x40,0x3f,0xf,0xd0,0xa8,
-  0x53,0x5,0xd,0x5c,0x5d,0x5b,0x3,0x91,0x44,0x9a,0x64,0xe8,0xce,0xce,0xd,0x46,
-  0x2,0x17,0x2,0x6,0x7d,0xe,0xc0,0x9d,0x97,0x22,0x14,0xec,0x47,0x0,0x8b,0xda,
-  0x4,0x24,0x26,0x6b,0x47,0x15,0x13,0x90,0xa6,0x29,0xfa,0x99,0x56,0xf9,0x32,0x0,
-  0xda,0x91,0x8e,0xfb,0x35,0x70,0x43,0x38,0xdb,0xcb,0x35,0x5e,0x2f,0x7c,0xa2,0x87,
-  0x99,0x70,0x16,0xe,0xe1,0xd5,0x84,0x10,0x31,0x10,0x5,0x96,0x89,0x1e,0xaa,0x90,
-  0x36,0xfd,0x36,0x34,0x3,0xad,0xc0,0x98,0xc1,0x8a,0xd0,0x2f,0x24,0xa6,0xea,0x55,
-  0xd,0xc0,0x44,0x40,0xc0,0xc8,0xb2,0x4,0xdd,0xee,0x8c,0xc2,0xd2,0x53,0x4f,0x17,
-  0xc,0xba,0xec,0x52,0x4e,0x6,0xb9,0x7a,0x80,0xd1,0xd1,0x51,0x4a,0xd3,0xd4,0x10,
-  0x3e,0x19,0xed,0x76,0xdb,0x71,0xed,0xf3,0x3c,0x47,0x2f,0x97,0xfa,0xf1,0x48,0xb3,
-  0x7c,0xad,0xe3,0xd7,0x4b,0x72,0xa4,0xa9,0x32,0x4e,0x9b,0x51,0xd3,0x36,0x91,0xa3,
-  0xca,0xa4,0x91,0x76,0xfa,0x4a,0x55,0x6e,0xcd,0x0,0x29,0x2f,0xd,0x6c,0x4d,0x80,
-  0xe5,0x2,0x2a,0x2a,0x4d,0x84,0xe2,0x8a,0x59,0x0,0x33,0x36,0x7,0xc0,0xa0,0x91,
-  0x91,0x11,0xe7,0x80,0xa6,0x49,0x86,0x4e,0x2b,0x5c,0xc3,0xa3,0x7f,0x7d,0x10,0x4c,
-  0x27,0xc1,0x2c,0x77,0x10,0xbf,0x6f,0xa5,0x5,0xe6,0x2f,0x55,0x1,0xf0,0x35,0xc0,
-  0xc2,0xf8,0xd8,0x18,0x34,0xc,0xac,0xbd,0x73,0x9b,0x5c,0xb1,0x4d,0x18,0xfa,0x85,
-  0x84,0x14,0x2,0xcd,0x9a,0x0,0x19,0xfb,0x4e,0x5,0x61,0xcd,0xd8,0x7e,0xfd,0x98,
-  0x67,0xc7,0x5d,0x6,0xd0,0xdc,0x56,0x83,0x36,0x9d,0x9d,0xb7,0xaf,0x27,0x1f,0xde,
-  0xe4,0x7b,0xe7,0x2b,0x4f,0x78,0x94,0xf6,0xf,0x1c,0x31,0x24,0xaf,0x72,0x3,0xdb,
-  0xed,0x36,0x88,0x49,0x67,0xb,0xd3,0x4,0xe3,0xe3,0xe3,0xc0,0xf1,0x47,0x15,0x7e,
-  0xff,0x5f,0xff,0x4b,0xa4,0x9b,0xbf,0x1,0x60,0xf5,0x2,0xc0,0xa0,0x69,0x3c,0xcb,
-  0xe8,0xe2,0x17,0x22,0x0,0xd3,0xb5,0x7a,0x3d,0x4c,0x92,0xc4,0xa5,0x62,0xeb,0xf5,
-  0x3a,0xf2,0x3c,0x77,0xa1,0xe0,0x66,0x11,0xa0,0x5d,0x97,0x6e,0x12,0x49,0x31,0xfa,
-  0xa9,0xf6,0xfc,0x7,0x53,0xb8,0x54,0x59,0xc9,0xec,0xb1,0x88,0xbd,0x54,0xb2,0x2a,
-  0x5,0xc1,0x86,0x89,0x7e,0xa,0x98,0xb7,0xd0,0x20,0x65,0x81,0xa8,0x3e,0xfa,0xb9,
-  0x18,0x82,0x83,0xad,0x93,0x98,0x26,0x29,0x6a,0xb5,0x5a,0x8,0x60,0x1a,0x8f,0xdc,
-  0x95,0xe1,0x5d,0x63,0x77,0xe0,0xf0,0x97,0x5f,0xe,0xe0,0x43,0x0,0xfa,0xbb,0x0,
-  0x83,0x2,0x68,0x7e,0xe1,0x25,0x6d,0x2,0xe6,0xc3,0x30,0x6c,0xeb,0xd5,0xce,0x90,
-  0x52,0xa2,0x5e,0x6f,0xb8,0x8a,0x20,0x0,0x48,0xa,0x89,0x66,0x28,0x5d,0xae,0x9f,
-  0x89,0x70,0xb6,0x5f,0x68,0x9b,0xab,0x7c,0xb5,0xae,0xef,0x93,0x8d,0xfd,0x15,0x9b,
-  0xe7,0xfd,0x49,0xaf,0xa,0x7,0x19,0xcf,0xdf,0xff,0x4b,0x46,0x13,0x69,0x41,0xa0,
-  0xaa,0x76,0x50,0x5a,0xa3,0x6c,0x64,0x72,0x28,0x21,0x24,0x8d,0x5f,0x92,0xe6,0x29,
-  0xc2,0x30,0x6c,0x1b,0x15,0xae,0x7f,0xe7,0xef,0xbc,0x72,0xfd,0xcd,0x7f,0xfb,0xb3,
-  0xb7,0x2,0xf8,0x41,0x0,0x7f,0xec,0xa5,0x60,0xcf,0xe7,0xd5,0xcf,0x5d,0xca,0x1a,
-  0x60,0x66,0x62,0x62,0x42,0x64,0x59,0x16,0x16,0x85,0xe,0xf3,0xea,0xf5,0x3a,0x9a,
-  0xcd,0x46,0xb5,0x2f,0x90,0xac,0x3b,0x5b,0xac,0x88,0x10,0xa7,0x84,0x34,0x2b,0xca,
-  0x15,0xaa,0xca,0x83,0xd8,0xbb,0xcf,0x64,0x56,0xbc,0xa5,0x7a,0x95,0x13,0xa9,0x27,
-  0xd8,0xab,0x14,0xf2,0x7c,0x87,0x6a,0xf8,0xc7,0x15,0xa2,0x89,0x4b,0x8,0x65,0x62,
-  0x8,0xe,0xae,0xd5,0x6b,0x3a,0x4c,0xcc,0xb,0x64,0x59,0x16,0x4e,0x4c,0x4c,0x58,
-  0xae,0xbf,0xae,0xf,0x20,0xc6,0x9b,0xbe,0xf0,0xe6,0x53,0x6f,0xfe,0xc2,0x9b,0xdf,
-  0xb,0xe0,0x46,0x0,0x7f,0xb5,0x83,0x90,0x6d,0xdf,0x25,0x25,0x0,0x3,0xf5,0x80,
-  0xf3,0xdd,0x6e,0xb7,0x48,0x92,0xd4,0x71,0xf1,0x5a,0xad,0x16,0x6a,0xb5,0x9a,0x8b,
-  0x2,0xa4,0x94,0x28,0x64,0x4,0x62,0xa1,0xd1,0x3c,0x45,0x38,0xdb,0x4b,0x7,0x50,
-  0x3f,0x1b,0xeb,0x53,0xa9,0xe6,0x8d,0xdd,0x76,0x2a,0x5c,0x55,0x31,0x1,0x67,0xdf,
-  0x49,0xb,0x8,0x51,0xb5,0x28,0xc4,0x4e,0xb8,0xd5,0x4,0xe4,0x9c,0x46,0x61,0x32,
-  0x82,0xd5,0x84,0x50,0xbd,0x5e,0x47,0xab,0xd9,0x72,0xd9,0xcc,0x24,0x49,0xd0,0xed,
-  0x76,0xb,0x78,0x4,0xd1,0x8f,0x7f,0xfc,0xe3,0xc2,0x16,0xb1,0x0,0x38,0xa,0xe0,
-  0x66,0x0,0xaf,0x7,0xf0,0xa5,0x6d,0x1c,0xc3,0x67,0x15,0x3f,0x70,0xb7,0x38,0xc0,
-  0xfc,0xec,0xec,0xac,0x4a,0xd3,0xc4,0xc5,0xfc,0x63,0x63,0x63,0xae,0x24,0xc,0xd0,
-  0x8d,0xa0,0xda,0xf5,0x3a,0x64,0xbd,0x8e,0x7a,0x28,0x91,0x15,0x84,0x66,0x4d,0x9a,
-  0xe4,0xe,0x6f,0x4d,0xe8,0xf5,0xca,0xbb,0x4,0xb,0x17,0xf2,0x9,0xe8,0x42,0x11,
-  0x87,0x1,0xa0,0x4c,0x15,0x3b,0x7a,0xb8,0xdf,0x21,0x94,0x51,0x61,0x14,0xd9,0x2e,
-  0x93,0x71,0xc6,0x68,0x7,0x0,0x70,0xa6,0xe2,0x3,0x8c,0x8d,0x8d,0xe9,0x7e,0x83,
-  0x8e,0x18,0x32,0xab,0x1e,0x7f,0xfc,0xf1,0xf9,0x4a,0x5a,0x6a,0xb8,0x39,0xc4,0x37,
-  0x0,0xfc,0xa,0x80,0xef,0x5,0xf0,0x36,0x0,0x2f,0x1c,0xd0,0x2,0x8b,0x97,0x2a,
-  0xe,0x20,0x1,0xec,0x5b,0x58,0x58,0x50,0xd6,0x1,0x4,0x74,0x77,0xcf,0x20,0xd0,
-  0xb9,0x7f,0x29,0x25,0x82,0x20,0xc0,0x75,0x33,0x6b,0xf8,0x66,0x3e,0x7,0x84,0x75,
-  0xf4,0x52,0x85,0xc9,0x56,0x88,0xa1,0x1e,0xac,0x43,0xd8,0xae,0x9f,0xfa,0xb5,0xf4,
-  0x6e,0x31,0x9c,0xf5,0x76,0x93,0x3e,0xc0,0x7,0x13,0x3,0x79,0x61,0xfb,0x71,0xc4,
-  0x10,0x45,0x1f,0x2f,0xa8,0xad,0x54,0x4c,0x40,0x18,0x86,0x98,0x9c,0x9c,0xc4,0xd1,
-  0xa3,0x47,0xb5,0xdf,0x92,0x24,0xb6,0x69,0x54,0x49,0x11,0x87,0x57,0x8a,0x3e,0x3c,
-  0x1e,0x4,0xf0,0xef,0x1,0xfc,0x0,0x80,0x9f,0xf3,0x56,0xbe,0xb8,0xd4,0x4,0xc0,
-  0x57,0x6f,0x33,0xd3,0xd3,0xd3,0x9c,0x24,0x31,0x98,0x18,0x61,0x14,0x61,0x66,0x66,
-  0xc6,0xd9,0xd9,0x5a,0x4d,0xdb,0xd4,0xb9,0xfa,0x26,0xe6,0x1b,0xff,0x8,0xa5,0x14,
-  0x52,0x4e,0x9f,0x71,0x3f,0xda,0xa,0xef,0xf4,0xf4,0xb4,0x96,0x31,0xa5,0x23,0x81,
-  0xd9,0xd9,0xd9,0xa1,0x2a,0x21,0x2e,0xbb,0x4e,0x9c,0x6b,0x7c,0xd9,0x1c,0xaf,0x84,
-  0xae,0x25,0xb8,0xe7,0x52,0xd6,0x0,0x8b,0x93,0x93,0x93,0xc5,0xfa,0xfa,0x3a,0x88,
-  0x19,0x61,0x28,0x31,0x3e,0x3e,0x8e,0x30,0xc,0x11,0x45,0x51,0xa5,0x2a,0x88,0x99,
-  0xb7,0x6d,0x18,0xf9,0xdd,0x1c,0x41,0x10,0xa0,0x56,0xab,0xe9,0xef,0x1e,0x84,0xc8,
-  0x54,0x8a,0x24,0x4b,0x31,0x3e,0x3e,0x3e,0x5c,0x27,0x48,0xbc,0xd3,0x35,0xfd,0x25,
-  0xcf,0x37,0xf8,0x8e,0x8d,0x2b,0xff,0x62,0xe,0xb9,0x52,0x28,0x94,0xce,0x6c,0x16,
-  0x4a,0xa1,0x20,0x82,0x52,0xa,0x9b,0x3f,0x9f,0x5c,0x34,0xd,0x60,0x2f,0xc8,0xec,
-  0xe8,0xe8,0x28,0x9f,0x3c,0x75,0xa,0xc,0x46,0xbf,0x17,0xe3,0xd4,0xa9,0x53,0xb8,
-  0xfa,0xea,0xab,0xb1,0x7f,0xff,0xfe,0xa,0x25,0xec,0x99,0x2c,0x0,0xf5,0x7a,0x1d,
-  0xf5,0x7a,0x1d,0x27,0x8e,0x9f,0x40,0x92,0x26,0x0,0x4,0x92,0x38,0xc6,0xe2,0xc2,
-  0x82,0xed,0x1b,0xe8,0x7e,0x33,0x55,0x88,0xa8,0xcf,0xbc,0x21,0x84,0x70,0x1c,0xc,
-  0xfb,0xbf,0xe0,0x9d,0x5b,0xa2,0xdd,0x6a,0x80,0xd9,0x46,0xa3,0x11,0xe8,0x4c,0xa0,
-  0x26,0x67,0x3c,0xfe,0xf8,0xe3,0xa8,0xd7,0xeb,0xb8,0xe2,0x8a,0x2b,0x9e,0x35,0x6a,
-  0x2f,0x8e,0x63,0xfc,0xfd,0xdf,0xff,0x3d,0xe,0x3d,0x7e,0xc8,0x15,0x9e,0x24,0x69,
-  0x8a,0x46,0xa3,0xe1,0xd7,0x9,0xea,0x2b,0x48,0x3a,0x59,0xf5,0xef,0xae,0xbf,0x1,
-  0x51,0x10,0x22,0xc,0x3,0x44,0x81,0x3e,0xc2,0x20,0xd8,0x1f,0x5,0xc1,0x3b,0x3,
-  0x19,0x1c,0xb,0x3,0xf9,0x89,0x40,0xca,0x25,0x29,0x24,0x2,0x29,0x20,0x84,0x74,
-  0xfc,0x46,0x2,0x1b,0x7e,0xa4,0xe,0x8b,0x15,0x29,0xe4,0x8a,0xf4,0x6a,0x35,0x47,
-  0xae,0x14,0xf2,0x42,0x21,0x57,0x5,0x72,0xa5,0x90,0x15,0x5,0x72,0x55,0x20,0x2b,
-  0x14,0xf2,0xc2,0x7f,0xcc,0xbe,0x56,0xdf,0x2e,0xa,0x63,0xab,0x84,0x75,0x86,0x79,
-  0x57,0x5e,0xc8,0x6e,0x7c,0x0,0x9,0x60,0x36,0x8,0x82,0x30,0xc9,0x32,0x83,0xa2,
-  0x11,0x8e,0x2e,0x2d,0xe1,0xe8,0xd2,0x51,0x8,0xae,0x72,0xf2,0x84,0xdf,0x6e,0xaf,
-  0x22,0x9f,0xa5,0x8f,0x5f,0xd9,0xd5,0xa1,0x92,0x1d,0x32,0xaf,0x65,0xd3,0x30,0x82,
-  0xab,0x89,0x1e,0x1d,0x41,0x58,0x22,0xa8,0xf0,0xb2,0x89,0x25,0x5d,0x50,0x78,0xe,
-  0xa6,0xdb,0x81,0x40,0xf0,0x70,0xc7,0x37,0xa1,0xb3,0x85,0x69,0x92,0x20,0x8,0x82,
-  0xe6,0x80,0x0,0x8,0x62,0x32,0xef,0x25,0x20,0x4,0x20,0x21,0x20,0xf5,0xaa,0xb,
-  0xa4,0x10,0xf7,0xa,0x81,0x45,0x29,0x5,0xa4,0x10,0xbf,0x29,0x85,0xf8,0x48,0x20,
-  0xc5,0x6d,0x52,0xca,0x63,0xfa,0x35,0xb2,0xe4,0x26,0xa,0xc3,0x68,0x12,0x2,0x4a,
-  0x6f,0x5e,0x1,0x29,0x4c,0xc3,0xc,0xfb,0x7b,0xfd,0xd5,0x6c,0x66,0xd4,0x3e,0x56,
-  0x1e,0xe5,0x24,0xbb,0x15,0x6f,0x24,0x40,0xff,0x46,0xb1,0x2b,0x4f,0x54,0xee,0x42,
-  0x0,0x46,0x9a,0xcd,0x66,0xab,0x28,0x8a,0x46,0x9e,0x9b,0xfa,0x3e,0xb0,0x63,0xe3,
-  0x10,0x97,0x54,0xac,0x4a,0x63,0x7,0xf6,0x5e,0x7,0xdd,0x16,0x86,0x8c,0xf0,0x54,
-  0x1a,0x3c,0x19,0xcc,0x1e,0xae,0xce,0xcf,0x26,0x84,0x4a,0x82,0x27,0x99,0xc7,0x2d,
-  0x40,0x4,0x66,0x10,0xa8,0x6c,0x13,0x63,0xbb,0xfb,0x92,0xf9,0x1c,0xf2,0x9b,0x4b,
-  0x79,0x30,0xb3,0xeb,0x22,0x52,0x7e,0x56,0x9e,0xe7,0x28,0x8a,0xa2,0xd1,0x6c,0x36,
-  0x5b,0x0,0x46,0xe0,0x35,0x8b,0xb0,0x6e,0x80,0x9e,0x2c,0x37,0x51,0x4d,0x1,0xb1,
-  0x28,0xca,0xa5,0x57,0x93,0x42,0xbc,0x4d,0x8,0xf1,0x84,0x14,0xe2,0xc3,0x81,0x94,
-  0x33,0xd2,0xf4,0x4c,0x8,0xbc,0x9,0x84,0x10,0x90,0x52,0x40,0x9a,0xcb,0x6a,0xa6,
-  0xcd,0x4d,0x6e,0x39,0xf9,0x70,0xcf,0x55,0xa6,0x93,0xcd,0x79,0xec,0xaf,0x34,0x51,
-  0x49,0x89,0x8b,0x5d,0x48,0x80,0xdc,0x1,0x8,0xe4,0x30,0x80,0x6e,0xb7,0x9b,0x27,
-  0x49,0x2,0x22,0xe5,0xa1,0x74,0x66,0x62,0xac,0x9a,0x2b,0xa,0x90,0x52,0xd5,0xa3,
-  0xd0,0x7f,0xf5,0x73,0xf6,0x50,0x50,0xaa,0x80,0x52,0x85,0x81,0x81,0x15,0x48,0x15,
-  0x50,0x4a,0x81,0x8a,0xc2,0x9d,0x63,0x5f,0xaf,0xfc,0xf3,0xa,0xa5,0x3f,0xcb,0xbe,
-  0x77,0x61,0x1e,0xb3,0xb7,0xdd,0x79,0xca,0x9c,0x57,0xde,0x2f,0xb,0x4a,0xa9,0xd2,
-  0x7b,0x48,0xd7,0x9,0x26,0xe8,0x76,0xbb,0xb9,0x7,0x9,0xe3,0xd3,0x9f,0xfe,0xb4,
-  0x60,0x26,0x2f,0x5a,0x75,0x38,0xc3,0x26,0x4,0xaf,0x0,0x66,0x25,0xbb,0x96,0xb7,
-  0xa2,0x29,0x20,0xde,0x9,0x81,0xc3,0x81,0x94,0xb7,0x4b,0x21,0xa6,0x30,0x60,0xa7,
-  0x85,0x7,0x86,0x88,0x4a,0x9a,0x89,0xab,0x90,0x82,0x18,0x5c,0x89,0x5e,0x83,0x2d,
-  0xf,0x1f,0xe1,0xa7,0xd1,0xd1,0x7a,0x37,0x4e,0xe0,0x42,0xb7,0xdb,0x55,0x71,0x1c,
-  0x97,0xf5,0xfb,0xa8,0xc6,0xde,0x2f,0xfb,0xbe,0xef,0xc3,0x4f,0xfc,0xe4,0x4f,0x56,
-  0x9a,0x44,0xec,0xc4,0x1e,0xdf,0xfa,0xfe,0xf7,0xe3,0x3f,0xff,0xe6,0x6f,0x22,0x8a,
-  0xa2,0x1d,0x9d,0x53,0x14,0x5,0xfe,0xfb,0x7,0x3e,0x80,0x9f,0x79,0xc3,0x1b,0xb0,
-  0x6f,0xdf,0xbe,0x2d,0x68,0xfc,0x5b,0x8f,0x8d,0x8d,0xd,0xfc,0xe9,0x9f,0xfe,0x29,
-  0x1e,0x79,0xe4,0x11,0xbf,0xe,0xc5,0xfd,0x96,0x38,0x8e,0xd1,0xed,0x76,0xd5,0xd1,
-  0xa3,0x47,0x17,0x4c,0x9c,0x6f,0x1b,0x8f,0xb8,0x62,0x13,0xaf,0xec,0x4,0x80,0x58,
-  0x62,0xc6,0x54,0xa9,0x81,0x8c,0x6,0xd3,0xa6,0x6d,0x84,0x98,0x6e,0x26,0xc6,0xdb,
-  0xc0,0xfc,0x41,0x6,0xff,0xae,0x0,0xce,0x1a,0xb7,0xc2,0xd9,0x6b,0x1e,0x6,0x41,
-  0x1c,0xb9,0xb5,0x14,0x39,0xd7,0x15,0xcb,0x63,0x46,0x8b,0xf2,0x7b,0xc,0x9a,0x40,
-  0xec,0xbc,0x68,0x60,0x37,0x3e,0xc0,0xe2,0xfc,0xfc,0xbc,0x6e,0x9,0xb3,0x45,0xeb,
-  0x54,0x1,0xe0,0xda,0x17,0xbf,0x18,0x4b,0x4b,0x47,0xf1,0xad,0x63,0xc7,0x41,0x4c,
-  0xae,0xdb,0x27,0xfb,0xf6,0xdf,0x33,0xf7,0xf5,0x7a,0xd,0xfb,0xf6,0x5d,0x86,0x30,
-  0xc,0x71,0xf6,0xec,0x59,0x3c,0xf8,0xe0,0x3f,0x54,0xfc,0x85,0xad,0x58,0x43,0x42,
-  0x8,0xbc,0xf4,0xa5,0x2f,0x5,0x0,0x2c,0x9f,0x5a,0xc6,0xe9,0xd3,0xa7,0x71,0x66,
-  0x65,0x65,0xcb,0xed,0x87,0xdc,0x42,0x63,0x40,0x48,0xe0,0xf2,0xcb,0x9f,0x8f,0x6b,
-  0x5e,0xf4,0x22,0x3c,0xf2,0xf0,0xc3,0xa0,0x2d,0x7e,0x68,0x9a,0xa6,0x98,0x9f,0x9f,
-  0xf7,0xbb,0x86,0x19,0x1,0x30,0x4c,0x22,0xe3,0xd0,0x59,0xf8,0x98,0x89,0x8f,0x40,
-  0xf2,0x4b,0xad,0x99,0x90,0xd6,0x5c,0x18,0xce,0x82,0x99,0xe5,0x11,0x62,0xba,0x85,
-  0x89,0xdf,0x49,0xcc,0xbf,0xcb,0xcc,0x1f,0x4,0xb0,0xc9,0xc6,0x4c,0xf9,0xd,0xc9,
-  0x98,0xb9,0x42,0x7c,0xe1,0xca,0x64,0xa,0x4f,0x60,0x4b,0x93,0x57,0x6d,0x9e,0x37,
-  0xd8,0x48,0xf7,0x2,0x4c,0x80,0xb5,0x55,0xaf,0x7b,0xdd,0xeb,0x6,0x1d,0xc0,0x6e,
-  0xb7,0xdb,0xe5,0x38,0x8e,0xab,0xf5,0xf8,0x25,0x56,0x8e,0x56,0xab,0x85,0xf5,0xf5,
-  0xd,0x14,0x4a,0xe9,0x5c,0xbb,0x51,0xb9,0xa4,0xbc,0xdb,0x44,0x50,0x86,0xf,0x10,
-  0x86,0x11,0xe2,0x38,0x76,0x34,0x6d,0x45,0xba,0xd4,0x5c,0x93,0x4b,0xc8,0xa9,0x79,
-  0x65,0xd8,0xc7,0xf6,0x3d,0x1,0xa0,0x56,0xaf,0x23,0x4e,0x62,0x44,0x51,0xd,0x6c,
-  0x5e,0xa3,0x88,0x40,0xe4,0x99,0x7,0xf3,0xb9,0x8a,0x15,0x8a,0x42,0x61,0x7d,0x7d,
-  0x1d,0x2d,0xd3,0xc0,0x6a,0xa8,0xaf,0x0,0xb3,0xd5,0x0,0xc,0xdd,0x35,0xcc,0x6b,
-  0x1a,0x45,0x25,0xd5,0x9c,0x50,0x9a,0x3c,0xf0,0x91,0x72,0x22,0xad,0xdf,0xa3,0xbd,
-  0xfd,0x82,0x48,0x7f,0xae,0xf5,0xfe,0x99,0xc7,0x89,0xf9,0x56,0x62,0x3e,0x4a,0xc4,
-  0x37,0x33,0x68,0x64,0xf0,0x1a,0x92,0xf5,0x75,0x9c,0xda,0x61,0xd7,0xbe,0xde,0x35,
-  0xbf,0xf2,0x9b,0x99,0x3,0x26,0xd7,0xe1,0x79,0xbf,0x3,0xae,0xf7,0x5,0x6b,0x0,
-  0xf,0x2,0x75,0x1a,0xa0,0xd3,0xe9,0x14,0x67,0xcf,0x9e,0xdd,0xba,0x7f,0xbe,0x10,
-  0x8,0x82,0x0,0xad,0x56,0x6b,0x68,0x53,0x88,0xed,0xc6,0xfa,0xfa,0x3a,0x82,0x30,
-  0xd4,0x94,0x31,0x62,0x94,0x45,0x21,0x5b,0x84,0x33,0x9e,0xba,0xe,0xcd,0xae,0x22,
-  0xa3,0xa3,0xa3,0x98,0x9d,0xdb,0x59,0x6,0xb6,0xa,0x54,0xd,0x5f,0xa8,0x34,0x4d,
-  0xd1,0xe9,0x74,0x8a,0x61,0xd,0x60,0x42,0x39,0xe8,0x62,0x57,0xc7,0x33,0x10,0x7c,
-  0x44,0x41,0x77,0x34,0xf1,0xbb,0xe4,0xb3,0x2c,0xed,0xbc,0x65,0x3b,0x13,0x11,0x94,
-  0x16,0xf2,0x29,0x62,0xba,0x9d,0x88,0x6f,0x66,0xe6,0xdb,0x88,0xf9,0xe,0xc5,0x1c,
-  0x5b,0xe7,0xd4,0x3a,0xce,0x84,0xea,0x7d,0xf6,0x7b,0x1f,0x59,0x47,0xda,0x5b,0xf3,
-  0xcc,0x4e,0x37,0xd,0xb3,0xa6,0x2f,0x48,0x0,0xca,0xa0,0xce,0xf5,0x4,0x6a,0xb5,
-  0x5a,0x74,0xf2,0xe4,0x49,0x27,0x89,0xfe,0xc,0x49,0x29,0xf1,0xb5,0xaf,0x7d,0x6d,
-  0x57,0xe0,0x8f,0x30,0xf6,0xbc,0x66,0x6c,0x3f,0x9b,0xc8,0xc2,0x5e,0x3d,0x66,0xe1,
-  0x88,0x9d,0xbe,0x4e,0x67,0xd6,0xdb,0xd3,0x3c,0xf9,0xc4,0x13,0x38,0x7d,0xfa,0xf4,
-  0x8e,0x37,0x74,0x10,0x80,0xae,0x7,0x70,0xd,0x26,0xab,0x9,0x89,0x24,0x89,0x31,
-  0x3f,0x3f,0x4f,0x26,0x25,0xec,0x85,0x82,0xba,0xcf,0x0,0x9,0x6,0x9,0x82,0x92,
-  0x2,0x92,0x24,0x48,0xf2,0x11,0x22,0x2d,0x18,0xca,0x70,0xb,0xac,0x86,0x10,0x9e,
-  0x63,0x48,0x3e,0x39,0x85,0x49,0x6b,0x3a,0xe6,0x19,0xc5,0xf4,0x7b,0xc4,0x7c,0x33,
-  0x31,0xdd,0x46,0x44,0x1f,0x21,0x70,0x56,0x46,0x2c,0x28,0x23,0x28,0x32,0xfa,0xc6,
-  0x98,0x18,0x82,0x6d,0xb8,0x59,0x15,0xa,0x37,0xef,0xcc,0x4f,0xdf,0x7,0xd8,0x42,
-  0x3,0x2c,0xb4,0xda,0x6d,0x69,0x4d,0x40,0x69,0xa4,0xf5,0x45,0x8c,0xa2,0x8,0xfd,
-  0x5e,0x6f,0xc7,0xe,0x99,0xfd,0xe2,0xbd,0x5e,0xf,0x8d,0x66,0xd3,0xfc,0x38,0xe5,
-  0x12,0x40,0x5c,0x71,0xb6,0x30,0xd0,0xc7,0x5f,0x9b,0x9b,0xe3,0xc7,0x8f,0xa3,0xd5,
-  0x6a,0xed,0xea,0x33,0xd3,0x2c,0x43,0x2d,0xd2,0xa6,0xc7,0x36,0x81,0xd4,0xda,0x86,
-  0x11,0xc7,0x9,0xda,0xed,0xb6,0xf4,0xd0,0x40,0xe7,0x8c,0xe8,0xb0,0x54,0xb8,0x70,
-  0x92,0x4,0x41,0x29,0x1c,0x71,0x39,0x2b,0x5,0x84,0x2c,0x1,0xc9,0x10,0x90,0x6e,
-  0xe7,0xd1,0xd2,0x9e,0x97,0x40,0x90,0x6,0x85,0xdc,0xb1,0xc8,0xc4,0xff,0x93,0x98,
-  0xdf,0xc3,0xa4,0x6e,0x23,0xe6,0x8f,0x30,0x93,0xb2,0xa6,0x84,0x3c,0x21,0x20,0x17,
-  0xba,0x92,0xc1,0x41,0xbc,0x30,0xdb,0xfa,0x10,0xbb,0x2c,0x19,0x3d,0xa7,0x0,0x10,
-  0xf,0x69,0x80,0x6e,0x28,0x83,0x5a,0x92,0xc4,0x15,0x89,0xb3,0x7e,0xc3,0xd4,0xd4,
-  0x14,0x5e,0xff,0x33,0xaf,0xd7,0x8d,0xa2,0x2c,0xf0,0xe2,0xd7,0x77,0x30,0x2a,0x80,
-  0xf,0xb,0x1,0x22,0x85,0x7,0xfe,0xee,0x1,0x3c,0xf9,0xe4,0x93,0x95,0x6,0x8f,
-  0x65,0x69,0x38,0xb9,0x14,0xb1,0xcd,0x12,0xb2,0x0,0x94,0x22,0x34,0x1a,0xd,0x5c,
-  0x79,0xd5,0x95,0xf8,0xd1,0x1f,0xbd,0x11,0x81,0x94,0x5e,0x86,0xb1,0x4,0x98,0xca,
-  0x46,0x53,0x70,0x5f,0xa4,0x28,0x72,0x7c,0xe8,0x83,0x1f,0x42,0xdf,0x8,0xb2,0x8b,
-  0x6,0x4c,0x9d,0x60,0x10,0x4,0xb5,0x61,0x1f,0x40,0x4f,0x9c,0x14,0x2,0x4a,0x58,
-  0x10,0x47,0x0,0xc0,0x92,0xdb,0x4d,0x44,0x5a,0x87,0x53,0x40,0xa,0x7f,0x43,0xac,
-  0x52,0x95,0x6b,0xd,0xa0,0xb4,0x20,0x18,0x9f,0x48,0x11,0x19,0x3f,0x81,0x9e,0xa7,
-  0x8,0x7f,0xa0,0x88,0x6e,0x56,0xc4,0xb7,0x11,0xd1,0xc7,0x18,0xe4,0x28,0x6d,0xa,
-  0x70,0xbd,0x93,0x1c,0xb6,0x1,0xae,0x60,0x1d,0x83,0x6d,0x73,0x9f,0x66,0x14,0xc0,
-  0xbe,0xa3,0x58,0x8f,0xa2,0xa8,0x43,0x4c,0x22,0x4d,0x73,0xf0,0x40,0x6d,0x9e,0x8,
-  0x80,0x5a,0xad,0x86,0x7e,0x3f,0xc6,0x57,0xbe,0xf2,0x95,0x73,0xeb,0xdf,0x81,0xef,
-  0x74,0xed,0x35,0xd7,0x60,0x63,0x63,0x3,0x61,0x10,0x40,0xc0,0xda,0xd1,0x81,0x20,
-  0x86,0xab,0x9d,0xc1,0x4,0x3,0x59,0x96,0x42,0x86,0x21,0x7a,0x9b,0x9b,0xd8,0xd8,
-  0xd8,0xc0,0x57,0xbf,0xfa,0x55,0xb8,0x1e,0xf2,0xe7,0xac,0x9c,0xd6,0x8f,0xbf,0xe2,
-  0x15,0xaf,0x30,0xe1,0xa6,0xd0,0x84,0x51,0x2f,0x4b,0x9d,0xa5,0x19,0x54,0xa1,0x5a,
-  0x51,0x14,0xb5,0xf3,0x3c,0xaf,0xdb,0x69,0xb5,0x93,0xa7,0x24,0x41,0x90,0xf0,0x11,
-  0xbb,0x4d,0x0,0xcb,0xc,0xcc,0x58,0xd5,0x2d,0x4d,0x21,0x6c,0xe9,0x93,0x9,0xb7,
-  0x52,0xc9,0x3a,0xba,0xcc,0x50,0x4c,0xfa,0x30,0xce,0xab,0x32,0x65,0x6a,0x8a,0xe8,
-  0x4a,0x22,0xfa,0x28,0x81,0xdf,0xa3,0x88,0xff,0xb,0x31,0x7d,0x42,0x79,0xad,0x73,
-  0xc8,0x4e,0x3c,0x7b,0xda,0xa1,0xe2,0x27,0xf0,0xae,0xf6,0x39,0x39,0xa7,0x0,0xdc,
-  0x75,0xd7,0x5d,0x15,0x96,0xcb,0xd4,0xd4,0x54,0xde,0xef,0xf5,0x6b,0x6c,0xc,0xf,
-  0xf9,0x40,0x14,0x4b,0xb4,0x47,0x46,0x2a,0x5f,0x44,0xb8,0x70,0xcc,0x28,0x73,0x2a,
-  0x61,0x57,0x3b,0x1f,0x61,0x14,0x21,0x49,0x12,0xd4,0xea,0x75,0xa7,0xda,0xac,0xa6,
-  0xa8,0x6e,0x20,0x5b,0xfe,0x30,0x1,0x81,0x2c,0xcb,0x50,0xb,0x23,0xac,0x9a,0x2e,
-  0xa5,0xda,0xf6,0xa,0x77,0x1e,0x7c,0x9f,0x41,0x94,0xe4,0x12,0xab,0x1f,0xdb,0xed,
-  0x36,0x4,0x0,0xc5,0xe4,0x34,0x95,0x96,0x65,0x85,0x24,0x89,0x65,0x67,0xb6,0x83,
-  0x2b,0x3e,0x3c,0x71,0x78,0x64,0xa1,0x81,0x5a,0x10,0x20,0xc,0x57,0x50,0x70,0x8,
-  0xa1,0x7c,0xec,0xae,0x6a,0x6b,0x99,0x5,0x2,0xd6,0xa6,0x41,0xa,0x31,0x18,0xd6,
-  0x57,0xd0,0x48,0x65,0xd8,0xcd,0x85,0x8d,0x7a,0x5c,0x4,0x43,0xee,0x79,0x45,0xb4,
-  0x9f,0x88,0x3e,0x4e,0xc4,0xef,0x21,0x52,0xff,0x45,0x31,0x1f,0x20,0xf6,0xa8,0x71,
-  0x83,0x91,0x98,0x45,0x42,0x1d,0xda,0x79,0x71,0x92,0x41,0x8e,0xe7,0x36,0x3f,0x3f,
-  0x5f,0x24,0x69,0x52,0xb3,0xab,0xd1,0x56,0xed,0x6a,0xa7,0x2d,0x40,0x20,0x25,0x4e,
-  0x9e,0x3c,0x85,0x7d,0x8b,0x8b,0x3,0xf8,0x3f,0x9f,0xe3,0xa6,0xc0,0xca,0xea,0xa,
-  0xd6,0xd7,0xcf,0x22,0x8a,0x6a,0x38,0x71,0xe2,0x4,0x16,0x17,0x17,0x7,0x16,0xb0,
-  0x9e,0x54,0x31,0x90,0x91,0xdf,0xdc,0xdc,0x44,0x51,0xe4,0xd8,0xdc,0xdc,0xc4,0xf2,
-  0xf2,0x32,0xf6,0x2d,0xee,0x43,0xb5,0xb9,0xeb,0x80,0x16,0xf0,0xee,0x9e,0x3c,0x79,
-  0x12,0x61,0x18,0xba,0xc7,0xc8,0x3b,0x53,0x0,0x48,0xd2,0x14,0xdd,0xb9,0x19,0xc4,
-  0x27,0x37,0xd1,0x9a,0xab,0xa1,0x90,0x2,0x42,0x9,0x8,0xa1,0xc,0xc4,0x2a,0x2a,
-  0x28,0x9d,0xf5,0xb8,0xa5,0x14,0xc6,0xf9,0x33,0x22,0x62,0x20,0x63,0xab,0x8a,0x4b,
-  0x47,0xd0,0x46,0x3,0xac,0x27,0x5e,0x69,0x41,0x28,0x9c,0x29,0x30,0x21,0xb0,0xb2,
-  0xce,0x22,0xbd,0x44,0x31,0x7f,0x8a,0x14,0x7d,0x9d,0x88,0x7f,0x83,0x98,0xff,0x4a,
-  0x99,0x70,0xb3,0xa4,0xd3,0x99,0xa4,0x95,0x11,0x48,0xeb,0x2b,0x5c,0x2c,0x1,0x90,
-  0x0,0x66,0x67,0x66,0x66,0x28,0x89,0x93,0xd2,0xfe,0x33,0x40,0x42,0xaf,0x20,0xa5,
-  0x14,0x8e,0x1f,0x3f,0x8e,0xfb,0xfe,0xdf,0xff,0x1d,0xda,0x35,0xec,0x7c,0xa9,0xcc,
-  0x95,0x95,0x15,0x84,0x61,0x88,0x8d,0xf5,0xf5,0x1d,0x9f,0x2b,0xa4,0x44,0xbf,0xd7,
-  0xc3,0xe6,0xe6,0x26,0xbe,0x70,0xdf,0x7d,0xbb,0xda,0xd6,0x4d,0x4a,0x89,0xb5,0xb5,
-  0x35,0x28,0x55,0x68,0x1f,0xc3,0xf5,0x32,0x34,0x1b,0x58,0xc6,0x9,0xba,0xb3,0x5d,
-  0x1c,0x5b,0x5e,0xd5,0x76,0x5f,0x49,0x14,0x20,0x2d,0x4,0x55,0x98,0xaa,0xa2,0x7e,
-  0x25,0x49,0x48,0xc9,0x3a,0x51,0x64,0x5,0xc4,0xd7,0x0,0xc6,0x93,0xd7,0x2b,0x9c,
-  0x3d,0x47,0x90,0x51,0xd8,0xc9,0x56,0xce,0x1f,0x40,0xc1,0xe5,0xf3,0x9a,0xf5,0xcc,
-  0xff,0x5c,0x11,0xfd,0xa5,0x22,0x7e,0x80,0x89,0xde,0xab,0x18,0x7f,0x53,0x46,0x6,
-  0xe4,0xcc,0x82,0x16,0x2,0x2,0x40,0x4f,0x5b,0x0,0xc4,0x0,0xa,0x48,0x71,0x92,
-  0x94,0xd,0x1d,0x8c,0xf7,0x4c,0x60,0x4,0x22,0xc0,0xfc,0xc2,0x3c,0x16,0x17,0x77,
-  0x47,0x88,0x25,0xa5,0xf0,0xd0,0xc1,0x83,0x98,0x9a,0x9c,0xc4,0x65,0xcf,0x7b,0xde,
-  0xae,0xbc,0xf9,0xd3,0xcb,0xcb,0x78,0xf2,0xc9,0x27,0x71,0xe5,0x55,0x57,0x21,0x8,
-  0x82,0x5d,0x45,0x1e,0x4f,0x3d,0xf5,0x14,0x8e,0x1f,0x3f,0xee,0x50,0x3b,0x57,0x85,
-  0x6c,0xe0,0xe0,0xb9,0x85,0x39,0x3c,0x79,0xe2,0x20,0xa,0x22,0x48,0xa1,0x20,0x4,
-  0x50,0xc,0x24,0x66,0x9c,0xfa,0x95,0x30,0xb6,0x9f,0x20,0x59,0x40,0xa,0xe9,0x9c,
-  0x4e,0xe1,0xbd,0x2f,0x9b,0x8e,0x65,0x8a,0x61,0x56,0x6f,0x39,0xc1,0x8a,0x94,0xd1,
-  0x0,0xca,0x1c,0x9e,0x6,0x50,0xca,0xf8,0xb,0x4a,0xb,0xe,0xab,0xef,0x57,0xcc,
-  0x77,0x33,0xd1,0xdf,0x12,0xf3,0x7f,0x22,0xe2,0xbf,0x2d,0x43,0x4c,0x2f,0x21,0xc7,
-  0xb8,0xa8,0x1a,0x60,0xae,0xd3,0xe9,0xa8,0xf5,0xf5,0xb3,0x95,0xe6,0xb,0xb6,0x8e,
-  0x2f,0xc,0x43,0xbc,0xf8,0x25,0x2f,0xc1,0xbe,0x7d,0x97,0x99,0xb,0x2a,0x6,0x10,
-  0xee,0xc1,0xc6,0xfe,0x5a,0x55,0x45,0x61,0x84,0x23,0x47,0x8e,0xe0,0xea,0xab,0xaf,
-  0xc6,0x55,0x57,0x5f,0xed,0x9,0x40,0x95,0x38,0x68,0x77,0xee,0xf3,0x21,0xde,0xd3,
-  0xcb,0xcb,0x58,0x7a,0xea,0x29,0x5c,0x77,0xdd,0x75,0xa6,0xfd,0x7b,0xd5,0x81,0x15,
-  0x18,0xe4,0x20,0x96,0xdb,0xc9,0x8f,0x8c,0x8c,0xe0,0xe0,0x43,0xf,0xe9,0xd,0xae,
-  0x9d,0xdf,0xa9,0x57,0x4c,0x9c,0x26,0x98,0x9c,0x9e,0x44,0x7a,0x38,0xd7,0x2b,0xd1,
-  0xcf,0xcd,0x28,0x7f,0x37,0x39,0x76,0xd0,0xb0,0x5e,0xfd,0x12,0x92,0x1,0x9,0x2a,
-  0xb3,0x86,0x8c,0xa,0x7c,0x4b,0x5c,0x7a,0xf2,0xd6,0xe6,0x17,0xac,0xeb,0x21,0xec,
-  0xe4,0x2b,0xc3,0x13,0xa8,0xf8,0x5,0xca,0xa0,0xa7,0x86,0xd,0x6d,0x1c,0xc9,0x57,
-  0x11,0xf1,0x17,0x89,0xe9,0xf3,0xc4,0xfc,0x5e,0x62,0xfe,0x32,0xf,0x64,0x60,0x2f,
-  0xa6,0x6,0x98,0x1b,0x1d,0x1d,0x55,0x27,0x4e,0x9c,0xac,0xbc,0xb1,0xc6,0xa,0xb4,
-  0x47,0x5c,0xaf,0xd5,0xf1,0xe8,0x23,0x8f,0xe0,0xcc,0x99,0x33,0x43,0x9b,0x38,0x94,
-  0x1c,0x5,0x2f,0x34,0x83,0xc0,0x2b,0xfe,0xc5,0xf7,0xeb,0x4d,0xa0,0x85,0xc4,0xd2,
-  0xd2,0x12,0x8e,0x2e,0x2d,0x79,0x8c,0xde,0x6a,0xad,0xb0,0x9f,0xe8,0x9f,0x9a,0x9c,
-  0xc2,0x4c,0x77,0x6,0x49,0x1c,0xa3,0xdf,0xef,0xe3,0x81,0xbf,0xfb,0xbb,0x1,0x2e,
-  0x82,0xf0,0xbe,0xa7,0xa8,0x24,0x4b,0xe6,0xe7,0xe6,0x50,0x6f,0x34,0x20,0x84,0xe9,
-  0x50,0x2e,0x6c,0x17,0x72,0x3,0x6,0xf5,0x63,0x74,0x47,0xa7,0x91,0x2e,0x6b,0x1,
-  0x90,0x16,0xcb,0x2b,0x4,0x38,0x80,0x87,0xd0,0x49,0x4,0xcc,0xba,0xa7,0x94,0x24,
-  0x4,0x2c,0x21,0xc8,0xcb,0xc,0x8a,0x72,0x73,0x1c,0x17,0xba,0x19,0x93,0xa1,0x4c,
-  0x9d,0x83,0xae,0x8b,0x31,0x2b,0x5c,0x71,0xe9,0x3,0x10,0xa1,0x30,0xf7,0xf5,0xc1,
-  0x46,0x3,0x68,0x8d,0x61,0xcb,0xe1,0xf4,0xfb,0xf0,0xf5,0x44,0xfc,0x25,0x6,0xdd,
-  0xc5,0xcc,0xef,0x65,0xf0,0xd7,0x9,0x17,0x5f,0x3,0xcc,0x36,0x1a,0xd,0x11,0x1b,
-  0x32,0xa8,0xf6,0xb6,0x85,0x3,0x50,0x84,0x10,0x68,0x8f,0xb4,0x71,0xf8,0xf0,0xe1,
-  0x8a,0xc7,0x5f,0x69,0xfd,0x22,0xfc,0x94,0x85,0xd1,0x2,0x66,0xd7,0x8e,0x28,0xa,
-  0x61,0xa9,0xe6,0x6e,0x9b,0x3e,0x51,0x5,0x9a,0xbc,0x9b,0x88,0xfb,0x31,0x1a,0xf5,
-  0x6,0xa,0xb3,0x45,0x3d,0xa3,0x8a,0x4b,0xb9,0x24,0x89,0xd9,0x7f,0x40,0x70,0x9,
-  0x2a,0x6d,0xf4,0x7a,0x98,0x9e,0x9e,0x71,0x31,0xba,0xc6,0xde,0x6d,0x3e,0x9d,0xd1,
-  0x8f,0xf5,0x7b,0x67,0xa7,0xb,0x14,0x4a,0x55,0xc2,0x50,0xb,0xbe,0xe8,0xd5,0x2f,
-  0xcd,0x41,0x10,0x2c,0xa1,0xa0,0x59,0xd1,0xf6,0x82,0x41,0xca,0x32,0x51,0xc3,0x65,
-  0x72,0x87,0xa8,0xe4,0x3a,0x18,0x27,0xcf,0xe4,0x2e,0xf4,0x84,0xe6,0x4a,0x95,0xaa,
-  0xdf,0x85,0x86,0x5c,0xb2,0x89,0x58,0xa1,0x70,0x42,0xc4,0xae,0x42,0x9b,0x98,0x6f,
-  0x64,0xe6,0x1b,0x89,0xf9,0x4e,0x26,0xfe,0x45,0x66,0xde,0xbc,0x58,0x1a,0x40,0x2,
-  0x98,0xd,0x83,0x30,0x4c,0x93,0xd8,0x6d,0xe8,0x54,0x82,0x3c,0x2,0x51,0x18,0xe2,
-  0xe4,0x89,0x93,0x68,0x36,0x9b,0x68,0x36,0x9b,0x3b,0xb6,0xc7,0x4b,0x4f,0x2d,0xa1,
-  0xdf,0xef,0x63,0x75,0x75,0x15,0x51,0x14,0x61,0x62,0x7c,0x7c,0xc7,0xce,0xe3,0xf2,
-  0xf2,0x32,0xd2,0x34,0xc5,0xb1,0x63,0xc7,0x74,0x61,0xe7,0x2e,0x1c,0xcf,0xb5,0xb3,
-  0x6b,0x90,0x52,0x9a,0x8d,0x2c,0x34,0x53,0xc7,0xaa,0x8f,0x34,0x4d,0x10,0xca,0x10,
-  0xd9,0xe9,0x2,0xca,0x6c,0x84,0x61,0xd3,0xdf,0x56,0xd4,0x74,0x7,0x54,0x6d,0xd7,
-  0x95,0xc,0x10,0x8,0x86,0x90,0x2,0xd2,0x34,0xbb,0xd4,0xdd,0xec,0x14,0x30,0x10,
-  0x2e,0xb2,0x47,0x6a,0x51,0x34,0x0,0xd,0x93,0x36,0x3,0xd6,0x37,0xc8,0xed,0xa,
-  0xb7,0xd1,0x82,0x87,0x17,0x90,0x37,0xf9,0xce,0xf6,0x97,0x7f,0x5f,0xcf,0xe0,0x80,
-  0x99,0x7f,0xfa,0x62,0x86,0x81,0x5d,0x8,0x88,0x34,0x49,0x2b,0xb9,0x71,0x18,0x84,
-  0xab,0xd7,0xef,0xe1,0xc0,0xa7,0x3e,0x75,0x41,0x84,0x84,0x34,0x4b,0xf1,0x37,0x77,
-  0xdf,0xbd,0x2b,0x7,0xb0,0x4c,0xde,0x64,0xf8,0xb3,0x3,0x7,0x2e,0xf0,0x73,0xb3,
-  0x32,0x8e,0xe7,0x32,0x95,0x9a,0x26,0x29,0x42,0x8a,0x90,0x9f,0xd6,0x36,0x59,0x6b,
-  0x9f,0xa0,0xc2,0x56,0xd2,0x2c,0x1f,0x9,0xa,0x74,0xec,0xaf,0x84,0x40,0x40,0x2,
-  0x42,0xa,0x9f,0x18,0x52,0x81,0xd4,0x4a,0x56,0x53,0xe9,0x7,0x10,0xfb,0xf0,0xb0,
-  0x51,0xf3,0x5e,0x24,0xa0,0x94,0x42,0xc1,0xde,0x7d,0x53,0x3f,0xa9,0x3c,0xe1,0x20,
-  0x1e,0x38,0x74,0x34,0xf0,0xe3,0xac,0xab,0x94,0xb3,0x8b,0xa1,0x1,0x66,0x26,0x26,
-  0x26,0x44,0x1c,0xc7,0x61,0xe1,0xb3,0x7e,0xed,0x1b,0x84,0x21,0x2e,0x7f,0xde,0xe5,
-  0x78,0xdb,0xdb,0xdf,0x81,0x28,0xa,0x77,0x39,0x81,0x29,0x6e,0xff,0x9d,0xdf,0xc1,
-  0xbb,0xdf,0xfd,0x6e,0xb4,0xbd,0x9d,0xc2,0x77,0x32,0xb2,0x34,0xc5,0xed,0xb7,0xdf,
-  0x8e,0x5f,0x79,0xd7,0xbb,0x30,0x36,0x3a,0xba,0x2b,0x46,0x4c,0x9e,0xe7,0xf8,0xf0,
-  0x87,0x3e,0x84,0xc3,0x47,0x8e,0xc,0xed,0x75,0x5c,0xa8,0x2,0x69,0x3f,0xc5,0xc4,
-  0xf8,0x38,0xd2,0x95,0x2,0x98,0xa,0x3d,0xfb,0xad,0x7d,0x80,0x80,0x19,0x2c,0x75,
-  0x43,0xb,0x25,0x34,0x6,0xa0,0x84,0xd0,0x28,0xa1,0xc5,0x0,0x20,0x2a,0x88,0x29,
-  0x9b,0x34,0xaf,0x9f,0xfe,0x55,0xc6,0x1,0x24,0x8b,0xa,0x2a,0x3,0x2,0x59,0xcf,
-  0xdf,0x13,0x4,0x77,0x9b,0x2b,0x60,0x91,0x8b,0x28,0x6,0x22,0x80,0x27,0x77,0x32,
-  0xf9,0xdb,0x9,0x80,0xaf,0xfe,0xf7,0xcd,0xcd,0xcd,0xe5,0xfd,0xb8,0x1f,0xb2,0xdf,
-  0xbd,0xd9,0x53,0xa9,0x51,0x14,0x61,0x6d,0x6d,0x15,0xf7,0x7d,0xe1,0x3e,0xe3,0x6f,
-  0x79,0xd,0x5c,0x7c,0x3f,0xce,0xe7,0x7d,0x2,0xf8,0x81,0x57,0xbe,0x12,0x59,0x96,
-  0xe1,0xec,0xfa,0x3a,0xee,0xfa,0xeb,0xbb,0x75,0xdb,0x57,0x1e,0x76,0x0,0x7d,0x94,
-  0xd7,0xfa,0x73,0xaf,0x7a,0xd5,0xab,0x20,0xa5,0xc4,0x89,0x13,0x27,0x70,0xff,0x97,
-  0xee,0x47,0x7f,0xb3,0x57,0x12,0x4f,0x44,0x89,0x84,0x89,0x1,0x58,0x54,0x0,0x78,
-  0xf5,0x6b,0x5e,0x83,0x30,0x8a,0x2a,0x40,0x8d,0xff,0x7c,0xbf,0xdf,0xc7,0xec,0xe2,
-  0x1c,0xfa,0x27,0x4e,0x23,0x18,0x97,0x60,0x69,0x54,0xb8,0xd0,0xdf,0x8b,0x84,0x9e,
-  0x0,0x29,0x24,0x2,0x13,0xfe,0xd9,0x4,0x90,0xf0,0x71,0x80,0x4a,0xa,0x9b,0x4b,
-  0x21,0x22,0x72,0x29,0x62,0xa7,0xc6,0x89,0x9c,0x93,0xe7,0xab,0x7b,0xad,0x11,0x78,
-  0x30,0x81,0x54,0xae,0x78,0xcb,0x7f,0x2c,0xcd,0xcb,0xd7,0x1,0xbc,0xe9,0x62,0x51,
-  0xc2,0x4,0x80,0xee,0xf4,0xf4,0x34,0xa5,0x71,0xea,0x54,0x66,0x59,0x87,0xa7,0x7f,
-  0x70,0xb3,0xd5,0xd2,0x52,0xad,0x68,0xeb,0x94,0xc2,0x16,0x9c,0xb7,0x30,0xc,0x51,
-  0xe4,0xb9,0x8b,0xe1,0x95,0x2a,0x30,0x98,0x33,0x3a,0x67,0x8a,0x42,0x94,0x29,0xe1,
-  0x38,0x8e,0x51,0xaf,0xd5,0xb1,0x41,0x1b,0xe7,0xf8,0xcc,0xaa,0xc6,0xb2,0xf,0x37,
-  0x9b,0x4d,0x4f,0x0,0xca,0xde,0x83,0x2c,0x4,0xd2,0x24,0x45,0x67,0xba,0x83,0xb5,
-  0x95,0x13,0xa8,0x2b,0x5,0x66,0xbd,0xad,0xd,0x5,0xda,0x61,0x94,0x82,0x11,0x18,
-  0xe0,0x47,0x9,0x1,0x49,0x2,0x52,0xd0,0x0,0xa3,0xd7,0xab,0x6e,0xf3,0x72,0xf8,
-  0xa8,0x84,0x83,0x54,0xc2,0xc3,0x16,0xf4,0xe1,0xea,0x44,0xfb,0x2,0x61,0x35,0x85,
-  0xcb,0x14,0x56,0x7c,0x1,0x8a,0x35,0xbf,0x0,0xbf,0xd,0x40,0x5d,0xc,0x1,0x70,
-  0x1a,0x60,0x7e,0x7e,0x5e,0xc5,0x71,0xdf,0x30,0x56,0xbc,0x70,0x8e,0x75,0x56,0xac,
-  0x5e,0xaf,0x9b,0x5d,0x38,0xa7,0xca,0x1c,0xbe,0x28,0x33,0x82,0x15,0x52,0xab,0xd1,
-  0xf,0xda,0x77,0xe8,0x23,0x8,0x2,0xe4,0x79,0x81,0x4e,0xa7,0x83,0x8a,0x4,0xd8,
-  0xcf,0x71,0x14,0xef,0x52,0xf8,0x98,0x81,0x2c,0xcb,0x35,0xa3,0xa8,0xdf,0x7,0x11,
-  0xe9,0xcf,0xf6,0x48,0x93,0xfa,0x7b,0xd8,0xd0,0xbf,0xda,0x5e,0x32,0xcd,0x32,0x34,
-  0x1a,0xd,0xd3,0x1f,0xc0,0xb,0x6b,0xcd,0xe,0x55,0xfd,0x24,0xc6,0xdc,0xc2,0x2c,
-  0x1e,0x3b,0xf5,0x20,0xa,0xd2,0x5b,0xcc,0xb1,0xd0,0xaa,0x9f,0xa4,0x44,0x20,0x18,
-  0x24,0x35,0x11,0x44,0x42,0x42,0x4a,0x40,0x8,0xa9,0xd3,0x87,0xa2,0x84,0x0,0x7,
-  0x5,0x8c,0x5c,0xe8,0xac,0xd1,0xc0,0xb2,0x3a,0xba,0x4c,0xfd,0x3a,0x4d,0xa0,0x74,
-  0xb,0x3e,0xc5,0xbe,0x20,0x94,0x0,0xd2,0x80,0x23,0xf8,0x0,0x33,0xff,0x1c,0x31,
-  0x1f,0xba,0x58,0xa4,0xd0,0xa,0x6,0xd0,0xed,0x76,0x79,0x63,0x63,0xc3,0x39,0x7f,
-  0xec,0x91,0xf5,0x88,0x8,0x71,0x1c,0xe3,0xe0,0xc1,0x83,0x86,0xc,0xe2,0x6f,0xb9,
-  0xee,0x71,0x1,0xbd,0x44,0x90,0x30,0x4b,0xfc,0xd0,0x21,0xfd,0x7d,0xf,0x7d,0xe3,
-  0x1b,0xa6,0x42,0xa7,0xca,0x30,0x82,0xcf,0xa,0xf2,0x4a,0x81,0x5,0x80,0xc7,0x1e,
-  0x7b,0x14,0x79,0x91,0xe3,0xf0,0x91,0x23,0x18,0x1b,0x1d,0x35,0x1d,0x62,0xcb,0xcd,
-  0xa6,0x86,0xb,0x13,0x5c,0xe6,0x2,0x8f,0x1c,0x3c,0x8,0x57,0xe0,0x6a,0x40,0x13,
-  0x9f,0x24,0x9a,0xc4,0x31,0xa6,0xa6,0xa6,0x90,0x1f,0x57,0x50,0x5,0x81,0x25,0xc0,
-  0x1,0x83,0x4,0x43,0x9a,0x7d,0xd0,0x4,0xb,0x3,0x0,0x11,0x24,0x9,0xbd,0x75,
-  0xad,0xf0,0x28,0xde,0x28,0xeb,0x24,0xec,0xa6,0x58,0xec,0xc1,0xb5,0x64,0x71,0x7b,
-  0x6b,0x6,0x98,0x2b,0xa6,0x80,0x68,0xd8,0x41,0xb4,0x9a,0xc2,0xbd,0x9e,0x39,0x26,
-  0xe2,0xf7,0x12,0xf3,0x7,0x69,0x17,0xab,0x7e,0xa7,0x1a,0xc0,0xee,0xa2,0x35,0x37,
-  0x36,0x36,0x56,0x2c,0x2f,0x9f,0x72,0x7c,0x35,0xe1,0x71,0xd6,0x88,0x19,0x27,0x8e,
-  0x1f,0xc7,0xea,0xca,0xca,0xee,0xda,0x57,0x33,0xa3,0x28,0xa,0xe4,0x79,0x8e,0x87,
-  0x1e,0x7a,0x70,0xf7,0xb4,0x66,0x66,0xc4,0xfd,0x3e,0x8e,0x1c,0x3e,0x8c,0x7a,0xbd,
-  0xbe,0xeb,0xf3,0xb3,0x34,0x75,0x1b,0x48,0x5a,0x8d,0x61,0x9d,0xb5,0x24,0x49,0xd0,
-  0x19,0xef,0xa0,0x78,0x48,0xa1,0x60,0x85,0x80,0xf4,0x8e,0x67,0x81,0x64,0xcb,0x4,
-  0x32,0xb0,0xaf,0x9f,0x1e,0x6,0xa4,0x90,0x15,0xd5,0x6f,0x1,0xa9,0xca,0xce,0x66,
-  0x64,0x34,0x1,0xca,0x8d,0x31,0x95,0xa1,0xd8,0x2b,0x17,0xce,0xd,0x9b,0x83,0x8a,
-  0x80,0xe8,0x85,0x77,0x1f,0x31,0xbf,0x95,0x98,0xf,0x31,0xef,0x86,0x7,0xbc,0x7b,
-  0xd,0x30,0xdb,0x6c,0x36,0xb9,0xdf,0x8f,0x2b,0xa0,0x8b,0x1d,0x8d,0x46,0x3,0xaf,
-  0x7b,0xdd,0x8f,0xe1,0xea,0xfd,0x57,0xed,0x8a,0x8d,0xca,0xcc,0x38,0x74,0xe8,0x10,
-  0xee,0xbf,0xff,0x7e,0xfc,0xdc,0xcf,0xff,0x3c,0xa2,0x70,0x77,0x11,0x84,0x52,0xa,
-  0x7f,0xfe,0x67,0x7f,0x86,0xe7,0x5d,0x7e,0x39,0x5e,0xfe,0xf2,0x97,0x57,0xf8,0x7e,
-  0xe7,0xfd,0x6c,0x30,0x1e,0x3e,0xf8,0x30,0x3e,0xf9,0xc9,0x4f,0x22,0x71,0xad,0x6d,
-  0x4a,0xb4,0xb0,0xdf,0xef,0xeb,0x5d,0xc6,0xcf,0x10,0xa,0x45,0x7a,0xcf,0x43,0x29,
-  0x41,0xc,0x4,0x42,0x3,0x3f,0xd2,0x14,0x78,0x8,0x53,0x29,0x4,0xa1,0x61,0xe0,
-  0xa,0x81,0xc5,0xf3,0x7a,0x1d,0x8e,0x40,0x16,0x4d,0x2c,0xf,0x9b,0xef,0x77,0x91,
-  0x81,0x75,0x14,0x6d,0xea,0xd8,0x73,0x14,0x89,0x68,0x93,0x80,0xf7,0x2a,0xe6,0xf,
-  0xb2,0xc7,0x9,0xb8,0xd0,0xb1,0x13,0x1f,0x60,0x21,0x8a,0xa2,0xd0,0xef,0x9,0xc0,
-  0x10,0x4e,0xdd,0x4a,0xc3,0xec,0xb9,0xef,0xbe,0x2f,0xe0,0xe4,0x89,0x13,0x86,0xb7,
-  0xee,0x59,0x5d,0xf6,0x5e,0xef,0x25,0x48,0xae,0xbe,0xfa,0x6a,0x6c,0x6e,0x6e,0x0,
-  0xcc,0x38,0xbb,0xb6,0x86,0x7b,0x3f,0x7f,0xef,0x40,0xa7,0xbf,0x1,0x6a,0xf8,0x80,
-  0x43,0xf7,0xc3,0x37,0xdc,0x0,0x66,0xc6,0xca,0xca,0xa,0x8e,0x1e,0x3d,0x8a,0xaf,
-  0x7e,0xf5,0xab,0x5b,0x27,0x83,0x7d,0x14,0xd9,0xf8,0x2d,0xf3,0xb,0xf3,0x98,0x9c,
-  0x9c,0xd4,0x13,0xc7,0x3e,0x95,0xda,0x6c,0x6e,0x95,0x26,0xa8,0x85,0x11,0xd4,0x8a,
-  0x86,0x66,0x59,0x18,0x9c,0x5f,0x10,0x58,0x48,0x8,0x36,0x59,0x3f,0x72,0x65,0x62,
-  0x5a,0x65,0x7a,0xb7,0x7,0x85,0xbd,0x34,0x2,0x1a,0x1,0x75,0x42,0x80,0xea,0x2e,
-  0x68,0x6e,0xf2,0xc1,0xae,0x93,0xa9,0x76,0xfe,0x18,0xc4,0x7c,0x1f,0x31,0xde,0xc2,
-  0x4c,0x9a,0x8d,0x6c,0x76,0x49,0x7f,0x3a,0x63,0x27,0x61,0xe0,0x34,0x33,0x85,0xa9,
-  0x69,0xd,0xeb,0x58,0x0,0xc6,0x3e,0x4b,0x29,0x31,0x32,0x3a,0x8a,0xc7,0x9f,0x78,
-  0x42,0x23,0x6b,0x6e,0xf,0x8f,0x72,0xd3,0xe7,0xd2,0x62,0xb0,0x73,0xf2,0x6a,0x51,
-  0x84,0x3c,0xcf,0x5d,0x31,0x8,0x93,0x4f,0x45,0x1d,0xe0,0x0,0x38,0xc7,0xd0,0xdf,
-  0x19,0x44,0x13,0x4a,0x52,0x5d,0xd4,0xa9,0x9b,0x49,0x7b,0x96,0xde,0xaf,0x45,0xb0,
-  0x1a,0xd2,0x8a,0xef,0xe6,0x66,0xf,0xfb,0x16,0x17,0x21,0xa5,0xac,0xec,0x53,0x64,
-  0x43,0xce,0x24,0x4e,0x21,0x55,0x8,0x5a,0xd5,0xa9,0xda,0x40,0x5a,0xa2,0x87,0x2e,
-  0xf8,0xc,0x20,0x40,0x90,0x66,0x2b,0x5c,0xbf,0x66,0xaf,0xc4,0x1,0xca,0x9a,0x4,
-  0xf3,0xfe,0x1e,0x9d,0xdb,0x22,0x77,0x36,0x37,0xe0,0x97,0xd1,0xb9,0x96,0xba,0xce,
-  0x3f,0x60,0x30,0xd1,0x26,0x31,0x7e,0x9d,0x98,0xee,0x20,0xbf,0x44,0xe,0x4f,0x7f,
-  0x9c,0x4f,0x0,0xc6,0xdb,0xed,0x76,0x33,0x49,0xd2,0x20,0x2f,0x8a,0xea,0xce,0xdd,
-  0xd0,0xe4,0xc7,0x30,0xc,0x91,0xe7,0x39,0x9e,0xf7,0xbc,0xcb,0xaa,0x3d,0x5b,0x7c,
-  0x18,0x44,0x94,0x5d,0x40,0x6d,0x88,0x97,0x66,0x19,0x36,0x37,0x7b,0x80,0x10,0x58,
-  0x5f,0x5f,0xc7,0xfe,0xfd,0x57,0xbb,0x6d,0x60,0x2a,0x6b,0xdd,0xf3,0x29,0xad,0x57,
-  0x2d,0x20,0xb0,0x7c,0x5a,0x6f,0x56,0x11,0xf7,0xfb,0xe8,0xf5,0x7a,0xf8,0x9e,0xfd,
-  0xfb,0x3d,0x7,0xb0,0xfc,0x9e,0x83,0x1a,0x48,0xf3,0x9,0xb4,0x7a,0x2e,0x89,0x21,
-  0x5e,0xc1,0xa,0x31,0x8a,0x22,0x87,0x4a,0xa,0xb4,0x44,0x4b,0x9d,0xfd,0xd9,0xde,
-  0x4b,0xa0,0x37,0x85,0x8c,0x27,0x3f,0xde,0xce,0x25,0x4,0x68,0xb,0xfb,0x2f,0x20,
-  0x6f,0x81,0xc0,0xad,0x55,0xfb,0xef,0xc7,0xcc,0x55,0x54,0x90,0xb9,0x2a,0x0,0x65,
-  0xd,0xe3,0x10,0xc2,0x77,0x17,0x13,0xbf,0x95,0xc0,0x4b,0x44,0x25,0x33,0xf8,0x62,
-  0x8d,0xf0,0x1c,0x93,0xef,0x30,0x80,0x4e,0xa7,0x53,0xc4,0x71,0x1c,0xf8,0x64,0xd,
-  0xbf,0xcf,0x8f,0x94,0x12,0x7,0xf,0x1e,0x1c,0x42,0xd4,0x76,0x32,0x96,0x4f,0x9d,
-  0x42,0x9e,0xe7,0x38,0x78,0xf0,0xe0,0xae,0x88,0x24,0x96,0xd8,0xb1,0x72,0xe6,0xc,
-  0x92,0x24,0xc1,0xc3,0xf,0x3f,0xbc,0x2b,0x52,0x8,0xa0,0x9b,0x44,0xb8,0x7d,0x87,
-  0x6,0x18,0xc7,0x6c,0x22,0x9b,0x4e,0xa7,0x53,0xf4,0x7a,0xbd,0x59,0x0,0xdf,0x2,
-  0x80,0xd5,0x37,0xf5,0xc4,0xf8,0x1f,0xb7,0xd9,0x99,0x0,0xf,0xf8,0x11,0x82,0x8e,
-  0xc0,0x2b,0xf4,0x1c,0xec,0x84,0x63,0x25,0x9b,0x9c,0x46,0x2a,0x91,0xc5,0x6a,0x81,
-  0x8,0xc,0x3e,0x80,0xb3,0xcc,0xf4,0xab,0xc,0xfe,0x18,0xd,0x14,0x8e,0x5c,0xcc,
-  0x11,0xee,0x0,0x3,0x28,0x92,0x38,0xae,0x6b,0x15,0x56,0x85,0x1,0x85,0x14,0x68,
-  0x34,0x1a,0x18,0x69,0xb7,0x21,0xb7,0x21,0x65,0x6c,0x45,0xd3,0x24,0xa5,0x70,0xe6,
-  0xf4,0x69,0x34,0x9b,0x4d,0x8c,0x8f,0x8d,0x6d,0xeb,0xc5,0x6f,0x49,0xf6,0x32,0x94,
-  0xf2,0x24,0x4d,0xdd,0xbe,0xc5,0xbb,0xd9,0x48,0x87,0x4c,0xab,0x38,0x21,0x5,0xa8,
-  0xa8,0x6e,0x3f,0x29,0xc,0x31,0x64,0x7e,0x7e,0xbe,0x58,0x5a,0x5a,0xda,0x7,0xaf,
-  0x4e,0x50,0x29,0xa5,0xcf,0xf1,0x27,0x5f,0x4f,0xfa,0x91,0xc1,0x1c,0x80,0x1f,0x5a,
-  0x5a,0x75,0xe4,0x8,0x55,0x46,0x85,0x57,0x58,0xbe,0xe5,0xed,0xcf,0x30,0xd3,0xdb,
-  0x89,0xf9,0x18,0x39,0xee,0xc1,0xd3,0x73,0xf6,0x2e,0xd4,0x4,0xcc,0x77,0xbb,0x5d,
-  0x8a,0xe3,0xc4,0xd8,0xf7,0x72,0x6b,0x75,0x8,0x20,0xc,0x42,0x8c,0x4f,0x4c,0xe0,
-  0xe5,0x2f,0xff,0xfe,0xe1,0x38,0xfe,0x3c,0xa3,0x56,0xaf,0x61,0x65,0x65,0x5,0x13,
-  0x13,0x93,0xb8,0xe6,0xda,0x6b,0x77,0x9d,0xc,0x62,0x66,0x34,0x5b,0x2d,0xa4,0x69,
-  0x8a,0xeb,0xae,0xbb,0xce,0xb5,0xa9,0xdd,0xe9,0x68,0xd4,0xeb,0x78,0xf2,0xc9,0x27,
-  0x11,0x5,0x21,0x8a,0x42,0x99,0x89,0x2f,0x77,0x1d,0x4b,0x92,0x18,0xdd,0x6e,0xd7,
-  0x36,0x8d,0x72,0x35,0x2,0x8a,0x94,0x61,0xfb,0x54,0x1d,0x40,0x1,0x2c,0x59,0x1c,
-  0xc0,0xaa,0x47,0xe1,0x21,0xa7,0x6c,0xf7,0xbb,0xf2,0x6b,0xfb,0xb8,0xca,0x15,0x20,
-  0xe6,0xb3,0xc,0x7e,0x3b,0x33,0x3e,0x51,0x29,0xbb,0xe3,0x6f,0xc7,0xd4,0x6f,0x6f,
-  0x2,0x5c,0x5f,0xc0,0xb9,0xb9,0x39,0xee,0xf7,0xfb,0xc3,0x9b,0x32,0xb0,0x56,0xc3,
-  0xf5,0x5a,0xd,0x71,0x12,0xe3,0xee,0xbb,0xff,0x1a,0x3e,0x53,0xb2,0xd2,0xa4,0xc1,
-  0x63,0xe3,0xd8,0xfb,0xd7,0x5f,0x7f,0x3,0xe2,0x38,0xc6,0xc4,0xe4,0x24,0xce,0xac,
-  0xac,0xe0,0xeb,0x5f,0xfb,0x5a,0xd9,0x3a,0xc2,0xe6,0xf1,0x5d,0x41,0x24,0x57,0x9a,
-  0x46,0x0,0x2,0x57,0x5e,0x79,0x25,0x84,0x14,0x88,0xe3,0x18,0xbd,0x5e,0xf,0x9f,
-  0xff,0xfc,0xe7,0x7,0x3e,0xa6,0x2c,0x4a,0xd8,0x2a,0x92,0x78,0xed,0x6b,0x5f,0x8b,
-  0x5a,0xad,0x6,0x21,0x65,0x25,0x54,0xb3,0xff,0xc7,0x71,0x8a,0xb9,0xb9,0x39,0x46,
-  0xb5,0x6b,0x98,0x50,0x4c,0x2c,0x20,0x4b,0x1e,0x81,0xb9,0x5a,0x12,0xe2,0x18,0x20,
-  0x62,0x8,0x6e,0xa,0xf8,0x26,0x80,0x3d,0x22,0x8c,0xa8,0xd4,0x3e,0x38,0x2f,0x5e,
-  0x4f,0xf0,0xa7,0x99,0xf9,0xad,0xcc,0xbc,0xec,0xa7,0x8e,0xbf,0xdd,0xe3,0x7c,0x1a,
-  0x60,0x6e,0x7c,0x7c,0xbc,0x58,0x39,0x73,0xa6,0x32,0x11,0xd6,0xc5,0x93,0x52,0xa2,
-  0x66,0xfa,0x4,0xdb,0x1d,0xc2,0x7d,0x47,0xa1,0x5a,0x7e,0xc7,0x95,0xee,0x6e,0x80,
-  0xee,0x21,0x14,0x85,0x21,0xb2,0x24,0xad,0xd8,0x70,0x1a,0x3a,0x99,0x3d,0xea,0x36,
-  0x1b,0xf6,0xae,0x6e,0xf0,0x5c,0xe4,0xb9,0x6b,0x16,0xe9,0x23,0x90,0xe4,0x84,0xc9,
-  0x38,0xa3,0x3,0xce,0x65,0x96,0x66,0x8,0xa3,0x8,0xd2,0x76,0xf1,0xf0,0x90,0x42,
-  0x1,0x8d,0x6,0xce,0xcf,0xcf,0x15,0xa8,0x76,0xd,0xd3,0x2c,0x22,0x10,0x20,0x6d,
-  0xd5,0x88,0xf5,0xfa,0x5,0x58,0x88,0x23,0x82,0xf9,0x1a,0xc1,0x3e,0x19,0x8e,0x7d,
-  0x5a,0x40,0x79,0x25,0xca,0x32,0xb7,0x65,0x66,0xbc,0x9d,0x81,0x3,0x0,0x99,0xd,
-  0xb7,0xbf,0xfd,0x13,0xbf,0x53,0xd,0x30,0xd7,0x6c,0x36,0x39,0x4e,0x4a,0xb6,0x8e,
-  0xaf,0x8e,0x92,0x24,0xc1,0xb1,0x6f,0x7e,0x13,0x4b,0x4b,0x4b,0x78,0xe1,0x15,0x2f,
-  0x84,0x94,0x81,0x17,0x78,0xfb,0x76,0x50,0xc,0xa5,0x3,0x8f,0x1f,0x3f,0x81,0xcd,
-  0x5e,0xf,0xbd,0x7e,0x1f,0xcd,0x56,0xb,0x57,0x5d,0x79,0x65,0x65,0xf3,0xa7,0xed,
-  0x7d,0x1,0x81,0x20,0x10,0xd8,0xec,0x6d,0x22,0x49,0x12,0x9c,0x3c,0x79,0x12,0x57,
-  0x5d,0x75,0x65,0x25,0x9e,0xaf,0x7c,0xee,0xc0,0xd9,0x44,0x84,0xa5,0xa7,0x96,0x70,
-  0xe2,0xf8,0x71,0x63,0xba,0xca,0x50,0xd5,0xca,0x4a,0x9c,0xc4,0x68,0x36,0x9b,0x8c,
-  0x6a,0xd7,0x30,0x51,0x98,0x5a,0x2,0x4d,0x15,0xb7,0x30,0xb7,0x7b,0xef,0x25,0x1,
-  0x71,0x8d,0x5f,0x35,0xe3,0x64,0x92,0x4b,0x8a,0x30,0x95,0x31,0xee,0x27,0x0,0xfc,
-  0x2a,0x33,0x2f,0x6b,0xf9,0xfd,0x4e,0x4e,0xfd,0xce,0x34,0x40,0x57,0x6,0x72,0x24,
-  0x71,0x18,0x80,0x89,0xb4,0x45,0x49,0xe6,0x38,0xf6,0xad,0x6f,0xe1,0xf3,0xf7,0xde,
-  0xab,0x43,0xaa,0x5d,0xc,0x21,0x25,0x92,0x38,0xc6,0x43,0xf,0x3e,0x78,0x41,0x64,
-  0x10,0xeb,0x70,0xc5,0x71,0x8c,0x7b,0xef,0xb9,0x67,0xd7,0x51,0x44,0x9e,0xe7,0x58,
-  0x5d,0x5d,0x43,0x96,0x65,0x2e,0x1a,0x10,0xc6,0xd1,0x15,0x60,0xdd,0x33,0x48,0xca,
-  0x11,0xe8,0x32,0x31,0xe1,0x6b,0x74,0x5b,0x8d,0xe7,0x7a,0x7,0x95,0x40,0xcf,0x91,
-  0xf2,0xfa,0xf8,0xf6,0xc8,0x33,0x3,0xda,0xfc,0x9f,0x60,0xe0,0xed,0xc,0xfe,0xf4,
-  0x40,0x11,0xd4,0x77,0x7c,0x9c,0x4f,0x0,0xda,0xf5,0x5a,0x3d,0x1a,0x64,0xd7,0xfa,
-  0xc5,0xc1,0x6b,0x6b,0xab,0xd8,0xd8,0xd8,0xa8,0x50,0xb3,0xcb,0x9f,0x5b,0xb5,0x86,
-  0x5b,0x4d,0x42,0x10,0x4,0x90,0x52,0xc,0x35,0x8b,0x62,0xcf,0xa1,0x1a,0xb6,0xe1,
-  0xa5,0x3d,0x2d,0x8a,0xc2,0xf4,0x17,0x28,0xf9,0x2,0xf0,0xaa,0x92,0x6,0xb6,0x9f,
-  0x76,0xd8,0x40,0x6e,0x5a,0xd3,0x8,0x94,0x61,0x20,0x19,0xe3,0xc1,0xc6,0x84,0xd4,
-  0xea,0xf5,0x8,0x40,0x1b,0xe7,0xd8,0xaf,0x87,0x2b,0x1a,0x91,0x1,0xe0,0x8,0xbc,
-  0x5d,0x4c,0x9d,0x46,0xa3,0xa,0x56,0xff,0x9,0x0,0x6f,0x87,0xe9,0x16,0xf2,0xdd,
-  0x1e,0xe7,0x5b,0xb6,0xdf,0xe8,0xf7,0xfb,0xb,0x13,0xe3,0xe3,0xb5,0xd5,0xb5,0xd5,
-  0xa,0xac,0x5a,0x92,0x33,0x74,0x61,0x48,0x61,0xfb,0x95,0x79,0x3d,0x7f,0x87,0x24,
-  0xbf,0x42,0xd8,0x30,0x13,0x95,0x13,0xaa,0x95,0x36,0x5c,0x6d,0x1a,0x26,0xaa,0x2c,
-  0x5f,0x9f,0x54,0x62,0xbf,0x83,0x6b,0x55,0x6f,0x2d,0x8d,0xdf,0x39,0x4c,0xf8,0x56,
-  0x49,0x78,0x7b,0x4a,0x1a,0xfa,0xba,0xfb,0xc,0x2e,0x89,0x1c,0xcc,0x98,0x9c,0x18,
-  0x47,0xbf,0xdf,0x2f,0xa0,0x7b,0x3,0xef,0x74,0x3c,0x59,0x5d,0xcd,0x95,0x92,0xa6,
-  0x63,0x0,0x7e,0x11,0xc0,0x5d,0x78,0x6,0xd,0xb9,0xd,0xed,0x82,0x1,0x7c,0xf2,
-  0xc0,0x81,0x3,0x7c,0xf5,0xfe,0xfd,0x68,0xd4,0x1b,0x95,0x8,0xa0,0xc2,0x74,0xf1,
-  0xf7,0x75,0x43,0x99,0x62,0xad,0xc0,0xbf,0x7e,0x4a,0xa4,0xe2,0xdb,0x55,0x2b,0x6c,
-  0x1c,0xf1,0x96,0x7c,0x4e,0x3d,0xf9,0x49,0xc0,0xa,0xb,0x98,0x7,0xbf,0xb1,0xed,
-  0x14,0xe6,0xb6,0xa0,0xf5,0xff,0xc,0x54,0xce,0x3a,0x8c,0xd8,0xa4,0x66,0xcd,0x77,
-  0x6b,0x34,0x9b,0x78,0xd1,0x8b,0x5e,0x84,0x3b,0xef,0xbc,0x93,0x1,0x7c,0x12,0x3b,
-  0x6f,0xbb,0xf3,0x65,0x0,0xf1,0x16,0x8f,0xdf,0x1,0xe0,0xda,0x67,0xda,0xe4,0x6f,
-  0x27,0x0,0x64,0x58,0x25,0x5f,0xf9,0xc6,0x37,0xbe,0xf1,0x97,0x71,0x1c,0x6f,0x4c,
-  0x4f,0x4f,0x6f,0x9f,0x36,0x1a,0xb2,0x1e,0xc3,0xe9,0xdb,0x1d,0x9c,0x5c,0x79,0xd8,
-  0x87,0x54,0xf8,0x1c,0x50,0xa5,0x97,0x41,0xc0,0x40,0x5f,0xf1,0x52,0xdf,0xc3,0x6f,
-  0x9e,0xc4,0x5b,0xda,0x5c,0xdf,0x50,0xcd,0xce,0xce,0x62,0x75,0x75,0x6d,0xf3,0x89,
-  0x27,0x9e,0xf8,0x4b,0x33,0xa9,0xa,0x3b,0xab,0xb5,0x3a,0x1,0xe0,0xa7,0x1,0xd8,
-  0xce,0xd4,0x87,0x0,0xbc,0x16,0xc0,0x5b,0x9f,0x29,0x2a,0x7f,0x27,0x26,0xc0,0xc4,
-  0x39,0x28,0xa0,0x89,0x85,0x77,0xde,0x71,0xc7,0x1d,0x3f,0x7e,0xcb,0x2d,0xb7,0x20,
-  0x49,0x12,0x9c,0x5d,0x5b,0x83,0xc,0x43,0x84,0x41,0x80,0x20,0x8,0x11,0x45,0x21,
-  0xc2,0x30,0x42,0x14,0x5,0x88,0xa2,0x1a,0xc2,0x48,0xf7,0xd,0xae,0x45,0x35,0xd4,
-  0xa2,0x8,0x61,0x14,0x21,0x8a,0x6a,0x88,0x6a,0x21,0x6a,0x51,0xcd,0xbc,0x36,0x44,
-  0x14,0x86,0x8,0xa3,0x8,0x41,0x18,0x20,0xc,0x42,0x4,0x41,0x8,0x19,0x48,0x4,
-  0x52,0x6a,0x76,0x8d,0x63,0xd8,0x7a,0x94,0x6a,0xc7,0x88,0xd1,0xad,0xe0,0x54,0xae,
-  0x50,0xa8,0x2,0x79,0x51,0x40,0xe5,0xb9,0xee,0x9e,0x99,0x67,0xc8,0xf3,0x1c,0x59,
-  0x96,0x23,0x2f,0x72,0xe4,0x59,0x8e,0x2c,0xcf,0x51,0x64,0x39,0xb2,0x22,0x47,0x91,
-  0xe7,0xc8,0xcd,0x51,0x14,0x45,0x79,0x98,0x96,0x76,0x13,0x13,0x13,0x78,0xd9,0xcb,
-  0x5e,0x86,0xdf,0xfa,0xad,0xdf,0x6a,0x1,0xf8,0x3f,0x0,0x72,0x73,0x2d,0x68,0x87,
-  0x5a,0xe0,0xaf,0x0,0x74,0x0,0x5c,0xe9,0x9b,0x84,0x67,0xea,0x38,0x9f,0x0,0xa4,
-  0x0,0x1e,0x8d,0xe3,0xf8,0xa3,0x9f,0xfb,0xdc,0xe7,0xde,0x30,0x39,0x39,0xd9,0x3a,
-  0xf8,0xf0,0xc3,0x48,0xb3,0x14,0xb6,0x13,0xa6,0x94,0x12,0x42,0xea,0x89,0x93,0x52,
-  0x42,0x6,0xe6,0xaf,0x8,0x10,0x6,0x12,0x22,0x90,0x8,0x64,0x60,0x5a,0xc9,0x4b,
-  0x48,0x73,0x5b,0x9a,0x73,0x20,0xa5,0xae,0xa9,0x97,0x96,0x56,0x5d,0x76,0xd7,0x10,
-  0x3,0x54,0x32,0xa6,0x1,0xdc,0x9c,0xaa,0x5b,0xc6,0xe8,0xd2,0x29,0x55,0xd2,0xa9,
-  0x6c,0xd3,0xa8,0x82,0x2a,0xd,0xa4,0x5c,0xe3,0x2a,0xc3,0xb2,0xb1,0xa9,0xd5,0x7a,
-  0xad,0x8e,0x1f,0xf9,0x91,0x1f,0xc1,0x67,0x3f,0xfb,0xd9,0x7e,0x1c,0xc7,0x1f,0x33,
-  0x13,0x98,0xee,0x52,0x0,0x86,0xfc,0x81,0x67,0x9b,0x0,0x60,0x40,0x0,0xfa,0x0,
-  0xfe,0xd7,0xfd,0xf7,0xdf,0x7f,0xd5,0xcd,0x37,0xdf,0xfc,0xe2,0xc3,0x87,0xf,0x4f,
-  0x1d,0x3a,0x74,0xa8,0x92,0xdb,0xdf,0x2a,0xff,0x2e,0x8c,0x63,0x2f,0xbd,0xc4,0x11,
-  0x6f,0x21,0x69,0xb2,0xa2,0x80,0x9d,0xab,0x56,0xe5,0x11,0x6e,0xd1,0x94,0x90,0x7,
-  0x6d,0x82,0x55,0xd0,0x5c,0xde,0x11,0x7e,0x76,0x70,0x0,0xa4,0xaa,0xec,0x38,0x21,
-  0x0,0xc1,0x12,0x2f,0x7c,0xe1,0xb,0xb0,0x7f,0xff,0xfe,0xd5,0xcf,0x7c,0xe6,0x33,
-  0xff,0x0,0xe0,0x7f,0x1b,0x7b,0x9e,0x1a,0x2d,0xa0,0xdf,0xf4,0xad,0x7e,0x8e,0xff,
-  0xd9,0x3f,0xe4,0x36,0xe,0xa0,0x35,0x1,0x31,0x74,0x27,0x8c,0x4f,0x7d,0xe4,0x23,
-  0x1f,0x19,0xbb,0xe1,0x86,0x1b,0xe2,0xce,0xd4,0xd4,0x80,0x55,0xae,0x76,0xc5,0xaa,
-  0x0,0x78,0x2c,0xb6,0xb7,0xf6,0x3c,0xe0,0x27,0x98,0x4c,0x1a,0xf,0xd6,0xf7,0x63,
-  0x9b,0xbd,0x53,0xbd,0x90,0xdb,0x6b,0x97,0x3b,0x80,0x40,0x8a,0xea,0xe4,0x7b,0xef,
-  0xc4,0xcc,0x98,0xea,0x4c,0xe2,0xfa,0x1b,0x7e,0x38,0xfe,0xc3,0x3f,0xfc,0xc3,0x31,
-  0x0,0x9f,0x2,0xd0,0x33,0xbf,0x3d,0x33,0x3e,0xc0,0x85,0xf3,0xae,0x9e,0x65,0x2,
-  0xe0,0x9b,0x81,0x1c,0x40,0x62,0x2e,0xc6,0x17,0x57,0x56,0x56,0xee,0x7c,0xec,0xb1,
-  0xc7,0xe8,0xc6,0x1b,0x6f,0xa4,0xce,0x74,0xc7,0x71,0xe0,0x6c,0xa5,0x30,0x5c,0x4a,
-  0xc5,0xc3,0xec,0x84,0xcf,0xb9,0x1b,0x80,0x8,0xdd,0xac,0x7a,0x34,0x6a,0x17,0x1f,
-  0x8a,0x2d,0x7d,0x45,0xde,0x2a,0xbf,0xe8,0x85,0x7a,0x5b,0x1,0xa9,0x96,0x55,0x6c,
-  0xa0,0xbb,0x52,0x5a,0xc,0xc7,0xa0,0x33,0xdd,0xc1,0x8d,0xaf,0xbd,0x91,0x1e,0x7b,
-  0xf4,0x51,0x5a,0x5b,0x5b,0xfb,0x13,0x0,0xf7,0x9b,0xdf,0x9c,0x78,0xab,0xff,0x92,
-  0x9b,0xfc,0x9d,0x8,0x80,0xf2,0xb4,0xc0,0x6,0x80,0xdf,0xbb,0xe7,0x9e,0x7b,0xee,
-  0x3d,0x72,0xf4,0x68,0xf2,0xc6,0x37,0xbe,0x29,0xbd,0xf6,0x25,0xd7,0x62,0x6c,0x7c,
-  0x1c,0x32,0x8,0x21,0x86,0x96,0xb4,0x18,0x58,0xe1,0x1e,0x63,0xf7,0x1c,0xb0,0x17,
-  0xb,0x4f,0x85,0x8,0x7f,0x2,0x79,0x78,0x6b,0x18,0x5f,0xd5,0xf0,0xc0,0x13,0xc3,
-  0x84,0x60,0x97,0x74,0xb1,0x8f,0x7,0x61,0x80,0xf1,0x89,0x71,0x5c,0x73,0xcd,0x35,
-  0x78,0xc3,0xcf,0xbc,0x21,0xfd,0xe6,0xb1,0x6f,0xc6,0xf7,0xdc,0x73,0xcf,0xbd,0x0,
-  0x7e,0xcf,0x68,0x3c,0x7f,0xf5,0x5f,0xb2,0x2,0x20,0x86,0x2a,0x63,0x4a,0xfd,0x69,
-  0xa7,0x23,0x4,0x50,0x37,0x88,0xd8,0x18,0x80,0x49,0x0,0xff,0x61,0x7a,0x7a,0xfa,
-  0xdf,0xbe,0xe5,0x2d,0x6f,0xe9,0x4b,0x29,0xc5,0xfa,0xfa,0xfa,0xa8,0x52,0xaa,0x4c,
-  0x91,0x4a,0xe3,0xd4,0x9,0xcf,0xa3,0xaf,0x3c,0x27,0x2b,0x2d,0xd0,0x2d,0xa1,0xd3,
-  0xd2,0xa9,0x21,0xaa,0x7a,0xdc,0x6a,0x6,0x9b,0x1d,0x2b,0xb,0x2d,0x68,0xc8,0x29,
-  0x74,0x45,0x92,0x76,0xf7,0x30,0x2e,0x77,0x2a,0x23,0xaf,0xb7,0x4e,0x10,0x4,0x18,
-  0x1b,0x1b,0xdb,0x60,0x66,0xfa,0xa3,0x3f,0xfa,0xa3,0xd6,0xc9,0x93,0x27,0xff,0x2,
-  0xc0,0x7f,0x85,0xde,0x31,0x74,0xdd,0x68,0x0,0xeb,0x0,0xe,0xa9,0xff,0x4b,0xc5,
-  0x7,0xd8,0x4e,0x0,0xe0,0x25,0x85,0x42,0x0,0xd,0x23,0x4,0xa3,0x0,0xc6,0x1,
-  0x7c,0x1f,0x80,0x9f,0x0,0xf0,0x32,0xe8,0x2d,0x53,0x9f,0x8d,0xe3,0x34,0x80,0x7f,
-  0x0,0xf0,0xe7,0x0,0xbe,0x6e,0x62,0xf5,0xd,0x4f,0xfd,0x9f,0xd3,0xfb,0x7f,0xae,
-  0x8,0x80,0x15,0x82,0xc0,0x13,0x82,0x26,0x74,0x3f,0xfd,0x36,0x80,0x96,0x79,0xac,
-  0x66,0x5e,0xf3,0x6d,0xd9,0xe3,0xfe,0x22,0xf,0xbb,0x9a,0xad,0x79,0x4b,0x4c,0xa4,
-  0xd3,0xf3,0x54,0xbf,0x9d,0x7c,0x75,0x2e,0xd5,0x7f,0xa9,0x8,0xc0,0x4e,0x53,0x78,
-  0x36,0x2c,0x4c,0x3c,0xdf,0x20,0x35,0x17,0xad,0x66,0xde,0x27,0xc0,0xb3,0x67,0xcb,
-  0x34,0x2b,0x0,0x36,0xd2,0x49,0xcd,0x6f,0x4b,0xcc,0xfd,0x2,0x3b,0xed,0xb2,0xf4,
-  0x1c,0x10,0x0,0x1e,0x10,0x2,0x7f,0xf5,0x44,0xde,0xe4,0xcb,0xed,0xb1,0xdd,0x67,
-  0xd4,0xe4,0xfb,0x70,0x77,0x61,0x3c,0xfd,0xdc,0x5b,0xf5,0x74,0xa9,0x86,0x7d,0x17,
-  0xaa,0x1,0xec,0x85,0x50,0x5b,0x40,0xc5,0xb6,0x84,0x4c,0x3c,0xcb,0x4,0xc0,0xfe,
-  0xe,0xf2,0x26,0xdd,0xef,0xaf,0xc6,0x7b,0x1a,0xe0,0xdc,0x2b,0xc7,0xd2,0x68,0x8b,
-  0x67,0xd1,0xc4,0x6f,0x27,0x8,0x3c,0x70,0xff,0x39,0x33,0xc4,0xa5,0xe2,0xcc,0xec,
-  0x8d,0x8b,0xb,0x4,0xed,0x8d,0x3d,0x1,0xd8,0x1b,0x7b,0x2,0xb0,0x37,0xf6,0x4,
-  0x60,0x6f,0xec,0x9,0xc0,0xde,0xd8,0x13,0x80,0xbd,0x71,0xa9,0x8e,0xff,0x3f,0x0,
-  0xda,0x6e,0xc6,0x3c,0x75,0xcb,0x54,0xe4,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,
-  0xae,0x42,0x60,0x82,
-  
-};
-
-static const unsigned char qt_resource_name[] = {
-  // resources
-  0x0,0x9,
-  0xa,0x6c,0x78,0x43,
-  0x0,0x72,
-  0x0,0x65,0x0,0x73,0x0,0x6f,0x0,0x75,0x0,0x72,0x0,0x63,0x0,0x65,0x0,0x73,
-    // sphone.png
-  0x0,0xa,
-  0x6,0x4b,0x1a,0xa7,
-  0x0,0x73,
-  0x0,0x70,0x0,0x68,0x0,0x6f,0x0,0x6e,0x0,0x65,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67,
-    // phone.png
-  0x0,0x9,
-  0x6,0x48,0xba,0xa7,
-  0x0,0x70,
-  0x0,0x68,0x0,0x6f,0x0,0x6e,0x0,0x65,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67,
-  
-};
-
-static const unsigned char qt_resource_struct[] = {
-  // :
-  0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1,
-  // :/resources
-  0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x2,
-  // :/resources/phone.png
-  0x0,0x0,0x0,0x32,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x6,0x60,
-  // :/resources/sphone.png
-  0x0,0x0,0x0,0x18,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,
-
-};
-
-QT_BEGIN_NAMESPACE
-
-extern Q_CORE_EXPORT bool qRegisterResourceData
-    (int, const unsigned char *, const unsigned char *, const unsigned char *);
-
-extern Q_CORE_EXPORT bool qUnregisterResourceData
-    (int, const unsigned char *, const unsigned char *, const unsigned char *);
-
-QT_END_NAMESPACE
-
-
-int QT_MANGLE_NAMESPACE(qInitResources_Resources1)()
-{
-    QT_PREPEND_NAMESPACE(qRegisterResourceData)
-        (0x01, qt_resource_struct, qt_resource_name, qt_resource_data);
-    return 1;
-}
-
-Q_CONSTRUCTOR_FUNCTION(QT_MANGLE_NAMESPACE(qInitResources_Resources1))
-
-int QT_MANGLE_NAMESPACE(qCleanupResources_Resources1)()
-{
-    QT_PREPEND_NAMESPACE(qUnregisterResourceData)
-       (0x01, qt_resource_struct, qt_resource_name, qt_resource_data);
-    return 1;
-}
-
-Q_DESTRUCTOR_FUNCTION(QT_MANGLE_NAMESPACE(qCleanupResources_Resources1))
-