From 0d1d851e3f321cf72d921bf91f05501b72fbce09 Mon Sep 17 00:00:00 2001 From: krivoshein Date: Thu, 30 Oct 2025 14:56:58 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A1=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=91=D0=94=20=D0=B8=D0=B7=20=D0=BA=D0=BE=D0=B4=D0=B0?= =?UTF-8?q?.=20=D0=A2=D1=80=D0=B5=D0=B1=D1=83=D0=B5=D1=82=D1=81=D1=8F=20?= =?UTF-8?q?=D1=80=D0=B5=D1=84=D0=B0=D0=BA=D1=82.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DataBaseLMS/databaselms.cpp | 248 +++++++++++++++++++++--- DataBaseLMS/databaselms.h | 9 + ServerLMS/CMakeLists.txt | 3 + ServerLMS/ServerLMS.qrc | 3 + ServerLMS/dialogcheckdb.cpp | 111 +++++++++++ ServerLMS/dialogcheckdb.h | 37 ++++ ServerLMS/dialogcheckdb.ui | 244 +++++++++++++++++++++++ ServerLMS/dialogsettingstray.cpp | 20 +- ServerLMS/dialogsettingstray.h | 7 +- ServerLMS/dialogsettingstray.ui | 33 +++- ServerLMS/providerdblms.cpp | 25 +++ ServerLMS/providerdblms.h | 8 + ServerLMS/resources/icons/checkDB.png | Bin 0 -> 37066 bytes ServerLMS/resources/icons/editorDB.png | Bin 0 -> 3780 bytes ServerLMS/resources/icons/procedure.png | Bin 0 -> 1341 bytes ServerLMS/serverlmswidget.cpp | 2 +- 16 files changed, 718 insertions(+), 32 deletions(-) create mode 100644 ServerLMS/dialogcheckdb.cpp create mode 100644 ServerLMS/dialogcheckdb.h create mode 100644 ServerLMS/dialogcheckdb.ui create mode 100644 ServerLMS/resources/icons/checkDB.png create mode 100644 ServerLMS/resources/icons/editorDB.png create mode 100644 ServerLMS/resources/icons/procedure.png diff --git a/DataBaseLMS/databaselms.cpp b/DataBaseLMS/databaselms.cpp index c11c6a6..252f4f9 100644 --- a/DataBaseLMS/databaselms.cpp +++ b/DataBaseLMS/databaselms.cpp @@ -5,6 +5,7 @@ #include #include #include +#include const QString DataBaseLMS::TypeUserDBInstructor = "instructor"; const QString DataBaseLMS::TypeUserDBTrainee = "trainee"; @@ -28,6 +29,225 @@ void DataBaseLMS::slot_LanguageChanged(QString language) QCoreApplication::installTranslator(&qtLanguageTranslator); } +bool DataBaseLMS::checkDriverQPSQLavailable() +{ + return QSqlDatabase::isDriverAvailable("QPSQL"); +} + +bool DataBaseLMS::checkUserLMSexist() +{ + DataBaseSettings dbSett = getDataBaseSettings(); + QSqlDatabase dbCheck = QSqlDatabase::addDatabase("QPSQL"); + + dbCheck.setUserName("postgres"); + dbCheck.setPassword("12345678"); + dbCheck.setHostName(dbSett.dbHostName); + dbCheck.setPort(dbSett.dbPort); + + if (dbCheck.open()) + { + QSqlQuery query = QSqlQuery(dbCheck); + query.prepare("SELECT 1 FROM pg_roles WHERE rolname = :username"); + query.bindValue(":username", dbSett.dbUserName); + + if (query.exec() && query.next()) + { + qDebug() << "Пользователь существует."; + return true; + } + else + { + qDebug() << "Пользователь не существует."; + return false; + } + } + else + { + qDebug() << "Ошибка подключения к PostreSQL."; + return false; + } +} + +bool DataBaseLMS::checkDataBaseLMSexist() +{ + DataBaseSettings dbSett = getDataBaseSettings(); + QSqlDatabase dbCheck = QSqlDatabase::addDatabase("QPSQL"); + + bool flDBexist = false; + + dbCheck.setUserName("postgres"); + dbCheck.setPassword("12345678"); + dbCheck.setHostName(dbSett.dbHostName); + dbCheck.setPort(dbSett.dbPort); + + if (dbCheck.open()) + { + QString queryStr = QString("SELECT datname FROM pg_database"); + QSqlQuery query = QSqlQuery(dbCheck); + + if(queryExec(queryStr, &query)) + { + while (query.next()) + {//Инструктор + QString nameDB = ""; + nameDB = query.value(0).toString(); + if(nameDB == dbSettings.dbName) + { + flDBexist = true; + break; + } + } + } + } + else + { + qDebug() << "Ошибка подключения к PostreSQL."; + return false; + } + return flDBexist; +} + +bool DataBaseLMS::createUser(QString name) +{ + DataBaseSettings dbSett = getDataBaseSettings(); + QSqlDatabase dbCheck = QSqlDatabase::addDatabase("QPSQL"); + + dbCheck.setUserName("postgres"); + dbCheck.setPassword("12345678"); + dbCheck.setHostName(dbSett.dbHostName); + dbCheck.setPort(dbSett.dbPort); + + if (dbCheck.open()) + { + QString queryStr = QString("CREATE USER %1 WITH ENCRYPTED PASSWORD '%2'").arg(dbSett.dbUserName, dbSett.dbPassword); + QSqlQuery query = QSqlQuery(dbCheck); + + if(queryExec(queryStr, &query)) + { + qDebug() << "Пользователь создан."; + return true; + } + else + { + qDebug() << "Пользователь не создан."; + return false; + } + } + else + { + qDebug() << "Ошибка подключения к PostreSQL."; + return false; + } +} + +bool DataBaseLMS::createDB(QString name) +{ + DataBaseSettings dbSett = getDataBaseSettings(); + QSqlDatabase dbCheck = QSqlDatabase::addDatabase("QPSQL"); + + dbCheck.setUserName("postgres"); + dbCheck.setPassword("12345678"); + dbCheck.setHostName(dbSett.dbHostName); + dbCheck.setPort(dbSett.dbPort); + + if (dbCheck.open()) + { + //Создание БД + QString queryStr = QString("CREATE DATABASE %1").arg(dbSett.dbName); + QSqlQuery query = QSqlQuery(dbCheck); + + if(queryExec(queryStr, &query)) + { + qDebug() << "БД создана."; + + //Залитие БД + + QProcess process; + //QString pgRestorePath = "C:\\restoreDB.bat"; // Замените на актуальный путь + QString pgRestorePath = "restoreDB.bat"; // Замените на актуальный путь + + /* + QString dbName = "databaselms2"; + QString user = "postgres"; + QString backupFile = "C:\\DBLMS_EMPTY_30_09_2025.backup"; + + QStringList arguments; + arguments << "-d" << dbName; + arguments << "-U" << user; + arguments << backupFile; + */ + + process.start("cmd /C " + pgRestorePath); + process.waitForFinished(-1); // Ждать бесконечно, пока процесс не завершится + + + //Назначение владельца + QString queryStr = QString("ALTER DATABASE %1 OWNER TO %2").arg(dbSett.dbName, dbSett.dbUserName); + QSqlQuery query = QSqlQuery(dbCheck); + if(queryExec(queryStr, &query)) + { + + } + else + return false; + + + + //return true; + } + else + { + qDebug() << "БД не создана."; + return false; + } + + + + + + } + else + { + qDebug() << "Ошибка подключения к PostreSQL."; + return false; + } + + dbCheck.close(); + + QSqlDatabase dbCheck2 = QSqlDatabase::addDatabase("QPSQL"); + + dbCheck2.setUserName("postgres"); + dbCheck2.setPassword("12345678"); + dbCheck2.setHostName(dbSett.dbHostName); + dbCheck2.setPort(dbSett.dbPort); + dbCheck2.setDatabaseName(dbSett.dbName); + + if (dbCheck2.open()) + { + QString newOwner = dbSett.dbUserName; + + // Получаем список таблиц + QSqlQuery query(dbCheck2); + query.exec("SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname = 'public';"); + + while (query.next()) + { + QString tableName = query.value(0).toString(); + QString alterQuery = QString("ALTER TABLE %1 OWNER TO %2;").arg(tableName).arg(newOwner); + qDebug() << "Executing: " << alterQuery; + dbCheck2.exec(alterQuery); + /* + if (dbCheck2.exec(alterQuery)) + { + qDebug() << "Error changing owner for table " << tableName << ":" << dbCheck2.lastError().text(); + return false; + }*/ + } + } + + return true; +} + bool DataBaseLMS::createConnection() { dbSettings = getDataBaseSettings(); @@ -36,34 +256,6 @@ bool DataBaseLMS::createConnection() db = new QSqlDatabase(QSqlDatabase::addDatabase(dbSettings.dbType, dbSettings.connectionName)); - /* - db->setUserName(dbSettings.dbUserName); - db->setPassword(dbSettings.dbPassword); - //db->setHostName(dbSettings.dbHostName); - //db->setPort(dbSettings.dbPort); - bool res1 = db->open(); - - //Проверка наличия БД - QString queryStr = QString("SELECT datname FROM pg_database"); - QSqlQuery query = QSqlQuery(*db); - bool flExist = false; - if(queryExec(queryStr, &query)) - { - while (query.next()) - {//Инструктор - QString nameDB = ""; - nameDB = query.value(0).toString(); - if(nameDB == dbSettings.dbName) - flExist = true; - - nameDB = query.value(1).toString(); - nameDB = query.value(2).toString(); - nameDB = query.value(3).toString(); - } - } - */ - - db->setDatabaseName(dbSettings.dbName); db->setUserName(dbSettings.dbUserName); db->setPassword(dbSettings.dbPassword); diff --git a/DataBaseLMS/databaselms.h b/DataBaseLMS/databaselms.h index cbd9b98..cc384ec 100644 --- a/DataBaseLMS/databaselms.h +++ b/DataBaseLMS/databaselms.h @@ -39,6 +39,15 @@ public: static const QString TypeUserDBInstructor; static const QString TypeUserDBTrainee; +public: + //PostgreSQL + bool checkDriverQPSQLavailable(); + bool checkUserLMSexist(); + bool checkDataBaseLMSexist(); + + bool createUser(QString name); + bool createDB(QString name); + protected: //Подключение bool createConnection(); diff --git a/ServerLMS/CMakeLists.txt b/ServerLMS/CMakeLists.txt index 606a643..9390473 100644 --- a/ServerLMS/CMakeLists.txt +++ b/ServerLMS/CMakeLists.txt @@ -12,6 +12,9 @@ add_library(ServerLMS SHARED dialogsettingstray.cpp dialogsettingstray.h dialogsettingstray.ui + dialogcheckdb.cpp + dialogcheckdb.h + dialogcheckdb.ui clienthandler.cpp clienthandler.h multithreadserver.cpp diff --git a/ServerLMS/ServerLMS.qrc b/ServerLMS/ServerLMS.qrc index 29a560f..42b4a34 100644 --- a/ServerLMS/ServerLMS.qrc +++ b/ServerLMS/ServerLMS.qrc @@ -16,5 +16,8 @@ resources/icons/stop.png resources/icons/settings.png resources/icons/circleGray.png + resources/icons/checkDB.png + resources/icons/editorDB.png + resources/icons/procedure.png diff --git a/ServerLMS/dialogcheckdb.cpp b/ServerLMS/dialogcheckdb.cpp new file mode 100644 index 0000000..4c639cf --- /dev/null +++ b/ServerLMS/dialogcheckdb.cpp @@ -0,0 +1,111 @@ +#include +#include +#include "dialogcheckdb.h" +#include "ui_dialogcheckdb.h" + +DialogCheckDB::DialogCheckDB(ProviderDBLMS* providerDBLMS, QWidget *parent) : + QDialog(parent), + ui(new Ui::DialogCheckDB), + providerDBLMS(providerDBLMS), + resDriver(false), + resUser(false), + resDB(false) +{ + ui->setupUi(this); + + ui->btnRepare->setEnabled(false); + + check(); +} + +DialogCheckDB::~DialogCheckDB() +{ + delete ui; +} + +void DialogCheckDB::check() +{ + resDriver = false; + resUser = false; + resDB = false; + + resDriver = providerDBLMS->checkDriverQPSQLavailable(); + if(resDriver) + { + ui->lblDriverRes->setText(tr("Installed")); + ui->lblDriverResIco->setPixmap(QPixmap(QStringLiteral(":/resources/icons/circleGreen.png"))); + } + else + { + ui->lblDriverRes->setText(tr("Not installed")); + ui->lblDriverResIco->setPixmap(QPixmap(QStringLiteral(":/resources/icons/circleRed.png"))); + } + + resUser = providerDBLMS->checkUserLMSexist(); + if(resUser) + { + ui->lblUserRes->setText(tr("Exist")); + ui->lblUserResIco->setPixmap(QPixmap(QStringLiteral(":/resources/icons/circleGreen.png"))); + } + else + { + ui->lblUserRes->setText(tr("Not exist")); + ui->lblUserResIco->setPixmap(QPixmap(QStringLiteral(":/resources/icons/circleRed.png"))); + } + + resDB = providerDBLMS->checkDataBaseLMSexist(); + if(resDB) + { + ui->lblDBRes->setText(tr("Exist")); + ui->lblDBResIco->setPixmap(QPixmap(QStringLiteral(":/resources/icons/circleGreen.png"))); + } + else + { + ui->lblDBRes->setText(tr("Not exist")); + ui->lblDBResIco->setPixmap(QPixmap(QStringLiteral(":/resources/icons/circleRed.png"))); + } + + if(!resDriver || !resUser || !resDB) + ui->btnRepare->setEnabled(true); + else + ui->btnRepare->setEnabled(false); +} + +void DialogCheckDB::on_btnRepare_clicked() +{ + if(!resDriver) + { + QMessageBox::warning(this, tr("Warning!"), tr("Install PostgreSQL.")); + return; + } + + if(!resUser) + { + if(!providerDBLMS->createUser("nameUser")) + { + QMessageBox::critical(this, tr("Error!"), tr("Failed to create user!")); + return; + } + } + + if(!resDB) + { + if(!providerDBLMS->createDB("nameDB")) + { + QMessageBox::critical(this, tr("Error!"), tr("Failed to create Database!")); + return; + } + } +} + +void DialogCheckDB::on_toolButton_clicked() +{ + QProcess process; + QString program = "cmd.exe"; + QStringList arguments; + arguments << "/C" << "echo Hello from QProcess" << "&&" << "pause"; + process.start(program, arguments); + process.waitForFinished(); + + int i = 0; +} diff --git a/ServerLMS/dialogcheckdb.h b/ServerLMS/dialogcheckdb.h new file mode 100644 index 0000000..43252bd --- /dev/null +++ b/ServerLMS/dialogcheckdb.h @@ -0,0 +1,37 @@ +#ifndef DIALOGCHECKDB_H +#define DIALOGCHECKDB_H + +#include +#include "providerdblms.h" + +namespace Ui { +class DialogCheckDB; +} + +class DialogCheckDB : public QDialog +{ + Q_OBJECT + +public: + explicit DialogCheckDB(ProviderDBLMS* providerDBLMS, QWidget *parent = nullptr); + ~DialogCheckDB(); + +private slots: + void on_btnRepare_clicked(); + + void on_toolButton_clicked(); + +private: + void check(); + +private: + Ui::DialogCheckDB *ui; + + ProviderDBLMS* providerDBLMS; + + bool resDriver; + bool resUser; + bool resDB; +}; + +#endif // DIALOGCHECKDB_H diff --git a/ServerLMS/dialogcheckdb.ui b/ServerLMS/dialogcheckdb.ui new file mode 100644 index 0000000..1bc6b07 --- /dev/null +++ b/ServerLMS/dialogcheckdb.ui @@ -0,0 +1,244 @@ + + + DialogCheckDB + + + + 0 + 0 + 400 + 300 + + + + Database + + + + + + + + + + + 0 + 0 + + + + + 150 + 0 + + + + Driver PostgreSQL + + + + + + + ... + + + + + + + + 0 + 0 + + + + + 32 + 32 + + + + + 32 + 32 + + + + + + + :/resources/icons/circleGray.png + + + + + + + + + + + + 0 + 0 + + + + + 150 + 0 + + + + User + + + + + + + ... + + + + + + + + 0 + 0 + + + + + 32 + 32 + + + + + 32 + 32 + + + + + + + :/resources/icons/circleGray.png + + + + + + + + + + + + 0 + 0 + + + + + 150 + 0 + + + + Database + + + + + + + ... + + + + + + + + 0 + 0 + + + + + 32 + 32 + + + + + 32 + 32 + + + + + + + :/resources/icons/circleGray.png + + + + + + + + + + + + 32 + 32 + + + + ... + + + + + + + + 58 + 58 + + + + Repare + + + + :/resources/icons/procedure.png:/resources/icons/procedure.png + + + + 32 + 32 + + + + Qt::ToolButtonTextUnderIcon + + + + + + + + + + + + + + diff --git a/ServerLMS/dialogsettingstray.cpp b/ServerLMS/dialogsettingstray.cpp index cc70e91..ba3d775 100644 --- a/ServerLMS/dialogsettingstray.cpp +++ b/ServerLMS/dialogsettingstray.cpp @@ -2,11 +2,13 @@ #include "dialogsettingstray.h" #include "Systems/tools.h" #include "ui_dialogsettingstray.h" +#include "dialogcheckdb.h" -DialogSettingsTray::DialogSettingsTray(QWidget *parent) : +DialogSettingsTray::DialogSettingsTray(ProviderDBLMS* providerDBLMS, QWidget *parent) : QDialog(parent), ui(new Ui::DialogSettingsTray), settings(nullptr), + providerDBLMS(providerDBLMS), flSettingsServerChanged(false) { ui->setupUi(this); @@ -226,3 +228,19 @@ void DialogSettingsTray::on_editPassword_textChanged(const QString &arg1) ui->btnSave->setEnabled(true); flSettingsServerChanged = true; } + +void DialogSettingsTray::on_btnCheckDB_clicked() +{ + DialogCheckDB dlgCheckDB(providerDBLMS, this); + dlgCheckDB.setWindowFlags(dlgCheckDB.windowFlags() & ~Qt::WindowContextHelpButtonHint); + + switch( dlgCheckDB.exec() ) + { + case QDialog::Accepted: + break; + case QDialog::Rejected: + break; + default: + break; + } +} diff --git a/ServerLMS/dialogsettingstray.h b/ServerLMS/dialogsettingstray.h index 956c17b..72f0916 100644 --- a/ServerLMS/dialogsettingstray.h +++ b/ServerLMS/dialogsettingstray.h @@ -4,6 +4,7 @@ #include #include #include +#include "providerdblms.h" class ServerDBSettings{ public: @@ -25,7 +26,7 @@ class DialogSettingsTray : public QDialog Q_OBJECT public: - explicit DialogSettingsTray(QWidget *parent = nullptr); + explicit DialogSettingsTray(ProviderDBLMS* providerDBLMS, QWidget *parent = nullptr); ~DialogSettingsTray(); ServerDBSettings getSettings(); @@ -55,6 +56,8 @@ private slots: void on_editPassword_textChanged(const QString &arg1); + void on_btnCheckDB_clicked(); + private: bool saveSettings(); @@ -63,6 +66,8 @@ private: ServerDBSettings *settings; + ProviderDBLMS* providerDBLMS; + bool flSettingsServerChanged; }; diff --git a/ServerLMS/dialogsettingstray.ui b/ServerLMS/dialogsettingstray.ui index eb88158..e970c9d 100644 --- a/ServerLMS/dialogsettingstray.ui +++ b/ServerLMS/dialogsettingstray.ui @@ -7,7 +7,7 @@ 0 0 400 - 324 + 427 @@ -179,6 +179,36 @@ + + + + + + + 58 + 58 + + + + Check DB + + + + :/resources/icons/checkDB.png:/resources/icons/checkDB.png + + + + 32 + 32 + + + + Qt::ToolButtonTextUnderIcon + + + + + @@ -238,6 +268,7 @@ + diff --git a/ServerLMS/providerdblms.cpp b/ServerLMS/providerdblms.cpp index f2d504e..c34bd4d 100644 --- a/ServerLMS/providerdblms.cpp +++ b/ServerLMS/providerdblms.cpp @@ -64,6 +64,31 @@ DataBaseSettings ProviderDBLMS::getDBSettings() return dbLMS->getDataBaseSettings(); } +bool ProviderDBLMS::checkDriverQPSQLavailable() +{ + return dbLMS->checkDriverQPSQLavailable(); +} + +bool ProviderDBLMS::checkUserLMSexist() +{ + return dbLMS->checkUserLMSexist(); +} + +bool ProviderDBLMS::checkDataBaseLMSexist() +{ + return dbLMS->checkDataBaseLMSexist(); +} + +bool ProviderDBLMS::createUser(QString name) +{ + return dbLMS->createUser(name); +} + +bool ProviderDBLMS::createDB(QString name) +{ + return dbLMS->createDB(name); +} + QString ProviderDBLMS::getMainInstructorName() { mtxAccess.lock(); diff --git a/ServerLMS/providerdblms.h b/ServerLMS/providerdblms.h index 15ad89d..d2821b2 100644 --- a/ServerLMS/providerdblms.h +++ b/ServerLMS/providerdblms.h @@ -80,6 +80,14 @@ public: bool DBisConnected(); DataBaseSettings getDBSettings(); + //PostgreSQL + bool checkDriverQPSQLavailable(); + bool checkUserLMSexist(); + bool checkDataBaseLMSexist(); + + bool createUser(QString name); + bool createDB(QString name); + private: InterfaceDataBaseLMS* dbLMS; QMutex mtxAccess; diff --git a/ServerLMS/resources/icons/checkDB.png b/ServerLMS/resources/icons/checkDB.png new file mode 100644 index 0000000000000000000000000000000000000000..91895c28a425b9cdbbe5b244de874fda6aadcd05 GIT binary patch literal 37066 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 Jv6ezl`5)WI-&z0w literal 0 HcmV?d00001 diff --git a/ServerLMS/resources/icons/editorDB.png b/ServerLMS/resources/icons/editorDB.png new file mode 100644 index 0000000000000000000000000000000000000000..bb4ab4ee157abe41c0da4fb85f768b1574d441b2 GIT binary patch literal 3780 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 Q%m0~V2Uq(tyTGKs1K!CnX#fBK literal 0 HcmV?d00001 diff --git a/ServerLMS/resources/icons/procedure.png b/ServerLMS/resources/icons/procedure.png new file mode 100644 index 0000000000000000000000000000000000000000..ca2800a2336a842b3b00de4b00c333c24dcc05fb GIT binary patch literal 1341 zcmV-D1;YA?P)Onv)+Ce3oYy_5XRX=nRt@Y2hVb9@67Umn4luVonC0{QRu~LJ92F<8D$)j{N)s1dMFDa3?k6q)IF6v}I?4fSgv~M!*he+paiC zQq-5r1=s*^bv53-SXQH)lZEOP(nl6c$G>JrM(K1xxe7~fD{AQ)0g0`^FT`xxro1x+ za&d7{pU_YNcW5!z%!Nz7(mhE>ezq$$BTuIb%9WmVTKT_}>APJ?0;+%kPr%JU(V`{G zB}qTVCkrU2F-2Z23;X-{Sd?tbm7`9&T=A#u#W$62FH^$7Y*jcOXkXe<0S{X=F#<)4 z7B|Aze;qBL46rop5$COG3ZU3M$?Dj?gT{^vmn5xOw^4wAH~$ZO zb1ds3dJJrN!Ri4sR9(WE>`K;X9Vbn#6wC>%N9@% zq|z9W)j-c@!(Cl;IdhJr@1+}S)hW*F@wD&-k^6gh;zg(@7$~$t@Ny)Zj@@a1oFwoG#x$SJ)EP@90fD6~5tqc6|H*~Ww zCdi);Hy)&<=Jr@%GjJ#&Zuh%E!M)u>`t-wbs~VHZMETX<`2BVb!-fr{{=R|SoQx1> zV4#k`#E4n(4ZwIHzR6G_aICbn7N|8;C=}lWXJ=@52wq0$ z)ss_~8jcNqfAvR>>gvj;1fsxx{v4j|%(%I^V-4uy47>%T->kYmA#C&;RNbh&Pun(z z>Z-$^NsqQkg-fOTTU2SAsjzom)sVrjv=-+s9v+@bO3Be(N!ce0)un5