From 4cedc7e49e4058e8f1e7ca99648132a7eec685fb Mon Sep 17 00:00:00 2001 From: Tina0595 <2825103297@qq.com> Date: Sat, 6 Jul 2024 21:23:41 +0800 Subject: [PATCH 1/2] mysql --- .../XEngine_Config/XEngine_Config.json | 11 +- .../AuthorizeModule_Configure/Config_Define.h | 18 +- .../ModuleConfigure_Json.cpp | 15 +- .../AuthorizeModule_Database.def | 100 +- .../AuthorizeModule_Database.vcxproj | 6 +- .../AuthorizeModule_Database.vcxproj.filters | 26 +- .../DBModule_MySQL/DBModule_MySQL.cpp | 2015 +++++++++++++++++ .../DBModule_MySQL/DBModule_MySQL.h | 61 + .../DBModule_SQLite.cpp} | 144 +- .../DBModule_SQLite.h} | 64 +- .../Database_Define.h | 601 ++++- .../AuthorizeModule_Database/Makefile | 8 +- .../AuthorizeModule_Database/pch.cpp | 234 +- .../AuthorizeHTTP_Get/AuthorizeHTTP_Token.cpp | 11 +- .../AuthorizeHTTP_Announcement.cpp | 36 +- .../AuthorizeHTTP_Banned.cpp | 36 +- .../AuthorizeHTTP_Client.cpp | 31 +- .../AuthorizeHTTP_Post/AuthorizeHTTP_Pass.cpp | 29 +- .../AuthorizeHTTP_Serial.cpp | 51 +- .../AuthorizeHTTP_Post/AuthorizeHTTP_Try.cpp | 27 +- .../AuthorizeHTTP_Post/AuthorizeHTTP_User.cpp | 94 +- .../XEngine_AuthorizeService/Authorize_Hdr.h | 2 + .../Authorize_HttpTask.cpp | 14 +- .../Authorize_TCPTask.cpp | 41 +- .../Authorize_Task.cpp | 9 +- .../XEngine_AuthorizeService | Bin 0 -> 811704 bytes .../XEngine_AuthorizeService.cpp | 42 +- 27 files changed, 3404 insertions(+), 322 deletions(-) create mode 100644 XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.cpp create mode 100644 XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.h rename XEngine_Source/AuthorizeModule_Database/{Database_SQLite/Database_SQLite.cpp => DBModule_SQLite/DBModule_SQLite.cpp} (94%) rename XEngine_Source/AuthorizeModule_Database/{Database_SQLite/Database_SQLite.h => DBModule_SQLite/DBModule_SQLite.h} (55%) create mode 100644 XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/XEngine_AuthorizeService diff --git a/XEngine_Release/XEngine_Config/XEngine_Config.json b/XEngine_Release/XEngine_Config/XEngine_Config.json index 977c10c..4d95f24 100644 --- a/XEngine_Release/XEngine_Config/XEngine_Config.json +++ b/XEngine_Release/XEngine_Config/XEngine_Config.json @@ -40,8 +40,13 @@ "bEnable":false, "nPass":123123 }, - "XSQL":{ - "tszSQLFile":"./XEngine_DataBase/SQL_User.db" + "XSql":{ + "nSQLType":1, + "SQLAddr": "127.0.0.1", + "SQLPort": 3306, + "SQLUser": "root", + "SQLPass": "123123", + "SQLFile":"./XEngine_DataBase/SQL_User.db" }, "XLog":{ "tszLogFile":"./XEngine_XLog/XEngine_Authorize.log", @@ -54,4 +59,4 @@ "tszServiceName":"XEngine_Authorize", "tszAPIUrl":"http://app.xyry.org:5501/api?function=machine" } -} \ No newline at end of file +} diff --git a/XEngine_Source/AuthorizeModule_Configure/Config_Define.h b/XEngine_Source/AuthorizeModule_Configure/Config_Define.h index fa980f6..687982a 100644 --- a/XEngine_Source/AuthorizeModule_Configure/Config_Define.h +++ b/XEngine_Source/AuthorizeModule_Configure/Config_Define.h @@ -15,6 +15,8 @@ ////////////////////////////////////////////////////////////////////////// typedef struct { + XCHAR tszIPAddr[128]; + XCHAR tszTopic[128]; int nTCPPort; //TCP端口 int nWSPort; //WEBSOCKET端口 int nHTTPPort; //HTTP管理端口 @@ -64,8 +66,20 @@ typedef struct int nPassword; //密码 }st_XCrypto; struct - { - XCHAR tszSQLite[MAX_PATH]; //数据库文件位置 + { + int nDBType; + struct + { + XCHAR tszSQLAddr[128]; //数据库地址 + XCHAR tszSQLUser[128]; //数据库账号 + XCHAR tszSQLPass[128]; //数据库密码 + XCHAR tszDBName[128]; //数据库名 + int nSQLPort; //数据库端口 + }st_MYSQL; + struct + { + XCHAR tszSQLite[MAX_PATH]; //数据库文件位置 + }st_SQLite; }st_XSql; struct { diff --git a/XEngine_Source/AuthorizeModule_Configure/ModuleConfigure_Json/ModuleConfigure_Json.cpp b/XEngine_Source/AuthorizeModule_Configure/ModuleConfigure_Json/ModuleConfigure_Json.cpp index 9eff1c2..33d79e2 100644 --- a/XEngine_Source/AuthorizeModule_Configure/ModuleConfigure_Json/ModuleConfigure_Json.cpp +++ b/XEngine_Source/AuthorizeModule_Configure/ModuleConfigure_Json/ModuleConfigure_Json.cpp @@ -147,14 +147,23 @@ bool CModuleConfigure_Json::ModuleConfigure_Json_File(LPCXSTR lpszConfigFile, XE pSt_ServerConfig->st_XCrypto.bEnable = st_JsonXCrypto["bEnable"].asBool(); pSt_ServerConfig->st_XCrypto.nPassword = st_JsonXCrypto["nPass"].asInt(); //数据库配置 - if (st_JsonRoot["XSQL"].empty() || (1 != st_JsonRoot["XSQL"].size())) + printf("%d\n", st_JsonRoot["XSql"].size()); + if (st_JsonRoot["XSql"].empty() || (6 != st_JsonRoot["XSql"].size())) { Config_IsErrorOccur = true; Config_dwErrorCode = ERROR_AUTHORIZE_MODULE_CONFIGURE_XSQL; return false; } - Json::Value st_JsonXSQL = st_JsonRoot["XSQL"]; - _tcsxcpy(pSt_ServerConfig->st_XSql.tszSQLite, st_JsonXSQL["tszSQLFile"].asCString()); + Json::Value st_JsonXSql = st_JsonRoot["XSql"]; + + pSt_ServerConfig->st_XSql.nDBType = st_JsonXSql["nSQLType"].asInt(); + + _tcsxcpy(pSt_ServerConfig->st_XSql.st_SQLite.tszSQLite, st_JsonXSql["SQLFile"].asCString()); + + pSt_ServerConfig->st_XSql.st_MYSQL.nSQLPort = st_JsonXSql["SQLPort"].asInt(); + _tcsxcpy(pSt_ServerConfig->st_XSql.st_MYSQL.tszSQLAddr, st_JsonXSql["SQLAddr"].asCString()); + _tcsxcpy(pSt_ServerConfig->st_XSql.st_MYSQL.tszSQLUser, st_JsonXSql["SQLUser"].asCString()); + _tcsxcpy(pSt_ServerConfig->st_XSql.st_MYSQL.tszSQLPass, st_JsonXSql["SQLPass"].asCString()); //日志配置 if (st_JsonRoot["XLog"].empty() || (4 != st_JsonRoot["XLog"].size())) { diff --git a/XEngine_Source/AuthorizeModule_Database/AuthorizeModule_Database.def b/XEngine_Source/AuthorizeModule_Database/AuthorizeModule_Database.def index eed0328..ca0bf35 100644 --- a/XEngine_Source/AuthorizeModule_Database/AuthorizeModule_Database.def +++ b/XEngine_Source/AuthorizeModule_Database/AuthorizeModule_Database.def @@ -3,36 +3,70 @@ LIBRARY EXPORTS DBModule_GetLastError - Database_SQLite_Init - Database_SQLite_Destroy - - Database_SQLite_UserDelete - Database_SQLite_UserRegister - Database_SQLite_UserQuery - Database_SQLite_UserPay - Database_SQLite_UserLeave - Database_SQLite_UserSet - Database_SQLite_UserList - - Database_SQLite_SerialInsert - Database_SQLite_SerialDelete - Database_SQLite_SerialQuery - Database_SQLite_SerialQueryAll - Database_SQLite_SerialPush - - Database_SQLite_TryInsert - Database_SQLite_TryQuery - Database_SQLite_TryDelete - Database_SQLite_TryClear - Database_SQLite_TrySet - Database_SQLite_TryList - - Database_SQLite_BannedInsert - Database_SQLite_BannedDelete - Database_SQLite_BannedList - Database_SQLite_BannedExist - Database_SQLite_BannedUPDate - - Database_SQLite_AnnouncementInsert - Database_SQLite_AnnouncementDelete - Database_SQLite_AnnouncementList \ No newline at end of file + DBModule_SQLite_Init + DBModule_SQLite_Destroy + + DBModule_SQLite_UserDelete + DBModule_SQLite_UserRegister + DBModule_SQLite_UserQuery + DBModule_SQLite_UserPay + DBModule_SQLite_UserLeave + DBModule_SQLite_UserSet + DBModule_SQLite_UserList + + DBModule_SQLite_SerialInsert + DBModule_SQLite_SerialDelete + DBModule_SQLite_SerialQuery + DBModule_SQLite_SerialQueryAll + DBModule_SQLite_SerialPush + + DBModule_SQLite_TryInsert + DBModule_SQLite_TryQuery + DBModule_SQLite_TryDelete + DBModule_SQLite_TryClear + DBModule_SQLite_TrySet + DBModule_SQLite_TryList + + DBModule_SQLite_BannedInsert + DBModule_SQLite_BannedDelete + DBModule_SQLite_BannedList + DBModule_SQLite_BannedExist + DBModule_SQLite_BannedUPDate + + DBModule_SQLite_AnnouncementInsert + DBModule_SQLite_AnnouncementDelete + DBModule_SQLite_AnnouncementList + + DBModule_MySQL_Init + DBModule_MySQL_Destroy + + DBModule_MySQL_UserDelete + DBModule_MySQL_UserRegister + DBModule_MySQL_UserQuery + DBModule_MySQL_UserPay + DBModule_MySQL_UserLeave + DBModule_MySQL_UserSet + DBModule_MySQL_UserList + + DBModule_MySQL_SerialInsert + DBModule_MySQL_SerialDelete + DBModule_MySQL_SerialQuery + DBModule_MySQL_SerialQueryAll + DBModule_MySQL_SerialPush + + DBModule_MySQL_TryInsert + DBModule_MySQL_TryQuery + DBModule_MySQL_TryDelete + DBModule_MySQL_TryClear + DBModule_MySQL_TrySet + DBModule_MySQL_TryList + + DBModule_MySQL_BannedInsert + DBModule_MySQL_BannedDelete + DBModule_MySQL_BannedList + DBModule_MySQL_BannedExist + DBModule_MySQL_BannedUPDate + + DBModule_MySQL_AnnouncementInsert + DBModule_MySQL_AnnouncementDelete + DBModule_MySQL_AnnouncementList \ No newline at end of file diff --git a/XEngine_Source/AuthorizeModule_Database/AuthorizeModule_Database.vcxproj b/XEngine_Source/AuthorizeModule_Database/AuthorizeModule_Database.vcxproj index d5e9218..b71286a 100644 --- a/XEngine_Source/AuthorizeModule_Database/AuthorizeModule_Database.vcxproj +++ b/XEngine_Source/AuthorizeModule_Database/AuthorizeModule_Database.vcxproj @@ -161,12 +161,14 @@ - + + - + + Create diff --git a/XEngine_Source/AuthorizeModule_Database/AuthorizeModule_Database.vcxproj.filters b/XEngine_Source/AuthorizeModule_Database/AuthorizeModule_Database.vcxproj.filters index 6cbd88b..1218446 100644 --- a/XEngine_Source/AuthorizeModule_Database/AuthorizeModule_Database.vcxproj.filters +++ b/XEngine_Source/AuthorizeModule_Database/AuthorizeModule_Database.vcxproj.filters @@ -13,10 +13,16 @@ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - + + {e8a2076d-4bed-4439-9493-1a33b0f6fd2b} + + + {dc9f7cbb-dd1b-4430-99ee-15793188c3a0} + + {bb64f825-b769-444e-b078-90c2727b694f} - + {be64df35-6ef0-4c8c-b95a-444977d7d1c4} @@ -27,15 +33,18 @@ 头文件 - - 头文件\Database_SQLite - 头文件 头文件 + + 头文件\DBModule_MySQL + + + 头文件\DBModule_SQLite + @@ -44,8 +53,11 @@ 源文件 - - 源文件\Database_SQLite + + 源文件\DBModule_MySQL + + + 源文件\DBModule_SQLite diff --git a/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.cpp b/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.cpp new file mode 100644 index 0000000..46ce206 --- /dev/null +++ b/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.cpp @@ -0,0 +1,2015 @@ +#include "pch.h" +#include "DBModule_MySQL.h" +/******************************************************************** +// Created: 2022/05/26 11:01:13 +// File Name: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_Database\Database_MySQL\Database_MySQL.cpp +// File Path: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_Database\Database_MySQL +// File Base: Database_SQLite +// File Ext: cpp +// Project: XEngine(网络通信引擎) +// Author: qyt +// Purpose: 数据库管理器 +// History: +*********************************************************************/ +CDBModule_MySQL::CDBModule_MySQL() +{ + m_bChange = false; + xhData = 0; +} + +CDBModule_MySQL::~CDBModule_MySQL() +{ +} +////////////////////////////////////////////////////////////////////////// +// 公有函数 +////////////////////////////////////////////////////////////////////////// +/******************************************************************** +函数名称:DBModule_MySQL_Init +函数功能:初始化数据库管理器 + 参数.一:pSt_DBConnector + In/Out:In + 类型:数据结构指针 + 可空:N + 意思:数据MYSQL数据库连接信息 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_Init(DATABASE_MYSQL_CONNECTINFO* pSt_DBConnector, bool bIsChange) +{ + SQLPacket_IsErrorOccur = false; + m_bChange = bIsChange; + if (NULL == pSt_DBConnector) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = DataBase_GetLastError(); + return false; + } + _tcsxcpy(pSt_DBConnector->tszDBName, _X("XEngine_Authorize")); //设置库名 + if (!DataBase_MySQL_Connect(&xhData, pSt_DBConnector)) //连接数据库 + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = DataBase_GetLastError(); + return false; + } + return true; +} +/******************************************************************** +函数名称:DBModule_MySQL_Destroy +函数功能:销毁数据库管理器 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_Destroy() +{ + SQLPacket_IsErrorOccur = false; + + DataBase_MySQL_Close(xhData); + return true; +} +/******************************************************************** +函数名称:DBModule_MySQL_UserDelete +函数功能:删除一个用户从数据库中 + 参数.一:lpszUserName + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:要删除的用户 +返回值 + 类型:逻辑型 + 意思:是否删除成功 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_UserDelete(LPCXSTR lpszUserName) +{ + SQLPacket_IsErrorOccur = false; + XCHAR tszSQLStatement[1024]; //SQL语句 + memset(tszSQLStatement, '\0', 1024); + _xstprintf(tszSQLStatement, _X("delete from `Authorize_User` where UserName = '%s'"), lpszUserName); + //执行 + if (!DataBase_MySQL_Execute(xhData, tszSQLStatement)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_EXEC; + return false; + } + return true; +} +/******************************************************************** +函数名称:DBModule_MySQL_UserRegister +函数功能:用户注册处理数据库语句函数 + 参数.一:pSt_UserInfo + In/Out:In + 类型:数据结构指针 + 可空:N + 意思:要插入的用户数据 +返回值 + 类型:逻辑型 + 意思:是否插入成功 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_UserRegister(AUTHREG_USERTABLE* pSt_UserInfo) +{ + SQLPacket_IsErrorOccur = false; + XCHAR tszSQLStatement[1024]; //SQL语句 + memset(tszSQLStatement, '\0', 1024); + + if (DBModule_MySQL_UserQuery(pSt_UserInfo->st_UserInfo.tszUserName)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_EXIST; + return false; + } + _xstprintf(tszSQLStatement, _X("INSERT INTO `Authorize_User`(UserName, Password, LeftTime, EmailAddr, HardCode, CardSerialType, PhoneNumber, IDCard, nUserLevel, CreateTime) values('%s','%s','%s','%s','%s','%d',%lld,%lld,%d,NOW())"), pSt_UserInfo->st_UserInfo.tszUserName, pSt_UserInfo->st_UserInfo.tszUserPass, pSt_UserInfo->tszLeftTime, pSt_UserInfo->st_UserInfo.tszEMailAddr, pSt_UserInfo->tszHardCode, pSt_UserInfo->enSerialType, pSt_UserInfo->st_UserInfo.nPhoneNumber, pSt_UserInfo->st_UserInfo.nIDNumber, pSt_UserInfo->st_UserInfo.nUserLevel); + if (!DataBase_MySQL_Execute(xhData, tszSQLStatement)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_INSERT; + return false; + } + return true; +} +/******************************************************************** +函数名称:DBModule_MySQL_UserQuery +函数功能:查询用户相对应的值 + 参数.一:lpszUserName + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:要查询的指定用户 + 参数.二:pSt_UserInfo + In/Out:Out + 类型:数据结构指针 + 可空:Y + 意思:如果为空NULL,那么将只判断此用户是否存在 +返回值 + 类型:逻辑型 + 意思:是否查询成功 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_UserQuery(LPCXSTR lpszUserName, AUTHREG_USERTABLE* pSt_UserInfo) +{ + SQLPacket_IsErrorOccur = false; + //查询 + XNETHANDLE xhTable = 0; + __int64u nColumn = 0; + __int64u nRow = 0; + + XCHAR tszSQLStatement[1024]; //SQL语句 + memset(tszSQLStatement, '\0', 1024); + + _xstprintf(tszSQLStatement, _X("select * from `Authorize_User` where UserName = '%s'"), lpszUserName); + if (!DataBase_MySQL_ExecuteQuery(xhData, &xhTable, tszSQLStatement, &nRow, &nColumn)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_GETTABLE; + return false; + } + if (nRow <= 0) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_GETTABLE; + return false; + } + XCHAR** pptszResult = DataBase_MySQL_GetResult(xhData, xhTable); + //XLONG* pInt_Length = DataBase_MySQL_GetLength(xhData, xhTable); + + if (NULL != pSt_UserInfo) + { + memset(pSt_UserInfo, '\0', sizeof(AUTHREG_USERTABLE)); + + //ID + int nFliedValue = 0; + + //用户名 + nFliedValue++; + if (NULL != pptszResult[nFliedValue]) + { + //printf("索引:%d 用户名:%s\n", nFliedValue, pptszResult[nFliedValue]); + _tcsxcpy(pSt_UserInfo->st_UserInfo.tszUserName, pptszResult[nFliedValue]); + } + + //密码 + nFliedValue++; + if (NULL != pptszResult[nFliedValue]) + { + //printf("索引:%d 密码:%s\n", nFliedValue, pptszResult[nFliedValue]); + _tcsxcpy(pSt_UserInfo->st_UserInfo.tszUserPass, pptszResult[nFliedValue]); + } + + //过期时间 + nFliedValue++; + if (NULL != pptszResult[nFliedValue]) + { + //printf("索引:%d 过期时间:%s\n", nFliedValue, pptszResult[nFliedValue]); + _tcsxcpy(pSt_UserInfo->tszLeftTime, pptszResult[nFliedValue]); + } + + //电子邮件 + nFliedValue++; + if (NULL != pptszResult[nFliedValue]) + { + //printf("索引:%d 电子邮件:%s\n", nFliedValue, pptszResult[nFliedValue]); + _tcsxcpy(pSt_UserInfo->st_UserInfo.tszEMailAddr, pptszResult[nFliedValue]); + } + + //硬件码 + nFliedValue++; + if (NULL != pptszResult[nFliedValue]) + { + //printf("索引:%d 硬件码:%s\n", nFliedValue, pptszResult[nFliedValue]); + _tcsxcpy(pSt_UserInfo->tszHardCode, pptszResult[nFliedValue]); + } + + //充值卡类型 + nFliedValue++; + if (NULL != pptszResult[nFliedValue]) + { + //printf("索引:%d 充值卡类型:%s\n", nFliedValue, pptszResult[nFliedValue]); + pSt_UserInfo->enSerialType = (ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE)_ttxoi(pptszResult[nFliedValue]); + } + + //QQ号 + nFliedValue++; + if (NULL != pptszResult[nFliedValue]) + { + //printf("索引:%d QQ号:%s\n", nFliedValue, pptszResult[nFliedValue]); + pSt_UserInfo->st_UserInfo.nPhoneNumber = _ttxoll(pptszResult[nFliedValue]); + } + + //身份证ID + nFliedValue++; + if (NULL != pptszResult[nFliedValue]) + { + //printf("索引:%d 身份证ID:%s\n", nFliedValue, pptszResult[nFliedValue]); + pSt_UserInfo->st_UserInfo.nIDNumber = _ttxoll(pptszResult[nFliedValue]); + } + + //用户级别 -1表示封禁 + nFliedValue++; + if (NULL != pptszResult[nFliedValue]) + { + //printf("索引:%d 用户级别 -1表示封禁:%s\n", nFliedValue, pptszResult[nFliedValue]); + pSt_UserInfo->st_UserInfo.nUserLevel = _ttxoi(pptszResult[nFliedValue]); + } + + //登录日期 + nFliedValue++; + if (NULL != pptszResult[nFliedValue] && _tcsxlen(pptszResult[nFliedValue]) > 0) + { + //printf("索引:%d 登录日期:%s\n", nFliedValue, pptszResult[nFliedValue]); + _tcsxcpy(pSt_UserInfo->st_UserInfo.tszLoginTime, pptszResult[nFliedValue]); + } + //注册日期 + nFliedValue++; + if (NULL != pptszResult[nFliedValue]) + { + //printf("索引:%d 注册日期:%s\n", nFliedValue, pptszResult[nFliedValue]); + _tcsxcpy(pSt_UserInfo->st_UserInfo.tszCreateTime, pptszResult[nFliedValue]); + } + + } + DataBase_MySQL_FreeResult(xhData, xhTable); + return true; +} +/******************************************************************** +函数名称:DBModule_MySQL_UserPay +函数功能:用户充值函数 + 参数.一:lpszUserName + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:要充值的用户名 + 参数.二:lpszSerialName + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:充值使用的序列号 +返回值 + 类型:逻辑型 + 意思:是否成功充值 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_UserPay(LPCXSTR lpszUserName, LPCXSTR lpszSerialName) +{ + SQLPacket_IsErrorOccur = false; + + AUTHREG_SERIALTABLE st_SerialTable; + AUTHREG_USERTABLE st_UserTable; + XCHAR tszSQLStatement[1024]; //SQL语句 + + memset(tszSQLStatement, '\0', 1024); + memset(&st_SerialTable, '\0', sizeof(st_SerialTable)); + memset(&st_UserTable, '\0', sizeof(st_UserTable)); + //参数检查 + if ((NULL == lpszUserName) || (NULL == lpszSerialName)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_PARAMENT; + return false; + } + //查询充值卡是否存在 + if (!DBModule_MySQL_SerialQuery(lpszSerialName, &st_SerialTable)) + { + return false; + } + //充值卡是否被使用 + if (st_SerialTable.bIsUsed) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_ISUSED; + return false; + } + //查询用户信息 + if (!DBModule_MySQL_UserQuery(lpszUserName, &st_UserTable)) + { + return false; + } + //分析插入方式 + switch (st_SerialTable.enSerialType) + { + case ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_SECOND: + if (!DBModule_MySQL_UserPayTime(lpszUserName, st_UserTable.tszLeftTime, st_SerialTable.tszMaxTime, st_SerialTable.enSerialType, st_UserTable.enSerialType)) + { + return false; + } + break; + case ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_DAY: + if (!DBModule_MySQL_UserPayTime(lpszUserName, st_UserTable.tszLeftTime, st_SerialTable.tszMaxTime, st_SerialTable.enSerialType, st_UserTable.enSerialType)) + { + return false; + } + break; + case ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_TIME: + if (!DBModule_MySQL_UserPayTime(lpszUserName, st_UserTable.tszLeftTime, st_SerialTable.tszMaxTime, st_SerialTable.enSerialType, st_UserTable.enSerialType)) + { + return false; + } + break; + case ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_CUSTOM: + if (!DBModule_MySQL_UserPayTime(lpszUserName, st_UserTable.tszLeftTime, st_SerialTable.tszMaxTime, st_SerialTable.enSerialType, st_UserTable.enSerialType)) + { + return false; + } + break; + default: + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_NOTSUPPORT; + return false; + } + _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_Serial` SET UserName = '%s',bIsUsed = '1' WHERE SerialNumber = '%s'"), lpszUserName, lpszSerialName); + if (!DataBase_MySQL_Execute(xhData, tszSQLStatement)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_UPDATAUSEDNAME; + return false; + } + return true; +} +/******************************************************************** +函数名称:DBModule_MySQL_UserLeave +函数功能:用户离开处理事件 + 参数.一:pSt_TimeProtocol + In/Out:In + 类型:数据结构指针 + 可空:N + 意思:离开的用户信息 +返回值 + 类型:逻辑型 + 意思:是否处理成功 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_UserLeave(AUTHREG_PROTOCOL_TIME* pSt_TimeProtocol) +{ + SQLPacket_IsErrorOccur = false; + + XCHAR tszSQLStatement[1024]; //SQL语句 + memset(tszSQLStatement, '\0', 1024); + + + if ((ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_DAY == pSt_TimeProtocol->enSerialType) || (ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_CUSTOM == pSt_TimeProtocol->enSerialType)) + { + //天数卡只有剩余时间没有的时候才需要做处理 + if (pSt_TimeProtocol->nTimeLeft <= 0) + { + _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_User` SET LeftTime = '0' WHERE UserName = '%s'"), pSt_TimeProtocol->tszUserName); + } + } + if (ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_SECOND == pSt_TimeProtocol->enSerialType) + { + //分钟卡必须要有在线时间才能计算 + if (pSt_TimeProtocol->nTimeLeft <= 0) + { + pSt_TimeProtocol->nTimeLeft = 0; + } + _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_User` SET LeftTime = '%lld' WHERE UserName = '%s'"), pSt_TimeProtocol->nTimeLeft, pSt_TimeProtocol->tszUserName); + } + else if (ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_TIME == pSt_TimeProtocol->enSerialType) + { + //次数卡不需要在线时间,直接减去一次就可以了 + _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_User` SET LeftTime = '%lld' WHERE UserName = '%s'"), _ttxoll(pSt_TimeProtocol->tszLeftTime), pSt_TimeProtocol->tszUserName); + } + else + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_UNKNOWTYPE; + return false; + } + //更新用户剩余时间 + if (!DataBase_MySQL_Execute(xhData, tszSQLStatement)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_UPDATA; + return false; + } + return true; +} +/******************************************************************** +函数名称:DBModule_MySQL_UserSet +函数功能:设置用户信息 + 参数.一:pSt_UserTable + In/Out:In + 类型:数据结构指针 + 可空:N + 意思:输入要设置的信息 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_UserSet(AUTHREG_USERTABLE* pSt_UserTable) +{ + SQLPacket_IsErrorOccur = false; + + XCHAR tszSQLStatement[1024]; //SQL语句 + memset(tszSQLStatement, '\0', 1024); + + _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_User` SET Password = '%s',LeftTime = '%s',EmailAddr = '%s',HardCode = '%s',CardSerialType = '%d',PhoneNumber = '%lld',IDCard = '%lld',nUserLevel = '%d',UPTime = NOW(),CreateTime = '%s' WHERE UserName = '%s'"), pSt_UserTable->st_UserInfo.tszUserPass, pSt_UserTable->tszLeftTime, pSt_UserTable->st_UserInfo.tszEMailAddr, pSt_UserTable->tszHardCode, pSt_UserTable->enSerialType, pSt_UserTable->st_UserInfo.nPhoneNumber, pSt_UserTable->st_UserInfo.nIDNumber, pSt_UserTable->st_UserInfo.nUserLevel/*, pSt_UserTable->st_UserInfo.tszLoginTime*/, pSt_UserTable->st_UserInfo.tszCreateTime, pSt_UserTable->st_UserInfo.tszUserName); + + //printf("22设置用户信息(SQL):%s\n", tszSQLStatement); + //更新用户剩余时间 + if (!DataBase_MySQL_Execute(xhData, tszSQLStatement)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = DataBase_GetLastError(); + return false; + } + return true; +} +/******************************************************************** +函数名称:DBModule_MySQL_UserList +函数功能:获取用户列表 + 参数.一:pppSt_UserInfo + In/Out:Out + 类型:三级指针 + 可空:N + 意思:输出用户列表,内存由用户释放 + 参数.二:pInt_ListCount + In/Out:Out + 类型:整数型 + 可空:N + 意思:输出列表个数 + 参数.三:nPosStart + In/Out:In + 类型:整数型 + 可空:Y + 意思:输入起始位置 + 参数.四:nPosEnd + In/Out:In + 类型:整数型 + 可空:Y + 意思:输入结束位置 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_UserList(AUTHREG_USERTABLE*** pppSt_UserInfo, int* pInt_ListCount, int nPosStart, int nPosEnd) +{ + SQLPacket_IsErrorOccur = false; + + //查询 + XNETHANDLE xhTable = 0; + __int64u nRow = 0; + __int64u nColumn = 0; + char** ppszResult = NULL; + XCHAR tszSQLStatement[1024]; //SQL语句 + memset(tszSQLStatement, '\0', 1024); + + _xstprintf(tszSQLStatement, _X("SELECT * FROM `Authorize_User` LIMIT %d,%d"), nPosStart, nPosEnd - nPosStart); + if (!DataBase_MySQL_ExecuteQuery(xhData, &xhTable, tszSQLStatement, &nRow, &nColumn)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_GETTABLE; + return false; + } + if (nRow <= 0) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_NOTUSER; + return false; + } + *pInt_ListCount = nRow; + BaseLib_OperatorMemory_Malloc((XPPPMEM)pppSt_UserInfo, (int)nRow, sizeof(AUTHREG_USERTABLE)); + + for (int i = 0; i < nRow; i++) + { + ppszResult = DataBase_MySQL_GetResult(xhData, xhTable); + //XLONG* pInt_Length = DataBase_MySQL_GetLength(xhData, xhTable); + + //ID + int nFliedValue = 0; + nFliedValue++; + //用户名 + _tcsxcpy((*pppSt_UserInfo)[i]->st_UserInfo.tszUserName, ppszResult[nFliedValue]); + //密码 + nFliedValue++; + _tcsxcpy((*pppSt_UserInfo)[i]->st_UserInfo.tszUserPass, ppszResult[nFliedValue]); + //过期时间 + nFliedValue++; + _tcsxcpy((*pppSt_UserInfo)[i]->tszLeftTime, ppszResult[nFliedValue]); + //电子邮件 + nFliedValue++; + _tcsxcpy((*pppSt_UserInfo)[i]->st_UserInfo.tszEMailAddr, ppszResult[nFliedValue]); + //硬件码 + nFliedValue++; + _tcsxcpy((*pppSt_UserInfo)[i]->tszHardCode, ppszResult[nFliedValue]); + //充值卡类型 + nFliedValue++; + (*pppSt_UserInfo)[i]->enSerialType = (ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); + //QQ号 + nFliedValue++; + (*pppSt_UserInfo)[i]->st_UserInfo.nPhoneNumber = _ttxoll(ppszResult[nFliedValue]); + //身份证ID + nFliedValue++; + (*pppSt_UserInfo)[i]->st_UserInfo.nIDNumber = _ttxoll(ppszResult[nFliedValue]); + //用户级别 -1表示封禁 + nFliedValue++; + (*pppSt_UserInfo)[i]->st_UserInfo.nUserLevel = _ttxoi(ppszResult[nFliedValue]); + //登录日期 + nFliedValue++; + if (NULL != ppszResult[nFliedValue] && _tcsxlen(ppszResult[nFliedValue]) > 0) + { + _tcsxcpy((*pppSt_UserInfo)[i]->st_UserInfo.tszLoginTime, ppszResult[nFliedValue]); + } + //注册日期 + nFliedValue++; + _tcsxcpy((*pppSt_UserInfo)[i]->st_UserInfo.tszCreateTime, ppszResult[nFliedValue]); + nFliedValue++; + } + DataBase_MySQL_FreeResult(xhData, xhTable); + return true; +} +/******************************************************************** +函数名称:DBModule_MySQL_SerialInsert +函数功能:插入一个序列号到数据库 + 参数.一:lpszSerialNumber + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:要插入的序列号 +返回值 + 类型:逻辑型 + 意思:是否插入成功 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_SerialInsert(LPCXSTR lpszSerialNumber) +{ + SQLPacket_IsErrorOccur = false; + + XCHAR tszSQLStatement[1024]; //SQL语句 + memset(tszSQLStatement, '\0', 1024); + + if (DBModule_MySQL_SerialQuery(lpszSerialNumber)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_EXIST; + return false; + } + ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE enAuthSerialType; + XENGINE_LIBTIMER st_AuthTimer; + memset(&st_AuthTimer, '\0', sizeof(st_AuthTimer)); + + if (!Authorize_Serial_GetType(lpszSerialNumber, &enAuthSerialType, &st_AuthTimer)) + { + return false; + } + if (ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_SECOND == enAuthSerialType) + { + _xstprintf(tszSQLStatement, _X("INSERT INTO `Authorize_Serial` values(NULL,'NOT','%s','%d','%d',0,NOW())"), lpszSerialNumber, st_AuthTimer.wSecond, enAuthSerialType); + } + else if (ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_DAY == enAuthSerialType) + { + _xstprintf(tszSQLStatement, _X("INSERT INTO `Authorize_Serial` values(NULL,'NOT','%s','%d','%d',0,NOW())"), lpszSerialNumber, st_AuthTimer.wDay, enAuthSerialType); + } + else if (ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_TIME == enAuthSerialType) + { + _xstprintf(tszSQLStatement, _X("INSERT INTO `Authorize_Serial` values(NULL,'NOT','%s','%d','%d',0,NOW())"), lpszSerialNumber, st_AuthTimer.wFlags, enAuthSerialType); + } + else if (ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_CUSTOM == enAuthSerialType) + { + XCHAR tszLeftTime[MAX_PATH]; + memset(tszLeftTime, '\0', MAX_PATH); + _xstprintf(tszLeftTime, _X("%04d-%02d-%02d %02d:%02d:%02d"), st_AuthTimer.wYear, st_AuthTimer.wMonth, st_AuthTimer.wDay, st_AuthTimer.wHour, st_AuthTimer.wMinute, st_AuthTimer.wSecond); + _xstprintf(tszSQLStatement, _X("INSERT INTO `Authorize_Serial` values(NULL,'NOT','%s','%s','%d',0,NOW())"), lpszSerialNumber, tszLeftTime, enAuthSerialType); + } + else + { + _xstprintf(tszSQLStatement, _X("INSERT INTO `Authorize_Serial` values(NULL,'NOT','%s',0,'%d',0,NOW())"), lpszSerialNumber, enAuthSerialType); + } + + if (!DataBase_MySQL_Execute(xhData, tszSQLStatement)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_ISFAILED; + return false; + } + return true; +} +/******************************************************************** +函数名称:DBModule_MySQL_SerialDelete +函数功能:从数据库删除指定序列号 + 参数.一:lpszSerialNumber + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:要删除的序列号 +返回值 + 类型:逻辑型 + 意思:是否删除成功 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_SerialDelete(LPCXSTR lpszSerialNumber) +{ + SQLPacket_IsErrorOccur = false; + + XCHAR tszSQLStatement[1024]; //SQL语句 + memset(tszSQLStatement, '\0', 1024); + _xstprintf(tszSQLStatement, _X("delete from `Authorize_Serial` where SerialNumber = '%s'"), lpszSerialNumber); + //执行 + if (!DataBase_MySQL_Execute(xhData, tszSQLStatement)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_ISFAILED; + return false; + } + return true; +} +/******************************************************************** +函数名称:DBModule_MySQL_SerialQuery +函数功能:查询一个指定的序列号信息 + 参数.一:lpszSerialNumber + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:要查询的序列号 + 参数.二:pSt_SerialTable + In/Out:Out + 类型:数据结构指针 + 可空:Y + 意思:导出查询到的信息,如果为NULL,此参数将不起作用 +返回值 + 类型:逻辑型 + 意思:是否查询成功,如果第二个参数为NULL,那么将只返回是否有这个序列号 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_SerialQuery(LPCXSTR lpszSerialNumber, LPAUTHREG_SERIALTABLE pSt_SerialTable) +{ + SQLPacket_IsErrorOccur = false; + XCHAR tszSQLStatement[1024]; //SQL语句 + char** ppszResult = NULL; + XNETHANDLE xhTable = 0; + __int64u nRow = 0; + __int64u nColumn = 0; + memset(tszSQLStatement, '\0', 1024); + + _xstprintf(tszSQLStatement, _X("select * from `Authorize_Serial` where SerialNumber = '%s'"), lpszSerialNumber); + if (!DataBase_MySQL_ExecuteQuery(xhData, &xhTable, tszSQLStatement, &nRow, &nColumn)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_GETTABLE; + return false; + } + + if (nRow <= 0) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_SERIAL; + return false; + } + ppszResult = DataBase_MySQL_GetResult(xhData, xhTable); + //XLONG* pInt_Length = DataBase_MySQL_GetLength(xhData, xhTable); + + if (NULL != pSt_SerialTable) + { + memset(pSt_SerialTable, '\0', sizeof(AUTHREG_SERIALTABLE)); + //ID + int nFliedValue = 0; + //使用者 + nFliedValue++; + _tcsxcpy(pSt_SerialTable->tszUserName, ppszResult[nFliedValue]); + //序列号 + nFliedValue++; + _tcsxcpy(pSt_SerialTable->tszSerialNumber, ppszResult[nFliedValue]); + //超时时间 + nFliedValue++; + _tcsxcpy(pSt_SerialTable->tszMaxTime, ppszResult[nFliedValue]); + //序列卡类型 + nFliedValue++; + pSt_SerialTable->enSerialType = (ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); + //是否已经使用 + nFliedValue++; + pSt_SerialTable->bIsUsed = _ttxoi(ppszResult[nFliedValue]); + //超时时间 + nFliedValue++; + _tcsxcpy(pSt_SerialTable->tszCreateTime, ppszResult[nFliedValue]); + } + + DataBase_MySQL_FreeResult(xhData, xhTable); + return true; +} +/******************************************************************** +函数名称:DBModule_MySQL_SerialQueryAll +函数功能:查询序列卡表中的所有序列号 + 参数.一:pppSt_SerialTable + In/Out:Out + 类型:三级指针 + 可空:N + 意思:输出序列卡列表 + 参数.二:pInt_ListCount + In/Out:Out + 类型:整数型指针 + 可空:Y + 意思:输出多少张卡 + 参数.三:nPosStart + In/Out:In + 类型:整数型 + 可空:Y + 意思:输入起始位置 + 参数.四:nPosEnd + In/Out:In + 类型:整数型 + 可空:Y + 意思:输入结束位置 +返回值 + 类型:逻辑型 + 意思:是否查询成功 +备注:参数一需要调用基础库的释放内存函数进行内存释放 +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_SerialQueryAll(AUTHREG_SERIALTABLE*** pppSt_SerialTable, int* pInt_ListCount, int nPosStart, int nPosEnd) +{ + SQLPacket_IsErrorOccur = false; + + XNETHANDLE xhTable = 0; + __int64u nRow = 0; + __int64u nColumn = 0; + char** ppszResult = NULL; + XCHAR tszSQLStatement[1024]; //SQL语句 + + memset(tszSQLStatement, '\0', 1024); + + _xstprintf(tszSQLStatement, _X("SELECT * FROM `Authorize_Serial` LIMIT %d,%d"), nPosStart, nPosEnd - nPosStart); + if (!DataBase_MySQL_ExecuteQuery(xhData, &xhTable, tszSQLStatement, &nRow, &nColumn)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_GETTABLE; + return false; + } + if (nRow <= 0) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_NONE; + return false; + } + BaseLib_OperatorMemory_Malloc((XPPPMEM)pppSt_SerialTable, (int)nRow, sizeof(AUTHREG_SERIALTABLE)); + + *pInt_ListCount = nRow; + + for (int i = 0; i < nRow; i++) + { + // 获取数据库结果 + ppszResult = DataBase_MySQL_GetResult(xhData, xhTable); + //XLONG* pInt_Length = DataBase_MySQL_GetLength(xhData, xhTable); + + int nFliedValue = 0; + //ID + nFliedValue++; + //使用者 + _tcsxcpy((*pppSt_SerialTable)[i]->tszUserName, ppszResult[nFliedValue]); + nFliedValue++; + //序列号 + _tcsxcpy((*pppSt_SerialTable)[i]->tszSerialNumber, ppszResult[nFliedValue]); + nFliedValue++; + //超时时间 + _tcsxcpy((*pppSt_SerialTable)[i]->tszMaxTime, ppszResult[nFliedValue]); + nFliedValue++; + //序列卡类型 + (*pppSt_SerialTable)[i]->enSerialType = (ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); + nFliedValue++; + //是否已经使用 + (*pppSt_SerialTable)[i]->bIsUsed = _ttxoi(ppszResult[nFliedValue]); + nFliedValue++; + //创建时间 + _tcsxcpy((*pppSt_SerialTable)[i]->tszCreateTime, ppszResult[nFliedValue]); + nFliedValue++; + } + DataBase_MySQL_FreeResult(xhData, xhTable); + return true; +} +/******************************************************************** +函数名称:DBModule_MySQL_SerialPush +函数功能:插入一条指定的序列号信息到服务器 + 参数.一:pSt_SerialTable + In/Out:In + 类型:数据结构指针 + 可空:N + 意思:输入要插入的信息 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_SerialPush(AUTHREG_SERIALTABLE* pSt_SerialTable) +{ + SQLPacket_IsErrorOccur = false; + + XCHAR tszSQLStatement[1024]; //SQL语句 + memset(tszSQLStatement, '\0', 1024); + + if (DBModule_MySQL_SerialQuery(pSt_SerialTable->tszSerialNumber)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_EXIST; + return false; + } + _xstprintf(tszSQLStatement, _X("INSERT INTO `Authorize_Serial` values(NULL,'%s','%s','%s',%d,%d,'%s')"), pSt_SerialTable->tszUserName, pSt_SerialTable->tszSerialNumber, pSt_SerialTable->tszMaxTime, pSt_SerialTable->enSerialType, pSt_SerialTable->bIsUsed, pSt_SerialTable->tszCreateTime); + + if (!DataBase_MySQL_Execute(xhData, tszSQLStatement)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_ISFAILED; + return false; + } + return true; +} +/******************************************************************** +函数名称:DBModule_MySQL_TryInsert +函数功能:网络使用模式插入一条数据 + 参数.一:pSt_AuthVer + In/Out:In + 类型:数据结构指针 + 可空:N + 意思:输入要插入的数据 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_TryInsert(AUTHREG_TEMPVER* pSt_AuthVer) +{ + SQLPacket_IsErrorOccur = false; + + if (NULL == pSt_AuthVer) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_PARAMENT; + return false; + } + XCHAR tszSQLStatement[1024]; + AUTHREG_TEMPVER st_AuthVer; + + memset(tszSQLStatement, '\0', 1024); + memset(&st_AuthVer, '\0', sizeof(AUTHREG_TEMPVER)); + //验证是否存在 + _tcsxcpy(st_AuthVer.tszVSerial, pSt_AuthVer->tszVSerial); + if (DBModule_MySQL_TryQuery(&st_AuthVer)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_EXIST; + return false; + } + //插入数据库 + _xstprintf(tszSQLStatement, _X("INSERT INTO `Authorize_TempVer`(tszVSerial,nVMode,nVTime,nLTime,CreateTime) VALUES('%s',%d,%d,%d,NOW())"), pSt_AuthVer->tszVSerial, pSt_AuthVer->enVMode, pSt_AuthVer->nVTime, pSt_AuthVer->nVTime); + + //printf("网络使用模式插入一条数据:SQL语句%s\n", tszSQLStatement); + if (!DataBase_MySQL_Execute(xhData, tszSQLStatement)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = DataBase_GetLastError(); + return false; + } + return true; +} +/******************************************************************** +函数名称:DBModule_MySQL_TryQuery +函数功能:试用序列号查询函数 + 参数.一:pSt_AuthVer + In/Out:In/Out + 类型:数据结构指针 + 可空:N + 意思:输入序列号,输出获取到的内容 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_TryQuery(AUTHREG_TEMPVER* pSt_AuthVer) +{ + SQLPacket_IsErrorOccur = false; + + if (NULL == pSt_AuthVer) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_PARAMENT; + return false; + } + XNETHANDLE xhTable = 0; + __int64u nColumn = 0; + __int64u nRow = 0; + XCHAR** ppszResult = NULL; + XCHAR tszSQLStatement[1024]; //SQL语句 + + memset(tszSQLStatement, '\0', 1024); + _xstprintf(tszSQLStatement, _X("SELECT * FROM `Authorize_TempVer` WHERE tszVSerial = '%s'"), pSt_AuthVer->tszVSerial); + + + if (!DataBase_MySQL_ExecuteQuery(xhData, &xhTable, tszSQLStatement, &nRow, &nColumn)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = DataBase_GetLastError(); + return false; + } + + if (nRow <= 0) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_NONE; + return false; + } + ppszResult = DataBase_MySQL_GetResult(xhData, xhTable); + //XLONG* pInt_Length = DataBase_MySQL_GetLength(xhData, xhTable); + + //ID + int nFliedValue = 0; + nFliedValue++; + //序列号 + nFliedValue++; + + //试用类型 + if (NULL != ppszResult[nFliedValue]) + { + pSt_AuthVer->enVMode = (ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); + } + + //试用时间 + nFliedValue++; + if (NULL != ppszResult[nFliedValue]) + { + pSt_AuthVer->nVTime = _ttxoi(ppszResult[nFliedValue]); + } + + //剩余时间 + nFliedValue++; + if (NULL != ppszResult[nFliedValue]) + { + pSt_AuthVer->nLTime = _ttxoi(ppszResult[nFliedValue]); + } + + //注册时间 + nFliedValue++; + if (NULL != ppszResult[nFliedValue]) + { + _tcsxcpy(pSt_AuthVer->tszVDate, ppszResult[nFliedValue]); + } + + DataBase_MySQL_FreeResult(xhData, xhTable); + return true; +} +/******************************************************************** +函数名称:DBModule_MySQL_TryDelete +函数功能:删除一条指定的试用数据 + 参数.一:lpszSerial + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:输入要删除的序列号 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_TryDelete(LPCXSTR lpszSerial) +{ + SQLPacket_IsErrorOccur = false; + + if (NULL == lpszSerial) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_PARAMENT; + return false; + } + XCHAR tszSQLStatement[1024]; + memset(tszSQLStatement, '\0', 1024); + + _xstprintf(tszSQLStatement, _X("DELETE FROM `Authorize_TempVer` WHERE tszVSerial = '%s'"), lpszSerial); + + if (!DataBase_MySQL_Execute(xhData, tszSQLStatement)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = DataBase_GetLastError(); + return false; + } + return true; +} +/******************************************************************** +函数名称:DBModule_MySQL_TryClear +函数功能:清理函数,自动清理过期数据 + 参数.一:nThanValue + In/Out:In + 类型:整数型 + 可空:N + 意思:清理用于判断需要大于此的值 + 参数.二:enVMode + In/Out:In + 类型:枚举型 + 可空:Y + 意思:判断注册类型,默认不判断全部执行 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_TryClear(int nThanValue, ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE enVerMode) +{ + SQLPacket_IsErrorOccur = false; + + XNETHANDLE xhTable = 0; + __int64u nRow = 0; + __int64u nColumn = 0; + XCHAR** ppszResult = NULL; + XCHAR tszSQLStatement[1024]; //SQL语句 + + memset(tszSQLStatement, '\0', 1024); + _xstprintf(tszSQLStatement, _X("SELECT * FROM `Authorize_TempVer`")); + + if (!DataBase_MySQL_ExecuteQuery(xhData, &xhTable, tszSQLStatement, &nRow, &nColumn)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = DataBase_GetLastError(); + return false; + } + + list stl_ListVer; + //轮训所有内容 + for (int i = 0; i < nRow; i++) + { + ppszResult = DataBase_MySQL_GetResult(xhData, xhTable); + //XLONG* pInt_Length = DataBase_MySQL_GetLength(xhData, xhTable); + + int nFliedValue = 0; + AUTHREG_TEMPVER st_AuthVer; + memset(&st_AuthVer, '\0', sizeof(AUTHREG_TEMPVER)); + //ID + nFliedValue++; + //序列号 + _tcsxcpy(st_AuthVer.tszVSerial, ppszResult[nFliedValue]); + nFliedValue++; + //模式 + st_AuthVer.enVMode = (ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); + nFliedValue++; + //测试时间 + st_AuthVer.nVTime = _ttxoi(ppszResult[nFliedValue]); + nFliedValue++; + //测试时间 + st_AuthVer.nLTime = _ttxoi(ppszResult[nFliedValue]); + nFliedValue++; + //注册时间 + _tcsxcpy(st_AuthVer.tszVDate, ppszResult[nFliedValue]); + + stl_ListVer.push_back(st_AuthVer); + } + DataBase_MySQL_FreeResult(xhData, xhTable); + //清理 + list::const_iterator stl_ListIterator = stl_ListVer.begin(); + for (; stl_ListIterator != stl_ListVer.end(); stl_ListIterator++) + { + //判断是不是不关心注册的模式直接清理 + if (ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_UNKNOW == enVerMode) + { + if (nThanValue > stl_ListIterator->nVTime) + { + memset(tszSQLStatement, '\0', 1024); + _xstprintf(tszSQLStatement, _X("DELETE FROM `Authorize_TempVer` WHERE tszVSerial = '%s'"), stl_ListIterator->tszVSerial); + + if (!DataBase_MySQL_Execute(xhData, tszSQLStatement)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = DataBase_GetLastError(); + return false; + } + } + } + else + { + if (enVerMode == stl_ListIterator->enVMode) + { + memset(tszSQLStatement, '\0', 1024); + _xstprintf(tszSQLStatement, _X("DELETE FROM `Authorize_TempVer` WHERE tszVSerial = '%s'"), stl_ListIterator->tszVSerial); + + if (!DataBase_MySQL_Execute(xhData, tszSQLStatement)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = DataBase_GetLastError(); + return false; + } + } + } + } + stl_ListVer.clear(); + return true; +} +/******************************************************************** +函数名称:DBModule_MySQL_TrySet +函数功能:设置用户信息函数 + 参数.一:pSt_AuthVer + In/Out:In + 类型:数据结构指针 + 可空:N + 意思:输入要更新的用户信息 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_TrySet(AUTHREG_TEMPVER* pSt_AuthVer) +{ + SQLPacket_IsErrorOccur = false; + + XCHAR tszSQLStatement[1024]; + memset(tszSQLStatement, '\0', sizeof(tszSQLStatement)); + + _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_TempVer` SET nVMode = '%d',nVTime = '%d',nLTime = '%d',CreateTime = '%s' WHERE tszVSerial = '%s'"), pSt_AuthVer->enVMode, pSt_AuthVer->nVTime, pSt_AuthVer->nLTime, pSt_AuthVer->tszVDate, pSt_AuthVer->tszVSerial); + //更新用户表 + if (!DataBase_MySQL_Execute(xhData, tszSQLStatement)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = DataBase_GetLastError(); + return false; + } + return true; +} +/******************************************************************** +函数名称:DBModule_MySQL_TryList +函数功能:请求试用期列表 + 参数.一:pppSt_AuthVer + In/Out:Out + 类型:三级指针 + 可空:N + 意思:输出获取到的列表 + 参数.二:pInt_ListCount + In/Out:Out + 类型:整数型指针 + 可空:N + 意思:输出列表个数 + 参数.三:nPosStart + In/Out:In + 类型:整数型 + 可空:N + 意思:输入查询起始编号 + 参数.四:nPosEnd + In/Out:In + 类型:整数型 + 可空:N + 意思:输入查询结束编号 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_TryList(AUTHREG_TEMPVER*** pppSt_AuthVer, int* pInt_ListCount, int nPosStart, int nPosEnd) +{ + SQLPacket_IsErrorOccur = false; + + XNETHANDLE xhTable = 0; + __int64u nColumn = 0; + __int64u nRow = 0; + XCHAR** ppszResult = NULL; + XCHAR tszSQLStr[1024]; //SQL语句 + + memset(tszSQLStr, '\0', 1024); + _xstprintf(tszSQLStr, _X("SELECT * FROM `Authorize_TempVer` LIMIT %d,%d"), nPosStart, nPosEnd - nPosStart); + + if (!DataBase_MySQL_ExecuteQuery(xhData, &xhTable, tszSQLStr, &nRow, &nColumn)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = DataBase_GetLastError(); + return false; + } + BaseLib_OperatorMemory_Malloc((XPPPMEM)pppSt_AuthVer, (int)nRow, sizeof(AUTHREG_TEMPVER)); + + //轮训所有内容 + for (int i = 0; i < nRow; i++) + { + ppszResult = DataBase_MySQL_GetResult(xhData, xhTable); + //XLONG* pInt_Length = DataBase_MySQL_GetLength(xhData, xhTable); + + int nFliedValue = 0; + //ID + (*pppSt_AuthVer)[i]->nID = _ttxoi(ppszResult[nFliedValue]); + nFliedValue++; + //是否启用 + _tcsxcpy((*pppSt_AuthVer)[i]->tszVSerial, ppszResult[nFliedValue]); + nFliedValue++; + //类型 + (*pppSt_AuthVer)[i]->enVMode = (ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE)_ttxoi(ppszResult[nFliedValue]); + nFliedValue++; + //时间 + (*pppSt_AuthVer)[i]->nVTime = _ttxoi(ppszResult[nFliedValue]); + nFliedValue++; + //时间 + (*pppSt_AuthVer)[i]->nLTime = _ttxoi(ppszResult[nFliedValue]); + nFliedValue++; + //注册时间 + _tcsxcpy((*pppSt_AuthVer)[i]->tszVDate, ppszResult[nFliedValue]); + nFliedValue++; + } + *pInt_ListCount = nRow; + DataBase_MySQL_FreeResult(xhData, xhTable); + return true; +} +/******************************************************************** +函数名称:DBModule_MySQL_BannedInsert +函数功能:黑名单列表插入 + 参数.一:pSt_Banned + In/Out:In + 类型:数据结构指针 + 可空:N + 意思:要操作的数据 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_BannedInsert(AUTHREG_BANNED* pSt_Banned) +{ + SQLPacket_IsErrorOccur = false; + + if (NULL == pSt_Banned) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_PARAMENT; + return false; + } + //存在直接返回 + if (DBModule_MySQL_BannedExist(pSt_Banned)) + { + return true; + } + XCHAR tszSQLStatement[1024]; + memset(tszSQLStatement, '\0', sizeof(tszSQLStatement)); + //处理的类型 + if (_tcsxlen(pSt_Banned->tszUserName) > 0) + { + _xstprintf(tszSQLStatement, _X("INSERT INTO `Authorize_BannedUser`(bEnable,tszUserName,tszLeftTime,tszCreateTime) VALUES(%d,'%s','%s',NOW())"), pSt_Banned->bEnable, pSt_Banned->tszUserName, pSt_Banned->tszLeftTime); + } + else + { + _xstprintf(tszSQLStatement, _X("INSERT INTO `Authorize_BannedAddr`(bEnable,tszIPAddr,tszLeftTime,tszCreateTime) VALUES(%d,'%s','%s',NOW())"), pSt_Banned->bEnable, pSt_Banned->tszIPAddr, pSt_Banned->tszLeftTime); + } + + if (!DataBase_MySQL_Execute(xhData, tszSQLStatement)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = DataBase_GetLastError(); + return false; + } + return true; +} +/******************************************************************** +函数名称:DBModule_MySQL_BannedDelete +函数功能:黑名单列表删除 + 参数.一:pSt_Banned + In/Out:In + 类型:数据结构指针 + 可空:N + 意思:要操作的数据 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_BannedDelete(AUTHREG_BANNED* pSt_Banned) +{ + SQLPacket_IsErrorOccur = false; + + if (NULL == pSt_Banned) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_PARAMENT; + return false; + } + XCHAR tszSQLStatement[1024]; + memset(tszSQLStatement, '\0', 1024); + //处理的类型 + if (_tcsxlen(pSt_Banned->tszUserName) > 0) + { + _xstprintf(tszSQLStatement, _X("DELETE FROM `Authorize_BannedUser` WHERE tszUserName = '%s'"), pSt_Banned->tszUserName); + } + else + { + _xstprintf(tszSQLStatement, _X("DELETE FROM `Authorize_BannedAddr` WHERE tszIPAddr = '%s'"), pSt_Banned->tszIPAddr); + } + + if (!DataBase_MySQL_Execute(xhData, tszSQLStatement)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = DataBase_GetLastError(); + return false; + } + return true; +} +/******************************************************************** +函数名称:DBModule_MySQL_BannedList +函数功能:黑名单列表查询 + 参数.一:pppSt_BannedUser + In/Out:Out + 类型:三级指针 + 可空:N + 意思:禁用的用户名列表 + 参数.二:pInt_UserCount + In/Out:Out + 类型:整数型指针 + 可空:N + 意思:输出用户禁用列表个数 + 参数.三:pppSt_BannedAddr + In/Out:Out + 类型:三级指针 + 可空:N + 意思:禁用的IP地址列表 + 参数.四:pInt_AddrCount + In/Out:Out + 类型:整数型指针 + 可空:N + 意思:输出地址禁用列表个数 + 参数.五:nPosStart + In/Out:In + 类型:整数型 + 可空:N + 意思:输入查找起始位置 + 参数.六:nPosEnd + In/Out:In + 类型:整数型 + 可空:N + 意思:输入查找结束位置 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_BannedList(AUTHREG_BANNED*** pppSt_BannedUser, int* pInt_UserCount, AUTHREG_BANNED*** pppSt_BannedAddr, int* pInt_AddrCount, int nPosStart, int nPosEnd) +{ + SQLPacket_IsErrorOccur = false; + //查询 + XNETHANDLE xhTable = 0; + __int64u nColumn = 0; + __int64u nRow = 0; + + XCHAR** ppszResult = NULL; + XCHAR tszSQLStatement[1024]; //SQL语句 + + memset(tszSQLStatement, '\0', 1024); + _xstprintf(tszSQLStatement, _X("SELECT * FROM `Authorize_BannedAddr` LIMIT %d,%d"), nPosStart, nPosEnd - nPosStart); + + if (!DataBase_MySQL_ExecuteQuery(xhData, &xhTable, tszSQLStatement, &nRow, &nColumn)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = DataBase_GetLastError(); + return false; + } + + list stl_ListAddr; + //轮训所有内容 + for (int i = 0; i < nRow; i++) + { + ppszResult = DataBase_MySQL_GetResult(xhData, xhTable); + //XLONG* pInt_Length = DataBase_MySQL_GetLength(xhData, xhTable); + int nFliedValue = 0; + + AUTHREG_BANNED st_Banned; + memset(&st_Banned, '\0', sizeof(AUTHREG_BANNED)); + //ID + st_Banned.nID = _ttxoll(ppszResult[nFliedValue]); + nFliedValue++; + //是否启用 + st_Banned.bEnable = _ttxoi(ppszResult[nFliedValue]); + nFliedValue++; + //地址 + _tcsxcpy(st_Banned.tszIPAddr, ppszResult[nFliedValue]); + nFliedValue++; + //过期时间 + _tcsxcpy(st_Banned.tszLeftTime, ppszResult[nFliedValue]); + nFliedValue++; + //注册时间 + _tcsxcpy(st_Banned.tszCreateTime, ppszResult[nFliedValue]); + nFliedValue++; + + stl_ListAddr.push_back(st_Banned); + } + DataBase_MySQL_FreeResult(xhData, xhTable); + //用户列表 + xhTable = 0; + nRow = 0; + nColumn = 0; + ppszResult = NULL; + memset(tszSQLStatement, '\0', 1024); + _xstprintf(tszSQLStatement, _X("SELECT * FROM `Authorize_BannedUser` LIMIT %d,%d"), nPosStart, nPosEnd - nPosStart); + + if (!DataBase_MySQL_ExecuteQuery(xhData, &xhTable, tszSQLStatement, &nRow, &nColumn)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = DataBase_GetLastError(); + return false; + } + + list stl_ListUser; + //轮训所有内容 + for (int i = 0; i < nRow; i++) + { + AUTHREG_BANNED st_Banned; + memset(&st_Banned, '\0', sizeof(AUTHREG_BANNED)); + + ppszResult = DataBase_MySQL_GetResult(xhData, xhTable); + //XLONG* pInt_Length = DataBase_MySQL_GetLength(xhData, xhTable); + int nFliedValue = 0; + + //ID + st_Banned.nID = _ttxoll(ppszResult[nFliedValue]); + nFliedValue++; + //是否启用 + st_Banned.bEnable = _ttxoi(ppszResult[nFliedValue]); + nFliedValue++; + //用户名 + _tcsxcpy(st_Banned.tszUserName, ppszResult[nFliedValue]); + nFliedValue++; + //过期时间 + _tcsxcpy(st_Banned.tszLeftTime, ppszResult[nFliedValue]); + nFliedValue++; + //注册时间 + _tcsxcpy(st_Banned.tszCreateTime, ppszResult[nFliedValue]); + nFliedValue++; + + stl_ListUser.push_back(st_Banned); + } + DataBase_MySQL_FreeResult(xhData, xhTable); + //导出 + *pInt_AddrCount = stl_ListAddr.size(); + *pInt_UserCount = stl_ListUser.size(); + BaseLib_OperatorMemory_Malloc((XPPPMEM)pppSt_BannedAddr, stl_ListAddr.size(), sizeof(AUTHREG_BANNED)); + BaseLib_OperatorMemory_Malloc((XPPPMEM)pppSt_BannedUser, stl_ListUser.size(), sizeof(AUTHREG_BANNED)); + + list::const_iterator stl_ListIterator = stl_ListAddr.begin(); + for (int i = 0; stl_ListIterator != stl_ListAddr.end(); stl_ListIterator++, i++) + { + (*pppSt_BannedAddr)[i]->nID = stl_ListIterator->nID; + (*pppSt_BannedAddr)[i]->bEnable = stl_ListIterator->bEnable; + _tcsxcpy((*pppSt_BannedAddr)[i]->tszIPAddr, stl_ListIterator->tszIPAddr); + _tcsxcpy((*pppSt_BannedAddr)[i]->tszLeftTime, stl_ListIterator->tszLeftTime); + _tcsxcpy((*pppSt_BannedAddr)[i]->tszCreateTime, stl_ListIterator->tszCreateTime); + } + stl_ListIterator = stl_ListUser.begin(); + for (int i = 0; stl_ListIterator != stl_ListUser.end(); stl_ListIterator++, i++) + { + (*pppSt_BannedUser)[i]->nID = stl_ListIterator->nID; + (*pppSt_BannedUser)[i]->bEnable = stl_ListIterator->bEnable; + _tcsxcpy((*pppSt_BannedUser)[i]->tszUserName, stl_ListIterator->tszUserName); + _tcsxcpy((*pppSt_BannedUser)[i]->tszLeftTime, stl_ListIterator->tszLeftTime); + _tcsxcpy((*pppSt_BannedUser)[i]->tszCreateTime, stl_ListIterator->tszCreateTime); + } + + stl_ListAddr.clear(); + stl_ListUser.clear(); + return true; +} +/******************************************************************** +函数名称:DBModule_MySQL_BannedExist +函数功能:名单是否存在黑名单列表 + 参数.一:pSt_Banned + In/Out:In + 类型:数据结构指针 + 可空:N + 意思:要操作的数据 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_BannedExist(AUTHREG_BANNED* pSt_Banned) +{ + SQLPacket_IsErrorOccur = false; + XCHAR** ppszResult = nullptr; + XLONG* pInt_Length = nullptr; + + //判断用户名是否存在 + if (_tcsxlen(pSt_Banned->tszUserName) > 0) + { + __int64u nRow = 0; + __int64u nColumn = 0; + XNETHANDLE xhTable = 0; + + XCHAR tszSQLStatement[1024]; + memset(tszSQLStatement, '\0', 1024); + + _xstprintf(tszSQLStatement, _X("SELECT * FROM Authorize_BannedUser WHERE tszUserName = '%s'"), pSt_Banned->tszUserName); + + + if (!DataBase_MySQL_ExecuteQuery(xhData, &xhTable, tszSQLStatement, &nRow, &nColumn)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = DataBase_GetLastError(); + return false; + } + + if (nRow <= 0) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_PARAMENT; + DataBase_MySQL_FreeResult(xhData, xhTable); + return false; + } + + ppszResult = DataBase_MySQL_GetResult(xhData, xhTable); + pInt_Length = DataBase_MySQL_GetLength(xhData, xhTable); + + //ID + int nFliedValue = 0; + if (NULL != ppszResult[nFliedValue]) { + pSt_Banned->nID = _ttxoll(ppszResult[nFliedValue]); + } + //是否启用 + nFliedValue++; + if (NULL != ppszResult[nFliedValue]) { + pSt_Banned->bEnable = _ttxoi(ppszResult[nFliedValue]); + } + + //地址 + nFliedValue++; + + //过期时间 + nFliedValue++; + if (NULL != ppszResult[nFliedValue]) { + _tcsxcpy(pSt_Banned->tszLeftTime, ppszResult[nFliedValue]); + } + + //注册时间 + nFliedValue++; + if (NULL != ppszResult[nFliedValue]) { + _tcsxcpy(pSt_Banned->tszCreateTime, ppszResult[nFliedValue]); + } + + DataBase_MySQL_FreeResult(xhData, xhTable); + } + + //判断IP地址是否存在 + if (_tcsxlen(pSt_Banned->tszIPAddr) > 0) + { + XNETHANDLE xhTable = 0; + __int64u nRow = 0; + __int64u nColumn = 0; + ppszResult = nullptr; + pInt_Length = nullptr; + + XCHAR tszSQLStatement[1024]; + memset(tszSQLStatement, '\0', 1024); + + _xstprintf(tszSQLStatement, _X("SELECT * FROM Authorize_BannedAddr WHERE tszIPAddr = '%s'"), pSt_Banned->tszIPAddr); + + if (!DataBase_MySQL_ExecuteQuery(xhData, &xhTable, tszSQLStatement, &nRow, &nColumn)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = DataBase_GetLastError(); + DataBase_MySQL_FreeResult(xhData, xhTable); + return false; + } + //printf("测试2 行:%d 列:%d\n", nRow, nColumn); + + if (nRow <= 0) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_PARAMENT; + DataBase_MySQL_FreeResult(xhData, xhTable); + return false; + } + ppszResult = DataBase_MySQL_GetResult(xhData, xhTable); + pInt_Length = DataBase_MySQL_GetLength(xhData, xhTable); + + //ID + int nFliedValue = 0; + if (NULL != ppszResult[nFliedValue]) + { + //printf("索引:%d ID:%s\n", nFliedValue, ppszResult[nFliedValue]); + pSt_Banned->nID = _ttxoll(ppszResult[nFliedValue]); + } + + //是否启用 + nFliedValue++; + if (NULL != ppszResult[nFliedValue]) + { + //printf("索引:%d 是否启用:%s\n", nFliedValue, ppszResult[nFliedValue]); + pSt_Banned->bEnable = _ttxoi(ppszResult[nFliedValue]); + } + + //地址 + nFliedValue++; + + //过期时间 + nFliedValue++; + if (NULL != ppszResult[nFliedValue]) + { + //printf("索引:%d 过期时间:%s\n", nFliedValue, ppszResult[nFliedValue]); + _tcsxcpy(pSt_Banned->tszLeftTime, ppszResult[nFliedValue]); + } + + + //注册时间 + nFliedValue++; + if (NULL != ppszResult[nFliedValue]) + { + //printf("索引:%d 注册时间:%s\n", nFliedValue, ppszResult[nFliedValue]); + _tcsxcpy(pSt_Banned->tszCreateTime, ppszResult[nFliedValue]); + } + + DataBase_MySQL_FreeResult(xhData, xhTable); + } + //处理是否被禁用 + if (!pSt_Banned->bEnable) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_NOTENABLE; + return false; + } + if (_tcsxlen(pSt_Banned->tszLeftTime) > 0) + { + __int64x nTimer = 0; + XCHAR tszStrTime[128]; + memset(tszStrTime, '\0', sizeof(tszStrTime)); + BaseLib_OperatorTime_TimeToStr(tszStrTime); + BaseLib_OperatorTimeSpan_GetForStr(pSt_Banned->tszLeftTime, tszStrTime, &nTimer, 3); + if (nTimer > 0) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_TIMELEFT; + return false; + } + } + return true; +} +/******************************************************************** +函数名称:DBModule_MySQL_BannedUPDate +函数功能:更新名单列表信息 + 参数.一:pSt_Banned + In/Out:In + 类型:数据结构指针 + 可空:N + 意思:要操作的数据 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_BannedUPDate(AUTHREG_BANNED* pSt_Banned) +{ + SQLPacket_IsErrorOccur = false; + + if (NULL == pSt_Banned) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_PARAMENT; + return false; + } + XCHAR tszSQLStatement[1024]; + memset(tszSQLStatement, '\0', sizeof(tszSQLStatement)); + //处理的类型 + if (_tcsxlen(pSt_Banned->tszUserName) > 0) + { + _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_BannedUser` SET bEnable = %d,tszLeftTime = '%s' WHERE tszUserName = '%s'"), pSt_Banned->bEnable, pSt_Banned->tszLeftTime, pSt_Banned->tszUserName); + } + else + { + _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_BannedAddr` SET bEnable = %d,tszLeftTime = '%s' WHERE tszIPAddr = '%s'"), pSt_Banned->bEnable, pSt_Banned->tszLeftTime, pSt_Banned->tszIPAddr); + } + //插入数据库 + if (!DataBase_MySQL_Execute(xhData, tszSQLStatement)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = DataBase_GetLastError(); + return false; + } + return true; +} +/******************************************************************** +函数名称:DBModule_MySQL_AnnouncementInsert +函数功能:公告插入 + 参数.一:pSt_Announcement + In/Out:In + 类型:数据结构指针 + 可空:N + 意思:输入要插入的信息 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_AnnouncementInsert(AUTHREG_ANNOUNCEMENT* pSt_Announcement) +{ + SQLPacket_IsErrorOccur = false; + + if (NULL == pSt_Announcement) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_PARAMENT; + return false; + } + XCHAR tszSQLStatement[8192]; + memset(tszSQLStatement, '\0', sizeof(tszSQLStatement)); + + _xstprintf(tszSQLStatement, _X("INSERT INTO `Authorize_Announcement`(tszContext,tszCreateTime) VALUES('%s',NOW())"), pSt_Announcement->tszContext); + + //插入数据库 + if (!DataBase_MySQL_Execute(xhData, tszSQLStatement)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = DataBase_GetLastError(); + return false; + } + return true; +} +/******************************************************************** +函数名称:DBModule_MySQL_AnnouncementDelete +函数功能:公告删除 + 参数.一:pSt_Announcement + In/Out:In + 类型:数据结构指针 + 可空:N + 意思:输入要删除的信息 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_AnnouncementDelete(AUTHREG_ANNOUNCEMENT* pSt_Announcement) +{ + SQLPacket_IsErrorOccur = false; + + if (NULL == pSt_Announcement) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_PARAMENT; + return false; + } + XCHAR tszSQLStatement[1024]; + memset(tszSQLStatement, '\0', sizeof(tszSQLStatement)); + + _xstprintf(tszSQLStatement, _X("DELETE FROM `Authorize_Announcement` WHERE ID = %lld"), pSt_Announcement->nID); + //插入数据库 + if (!DataBase_MySQL_Execute(xhData, tszSQLStatement)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = DataBase_GetLastError(); + return false; + } + return true; +} +/******************************************************************** +函数名称:DBModule_MySQL_AnnouncementList +函数功能:列举所有公告 + 参数.一:ppppSt_Announcement + In/Out:Out + 类型:三级指针 + 可空:N + 意思:输出列举数据 + 参数.二:pInt_ListCount + In/Out:Out + 类型:整数型指针 + 可空:N + 意思:导出数据个数 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_AnnouncementList(AUTHREG_ANNOUNCEMENT*** ppppSt_Announcement, int* pInt_ListCount) +{ + SQLPacket_IsErrorOccur = false; + XNETHANDLE xhTable = 0; + __int64u nRow = 0; + __int64u nColumn = 0; + XCHAR** ppszResult = NULL; + XCHAR tszSQLStatement[1024]; //SQL语句 + memset(tszSQLStatement, '\0', 1024); + _xstprintf(tszSQLStatement, _X("SELECT * FROM `Authorize_Announcement`")); + + if (!DataBase_MySQL_ExecuteQuery(xhData, &xhTable, tszSQLStatement, &nRow, &nColumn)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = DataBase_GetLastError(); + return false; + } + *pInt_ListCount = nRow; + if (NULL == ppppSt_Announcement) + { + return true; + } + BaseLib_OperatorMemory_Malloc((XPPPMEM)ppppSt_Announcement, (int)nRow, sizeof(AUTHREG_ANNOUNCEMENT)); + + //轮训所有内容 + for (int i = 0; i < nRow; i++) + { + ppszResult = DataBase_MySQL_GetResult(xhData, xhTable); + //XLONG* pInt_Length = DataBase_MySQL_GetLength(xhData, xhTable); + int nFliedValue = 0; + (*ppppSt_Announcement)[i]->nID = _ttxoll(ppszResult[nFliedValue]); + nFliedValue++; + _tcsxcpy((*ppppSt_Announcement)[i]->tszContext, ppszResult[nFliedValue]); + nFliedValue++; + _tcsxcpy((*ppppSt_Announcement)[i]->tszCreateTime, ppszResult[nFliedValue]); + nFliedValue++; + + } + DataBase_MySQL_FreeResult(xhData, xhTable); + return true; +} + +////////////////////////////////////////////////////////////////////////// +// 保护函数 +////////////////////////////////////////////////////////////////////////// +/******************************************************************** +函数名称:DBModule_MySQL_UserPayTime +函数功能:日期方式充值方式 + 参数.一:lpszUserName + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:充值的用户 + 参数.二:lpszUserTime + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:用户以前的超时时间 + 参数.三:lpszCardTime + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:充值卡时间 + 参数.四:en_AuthSerialType + In/Out:In + 类型:枚举型 + 可空:N + 意思:充值卡的充值类型 + 参数.五:en_AuthUserType + In/Out:In + 类型:枚举型 + 可空:N + 意思:用户表中以前的充值卡类型 +返回值 + 类型:逻辑型 + 意思:是否成功充值 +备注: +*********************************************************************/ +bool CDBModule_MySQL::DBModule_MySQL_UserPayTime(LPCXSTR lpszUserName, LPCXSTR lpszUserTime, LPCXSTR lpszCardTime, ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE en_AuthSerialType, ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE en_AuthUserType) +{ + SQLPacket_IsErrorOccur = false; + XCHAR tszSQLStatement[1024]; + memset(tszSQLStatement, '\0', sizeof(tszSQLStatement)); + //判断和以前的充值卡是否匹配。 + if (en_AuthSerialType != en_AuthUserType) + { + //如果不等于,需要重写 + if (ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_UNKNOW != en_AuthUserType) + { + //判断是否允许改写。 + if (!m_bChange) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_NOTMATCH; + return false; + } + } + //更新用户表的充值卡类型 + memset(tszSQLStatement, '\0', sizeof(tszSQLStatement)); + _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_User` SET CardSerialType = '%d' WHERE UserName = '%s'"), en_AuthSerialType, lpszUserName); + //执行用户表更新,因为序列卡类型被改变,所以需要更新。 + if (!DataBase_MySQL_Execute(xhData, tszSQLStatement)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_UPDATATYPE; + return false; + } + //处理卡类型 + switch (en_AuthSerialType) + { + case ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_SECOND: + { + //如果是分钟卡 + //如果当前的充值卡类型不匹配,那么他以前的充值内容全部都会被删除! + _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_User` SET LeftTime = '%d' WHERE UserName = '%s'"), _ttxoi(lpszCardTime), lpszUserName); //更新用户表的过期时间 + } + break; + case ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_DAY: + { + //如果是天数卡 + //更新用户表的过期时间 + _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_User` SET LeftTime = '%d' WHERE UserName = '%s'"), _ttxoi(lpszCardTime), lpszUserName); //更新用户表的过期时间 + } + break; + case ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_TIME: + { + //如果是次数卡 + //更新用户表的过期时间 + _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_User` SET LeftTime = '%d' WHERE UserName = '%s'"), _ttxoi(lpszCardTime), lpszUserName); + } + break; + case ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_CUSTOM: + { + XCHAR tszTime[128]; + XENGINE_LIBTIMER st_AuthTime; + ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE en_GeneraterSerialType; + + memset(tszTime, '\0', sizeof(tszTime)); + memset(&st_AuthTime, '\0', sizeof(XENGINE_LIBTIMER)); + //获取重置卡类型和时间 + if (!Authorize_Serial_GetType(lpszCardTime, &en_GeneraterSerialType, &st_AuthTime)) + { + return false; + } + _xstprintf(tszTime, _X("%04d-%02d-%02d %02d:%02d:%02d"), st_AuthTime.wYear, st_AuthTime.wMonth, st_AuthTime.wDay, st_AuthTime.wHour, st_AuthTime.wMinute, st_AuthTime.wSecond); + //更新用户表的过期时间 + _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_User` SET LeftTime = '%s' WHERE UserName = '%s'"), tszTime, lpszUserName); + } + break; + default: + break; + } + } + else + { + switch (en_AuthSerialType) + { + case ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_SECOND: + { + int nCardTime = _ttxoi(lpszCardTime); + nCardTime += _ttxoi(lpszUserTime); //我们把用户以前的时间也加上 + _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_User` SET LeftTime = '%d' WHERE UserName = '%s'"), nCardTime, lpszUserName); //更新用户表的过期时间 + } + break; + case ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_DAY: + { + int nCardTime = _ttxoi(lpszCardTime); + nCardTime += _ttxoi(lpszUserTime); //我们把用户以前的时间也加上 + //更新用户表的过期时间 + _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_User` SET LeftTime = '%d' WHERE UserName = '%s'"), nCardTime, lpszUserName); + } + break; + case ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_TIME: + { + //如果是次数卡 + int nCardTime = _ttxoi(lpszCardTime); + nCardTime += _ttxoi(lpszUserTime); //我们把用户以前的时间也加上 + _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_User` SET LeftTime = '%d' WHERE UserName = '%s'"), nCardTime, lpszUserName); //更新用户表的过期时间 + } + break; + case ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_CUSTOM: + { + //自定义卡,无法相加 + XCHAR tszTime[128]; + XENGINE_LIBTIMER st_AuthTime; + ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE en_GeneraterSerialType; + + memset(tszTime, '\0', sizeof(tszTime)); + memset(&st_AuthTime, '\0', sizeof(XENGINE_LIBTIMER)); + //获取重置卡类型和时间 + if (!Authorize_Serial_GetType(lpszCardTime, &en_GeneraterSerialType, &st_AuthTime)) + { + return false; + } + _xstprintf(tszTime, _X("%04d-%02d-%02d %02d:%02d:%02d"), st_AuthTime.wYear, st_AuthTime.wMonth, st_AuthTime.wDay, st_AuthTime.wHour, st_AuthTime.wMinute, st_AuthTime.wSecond); + //更新用户表的过期时间 + _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_User` SET LeftTime = '%s' WHERE UserName = '%s'"), tszTime, lpszUserName); + } + break; + default: + break; + } + } + //更新用户表的过期时间 + if (!DataBase_MySQL_Execute(xhData, tszSQLStatement)) + { + SQLPacket_IsErrorOccur = true; + SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_UPDATA; + return false; + } + return true; +} + diff --git a/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.h b/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.h new file mode 100644 index 0000000..eea88f3 --- /dev/null +++ b/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.h @@ -0,0 +1,61 @@ +#pragma once +/******************************************************************** +// Created: 2022/05/26 11:01:06 +// File Name: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_Database\Database_MySQL\Database_MySQL.h +// File Path: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_Database\Database_MySQL +// File Base: Database_MySQL +// File Ext: h +// Project: XEngine(网络通信引擎) +// Author: qyt +// Purpose: 数据库管理器 +// History: +*********************************************************************/ +////////////////////////////////////////////////////////////////////////// +// AuthReg_UserTable内容:ID 用户名 密码 注册日期 剩余时间 硬件码 注册文件密码 QQ 身份证 +// AuthReg_SerialTable内容:ID 使用者 序列号 使用时间 最大可允许时间 是否使用 +////////////////////////////////////////////////////////////////////////// +class CDBModule_MySQL +{ +public: + CDBModule_MySQL(); + ~CDBModule_MySQL(); +public: + bool DBModule_MySQL_Init(DATABASE_MYSQL_CONNECTINFO* pSt_DBConnector, bool bIsChange = true); //初始化 + bool DBModule_MySQL_Destroy(); //销毁 +public: + bool DBModule_MySQL_UserDelete(LPCXSTR lpszUserName); //删除用户 + bool DBModule_MySQL_UserRegister(AUTHREG_USERTABLE* pSt_UserInfo); //用户注册 + bool DBModule_MySQL_UserQuery(LPCXSTR lpszUserName, AUTHREG_USERTABLE* pSt_UserInfo = NULL); //用户查询 + bool DBModule_MySQL_UserPay(LPCXSTR lpszUserName, LPCXSTR lpszSerialName); //充值卡充值 + bool DBModule_MySQL_UserLeave(AUTHREG_PROTOCOL_TIME* pSt_TimeProtocol); //用户离开更新表 + bool DBModule_MySQL_UserSet(AUTHREG_USERTABLE* pSt_UserTable); //设置用户信息 + bool DBModule_MySQL_UserList(AUTHREG_USERTABLE*** pppSt_UserInfo, int* pInt_ListCount, int nPosStart, int nPosEnd); //获取用户列表 +public: + bool DBModule_MySQL_SerialInsert(LPCXSTR lpszSerialNumber); //插入序列卡 + bool DBModule_MySQL_SerialDelete(LPCXSTR lpszSerialNumber); //删除一个序列号 + bool DBModule_MySQL_SerialQuery(LPCXSTR lpszSerialNumber, LPAUTHREG_SERIALTABLE pSt_SerialTable = NULL); //按照卡号或者用户查询 + bool DBModule_MySQL_SerialQueryAll(AUTHREG_SERIALTABLE*** pppSt_SerialTable, int* pInt_ListCount, int nPosStart, int nPosEnd);//查询所有序列卡 + bool DBModule_MySQL_SerialPush(AUTHREG_SERIALTABLE* pSt_SerialTable);//插入一条指定的序列号信息到服务器 +public: + bool DBModule_MySQL_TryInsert(AUTHREG_TEMPVER* pSt_AuthVer); //网络使用模式插入一条数据 + bool DBModule_MySQL_TryQuery(AUTHREG_TEMPVER* pSt_AuthVer); //试用序列号查询函数 + bool DBModule_MySQL_TryDelete(LPCXSTR lpszSerial); //删除一条指定的试用数据 + bool DBModule_MySQL_TryClear(int nThanValue, ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE enVerMode = ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_UNKNOW); //清理函数,自动清理过期数据 + bool DBModule_MySQL_TrySet(AUTHREG_TEMPVER* pSt_AuthVer); //设置用户信息函数 + bool DBModule_MySQL_TryList(AUTHREG_TEMPVER*** pppSt_AuthVer, int* pInt_ListCount, int nPosStart = 0, int nPosEnd = 1000); //请求试用期列表 +public: + bool DBModule_MySQL_BannedInsert(AUTHREG_BANNED* pSt_Banned); //黑名单列表插入 + bool DBModule_MySQL_BannedDelete(AUTHREG_BANNED* pSt_Banned); //黑名单列表删除 + bool DBModule_MySQL_BannedList(AUTHREG_BANNED*** pppSt_BannedUser, int* pInt_UserCount, AUTHREG_BANNED*** pppSt_BannedAddr, int* pInt_AddrCount, int nPosStart, int nPosEnd); //黑名单列表查询 + bool DBModule_MySQL_BannedExist(AUTHREG_BANNED* pSt_Banned); //名单是否存在黑名单列表 + bool DBModule_MySQL_BannedUPDate(AUTHREG_BANNED* pSt_Banned); //更新名单列表信息 +public: + bool DBModule_MySQL_AnnouncementInsert(AUTHREG_ANNOUNCEMENT* pSt_Announcement); //公告插入 + bool DBModule_MySQL_AnnouncementDelete(AUTHREG_ANNOUNCEMENT* pSt_Announcement); //公告删除 + bool DBModule_MySQL_AnnouncementList(AUTHREG_ANNOUNCEMENT*** ppppSt_Announcement, int* pInt_ListCount); //列举所有公告 +protected: + bool DBModule_MySQL_UserPayTime(LPCXSTR lpszUserName, LPCXSTR lpszUserTime, LPCXSTR lpszCardTime, ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE en_AuthSerialType, ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE en_AuthUserType); //日期方式充值方式 +private: + bool m_bChange; + XNETHANDLE xhData; //数据库句柄 +}; diff --git a/XEngine_Source/AuthorizeModule_Database/Database_SQLite/Database_SQLite.cpp b/XEngine_Source/AuthorizeModule_Database/DBModule_SQLite/DBModule_SQLite.cpp similarity index 94% rename from XEngine_Source/AuthorizeModule_Database/Database_SQLite/Database_SQLite.cpp rename to XEngine_Source/AuthorizeModule_Database/DBModule_SQLite/DBModule_SQLite.cpp index e5c42f0..08c33ef 100644 --- a/XEngine_Source/AuthorizeModule_Database/Database_SQLite/Database_SQLite.cpp +++ b/XEngine_Source/AuthorizeModule_Database/DBModule_SQLite/DBModule_SQLite.cpp @@ -1,5 +1,5 @@ #include "pch.h" -#include "Database_SQLite.h" +#include "DBModule_SQLite.h" /******************************************************************** // Created: 2022/05/26 11:01:13 // File Name: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_Database\Database_SQLite\Database_SQLite.cpp @@ -11,11 +11,11 @@ // Purpose: 数据库管理器 // History: *********************************************************************/ -CDatabase_SQLite::CDatabase_SQLite() +CDBModule_SQLite::CDBModule_SQLite() { m_bChange = false; } -CDatabase_SQLite::~CDatabase_SQLite() +CDBModule_SQLite::~CDBModule_SQLite() { } @@ -23,7 +23,7 @@ CDatabase_SQLite::~CDatabase_SQLite() // 公有函数 ////////////////////////////////////////////////////////////////////////// /******************************************************************** -函数名称:Database_SQLite_Init +函数名称:DBModule_SQLite_Init 函数功能:初始化数据库服务 参数.一:lpszSQLFile In/Out:In @@ -40,7 +40,7 @@ CDatabase_SQLite::~CDatabase_SQLite() 意思:是否成功 备注:先初始化数据库服务,在初始化网络服务,才可以使用本验证服务器! *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_Init(LPCXSTR lpszSQLFile, bool bIsChange /* = true */) +bool CDBModule_SQLite::DBModule_SQLite_Init(LPCXSTR lpszSQLFile, bool bIsChange /* = true */) { SQLPacket_IsErrorOccur = false; m_bChange = bIsChange; @@ -54,14 +54,14 @@ bool CDatabase_SQLite::Database_SQLite_Init(LPCXSTR lpszSQLFile, bool bIsChange return true; } /******************************************************************** -函数名称:Database_SQLite_Destroy +函数名称:DBModule_SQLite_Destroy 函数功能:销毁数据库服务 返回值 类型:逻辑型 意思:是否销毁成功 备注: *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_Destroy() +bool CDBModule_SQLite::DBModule_SQLite_Destroy() { SQLPacket_IsErrorOccur = false; @@ -74,7 +74,7 @@ bool CDatabase_SQLite::Database_SQLite_Destroy() return true; } /******************************************************************** -函数名称:Database_SQLite_UserDelete +函数名称:DBModule_SQLite_UserDelete 函数功能:删除一个用户从数据库中 参数.一:lpszUserName In/Out:In @@ -86,7 +86,7 @@ bool CDatabase_SQLite::Database_SQLite_Destroy() 意思:是否删除成功 备注: *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_UserDelete(LPCXSTR lpszUserName) +bool CDBModule_SQLite::DBModule_SQLite_UserDelete(LPCXSTR lpszUserName) { SQLPacket_IsErrorOccur = false; XCHAR tszSQLStatement[1024]; //SQL语句 @@ -102,7 +102,7 @@ bool CDatabase_SQLite::Database_SQLite_UserDelete(LPCXSTR lpszUserName) return true; } /******************************************************************** -函数名称:Database_SQLite_UserRegister +函数名称:DBModule_SQLite_UserRegister 函数功能:用户注册处理数据库语句函数 参数.一:pSt_UserInfo In/Out:In @@ -114,13 +114,13 @@ bool CDatabase_SQLite::Database_SQLite_UserDelete(LPCXSTR lpszUserName) 意思:是否插入成功 备注: *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_UserRegister(AUTHREG_USERTABLE* pSt_UserInfo) +bool CDBModule_SQLite::DBModule_SQLite_UserRegister(AUTHREG_USERTABLE* pSt_UserInfo) { SQLPacket_IsErrorOccur = false; XCHAR tszSQLStatement[1024]; //SQL语句 memset(tszSQLStatement, '\0', 1024); - if (Database_SQLite_UserQuery(pSt_UserInfo->st_UserInfo.tszUserName)) + if (DBModule_SQLite_UserQuery(pSt_UserInfo->st_UserInfo.tszUserName)) { SQLPacket_IsErrorOccur = true; SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_EXIST; @@ -136,7 +136,7 @@ bool CDatabase_SQLite::Database_SQLite_UserRegister(AUTHREG_USERTABLE* pSt_UserI return true; } /******************************************************************** -函数名称:Database_SQLite_UserQuery +函数名称:DBModule_SQLite_UserQuery 函数功能:查询用户相对应的值 参数.一:lpszUserName In/Out:In @@ -153,7 +153,7 @@ bool CDatabase_SQLite::Database_SQLite_UserRegister(AUTHREG_USERTABLE* pSt_UserI 意思:是否查询成功 备注: *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_UserQuery(LPCXSTR lpszUserName, AUTHREG_USERTABLE* pSt_UserInfo /* = NULL */) +bool CDBModule_SQLite::DBModule_SQLite_UserQuery(LPCXSTR lpszUserName, AUTHREG_USERTABLE* pSt_UserInfo /* = NULL */) { SQLPacket_IsErrorOccur = false; XCHAR tszSQLStatement[1024]; //SQL语句 @@ -223,7 +223,7 @@ bool CDatabase_SQLite::Database_SQLite_UserQuery(LPCXSTR lpszUserName, AUTHREG_U return true; } /******************************************************************** -函数名称:Database_SQLite_UserPay +函数名称:DBModule_SQLite_UserPay 函数功能:用户充值函数 参数.一:lpszUserName In/Out:In @@ -240,7 +240,7 @@ bool CDatabase_SQLite::Database_SQLite_UserQuery(LPCXSTR lpszUserName, AUTHREG_U 意思:是否成功充值 备注: *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_UserPay(LPCXSTR lpszUserName, LPCXSTR lpszSerialName) +bool CDBModule_SQLite::DBModule_SQLite_UserPay(LPCXSTR lpszUserName, LPCXSTR lpszSerialName) { SQLPacket_IsErrorOccur = false; @@ -259,7 +259,7 @@ bool CDatabase_SQLite::Database_SQLite_UserPay(LPCXSTR lpszUserName, LPCXSTR lps return false; } //查询充值卡是否存在 - if (!Database_SQLite_SerialQuery(lpszSerialName, &st_SerialTable)) + if (!DBModule_SQLite_SerialQuery(lpszSerialName, &st_SerialTable)) { return false; } @@ -271,7 +271,7 @@ bool CDatabase_SQLite::Database_SQLite_UserPay(LPCXSTR lpszUserName, LPCXSTR lps return false; } //查询用户信息 - if (!Database_SQLite_UserQuery(lpszUserName, &st_UserTable)) + if (!DBModule_SQLite_UserQuery(lpszUserName, &st_UserTable)) { return false; } @@ -279,25 +279,25 @@ bool CDatabase_SQLite::Database_SQLite_UserPay(LPCXSTR lpszUserName, LPCXSTR lps switch (st_SerialTable.enSerialType) { case ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_SECOND: - if (!Database_SQLite_UserPayTime(lpszUserName, st_UserTable.tszLeftTime, st_SerialTable.tszMaxTime, st_SerialTable.enSerialType, st_UserTable.enSerialType)) + if (!DBModule_SQLite_UserPayTime(lpszUserName, st_UserTable.tszLeftTime, st_SerialTable.tszMaxTime, st_SerialTable.enSerialType, st_UserTable.enSerialType)) { return false; } break; case ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_DAY: - if (!Database_SQLite_UserPayTime(lpszUserName, st_UserTable.tszLeftTime, st_SerialTable.tszMaxTime, st_SerialTable.enSerialType, st_UserTable.enSerialType)) + if (!DBModule_SQLite_UserPayTime(lpszUserName, st_UserTable.tszLeftTime, st_SerialTable.tszMaxTime, st_SerialTable.enSerialType, st_UserTable.enSerialType)) { return false; } break; case ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_TIME: - if (!Database_SQLite_UserPayTime(lpszUserName, st_UserTable.tszLeftTime, st_SerialTable.tszMaxTime, st_SerialTable.enSerialType, st_UserTable.enSerialType)) + if (!DBModule_SQLite_UserPayTime(lpszUserName, st_UserTable.tszLeftTime, st_SerialTable.tszMaxTime, st_SerialTable.enSerialType, st_UserTable.enSerialType)) { return false; } break; case ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_CUSTOM: - if (!Database_SQLite_UserPayTime(lpszUserName, st_UserTable.tszLeftTime, st_SerialTable.tszMaxTime, st_SerialTable.enSerialType, st_UserTable.enSerialType)) + if (!DBModule_SQLite_UserPayTime(lpszUserName, st_UserTable.tszLeftTime, st_SerialTable.tszMaxTime, st_SerialTable.enSerialType, st_UserTable.enSerialType)) { return false; } @@ -317,7 +317,7 @@ bool CDatabase_SQLite::Database_SQLite_UserPay(LPCXSTR lpszUserName, LPCXSTR lps return true; } /******************************************************************** -函数名称:Database_SQLite_UserLeave +函数名称:DBModule_SQLite_UserLeave 函数功能:用户离开处理事件 参数.一:pSt_TimeProtocol In/Out:In @@ -329,7 +329,7 @@ bool CDatabase_SQLite::Database_SQLite_UserPay(LPCXSTR lpszUserName, LPCXSTR lps 意思:是否处理成功 备注: *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_UserLeave(AUTHREG_PROTOCOL_TIME* pSt_TimeProtocol) +bool CDBModule_SQLite::DBModule_SQLite_UserLeave(AUTHREG_PROTOCOL_TIME* pSt_TimeProtocol) { SQLPacket_IsErrorOccur = false; @@ -374,7 +374,7 @@ bool CDatabase_SQLite::Database_SQLite_UserLeave(AUTHREG_PROTOCOL_TIME* pSt_Time return true; } /******************************************************************** -函数名称:Database_SQLite_UserSet +函数名称:DBModule_SQLite_UserSet 函数功能:设置用户信息 参数.一:pSt_UserTable In/Out:In @@ -386,7 +386,7 @@ bool CDatabase_SQLite::Database_SQLite_UserLeave(AUTHREG_PROTOCOL_TIME* pSt_Time 意思:是否成功 备注: *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_UserSet(AUTHREG_USERTABLE* pSt_UserTable) +bool CDBModule_SQLite::DBModule_SQLite_UserSet(AUTHREG_USERTABLE* pSt_UserTable) { SQLPacket_IsErrorOccur = false; @@ -404,7 +404,7 @@ bool CDatabase_SQLite::Database_SQLite_UserSet(AUTHREG_USERTABLE* pSt_UserTable) return true; } /******************************************************************** -函数名称:Database_SQLite_UserList +函数名称:DBModule_SQLite_UserList 函数功能:获取用户列表 参数.一:pppSt_UserInfo In/Out:Out @@ -431,7 +431,7 @@ bool CDatabase_SQLite::Database_SQLite_UserSet(AUTHREG_USERTABLE* pSt_UserTable) 意思:是否成功 备注: *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_UserList(AUTHREG_USERTABLE*** pppSt_UserInfo, int* pInt_ListCount, int nPosStart, int nPosEnd) +bool CDBModule_SQLite::DBModule_SQLite_UserList(AUTHREG_USERTABLE*** pppSt_UserInfo, int* pInt_ListCount, int nPosStart, int nPosEnd) { SQLPacket_IsErrorOccur = false; @@ -502,7 +502,7 @@ bool CDatabase_SQLite::Database_SQLite_UserList(AUTHREG_USERTABLE*** pppSt_UserI return true; } /******************************************************************** -函数名称:Database_SQLite_SerialInsert +函数名称:DBModule_SQLite_SerialInsert 函数功能:插入一个序列号到数据库 参数.一:lpszSerialNumber In/Out:In @@ -514,14 +514,14 @@ bool CDatabase_SQLite::Database_SQLite_UserList(AUTHREG_USERTABLE*** pppSt_UserI 意思:是否插入成功 备注: *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_SerialInsert(LPCXSTR lpszSerialNumber) +bool CDBModule_SQLite::DBModule_SQLite_SerialInsert(LPCXSTR lpszSerialNumber) { SQLPacket_IsErrorOccur = false; XCHAR tszSQLStatement[1024]; //SQL语句 memset(tszSQLStatement, '\0', 1024); - if (Database_SQLite_SerialQuery(lpszSerialNumber)) + if (DBModule_SQLite_SerialQuery(lpszSerialNumber)) { SQLPacket_IsErrorOccur = true; SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_EXIST; @@ -568,7 +568,7 @@ bool CDatabase_SQLite::Database_SQLite_SerialInsert(LPCXSTR lpszSerialNumber) return true; } /******************************************************************** -函数名称:Database_SQLite_SerialDelete +函数名称:DBModule_SQLite_SerialDelete 函数功能:从数据库删除指定序列号 参数.一:lpszSerialNumber In/Out:In @@ -580,7 +580,7 @@ bool CDatabase_SQLite::Database_SQLite_SerialInsert(LPCXSTR lpszSerialNumber) 意思:是否删除成功 备注: *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_SerialDelete(LPCXSTR lpszSerialNumber) +bool CDBModule_SQLite::DBModule_SQLite_SerialDelete(LPCXSTR lpszSerialNumber) { SQLPacket_IsErrorOccur = false; @@ -597,7 +597,7 @@ bool CDatabase_SQLite::Database_SQLite_SerialDelete(LPCXSTR lpszSerialNumber) return true; } /******************************************************************** -函数名称:Database_SQLite_SerialQuery +函数名称:DBModule_SQLite_SerialQuery 函数功能:查询一个指定的序列号信息 参数.一:lpszSerialNumber In/Out:In @@ -614,7 +614,7 @@ bool CDatabase_SQLite::Database_SQLite_SerialDelete(LPCXSTR lpszSerialNumber) 意思:是否查询成功,如果第二个参数为NULL,那么将只返回是否有这个序列号 备注: *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_SerialQuery(LPCXSTR lpszSerialNumber, LPAUTHREG_SERIALTABLE pSt_SerialTable /* = NULL */) +bool CDBModule_SQLite::DBModule_SQLite_SerialQuery(LPCXSTR lpszSerialNumber, LPAUTHREG_SERIALTABLE pSt_SerialTable /* = NULL */) { SQLPacket_IsErrorOccur = false; XCHAR tszSQLStatement[1024]; //SQL语句 @@ -665,7 +665,7 @@ bool CDatabase_SQLite::Database_SQLite_SerialQuery(LPCXSTR lpszSerialNumber, LPA return true; } /******************************************************************** -函数名称:Database_SQLite_SerialQueryAll +函数名称:DBModule_SQLite_SerialQueryAll 函数功能:查询序列卡表中的所有序列号 参数.一:pppSt_SerialTable In/Out:Out @@ -692,7 +692,7 @@ bool CDatabase_SQLite::Database_SQLite_SerialQuery(LPCXSTR lpszSerialNumber, LPA 意思:是否查询成功 备注:参数一需要调用基础库的释放内存函数进行内存释放 *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_SerialQueryAll(AUTHREG_SERIALTABLE*** pppSt_SerialTable, int* pInt_ListCount, int nPosStart, int nPosEnd) +bool CDBModule_SQLite::DBModule_SQLite_SerialQueryAll(AUTHREG_SERIALTABLE*** pppSt_SerialTable, int* pInt_ListCount, int nPosStart, int nPosEnd) { SQLPacket_IsErrorOccur = false; @@ -747,7 +747,7 @@ bool CDatabase_SQLite::Database_SQLite_SerialQueryAll(AUTHREG_SERIALTABLE*** ppp return true; } /******************************************************************** -函数名称:Database_SQLite_SerialPush +函数名称:DBModule_SQLite_SerialPush 函数功能:插入一条指定的序列号信息到服务器 参数.一:pSt_SerialTable In/Out:In @@ -759,14 +759,14 @@ bool CDatabase_SQLite::Database_SQLite_SerialQueryAll(AUTHREG_SERIALTABLE*** ppp 意思:是否成功 备注: *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_SerialPush(AUTHREG_SERIALTABLE* pSt_SerialTable) +bool CDBModule_SQLite::DBModule_SQLite_SerialPush(AUTHREG_SERIALTABLE* pSt_SerialTable) { SQLPacket_IsErrorOccur = false; XCHAR tszSQLStatement[1024]; //SQL语句 memset(tszSQLStatement, '\0', 1024); - if (Database_SQLite_SerialQuery(pSt_SerialTable->tszSerialNumber)) + if (DBModule_SQLite_SerialQuery(pSt_SerialTable->tszSerialNumber)) { SQLPacket_IsErrorOccur = true; SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_EXIST; @@ -783,7 +783,7 @@ bool CDatabase_SQLite::Database_SQLite_SerialPush(AUTHREG_SERIALTABLE* pSt_Seria return true; } /******************************************************************** -函数名称:Database_SQLite_TryInsert +函数名称:DBModule_SQLite_TryInsert 函数功能:网络使用模式插入一条数据 参数.一:pSt_AuthVer In/Out:In @@ -795,7 +795,7 @@ bool CDatabase_SQLite::Database_SQLite_SerialPush(AUTHREG_SERIALTABLE* pSt_Seria 意思:是否成功 备注: *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_TryInsert(AUTHREG_TEMPVER* pSt_AuthVer) +bool CDBModule_SQLite::DBModule_SQLite_TryInsert(AUTHREG_TEMPVER* pSt_AuthVer) { SQLPacket_IsErrorOccur = false; @@ -813,7 +813,7 @@ bool CDatabase_SQLite::Database_SQLite_TryInsert(AUTHREG_TEMPVER* pSt_AuthVer) //验证是否存在 _tcsxcpy(st_AuthVer.tszVSerial, pSt_AuthVer->tszVSerial); - if (Database_SQLite_TryQuery(&st_AuthVer)) + if (DBModule_SQLite_TryQuery(&st_AuthVer)) { SQLPacket_IsErrorOccur = true; SQLPacket_dwErrorCode = ERROR_AUTHORIZE_MODULE_DATABASE_EXIST; @@ -830,7 +830,7 @@ bool CDatabase_SQLite::Database_SQLite_TryInsert(AUTHREG_TEMPVER* pSt_AuthVer) return true; } /******************************************************************** -函数名称:Database_SQLite_TryQuery +函数名称:DBModule_SQLite_TryQuery 函数功能:试用序列号查询函数 参数.一:pSt_AuthVer In/Out:In/Out @@ -842,7 +842,7 @@ bool CDatabase_SQLite::Database_SQLite_TryInsert(AUTHREG_TEMPVER* pSt_AuthVer) 意思:是否成功 备注: *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_TryQuery(AUTHREG_TEMPVER* pSt_AuthVer) +bool CDBModule_SQLite::DBModule_SQLite_TryQuery(AUTHREG_TEMPVER* pSt_AuthVer) { SQLPacket_IsErrorOccur = false; @@ -892,7 +892,7 @@ bool CDatabase_SQLite::Database_SQLite_TryQuery(AUTHREG_TEMPVER* pSt_AuthVer) return true; } /******************************************************************** -函数名称:Database_SQLite_TryDelete +函数名称:DBModule_SQLite_TryDelete 函数功能:删除一条指定的试用数据 参数.一:lpszSerial In/Out:In @@ -904,7 +904,7 @@ bool CDatabase_SQLite::Database_SQLite_TryQuery(AUTHREG_TEMPVER* pSt_AuthVer) 意思:是否成功 备注: *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_TryDelete(LPCXSTR lpszSerial) +bool CDBModule_SQLite::DBModule_SQLite_TryDelete(LPCXSTR lpszSerial) { SQLPacket_IsErrorOccur = false; @@ -928,7 +928,7 @@ bool CDatabase_SQLite::Database_SQLite_TryDelete(LPCXSTR lpszSerial) return true; } /******************************************************************** -函数名称:Database_SQLite_TryClear +函数名称:DBModule_SQLite_TryClear 函数功能:清理函数,自动清理过期数据 参数.一:nThanValue In/Out:In @@ -945,7 +945,7 @@ bool CDatabase_SQLite::Database_SQLite_TryDelete(LPCXSTR lpszSerial) 意思:是否成功 备注: *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_TryClear(int nThanValue, ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE enVMode /* = ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_UNKNOW */) +bool CDBModule_SQLite::DBModule_SQLite_TryClear(int nThanValue, ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE enVMode /* = ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_UNKNOW */) { SQLPacket_IsErrorOccur = false; @@ -1030,7 +1030,7 @@ bool CDatabase_SQLite::Database_SQLite_TryClear(int nThanValue, ENUM_HELPCOMPONE return true; } /******************************************************************** -函数名称:Database_SQLite_TrySet +函数名称:DBModule_SQLite_TrySet 函数功能:设置用户信息函数 参数.一:pSt_AuthVer In/Out:In @@ -1042,7 +1042,7 @@ bool CDatabase_SQLite::Database_SQLite_TryClear(int nThanValue, ENUM_HELPCOMPONE 意思:是否成功 备注: *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_TrySet(AUTHREG_TEMPVER* pSt_AuthVer) +bool CDBModule_SQLite::DBModule_SQLite_TrySet(AUTHREG_TEMPVER* pSt_AuthVer) { SQLPacket_IsErrorOccur = false; @@ -1060,7 +1060,7 @@ bool CDatabase_SQLite::Database_SQLite_TrySet(AUTHREG_TEMPVER* pSt_AuthVer) return true; } /******************************************************************** -函数名称:Database_SQLite_TryList +函数名称:DBModule_SQLite_TryList 函数功能:请求试用期列表 参数.一:pppSt_AuthVer In/Out:Out @@ -1087,7 +1087,7 @@ bool CDatabase_SQLite::Database_SQLite_TrySet(AUTHREG_TEMPVER* pSt_AuthVer) 意思:是否成功 备注: *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_TryList(AUTHREG_TEMPVER*** pppSt_AuthVer, int* pInt_ListCount, int nPosStart, int nPosEnd) +bool CDBModule_SQLite::DBModule_SQLite_TryList(AUTHREG_TEMPVER*** pppSt_AuthVer, int* pInt_ListCount, int nPosStart, int nPosEnd) { SQLPacket_IsErrorOccur = false; @@ -1134,7 +1134,7 @@ bool CDatabase_SQLite::Database_SQLite_TryList(AUTHREG_TEMPVER*** pppSt_AuthVer, return true; } /******************************************************************** -函数名称:Database_SQLite_BannedInsert +函数名称:DBModule_SQLite_BannedInsert 函数功能:黑名单列表插入 参数.一:pSt_Banned In/Out:In @@ -1146,7 +1146,7 @@ bool CDatabase_SQLite::Database_SQLite_TryList(AUTHREG_TEMPVER*** pppSt_AuthVer, 意思:是否成功 备注: *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_BannedInsert(AUTHREG_BANNED* pSt_Banned) +bool CDBModule_SQLite::DBModule_SQLite_BannedInsert(AUTHREG_BANNED* pSt_Banned) { SQLPacket_IsErrorOccur = false; @@ -1157,7 +1157,7 @@ bool CDatabase_SQLite::Database_SQLite_BannedInsert(AUTHREG_BANNED* pSt_Banned) return false; } //存在直接返回 - if (Database_SQLite_BannedExist(pSt_Banned)) + if (DBModule_SQLite_BannedExist(pSt_Banned)) { return true; } @@ -1182,7 +1182,7 @@ bool CDatabase_SQLite::Database_SQLite_BannedInsert(AUTHREG_BANNED* pSt_Banned) return true; } /******************************************************************** -函数名称:Database_SQLite_BannedDelete +函数名称:DBModule_SQLite_BannedDelete 函数功能:黑名单列表删除 参数.一:pSt_Banned In/Out:In @@ -1194,7 +1194,7 @@ bool CDatabase_SQLite::Database_SQLite_BannedInsert(AUTHREG_BANNED* pSt_Banned) 意思:是否成功 备注: *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_BannedDelete(AUTHREG_BANNED* pSt_Banned) +bool CDBModule_SQLite::DBModule_SQLite_BannedDelete(AUTHREG_BANNED* pSt_Banned) { SQLPacket_IsErrorOccur = false; @@ -1225,7 +1225,7 @@ bool CDatabase_SQLite::Database_SQLite_BannedDelete(AUTHREG_BANNED* pSt_Banned) return true; } /******************************************************************** -函数名称:Database_SQLite_BannedList +函数名称:DBModule_SQLite_BannedList 函数功能:黑名单列表查询 参数.一:pppSt_BannedUser In/Out:Out @@ -1262,7 +1262,7 @@ bool CDatabase_SQLite::Database_SQLite_BannedDelete(AUTHREG_BANNED* pSt_Banned) 意思:是否成功 备注: *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_BannedList(AUTHREG_BANNED*** pppSt_BannedUser, int* pInt_UserCount, AUTHREG_BANNED*** pppSt_BannedAddr, int* pInt_AddrCount, int nPosStart, int nPosEnd) +bool CDBModule_SQLite::DBModule_SQLite_BannedList(AUTHREG_BANNED*** pppSt_BannedUser, int* pInt_UserCount, AUTHREG_BANNED*** pppSt_BannedAddr, int* pInt_AddrCount, int nPosStart, int nPosEnd) { SQLPacket_IsErrorOccur = false; @@ -1374,7 +1374,7 @@ bool CDatabase_SQLite::Database_SQLite_BannedList(AUTHREG_BANNED*** pppSt_Banned return true; } /******************************************************************** -函数名称:Database_SQLite_BannedExist +函数名称:DBModule_SQLite_BannedExist 函数功能:名单是否存在黑名单列表 参数.一:pSt_Banned In/Out:In @@ -1386,7 +1386,7 @@ bool CDatabase_SQLite::Database_SQLite_BannedList(AUTHREG_BANNED*** pppSt_Banned 意思:是否成功 备注: *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_BannedExist(AUTHREG_BANNED* pSt_Banned) +bool CDBModule_SQLite::DBModule_SQLite_BannedExist(AUTHREG_BANNED* pSt_Banned) { SQLPacket_IsErrorOccur = false; //判断用域名是否存在 @@ -1493,7 +1493,7 @@ bool CDatabase_SQLite::Database_SQLite_BannedExist(AUTHREG_BANNED* pSt_Banned) return true; } /******************************************************************** -函数名称:Database_SQLite_BannedUPDate +函数名称:DBModule_SQLite_BannedUPDate 函数功能:更新名单列表信息 参数.一:pSt_Banned In/Out:In @@ -1505,7 +1505,7 @@ bool CDatabase_SQLite::Database_SQLite_BannedExist(AUTHREG_BANNED* pSt_Banned) 意思:是否成功 备注: *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_BannedUPDate(AUTHREG_BANNED* pSt_Banned) +bool CDBModule_SQLite::DBModule_SQLite_BannedUPDate(AUTHREG_BANNED* pSt_Banned) { SQLPacket_IsErrorOccur = false; @@ -1536,7 +1536,7 @@ bool CDatabase_SQLite::Database_SQLite_BannedUPDate(AUTHREG_BANNED* pSt_Banned) return true; } /******************************************************************** -函数名称:Database_SQLite_AnnouncementInsert +函数名称:DBModule_SQLite_AnnouncementInsert 函数功能:公告插入 参数.一:pSt_Announcement In/Out:In @@ -1548,7 +1548,7 @@ bool CDatabase_SQLite::Database_SQLite_BannedUPDate(AUTHREG_BANNED* pSt_Banned) 意思:是否成功 备注: *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_AnnouncementInsert(AUTHREG_ANNOUNCEMENT* pSt_Announcement) +bool CDBModule_SQLite::DBModule_SQLite_AnnouncementInsert(AUTHREG_ANNOUNCEMENT* pSt_Announcement) { SQLPacket_IsErrorOccur = false; @@ -1572,7 +1572,7 @@ bool CDatabase_SQLite::Database_SQLite_AnnouncementInsert(AUTHREG_ANNOUNCEMENT* return true; } /******************************************************************** -函数名称:Database_SQLite_AnnouncementDelete +函数名称:DBModule_SQLite_AnnouncementDelete 函数功能:公告删除 参数.一:pSt_Announcement In/Out:In @@ -1584,7 +1584,7 @@ bool CDatabase_SQLite::Database_SQLite_AnnouncementInsert(AUTHREG_ANNOUNCEMENT* 意思:是否成功 备注: *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_AnnouncementDelete(AUTHREG_ANNOUNCEMENT* pSt_Announcement) +bool CDBModule_SQLite::DBModule_SQLite_AnnouncementDelete(AUTHREG_ANNOUNCEMENT* pSt_Announcement) { SQLPacket_IsErrorOccur = false; @@ -1608,7 +1608,7 @@ bool CDatabase_SQLite::Database_SQLite_AnnouncementDelete(AUTHREG_ANNOUNCEMENT* return true; } /******************************************************************** -函数名称:Database_SQLite_AnnouncementList +函数名称:DBModule_SQLite_AnnouncementList 函数功能:列举所有公告 参数.一:ppppSt_Announcement In/Out:Out @@ -1625,7 +1625,7 @@ bool CDatabase_SQLite::Database_SQLite_AnnouncementDelete(AUTHREG_ANNOUNCEMENT* 意思:是否成功 备注: *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_AnnouncementList(AUTHREG_ANNOUNCEMENT*** ppppSt_Announcement, int* pInt_ListCount) +bool CDBModule_SQLite::DBModule_SQLite_AnnouncementList(AUTHREG_ANNOUNCEMENT*** ppppSt_Announcement, int* pInt_ListCount) { SQLPacket_IsErrorOccur = false; @@ -1669,7 +1669,7 @@ bool CDatabase_SQLite::Database_SQLite_AnnouncementList(AUTHREG_ANNOUNCEMENT*** // 保护函数 ////////////////////////////////////////////////////////////////////////// /******************************************************************** -函数名称:Database_SQLite_UserPayTime +函数名称:DBModule_SQLite_UserPayTime 函数功能:日期方式充值方式 参数.一:lpszUserName In/Out:In @@ -1701,7 +1701,7 @@ bool CDatabase_SQLite::Database_SQLite_AnnouncementList(AUTHREG_ANNOUNCEMENT*** 意思:是否成功充值 备注: *********************************************************************/ -bool CDatabase_SQLite::Database_SQLite_UserPayTime(LPCXSTR lpszUserName, LPCXSTR lpszUserTime, LPCXSTR lpszCardTime, ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE en_AuthSerialType, ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE en_AuthUserType) +bool CDBModule_SQLite::DBModule_SQLite_UserPayTime(LPCXSTR lpszUserName, LPCXSTR lpszUserTime, LPCXSTR lpszCardTime, ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE en_AuthSerialType, ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE en_AuthUserType) { SQLPacket_IsErrorOccur = false; diff --git a/XEngine_Source/AuthorizeModule_Database/Database_SQLite/Database_SQLite.h b/XEngine_Source/AuthorizeModule_Database/DBModule_SQLite/DBModule_SQLite.h similarity index 55% rename from XEngine_Source/AuthorizeModule_Database/Database_SQLite/Database_SQLite.h rename to XEngine_Source/AuthorizeModule_Database/DBModule_SQLite/DBModule_SQLite.h index 5f8a66f..417c673 100644 --- a/XEngine_Source/AuthorizeModule_Database/Database_SQLite/Database_SQLite.h +++ b/XEngine_Source/AuthorizeModule_Database/DBModule_SQLite/DBModule_SQLite.h @@ -14,47 +14,47 @@ // AuthReg_UserTable内容:ID 用户名 密码 注册日期 剩余时间 硬件码 注册文件密码 QQ 身份证 // AuthReg_SerialTable内容:ID 使用者 序列号 使用时间 最大可允许时间 是否使用 ////////////////////////////////////////////////////////////////////////// -class CDatabase_SQLite +class CDBModule_SQLite { public: - CDatabase_SQLite(); - ~CDatabase_SQLite(); + CDBModule_SQLite(); + ~CDBModule_SQLite(); public: - bool Database_SQLite_Init(LPCXSTR lpszSQLFile, bool bIsChange = true); //初始化 - bool Database_SQLite_Destroy(); //销毁 + bool DBModule_SQLite_Init(LPCXSTR lpszSQLFile, bool bIsChange = true); //初始化 + bool DBModule_SQLite_Destroy(); //销毁 public: - bool Database_SQLite_UserDelete(LPCXSTR lpszUserName); //删除用户 - bool Database_SQLite_UserRegister(AUTHREG_USERTABLE*pSt_UserInfo); //用户注册 - bool Database_SQLite_UserQuery(LPCXSTR lpszUserName, AUTHREG_USERTABLE* pSt_UserInfo = NULL); //用户查询 - bool Database_SQLite_UserPay(LPCXSTR lpszUserName,LPCXSTR lpszSerialName); //充值卡充值 - bool Database_SQLite_UserLeave(AUTHREG_PROTOCOL_TIME* pSt_TimeProtocol); //用户离开更新表 - bool Database_SQLite_UserSet(AUTHREG_USERTABLE* pSt_UserTable); - bool Database_SQLite_UserList(AUTHREG_USERTABLE*** pppSt_UserInfo, int* pInt_ListCount, int nPosStart, int nPosEnd); + bool DBModule_SQLite_UserDelete(LPCXSTR lpszUserName); //删除用户 + bool DBModule_SQLite_UserRegister(AUTHREG_USERTABLE*pSt_UserInfo); //用户注册 + bool DBModule_SQLite_UserQuery(LPCXSTR lpszUserName, AUTHREG_USERTABLE* pSt_UserInfo = NULL); //用户查询 + bool DBModule_SQLite_UserPay(LPCXSTR lpszUserName,LPCXSTR lpszSerialName); //充值卡充值 + bool DBModule_SQLite_UserLeave(AUTHREG_PROTOCOL_TIME* pSt_TimeProtocol); //用户离开更新表 + bool DBModule_SQLite_UserSet(AUTHREG_USERTABLE* pSt_UserTable); + bool DBModule_SQLite_UserList(AUTHREG_USERTABLE*** pppSt_UserInfo, int* pInt_ListCount, int nPosStart, int nPosEnd); public: - bool Database_SQLite_SerialInsert(LPCXSTR lpszSerialNumber); //插入序列卡 - bool Database_SQLite_SerialDelete(LPCXSTR lpszSerialNumber); //删除一个序列号 - bool Database_SQLite_SerialQuery(LPCXSTR lpszSerialNumber,LPAUTHREG_SERIALTABLE pSt_SerialTable = NULL); //按照卡号或者用户查询 - bool Database_SQLite_SerialQueryAll(AUTHREG_SERIALTABLE ***pppSt_SerialTable,int *pInt_ListCount, int nPosStart, int nPosEnd);//查询所有序列卡 - bool Database_SQLite_SerialPush(AUTHREG_SERIALTABLE* pSt_SerialTable); + bool DBModule_SQLite_SerialInsert(LPCXSTR lpszSerialNumber); //插入序列卡 + bool DBModule_SQLite_SerialDelete(LPCXSTR lpszSerialNumber); //删除一个序列号 + bool DBModule_SQLite_SerialQuery(LPCXSTR lpszSerialNumber,LPAUTHREG_SERIALTABLE pSt_SerialTable = NULL); //按照卡号或者用户查询 + bool DBModule_SQLite_SerialQueryAll(AUTHREG_SERIALTABLE ***pppSt_SerialTable,int *pInt_ListCount, int nPosStart, int nPosEnd);//查询所有序列卡 + bool DBModule_SQLite_SerialPush(AUTHREG_SERIALTABLE* pSt_SerialTable); public: - bool Database_SQLite_TryInsert(AUTHREG_TEMPVER* pSt_AuthVer); - bool Database_SQLite_TryQuery(AUTHREG_TEMPVER* pSt_AuthVer); - bool Database_SQLite_TryDelete(LPCXSTR lpszSerial); - bool Database_SQLite_TryClear(int nThanValue, ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE enVerMode = ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_UNKNOW); - bool Database_SQLite_TrySet(AUTHREG_TEMPVER* pSt_AuthVer); - bool Database_SQLite_TryList(AUTHREG_TEMPVER*** pppSt_AuthVer, int* pInt_ListCount, int nPosStart = 0, int nPosEnd = 1000); + bool DBModule_SQLite_TryInsert(AUTHREG_TEMPVER* pSt_AuthVer); + bool DBModule_SQLite_TryQuery(AUTHREG_TEMPVER* pSt_AuthVer); + bool DBModule_SQLite_TryDelete(LPCXSTR lpszSerial); + bool DBModule_SQLite_TryClear(int nThanValue, ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE enVerMode = ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_UNKNOW); + bool DBModule_SQLite_TrySet(AUTHREG_TEMPVER* pSt_AuthVer); + bool DBModule_SQLite_TryList(AUTHREG_TEMPVER*** pppSt_AuthVer, int* pInt_ListCount, int nPosStart = 0, int nPosEnd = 1000); public: - bool Database_SQLite_BannedInsert(AUTHREG_BANNED* pSt_Banned); - bool Database_SQLite_BannedDelete(AUTHREG_BANNED* pSt_Banned); - bool Database_SQLite_BannedList(AUTHREG_BANNED*** pppSt_BannedUser, int* pInt_UserCount, AUTHREG_BANNED*** pppSt_BannedAddr, int* pInt_AddrCount, int nPosStart, int nPosEnd); - bool Database_SQLite_BannedExist(AUTHREG_BANNED* pSt_Banned); - bool Database_SQLite_BannedUPDate(AUTHREG_BANNED* pSt_Banned); + bool DBModule_SQLite_BannedInsert(AUTHREG_BANNED* pSt_Banned); + bool DBModule_SQLite_BannedDelete(AUTHREG_BANNED* pSt_Banned); + bool DBModule_SQLite_BannedList(AUTHREG_BANNED*** pppSt_BannedUser, int* pInt_UserCount, AUTHREG_BANNED*** pppSt_BannedAddr, int* pInt_AddrCount, int nPosStart, int nPosEnd); + bool DBModule_SQLite_BannedExist(AUTHREG_BANNED* pSt_Banned); + bool DBModule_SQLite_BannedUPDate(AUTHREG_BANNED* pSt_Banned); public: - bool Database_SQLite_AnnouncementInsert(AUTHREG_ANNOUNCEMENT* pSt_Announcement); - bool Database_SQLite_AnnouncementDelete(AUTHREG_ANNOUNCEMENT* pSt_Announcement); - bool Database_SQLite_AnnouncementList(AUTHREG_ANNOUNCEMENT*** ppppSt_Announcement, int* pInt_ListCount); + bool DBModule_SQLite_AnnouncementInsert(AUTHREG_ANNOUNCEMENT* pSt_Announcement); + bool DBModule_SQLite_AnnouncementDelete(AUTHREG_ANNOUNCEMENT* pSt_Announcement); + bool DBModule_SQLite_AnnouncementList(AUTHREG_ANNOUNCEMENT*** ppppSt_Announcement, int* pInt_ListCount); protected: - bool Database_SQLite_UserPayTime(LPCXSTR lpszUserName, LPCXSTR lpszUserTime, LPCXSTR lpszCardTime, ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE en_AuthSerialType, ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE en_AuthUserType); + bool DBModule_SQLite_UserPayTime(LPCXSTR lpszUserName, LPCXSTR lpszUserTime, LPCXSTR lpszCardTime, ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE en_AuthSerialType, ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE en_AuthUserType); private: bool m_bChange; XNETHANDLE xhData; //数据库句柄 diff --git a/XEngine_Source/AuthorizeModule_Database/Database_Define.h b/XEngine_Source/AuthorizeModule_Database/Database_Define.h index dd02840..7f77743 100644 --- a/XEngine_Source/AuthorizeModule_Database/Database_Define.h +++ b/XEngine_Source/AuthorizeModule_Database/Database_Define.h @@ -18,7 +18,7 @@ extern "C" XLONG DBModule_GetLastError(int *pInt_SysError = NULL); /* 数据库服务导出函数 */ /************************************************************************/ /******************************************************************** -函数名称:Database_SQLite_Init +函数名称:DBModule_SQLite_Init 函数功能:初始化数据库服务 参数.一:lpszSQLFile In/Out:In @@ -35,18 +35,18 @@ extern "C" XLONG DBModule_GetLastError(int *pInt_SysError = NULL); 意思:是否成功 备注:先初始化数据库服务,在初始化网络服务,才可以使用本验证服务器! *********************************************************************/ -extern "C" bool Database_SQLite_Init(LPCXSTR lpszSQLFile, bool bIsChange = true); +extern "C" bool DBModule_SQLite_Init(LPCXSTR lpszSQLFile, bool bIsChange = true); /******************************************************************** -函数名称:Database_SQLite_Destroy +函数名称:DBModule_SQLite_Destroy 函数功能:销毁数据库服务 返回值 类型:逻辑型 意思:是否销毁成功 备注: *********************************************************************/ -extern "C" bool Database_SQLite_Destroy(); +extern "C" bool DBModule_SQLite_Destroy(); /******************************************************************** -函数名称:Database_SQLite_UserDelete +函数名称:DBModule_SQLite_UserDelete 函数功能:删除一个用户从数据库中 参数.一:lpszUserName In/Out:In @@ -58,9 +58,9 @@ extern "C" bool Database_SQLite_Destroy(); 意思:是否删除成功 备注: *********************************************************************/ -extern "C" bool Database_SQLite_UserDelete(LPCXSTR lpszUserName); +extern "C" bool DBModule_SQLite_UserDelete(LPCXSTR lpszUserName); /******************************************************************** -函数名称:Database_SQLite_UserRegister +函数名称:DBModule_SQLite_UserRegister 函数功能:用户注册处理数据库语句函数 参数.一:pSt_UserInfo In/Out:In @@ -72,9 +72,9 @@ extern "C" bool Database_SQLite_UserDelete(LPCXSTR lpszUserName); 意思:是否插入成功 备注: *********************************************************************/ -extern "C" bool Database_SQLite_UserRegister(AUTHREG_USERTABLE * pSt_UserInfo); +extern "C" bool DBModule_SQLite_UserRegister(AUTHREG_USERTABLE * pSt_UserInfo); /******************************************************************** -函数名称:Database_SQLite_UserQuery +函数名称:DBModule_SQLite_UserQuery 函数功能:查询用户相对应的值 参数.一:lpszUserName In/Out:In @@ -91,9 +91,9 @@ extern "C" bool Database_SQLite_UserRegister(AUTHREG_USERTABLE * pSt_UserInfo); 意思:是否查询成功 备注: *********************************************************************/ -extern "C" bool Database_SQLite_UserQuery(LPCXSTR lpszUserName,AUTHREG_USERTABLE *pSt_UserInfo); +extern "C" bool DBModule_SQLite_UserQuery(LPCXSTR lpszUserName,AUTHREG_USERTABLE *pSt_UserInfo); /******************************************************************** -函数名称:Database_SQLite_UserPay +函数名称:DBModule_SQLite_UserPay 函数功能:用户充值函数 参数.一:lpszUserName In/Out:In @@ -110,9 +110,9 @@ extern "C" bool Database_SQLite_UserQuery(LPCXSTR lpszUserName,AUTHREG_USERTABLE 意思:是否成功充值 备注: *********************************************************************/ -extern "C" bool Database_SQLite_UserPay(LPCXSTR lpszUserName,LPCXSTR lpszSerialName); +extern "C" bool DBModule_SQLite_UserPay(LPCXSTR lpszUserName,LPCXSTR lpszSerialName); /******************************************************************** -函数名称:Database_SQLite_UserLeave +函数名称:DBModule_SQLite_UserLeave 函数功能:用户离开处理事件 参数.一:pSt_TimeProtocol In/Out:In @@ -124,9 +124,9 @@ extern "C" bool Database_SQLite_UserPay(LPCXSTR lpszUserName,LPCXSTR lpszSerialN 意思:是否处理成功 备注: *********************************************************************/ -extern "C" bool Database_SQLite_UserLeave(AUTHREG_PROTOCOL_TIME * pSt_TimeProtocol); +extern "C" bool DBModule_SQLite_UserLeave(AUTHREG_PROTOCOL_TIME * pSt_TimeProtocol); /******************************************************************** -函数名称:Database_SQLite_UserSet +函数名称:DBModule_SQLite_UserSet 函数功能:设置用户信息 参数.一:pSt_UserTable In/Out:In @@ -138,9 +138,9 @@ extern "C" bool Database_SQLite_UserLeave(AUTHREG_PROTOCOL_TIME * pSt_TimeProtoc 意思:是否成功 备注: *********************************************************************/ -extern "C" bool Database_SQLite_UserSet(AUTHREG_USERTABLE* pSt_UserTable); +extern "C" bool DBModule_SQLite_UserSet(AUTHREG_USERTABLE* pSt_UserTable); /******************************************************************** -函数名称:Database_SQLite_UserList +函数名称:DBModule_SQLite_UserList 函数功能:获取用户列表 参数.一:pppSt_UserInfo In/Out:Out @@ -167,9 +167,9 @@ extern "C" bool Database_SQLite_UserSet(AUTHREG_USERTABLE* pSt_UserTable); 意思:是否成功 备注: *********************************************************************/ -extern "C" bool Database_SQLite_UserList(AUTHREG_USERTABLE*** pppSt_UserInfo, int* pInt_ListCount, int nPosStart, int nPosEnd); +extern "C" bool DBModule_SQLite_UserList(AUTHREG_USERTABLE*** pppSt_UserInfo, int* pInt_ListCount, int nPosStart, int nPosEnd); /******************************************************************** -函数名称:Database_SQLite_SerialInsert +函数名称:DBModule_SQLite_SerialInsert 函数功能:插入一个序列号到数据库 参数.一:lpszSerialNumber In/Out:In @@ -181,9 +181,9 @@ extern "C" bool Database_SQLite_UserList(AUTHREG_USERTABLE*** pppSt_UserInfo, in 意思:是否插入成功 备注: *********************************************************************/ -extern "C" bool Database_SQLite_SerialInsert(LPCXSTR lpszSerialNumber); +extern "C" bool DBModule_SQLite_SerialInsert(LPCXSTR lpszSerialNumber); /******************************************************************** -函数名称:Database_SQLite_SerialDelete +函数名称:DBModule_SQLite_SerialDelete 函数功能:从数据库删除指定序列号 参数.一:lpszSerialNumber In/Out:In @@ -195,9 +195,9 @@ extern "C" bool Database_SQLite_SerialInsert(LPCXSTR lpszSerialNumber); 意思:是否删除成功 备注: *********************************************************************/ -extern "C" bool Database_SQLite_SerialDelete(LPCXSTR lpszSerialNumber); +extern "C" bool DBModule_SQLite_SerialDelete(LPCXSTR lpszSerialNumber); /******************************************************************** -函数名称:Database_SQLite_SerialQuery +函数名称:DBModule_SQLite_SerialQuery 函数功能:查询一个指定的序列号信息 参数.一:lpszSerialNumber In/Out:In @@ -214,9 +214,9 @@ extern "C" bool Database_SQLite_SerialDelete(LPCXSTR lpszSerialNumber); 意思:是否查询成功,如果第二个参数为NULL,那么将只返回是否有这个序列号 备注: *********************************************************************/ -extern "C" bool Database_SQLite_SerialQuery(LPCXSTR lpszSerialNumber,LPAUTHREG_SERIALTABLE pSt_SerialTable); +extern "C" bool DBModule_SQLite_SerialQuery(LPCXSTR lpszSerialNumber,LPAUTHREG_SERIALTABLE pSt_SerialTable); /******************************************************************** -函数名称:Database_SQLite_SerialQueryAll +函数名称:DBModule_SQLite_SerialQueryAll 函数功能:查询序列卡表中的所有序列号 参数.一:pppSt_SerialTable In/Out:Out @@ -243,9 +243,9 @@ extern "C" bool Database_SQLite_SerialQuery(LPCXSTR lpszSerialNumber,LPAUTHREG_S 意思:是否查询成功 备注:参数一需要调用基础库的释放内存函数进行内存释放 *********************************************************************/ -extern "C" bool Database_SQLite_SerialQueryAll(AUTHREG_SERIALTABLE * **pppSt_SerialTable, int* pInt_ListCount, int nPosStart, int nPosEnd); +extern "C" bool DBModule_SQLite_SerialQueryAll(AUTHREG_SERIALTABLE * **pppSt_SerialTable, int* pInt_ListCount, int nPosStart, int nPosEnd); /******************************************************************** -函数名称:Database_SQLite_SerialPush +函数名称:DBModule_SQLite_SerialPush 函数功能:插入一条指定的序列号信息到服务器 参数.一:pSt_SerialTable In/Out:In @@ -257,9 +257,9 @@ extern "C" bool Database_SQLite_SerialQueryAll(AUTHREG_SERIALTABLE * **pppSt_Ser 意思:是否成功 备注: *********************************************************************/ -extern "C" bool Database_SQLite_SerialPush(AUTHREG_SERIALTABLE* pSt_SerialTable); +extern "C" bool DBModule_SQLite_SerialPush(AUTHREG_SERIALTABLE* pSt_SerialTable); /******************************************************************** -函数名称:Database_SQLite_TryInsert +函数名称:DBModule_SQLite_TryInsert 函数功能:网络使用模式插入一条数据 参数.一:pSt_AuthVer In/Out:In @@ -271,9 +271,9 @@ extern "C" bool Database_SQLite_SerialPush(AUTHREG_SERIALTABLE* pSt_SerialTable) 意思:是否成功 备注: *********************************************************************/ -extern "C" bool Database_SQLite_TryInsert(AUTHREG_TEMPVER* pSt_AuthVer); +extern "C" bool DBModule_SQLite_TryInsert(AUTHREG_TEMPVER* pSt_AuthVer); /******************************************************************** -函数名称:Database_SQLite_TryQuery +函数名称:DBModule_SQLite_TryQuery 函数功能:试用序列号查询函数 参数.一:pSt_AuthVer In/Out:In/Out @@ -285,9 +285,9 @@ extern "C" bool Database_SQLite_TryInsert(AUTHREG_TEMPVER* pSt_AuthVer); 意思:是否成功 备注: *********************************************************************/ -extern "C" bool Database_SQLite_TryQuery(AUTHREG_TEMPVER* pSt_AuthVer); +extern "C" bool DBModule_SQLite_TryQuery(AUTHREG_TEMPVER* pSt_AuthVer); /******************************************************************** -函数名称:Database_SQLite_TryDelete +函数名称:DBModule_SQLite_TryDelete 函数功能:删除一条指定的试用数据 参数.一:lpszSerial In/Out:In @@ -299,9 +299,9 @@ extern "C" bool Database_SQLite_TryQuery(AUTHREG_TEMPVER* pSt_AuthVer); 意思:是否成功 备注: *********************************************************************/ -extern "C" bool Database_SQLite_TryDelete(LPCXSTR lpszSerial); +extern "C" bool DBModule_SQLite_TryDelete(LPCXSTR lpszSerial); /******************************************************************** -函数名称:Database_SQLite_TryClear +函数名称:DBModule_SQLite_TryClear 函数功能:清理函数,自动清理过期数据 参数.一:nThanValue In/Out:In @@ -318,9 +318,9 @@ extern "C" bool Database_SQLite_TryDelete(LPCXSTR lpszSerial); 意思:是否成功 备注: *********************************************************************/ -extern "C" bool Database_SQLite_TryClear(int nThanValue, ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE enVerMode = ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_UNKNOW); +extern "C" bool DBModule_SQLite_TryClear(int nThanValue, ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE enVerMode = ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_UNKNOW); /******************************************************************** -函数名称:Database_SQLite_TrySet +函数名称:DBModule_SQLite_TrySet 函数功能:设置用户信息函数 参数.一:pSt_AuthVer In/Out:In @@ -332,9 +332,9 @@ extern "C" bool Database_SQLite_TryClear(int nThanValue, ENUM_HELPCOMPONENTS_AUT 意思:是否成功 备注: *********************************************************************/ -extern "C" bool Database_SQLite_TrySet(AUTHREG_TEMPVER* pSt_AuthVer); +extern "C" bool DBModule_SQLite_TrySet(AUTHREG_TEMPVER* pSt_AuthVer); /******************************************************************** -函数名称:Database_SQLite_TryList +函数名称:DBModule_SQLite_TryList 函数功能:请求试用期列表 参数.一:pppSt_AuthVer In/Out:Out @@ -361,9 +361,9 @@ extern "C" bool Database_SQLite_TrySet(AUTHREG_TEMPVER* pSt_AuthVer); 意思:是否成功 备注: *********************************************************************/ -extern "C" bool Database_SQLite_TryList(AUTHREG_TEMPVER*** pppSt_AuthVer, int* pInt_ListCount, int nPosStart = 0, int nPosEnd = 1000); +extern "C" bool DBModule_SQLite_TryList(AUTHREG_TEMPVER*** pppSt_AuthVer, int* pInt_ListCount, int nPosStart = 0, int nPosEnd = 1000); /******************************************************************** -函数名称:Database_SQLite_BannedInsert +函数名称:DBModule_SQLite_BannedInsert 函数功能:黑名单列表插入 参数.一:pSt_Banned In/Out:In @@ -375,9 +375,9 @@ extern "C" bool Database_SQLite_TryList(AUTHREG_TEMPVER*** pppSt_AuthVer, int* p 意思:是否成功 备注: *********************************************************************/ -extern "C" bool Database_SQLite_BannedInsert(AUTHREG_BANNED* pSt_Banned); +extern "C" bool DBModule_SQLite_BannedInsert(AUTHREG_BANNED* pSt_Banned); /******************************************************************** -函数名称:Database_SQLite_BannedDelete +函数名称:DBModule_SQLite_BannedDelete 函数功能:黑名单列表删除 参数.一:pSt_Banned In/Out:In @@ -389,9 +389,9 @@ extern "C" bool Database_SQLite_BannedInsert(AUTHREG_BANNED* pSt_Banned); 意思:是否成功 备注: *********************************************************************/ -extern "C" bool Database_SQLite_BannedDelete(AUTHREG_BANNED* pSt_Banned); +extern "C" bool DBModule_SQLite_BannedDelete(AUTHREG_BANNED* pSt_Banned); /******************************************************************** -函数名称:Database_SQLite_BannedList +函数名称:DBModule_SQLite_BannedList 函数功能:黑名单列表查询 参数.一:pppSt_BannedUser In/Out:Out @@ -428,9 +428,9 @@ extern "C" bool Database_SQLite_BannedDelete(AUTHREG_BANNED* pSt_Banned); 意思:是否成功 备注: *********************************************************************/ -extern "C" bool Database_SQLite_BannedList(AUTHREG_BANNED*** pppSt_BannedUser, int* pInt_UserCount, AUTHREG_BANNED*** pppSt_BannedAddr, int* pInt_AddrCount, int nPosStart, int nPosEnd); +extern "C" bool DBModule_SQLite_BannedList(AUTHREG_BANNED*** pppSt_BannedUser, int* pInt_UserCount, AUTHREG_BANNED*** pppSt_BannedAddr, int* pInt_AddrCount, int nPosStart, int nPosEnd); /******************************************************************** -函数名称:Database_SQLite_BannedExist +函数名称:DBModule_SQLite_BannedExist 函数功能:名单是否存在黑名单列表 参数.一:pSt_Banned In/Out:In @@ -442,9 +442,9 @@ extern "C" bool Database_SQLite_BannedList(AUTHREG_BANNED*** pppSt_BannedUser, i 意思:是否成功 备注: *********************************************************************/ -extern "C" bool Database_SQLite_BannedExist(AUTHREG_BANNED* pSt_Banned); +extern "C" bool DBModule_SQLite_BannedExist(AUTHREG_BANNED* pSt_Banned); /******************************************************************** -函数名称:Database_SQLite_BannedUPDate +函数名称:DBModule_SQLite_BannedUPDate 函数功能:更新名单列表信息 参数.一:pSt_Banned In/Out:In @@ -456,9 +456,9 @@ extern "C" bool Database_SQLite_BannedExist(AUTHREG_BANNED* pSt_Banned); 意思:是否成功 备注: *********************************************************************/ -extern "C" bool Database_SQLite_BannedUPDate(AUTHREG_BANNED* pSt_Banned); +extern "C" bool DBModule_SQLite_BannedUPDate(AUTHREG_BANNED* pSt_Banned); /******************************************************************** -函数名称:Database_SQLite_AnnouncementInsert +函数名称:DBModule_SQLite_AnnouncementInsert 函数功能:公告插入 参数.一:pSt_Announcement In/Out:In @@ -470,9 +470,9 @@ extern "C" bool Database_SQLite_BannedUPDate(AUTHREG_BANNED* pSt_Banned); 意思:是否成功 备注: *********************************************************************/ -extern "C" bool Database_SQLite_AnnouncementInsert(AUTHREG_ANNOUNCEMENT* pSt_Announcement); +extern "C" bool DBModule_SQLite_AnnouncementInsert(AUTHREG_ANNOUNCEMENT* pSt_Announcement); /******************************************************************** -函数名称:Database_SQLite_AnnouncementDelete +函数名称:DBModule_SQLite_AnnouncementDelete 函数功能:公告删除 参数.一:pSt_Announcement In/Out:In @@ -484,9 +484,9 @@ extern "C" bool Database_SQLite_AnnouncementInsert(AUTHREG_ANNOUNCEMENT* pSt_Ann 意思:是否成功 备注: *********************************************************************/ -extern "C" bool Database_SQLite_AnnouncementDelete(AUTHREG_ANNOUNCEMENT* pSt_Announcement); +extern "C" bool DBModule_SQLite_AnnouncementDelete(AUTHREG_ANNOUNCEMENT* pSt_Announcement); /******************************************************************** -函数名称:Database_SQLite_AnnouncementList +函数名称:DBModule_SQLite_AnnouncementList 函数功能:列举所有公告 参数.一:ppppSt_Announcement In/Out:Out @@ -503,4 +503,493 @@ extern "C" bool Database_SQLite_AnnouncementDelete(AUTHREG_ANNOUNCEMENT* pSt_Ann 意思:是否成功 备注: *********************************************************************/ -extern "C" bool Database_SQLite_AnnouncementList(AUTHREG_ANNOUNCEMENT*** ppppSt_Announcement, int* pInt_ListCount); \ No newline at end of file +extern "C" bool DBModule_SQLite_AnnouncementList(AUTHREG_ANNOUNCEMENT*** ppppSt_Announcement, int* pInt_ListCount); + +/************************************************************************/ +/* MYSQL数据库服务导出函数 */ +/************************************************************************/ +/******************************************************************** +函数名称:DBModule_MySQL_Init +函数功能:初始化数据库管理器 + 参数.一:pSt_DBConnector + In/Out:In + 类型:数据结构指针 + 参数.二:bIsChange + In/Out:In + 类型:逻辑型 + 可空:Y + 意思:是否允许更改用户充值类型 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注:先初始化数据库服务,在初始化网络服务,才可以使用本验证服务器! +*********************************************************************/ +extern "C" bool DBModule_MySQL_Init(DATABASE_MYSQL_CONNECTINFO* pSt_DBConnector, bool bIsChange = true); +/******************************************************************** +函数名称:DBModule_MySQL_Destroy +函数功能:销毁数据库服务 +返回值 + 类型:逻辑型 + 意思:是否销毁成功 +备注: +*********************************************************************/ +extern "C" bool DBModule_MySQL_Destroy(); +/******************************************************************** +函数名称:DBModule_MySQL_UserDelete +函数功能:删除一个用户从数据库中 + 参数.一:lpszUserName + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:要删除的用户 +返回值 + 类型:逻辑型 + 意思:是否删除成功 +备注: +*********************************************************************/ +extern "C" bool DBModule_MySQL_UserDelete(LPCXSTR lpszUserName); +/******************************************************************** +函数名称:DBModule_MySQL_UserRegister +函数功能:用户注册处理数据库语句函数 + 参数.一:pSt_UserInfo + In/Out:In + 类型:数据结构指针 + 可空:N + 意思:要插入的用户数据 +返回值 + 类型:逻辑型 + 意思:是否插入成功 +备注: +*********************************************************************/ +extern "C" bool DBModule_MySQL_UserRegister(AUTHREG_USERTABLE* pSt_UserInfo); +/******************************************************************** +函数名称:DBModule_MySQL_UserQuery +函数功能:查询用户相对应的值 + 参数.一:lpszUserName + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:要查询的指定用户 + 参数.二:pSt_UserInfo + In/Out:Out + 类型:数据结构指针 + 可空:Y + 意思:如果为空NULL,那么将只判断此用户是否存在 +返回值 + 类型:逻辑型 + 意思:是否查询成功 +备注: +*********************************************************************/ +extern "C" bool DBModule_MySQL_UserQuery(LPCXSTR lpszUserName, AUTHREG_USERTABLE* pSt_UserInfo); +/******************************************************************** +函数名称:DBModule_MySQL_UserPay +函数功能:用户充值函数 + 参数.一:lpszUserName + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:要充值的用户名 + 参数.二:lpszSerialName + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:充值使用的序列号 +返回值 + 类型:逻辑型 + 意思:是否成功充值 +备注: +*********************************************************************/ +extern "C" bool DBModule_MySQL_UserPay(LPCXSTR lpszUserName, LPCXSTR lpszSerialName); +/******************************************************************** +函数名称:DBModule_MySQL_UserLeave +函数功能:用户离开处理事件 + 参数.一:pSt_TimeProtocol + In/Out:In + 类型:数据结构指针 + 可空:N + 意思:离开的用户信息 +返回值 + 类型:逻辑型 + 意思:是否处理成功 +备注: +*********************************************************************/ +extern "C" bool DBModule_MySQL_UserLeave(AUTHREG_PROTOCOL_TIME* pSt_TimeProtocol); +/******************************************************************** +函数名称:DBModule_MySQL_UserSet +函数功能:设置用户信息 + 参数.一:pSt_UserTable + In/Out:In + 类型:数据结构指针 + 可空:N + 意思:输入要设置的信息 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +extern "C" bool DBModule_MySQL_UserSet(AUTHREG_USERTABLE* pSt_UserTable); +/******************************************************************** +函数名称:DBModule_MySQL_UserList +函数功能:获取用户列表 + 参数.一:pppSt_UserInfo + In/Out:Out + 类型:三级指针 + 可空:N + 意思:输出用户列表,内存由用户释放 + 参数.二:pInt_ListCount + In/Out:Out + 类型:整数型 + 可空:N + 意思:输出列表个数 + 参数.三:nPosStart + In/Out:In + 类型:整数型 + 可空:Y + 意思:输入起始位置 + 参数.四:nPosEnd + In/Out:In + 类型:整数型 + 可空:Y + 意思:输入结束位置 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +extern "C" bool DBModule_MySQL_UserList(AUTHREG_USERTABLE*** pppSt_UserInfo, int* pInt_ListCount, int nPosStart, int nPosEnd); +/******************************************************************** +函数名称:DBModule_MySQL_SerialInsert +函数功能:插入一个序列号到数据库 + 参数.一:lpszSerialNumber + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:要插入的序列号 +返回值 + 类型:逻辑型 + 意思:是否插入成功 +备注: +*********************************************************************/ +extern "C" bool DBModule_MySQL_SerialInsert(LPCXSTR lpszSerialNumber); +/******************************************************************** +函数名称:DBModule_MySQL_SerialDelete +函数功能:从数据库删除指定序列号 + 参数.一:lpszSerialNumber + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:要删除的序列号 +返回值 + 类型:逻辑型 + 意思:是否删除成功 +备注: +*********************************************************************/ +extern "C" bool DBModule_MySQL_SerialDelete(LPCXSTR lpszSerialNumber); +/******************************************************************** +函数名称:DBModule_MySQL_SerialQuery +函数功能:查询一个指定的序列号信息 + 参数.一:lpszSerialNumber + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:要查询的序列号 + 参数.二:pSt_SerialTable + In/Out:Out + 类型:数据结构指针 + 可空:Y + 意思:导出查询到的信息,如果为NULL,此参数将不起作用 +返回值 + 类型:逻辑型 + 意思:是否查询成功,如果第二个参数为NULL,那么将只返回是否有这个序列号 +备注: +*********************************************************************/ +extern "C" bool DBModule_MySQL_SerialQuery(LPCXSTR lpszSerialNumber, LPAUTHREG_SERIALTABLE pSt_SerialTable); +/******************************************************************** +函数名称:DBModule_MySQL_SerialQueryAll +函数功能:查询序列卡表中的所有序列号 + 参数.一:pppSt_SerialTable + In/Out:Out + 类型:三级指针 + 可空:N + 意思:输出序列卡列表 + 参数.二:pInt_ListCount + In/Out:Out + 类型:整数型指针 + 可空:Y + 意思:输出多少张卡 + 参数.三:nPosStart + In/Out:In + 类型:整数型 + 可空:Y + 意思:输入起始位置 + 参数.四:nPosEnd + In/Out:In + 类型:整数型 + 可空:Y + 意思:输入结束位置 +返回值 + 类型:逻辑型 + 意思:是否查询成功 +备注:参数一需要调用基础库的释放内存函数进行内存释放 +*********************************************************************/ +extern "C" bool DBModule_MySQL_SerialQueryAll(AUTHREG_SERIALTABLE*** pppSt_SerialTable, int* pInt_ListCount, int nPosStart, int nPosEnd); +/******************************************************************** +函数名称:DBModule_MySQL_SerialPush +函数功能:插入一条指定的序列号信息到服务器 + 参数.一:pSt_SerialTable + In/Out:In + 类型:数据结构指针 + 可空:N + 意思:输入要插入的信息 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +extern "C" bool DBModule_MySQL_SerialPush(AUTHREG_SERIALTABLE* pSt_SerialTable); +/******************************************************************** +函数名称:DBModule_MySQL_TryInsert +函数功能:网络使用模式插入一条数据 + 参数.一:pSt_AuthVer + In/Out:In + 类型:数据结构指针 + 可空:N + 意思:输入要插入的数据 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +extern "C" bool DBModule_MySQL_TryInsert(AUTHREG_TEMPVER* pSt_AuthVer); +/******************************************************************** +函数名称:DBModule_MySQL_TryQuery +函数功能:试用序列号查询函数 + 参数.一:pSt_AuthVer + In/Out:In/Out + 类型:数据结构指针 + 可空:N + 意思:输入序列号,输出获取到的内容 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +extern "C" bool DBModule_MySQL_TryQuery(AUTHREG_TEMPVER* pSt_AuthVer); +/******************************************************************** +函数名称:DBModule_MySQL_TryDelete +函数功能:删除一条指定的试用数据 + 参数.一:lpszSerial + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:输入要删除的序列号 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +extern "C" bool DBModule_MySQL_TryDelete(LPCXSTR lpszSerial); +/******************************************************************** +函数名称:DBModule_MySQL_TryClear +函数功能:清理函数,自动清理过期数据 + 参数.一:nThanValue + In/Out:In + 类型:整数型 + 可空:N + 意思:清理用于判断需要大于此的值 + 参数.二:enVerMode + In/Out:In + 类型:枚举型 + 可空:Y + 意思:判断注册类型,默认不判断全部执行 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +extern "C" bool DBModule_MySQL_TryClear(int nThanValue, ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE enVerMode = ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_UNKNOW); +/******************************************************************** +函数名称:DBModule_MySQL_TrySet +函数功能:设置用户信息函数 + 参数.一:pSt_AuthVer + In/Out:In + 类型:数据结构指针 + 可空:N + 意思:输入要更新的用户信息 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +extern "C" bool DBModule_MySQL_TrySet(AUTHREG_TEMPVER* pSt_AuthVer); +/******************************************************************** +函数名称:DBModule_MySQL_TryList +函数功能:请求试用期列表 + 参数.一:pppSt_AuthVer + In/Out:Out + 类型:三级指针 + 可空:N + 意思:输出获取到的列表 + 参数.二:pInt_ListCount + In/Out:Out + 类型:整数型指针 + 可空:N + 意思:输出列表个数 + 参数.三:nPosStart + In/Out:In + 类型:整数型 + 可空:N + 意思:输入查询起始编号 + 参数.四:nPosEnd + In/Out:In + 类型:整数型 + 可空:N + 意思:输入查询结束编号 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +extern "C" bool DBModule_MySQL_TryList(AUTHREG_TEMPVER*** pppSt_AuthVer, int* pInt_ListCount, int nPosStart = 0, int nPosEnd = 1000); +/******************************************************************** +函数名称:DBModule_MySQL_BannedInsert +函数功能:黑名单列表插入 + 参数.一:pSt_Banned + In/Out:In + 类型:数据结构指针 + 可空:N + 意思:要操作的数据 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +extern "C" bool DBModule_MySQL_BannedInsert(AUTHREG_BANNED* pSt_Banned); +/******************************************************************** +函数名称:DBModule_MySQL_BannedDelete +函数功能:黑名单列表删除 + 参数.一:pSt_Banned + In/Out:In + 类型:数据结构指针 + 可空:N + 意思:要操作的数据 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +extern "C" bool DBModule_MySQL_BannedDelete(AUTHREG_BANNED* pSt_Banned); +/******************************************************************** +函数名称:DBModule_MySQL_BannedList +函数功能:黑名单列表查询 + 参数.一:pppSt_BannedUser + In/Out:Out + 类型:三级指针 + 可空:N + 意思:禁用的用户名列表 + 参数.二:pInt_UserCount + In/Out:Out + 类型:整数型指针 + 可空:N + 意思:输出用户禁用列表个数 + 参数.三:pppSt_BannedAddr + In/Out:Out + 类型:三级指针 + 可空:N + 意思:禁用的IP地址列表 + 参数.四:pInt_AddrCount + In/Out:Out + 类型:整数型指针 + 可空:N + 意思:输出地址禁用列表个数 + 参数.五:nPosStart + In/Out:In + 类型:整数型 + 可空:N + 意思:输入查找起始位置 + 参数.六:nPosEnd + In/Out:In + 类型:整数型 + 可空:N + 意思:输入查找结束位置 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +extern "C" bool DBModule_MySQL_BannedList(AUTHREG_BANNED*** pppSt_BannedUser, int* pInt_UserCount, AUTHREG_BANNED*** pppSt_BannedAddr, int* pInt_AddrCount, int nPosStart, int nPosEnd); +/******************************************************************** +函数名称:DBModule_MySQL_BannedExist +函数功能:名单是否存在黑名单列表 + 参数.一:pSt_Banned + In/Out:In + 类型:数据结构指针 + 可空:N + 意思:要操作的数据 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +extern "C" bool DBModule_MySQL_BannedExist(AUTHREG_BANNED* pSt_Banned); +/******************************************************************** +函数名称:DBModule_MySQL_BannedUPDate +函数功能:更新名单列表信息 + 参数.一:pSt_Banned + In/Out:In + 类型:数据结构指针 + 可空:N + 意思:要操作的数据 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +extern "C" bool DBModule_MySQL_BannedUPDate(AUTHREG_BANNED* pSt_Banned); +/******************************************************************** +函数名称:DBModule_MySQL_AnnouncementInsert +函数功能:公告插入 + 参数.一:pSt_Announcement + In/Out:In + 类型:数据结构指针 + 可空:N + 意思:输入要插入的信息 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +extern "C" bool DBModule_MySQL_AnnouncementInsert(AUTHREG_ANNOUNCEMENT* pSt_Announcement); +/******************************************************************** +函数名称:DBModule_MySQL_AnnouncementDelete +函数功能:公告删除 + 参数.一:pSt_Announcement + In/Out:In + 类型:数据结构指针 + 可空:N + 意思:输入要删除的信息 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +extern "C" bool DBModule_MySQL_AnnouncementDelete(AUTHREG_ANNOUNCEMENT* pSt_Announcement); +/******************************************************************** +函数名称:DBModule_MySQL_AnnouncementList +函数功能:列举所有公告 + 参数.一:ppppSt_Announcement + In/Out:Out + 类型:三级指针 + 可空:N + 意思:输出列举数据 + 参数.二:pInt_ListCount + In/Out:Out + 类型:整数型指针 + 可空:N + 意思:导出数据个数 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +extern "C" bool DBModule_MySQL_AnnouncementList(AUTHREG_ANNOUNCEMENT*** ppppSt_Announcement, int* pInt_ListCount); diff --git a/XEngine_Source/AuthorizeModule_Database/Makefile b/XEngine_Source/AuthorizeModule_Database/Makefile index 2e02eb4..69def22 100644 --- a/XEngine_Source/AuthorizeModule_Database/Makefile +++ b/XEngine_Source/AuthorizeModule_Database/Makefile @@ -10,7 +10,7 @@ LOADHDR = -I ./ LOADSO = LIB = -lXEngine_BaseLib -lHelpComponents_DataBase -lHelpComponents_Authorize LIBEX = -OBJECTS = Database_SQLite.o pch.o +OBJECTS = DBModule_SQLite.o DBModule_MySQL.o pch.o ifeq ($(RELEASE),1) FLAGS = -c @@ -51,8 +51,10 @@ endif all:$(OBJECTS) $(CC) $(DEBUG) $(OBJECTS) -o libAuthorizeModule_Database.$(FILEEXT) $(LIBFLAG) $(LIB) $(LIBEX) $(LOADSO) $(LOADBIN) -Database_SQLite.o:./Database_SQLite/Database_SQLite.cpp - $(CC) $(DEBUG) $(FLAGS) $(UNICODE) $(PLATVER) $(LOADHDR) ./Database_SQLite/Database_SQLite.cpp +DBModule_SQLite.o:./DBModule_SQLite/DBModule_SQLite.cpp + $(CC) $(DEBUG) $(FLAGS) $(UNICODE) $(PLATVER) $(LOADHDR) ./DBModule_SQLite/DBModule_SQLite.cpp +DBModule_MySQL.o:./DBModule_MySQL/DBModule_MySQL.cpp + $(CC) $(DEBUG) $(FLAGS) $(UNICODE) $(PLATVER) $(LOADHDR) ./DBModule_MySQL/DBModule_MySQL.cpp pch.o:pch.cpp $(CC) $(DEBUG) $(FLAGS) $(UNICODE) $(PLATVER) $(LOADHDR) pch.cpp diff --git a/XEngine_Source/AuthorizeModule_Database/pch.cpp b/XEngine_Source/AuthorizeModule_Database/pch.cpp index 7b844cf..390f698 100644 --- a/XEngine_Source/AuthorizeModule_Database/pch.cpp +++ b/XEngine_Source/AuthorizeModule_Database/pch.cpp @@ -1,5 +1,6 @@ #include "pch.h" -#include "Database_SQLite/Database_SQLite.h" +#include "DBModule_SQLite/DBModule_SQLite.h" +#include "DBModule_MySQL/DBModule_MySQL.h" /******************************************************************** // Created: 2022/05/26 11:02:23 // File Name: D:\XEngine_Authorize\XEngine_Source\AuthorizeModule_Database\pch.cpp @@ -14,7 +15,8 @@ bool SQLPacket_IsErrorOccur = false; XLONG SQLPacket_dwErrorCode = 0; ////////////////////////////////////////////////////////////////////////// -CDatabase_SQLite m_SQLAuth; +CDBModule_SQLite m_DBSQLite; +CDBModule_MySQL m_DBMySQL; ////////////////////////////////////////////////////////////////////////// // 导出的函数 ////////////////////////////////////////////////////////////////////////// @@ -29,115 +31,231 @@ extern "C" XLONG DBModule_GetLastError(int* pInt_SysError) /************************************************************************/ /* 数据库服务导出函数 */ /************************************************************************/ -extern "C" bool Database_SQLite_Init(LPCXSTR lpszSQLFile, bool bIsChange) +extern "C" bool DBModule_SQLite_Init(LPCXSTR lpszSQLFile, bool bIsChange) { - return m_SQLAuth.Database_SQLite_Init(lpszSQLFile, bIsChange); + return m_DBSQLite.DBModule_SQLite_Init(lpszSQLFile, bIsChange); } -extern "C" bool Database_SQLite_Destroy() +extern "C" bool DBModule_SQLite_Destroy() { - return m_SQLAuth.Database_SQLite_Destroy(); + return m_DBSQLite.DBModule_SQLite_Destroy(); } -extern "C" bool Database_SQLite_UserDelete(LPCXSTR lpszUserName) +extern "C" bool DBModule_SQLite_UserDelete(LPCXSTR lpszUserName) { - return m_SQLAuth.Database_SQLite_UserDelete(lpszUserName); + return m_DBSQLite.DBModule_SQLite_UserDelete(lpszUserName); } -extern "C" bool Database_SQLite_UserRegister(AUTHREG_USERTABLE * pSt_UserInfo) +extern "C" bool DBModule_SQLite_UserRegister(AUTHREG_USERTABLE * pSt_UserInfo) { - return m_SQLAuth.Database_SQLite_UserRegister(pSt_UserInfo); + return m_DBSQLite.DBModule_SQLite_UserRegister(pSt_UserInfo); } -extern "C" bool Database_SQLite_UserQuery(LPCXSTR lpszUserName, AUTHREG_USERTABLE * pSt_UserInfo) +extern "C" bool DBModule_SQLite_UserQuery(LPCXSTR lpszUserName, AUTHREG_USERTABLE * pSt_UserInfo) { - return m_SQLAuth.Database_SQLite_UserQuery(lpszUserName, pSt_UserInfo); + return m_DBSQLite.DBModule_SQLite_UserQuery(lpszUserName, pSt_UserInfo); } -extern "C" bool Database_SQLite_UserPay(LPCXSTR lpszUserName, LPCXSTR lpszSerialName) +extern "C" bool DBModule_SQLite_UserPay(LPCXSTR lpszUserName, LPCXSTR lpszSerialName) { - return m_SQLAuth.Database_SQLite_UserPay(lpszUserName, lpszSerialName); + return m_DBSQLite.DBModule_SQLite_UserPay(lpszUserName, lpszSerialName); } -extern "C" bool Database_SQLite_UserLeave(AUTHREG_PROTOCOL_TIME * pSt_TimeProtocol) +extern "C" bool DBModule_SQLite_UserLeave(AUTHREG_PROTOCOL_TIME * pSt_TimeProtocol) { - return m_SQLAuth.Database_SQLite_UserLeave(pSt_TimeProtocol); + return m_DBSQLite.DBModule_SQLite_UserLeave(pSt_TimeProtocol); } -extern "C" bool Database_SQLite_UserSet(AUTHREG_USERTABLE * pSt_UserTable) +extern "C" bool DBModule_SQLite_UserSet(AUTHREG_USERTABLE * pSt_UserTable) { - return m_SQLAuth.Database_SQLite_UserSet(pSt_UserTable); + return m_DBSQLite.DBModule_SQLite_UserSet(pSt_UserTable); } -extern "C" bool Database_SQLite_UserList(AUTHREG_USERTABLE * **pppSt_UserInfo, int* pInt_ListCount, int nPosStart, int nPosEnd) +extern "C" bool DBModule_SQLite_UserList(AUTHREG_USERTABLE * **pppSt_UserInfo, int* pInt_ListCount, int nPosStart, int nPosEnd) { - return m_SQLAuth.Database_SQLite_UserList(pppSt_UserInfo, pInt_ListCount, nPosStart, nPosEnd); + return m_DBSQLite.DBModule_SQLite_UserList(pppSt_UserInfo, pInt_ListCount, nPosStart, nPosEnd); } -extern "C" bool Database_SQLite_SerialInsert(LPCXSTR lpszSerialNumber) +extern "C" bool DBModule_SQLite_SerialInsert(LPCXSTR lpszSerialNumber) { - return m_SQLAuth.Database_SQLite_SerialInsert(lpszSerialNumber); + return m_DBSQLite.DBModule_SQLite_SerialInsert(lpszSerialNumber); } -extern "C" bool Database_SQLite_SerialDelete(LPCXSTR lpszSerialNumber) +extern "C" bool DBModule_SQLite_SerialDelete(LPCXSTR lpszSerialNumber) { - return m_SQLAuth.Database_SQLite_SerialDelete(lpszSerialNumber); + return m_DBSQLite.DBModule_SQLite_SerialDelete(lpszSerialNumber); } -extern "C" bool Database_SQLite_SerialQuery(LPCXSTR lpszSerialNumber, LPAUTHREG_SERIALTABLE pSt_SerialTable) +extern "C" bool DBModule_SQLite_SerialQuery(LPCXSTR lpszSerialNumber, LPAUTHREG_SERIALTABLE pSt_SerialTable) { - return m_SQLAuth.Database_SQLite_SerialQuery(lpszSerialNumber, pSt_SerialTable); + return m_DBSQLite.DBModule_SQLite_SerialQuery(lpszSerialNumber, pSt_SerialTable); } -extern "C" bool Database_SQLite_SerialQueryAll(AUTHREG_SERIALTABLE * **pppSt_SerialTable, int* pInt_ListCount, int nPosStart, int nPosEnd) +extern "C" bool DBModule_SQLite_SerialQueryAll(AUTHREG_SERIALTABLE * **pppSt_SerialTable, int* pInt_ListCount, int nPosStart, int nPosEnd) { - return m_SQLAuth.Database_SQLite_SerialQueryAll(pppSt_SerialTable, pInt_ListCount, nPosStart, nPosEnd); + return m_DBSQLite.DBModule_SQLite_SerialQueryAll(pppSt_SerialTable, pInt_ListCount, nPosStart, nPosEnd); } -extern "C" bool Database_SQLite_SerialPush(AUTHREG_SERIALTABLE * pSt_SerialTable) +extern "C" bool DBModule_SQLite_SerialPush(AUTHREG_SERIALTABLE * pSt_SerialTable) { - return m_SQLAuth.Database_SQLite_SerialPush(pSt_SerialTable); + return m_DBSQLite.DBModule_SQLite_SerialPush(pSt_SerialTable); } -extern "C" bool Database_SQLite_TryInsert(AUTHREG_TEMPVER * pSt_AuthVer) +extern "C" bool DBModule_SQLite_TryInsert(AUTHREG_TEMPVER * pSt_AuthVer) { - return m_SQLAuth.Database_SQLite_TryInsert(pSt_AuthVer); + return m_DBSQLite.DBModule_SQLite_TryInsert(pSt_AuthVer); } -extern "C" bool Database_SQLite_TryQuery(AUTHREG_TEMPVER * pSt_AuthVer) +extern "C" bool DBModule_SQLite_TryQuery(AUTHREG_TEMPVER * pSt_AuthVer) { - return m_SQLAuth.Database_SQLite_TryQuery(pSt_AuthVer); + return m_DBSQLite.DBModule_SQLite_TryQuery(pSt_AuthVer); } -extern "C" bool Database_SQLite_TryDelete(LPCXSTR lpszSerial) +extern "C" bool DBModule_SQLite_TryDelete(LPCXSTR lpszSerial) { - return m_SQLAuth.Database_SQLite_TryDelete(lpszSerial); + return m_DBSQLite.DBModule_SQLite_TryDelete(lpszSerial); } -extern "C" bool Database_SQLite_TryClear(int nThanValue, ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE enVerMode) +extern "C" bool DBModule_SQLite_TryClear(int nThanValue, ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE enVerMode) { - return m_SQLAuth.Database_SQLite_TryClear(nThanValue, enVerMode); + return m_DBSQLite.DBModule_SQLite_TryClear(nThanValue, enVerMode); } -extern "C" bool Database_SQLite_TrySet(AUTHREG_TEMPVER * pSt_AuthVer) +extern "C" bool DBModule_SQLite_TrySet(AUTHREG_TEMPVER * pSt_AuthVer) { - return m_SQLAuth.Database_SQLite_TrySet(pSt_AuthVer); + return m_DBSQLite.DBModule_SQLite_TrySet(pSt_AuthVer); } -extern "C" bool Database_SQLite_TryList(AUTHREG_TEMPVER * **pppSt_AuthVer, int* pInt_ListCount, int nPosStart, int nPosEnd) +extern "C" bool DBModule_SQLite_TryList(AUTHREG_TEMPVER * **pppSt_AuthVer, int* pInt_ListCount, int nPosStart, int nPosEnd) { - return m_SQLAuth.Database_SQLite_TryList(pppSt_AuthVer, pInt_ListCount, nPosStart, nPosEnd); + return m_DBSQLite.DBModule_SQLite_TryList(pppSt_AuthVer, pInt_ListCount, nPosStart, nPosEnd); } -extern "C" bool Database_SQLite_BannedInsert(AUTHREG_BANNED * pSt_Banned) +extern "C" bool DBModule_SQLite_BannedInsert(AUTHREG_BANNED * pSt_Banned) { - return m_SQLAuth.Database_SQLite_BannedInsert(pSt_Banned); + return m_DBSQLite.DBModule_SQLite_BannedInsert(pSt_Banned); } -extern "C" bool Database_SQLite_BannedDelete(AUTHREG_BANNED * pSt_Banned) +extern "C" bool DBModule_SQLite_BannedDelete(AUTHREG_BANNED * pSt_Banned) { - return m_SQLAuth.Database_SQLite_BannedDelete(pSt_Banned); + return m_DBSQLite.DBModule_SQLite_BannedDelete(pSt_Banned); } -extern "C" bool Database_SQLite_BannedList(AUTHREG_BANNED * **pppSt_BannedUser, int* pInt_UserCount, AUTHREG_BANNED * **pppSt_BannedAddr, int* pInt_AddrCount, int nPosStart, int nPosEnd) +extern "C" bool DBModule_SQLite_BannedList(AUTHREG_BANNED * **pppSt_BannedUser, int* pInt_UserCount, AUTHREG_BANNED * **pppSt_BannedAddr, int* pInt_AddrCount, int nPosStart, int nPosEnd) { - return m_SQLAuth.Database_SQLite_BannedList(pppSt_BannedUser, pInt_UserCount, pppSt_BannedAddr, pInt_AddrCount, nPosStart, nPosEnd); + return m_DBSQLite.DBModule_SQLite_BannedList(pppSt_BannedUser, pInt_UserCount, pppSt_BannedAddr, pInt_AddrCount, nPosStart, nPosEnd); } -extern "C" bool Database_SQLite_BannedExist(AUTHREG_BANNED * pSt_Banned) +extern "C" bool DBModule_SQLite_BannedExist(AUTHREG_BANNED * pSt_Banned) { - return m_SQLAuth.Database_SQLite_BannedExist(pSt_Banned); + return m_DBSQLite.DBModule_SQLite_BannedExist(pSt_Banned); } -extern "C" bool Database_SQLite_BannedUPDate(AUTHREG_BANNED * pSt_Banned) +extern "C" bool DBModule_SQLite_BannedUPDate(AUTHREG_BANNED * pSt_Banned) { - return m_SQLAuth.Database_SQLite_BannedUPDate(pSt_Banned); + return m_DBSQLite.DBModule_SQLite_BannedUPDate(pSt_Banned); } -extern "C" bool Database_SQLite_AnnouncementInsert(AUTHREG_ANNOUNCEMENT * pSt_Announcement) +extern "C" bool DBModule_SQLite_AnnouncementInsert(AUTHREG_ANNOUNCEMENT * pSt_Announcement) { - return m_SQLAuth.Database_SQLite_AnnouncementInsert(pSt_Announcement); + return m_DBSQLite.DBModule_SQLite_AnnouncementInsert(pSt_Announcement); } -extern "C" bool Database_SQLite_AnnouncementDelete(AUTHREG_ANNOUNCEMENT * pSt_Announcement) +extern "C" bool DBModule_SQLite_AnnouncementDelete(AUTHREG_ANNOUNCEMENT * pSt_Announcement) { - return m_SQLAuth.Database_SQLite_AnnouncementDelete(pSt_Announcement); + return m_DBSQLite.DBModule_SQLite_AnnouncementDelete(pSt_Announcement); } -extern "C" bool Database_SQLite_AnnouncementList(AUTHREG_ANNOUNCEMENT * **ppppSt_Announcement, int* pInt_ListCount) +extern "C" bool DBModule_SQLite_AnnouncementList(AUTHREG_ANNOUNCEMENT * **ppppSt_Announcement, int* pInt_ListCount) { - return m_SQLAuth.Database_SQLite_AnnouncementList(ppppSt_Announcement, pInt_ListCount); + return m_DBSQLite.DBModule_SQLite_AnnouncementList(ppppSt_Announcement, pInt_ListCount); +} + +/************************************************************************/ +/* MYSQL数据库服务导出函数 */ +/************************************************************************/ +extern "C" bool DBModule_MySQL_Init(DATABASE_MYSQL_CONNECTINFO* pSt_DBConnector, bool bIsChange) +{ + return m_DBMySQL.DBModule_MySQL_Init(pSt_DBConnector, bIsChange); +} +extern "C" bool DBModule_MySQL_Destroy() +{ + return m_DBMySQL.DBModule_MySQL_Destroy(); +} +extern "C" bool DBModule_MySQL_UserDelete(LPCXSTR lpszUserName) +{ + return m_DBMySQL.DBModule_MySQL_UserDelete(lpszUserName); +} +extern "C" bool DBModule_MySQL_UserRegister(AUTHREG_USERTABLE* pSt_UserInfo) +{ + return m_DBMySQL.DBModule_MySQL_UserRegister(pSt_UserInfo); +} +extern "C" bool DBModule_MySQL_UserQuery(LPCXSTR lpszUserName, AUTHREG_USERTABLE* pSt_UserInfo) +{ + return m_DBMySQL.DBModule_MySQL_UserQuery(lpszUserName, pSt_UserInfo); +} +extern "C" bool DBModule_MySQL_UserPay(LPCXSTR lpszUserName, LPCXSTR lpszSerialName) +{ + return m_DBMySQL.DBModule_MySQL_UserPay(lpszUserName, lpszSerialName); +} +extern "C" bool DBModule_MySQL_UserLeave(AUTHREG_PROTOCOL_TIME* pSt_TimeProtocol) +{ + return m_DBMySQL.DBModule_MySQL_UserLeave(pSt_TimeProtocol); +} +extern "C" bool DBModule_MySQL_UserSet(AUTHREG_USERTABLE* pSt_UserTable) +{ + return m_DBMySQL.DBModule_MySQL_UserSet(pSt_UserTable); +} +extern "C" bool DBModule_MySQL_UserList(AUTHREG_USERTABLE*** pppSt_UserInfo, int* pInt_ListCount, int nPosStart, int nPosEnd) +{ + return m_DBMySQL.DBModule_MySQL_UserList(pppSt_UserInfo, pInt_ListCount, nPosStart, nPosEnd); +} +extern "C" bool DBModule_MySQL_SerialInsert(LPCXSTR lpszSerialNumber) +{ + return m_DBMySQL.DBModule_MySQL_SerialInsert(lpszSerialNumber); +} +extern "C" bool DBModule_MySQL_SerialDelete(LPCXSTR lpszSerialNumber) +{ + return m_DBMySQL.DBModule_MySQL_SerialDelete(lpszSerialNumber); +} +extern "C" bool DBModule_MySQL_SerialQuery(LPCXSTR lpszSerialNumber, LPAUTHREG_SERIALTABLE pSt_SerialTable) +{ + return m_DBMySQL.DBModule_MySQL_SerialQuery(lpszSerialNumber, pSt_SerialTable); +} +extern "C" bool DBModule_MySQL_SerialQueryAll(AUTHREG_SERIALTABLE*** pppSt_SerialTable, int* pInt_ListCount, int nPosStart, int nPosEnd) +{ + return m_DBMySQL.DBModule_MySQL_SerialQueryAll(pppSt_SerialTable, pInt_ListCount, nPosStart, nPosEnd); +} +extern "C" bool DBModule_MySQL_SerialPush(AUTHREG_SERIALTABLE* pSt_SerialTable) +{ + return m_DBMySQL.DBModule_MySQL_SerialPush(pSt_SerialTable); +} +extern "C" bool DBModule_MySQL_TryInsert(AUTHREG_TEMPVER* pSt_AuthVer) +{ + return m_DBMySQL.DBModule_MySQL_TryInsert(pSt_AuthVer); +} +extern "C" bool DBModule_MySQL_TryQuery(AUTHREG_TEMPVER* pSt_AuthVer) +{ + return m_DBMySQL.DBModule_MySQL_TryQuery(pSt_AuthVer); +} +extern "C" bool DBModule_MySQL_TryDelete(LPCXSTR lpszSerial) +{ + return m_DBMySQL.DBModule_MySQL_TryDelete(lpszSerial); +} +extern "C" bool DBModule_MySQL_TryClear(int nThanValue, ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE enVerMode) +{ + return m_DBMySQL.DBModule_MySQL_TryClear(nThanValue, enVerMode); +} +extern "C" bool DBModule_MySQL_TrySet(AUTHREG_TEMPVER* pSt_AuthVer) +{ + return m_DBMySQL.DBModule_MySQL_TrySet(pSt_AuthVer); +} +extern "C" bool DBModule_MySQL_TryList(AUTHREG_TEMPVER*** pppSt_AuthVer, int* pInt_ListCount, int nPosStart, int nPosEnd) +{ + return m_DBMySQL.DBModule_MySQL_TryList(pppSt_AuthVer, pInt_ListCount, nPosStart, nPosEnd); +} +extern "C" bool DBModule_MySQL_BannedInsert(AUTHREG_BANNED* pSt_Banned) +{ + return m_DBMySQL.DBModule_MySQL_BannedInsert(pSt_Banned); +} +extern "C" bool DBModule_MySQL_BannedDelete(AUTHREG_BANNED* pSt_Banned) +{ + return m_DBMySQL.DBModule_MySQL_BannedDelete(pSt_Banned); +} +extern "C" bool DBModule_MySQL_BannedList(AUTHREG_BANNED*** pppSt_BannedUser, int* pInt_UserCount, AUTHREG_BANNED*** pppSt_BannedAddr, int* pInt_AddrCount, int nPosStart, int nPosEnd) +{ + return m_DBMySQL.DBModule_MySQL_BannedList(pppSt_BannedUser, pInt_UserCount, pppSt_BannedAddr, pInt_AddrCount, nPosStart, nPosEnd); +} +extern "C" bool DBModule_MySQL_BannedExist(AUTHREG_BANNED* pSt_Banned) +{ + return m_DBMySQL.DBModule_MySQL_BannedExist(pSt_Banned); +} +extern "C" bool DBModule_MySQL_BannedUPDate(AUTHREG_BANNED* pSt_Banned) +{ + return m_DBMySQL.DBModule_MySQL_BannedUPDate(pSt_Banned); +} +extern "C" bool DBModule_MySQL_AnnouncementInsert(AUTHREG_ANNOUNCEMENT* pSt_Announcement) +{ + return m_DBMySQL.DBModule_MySQL_AnnouncementInsert(pSt_Announcement); +} +extern "C" bool DBModule_MySQL_AnnouncementDelete(AUTHREG_ANNOUNCEMENT* pSt_Announcement) +{ + return m_DBMySQL.DBModule_MySQL_AnnouncementDelete(pSt_Announcement); +} +extern "C" bool DBModule_MySQL_AnnouncementList(AUTHREG_ANNOUNCEMENT*** ppppSt_Announcement, int* pInt_ListCount) +{ + return m_DBMySQL.DBModule_MySQL_AnnouncementList(ppppSt_Announcement, pInt_ListCount); } \ No newline at end of file diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Get/AuthorizeHTTP_Token.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Get/AuthorizeHTTP_Token.cpp index f7d2290..9ac2150 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Get/AuthorizeHTTP_Token.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Get/AuthorizeHTTP_Token.cpp @@ -68,7 +68,16 @@ bool XEngine_AuthorizeHTTP_Token(LPCXSTR lpszClientAddr, XCHAR** pptszList, int return false; } } - if (!Database_SQLite_UserQuery(tszUserName, &st_UserTable)) + bool bSuccess = false; + if (0 == st_AuthConfig.st_XSql.nDBType) + { + bSuccess = DBModule_SQLite_UserQuery(tszUserName, &st_UserTable); + } + else + { + bSuccess = DBModule_MySQL_UserQuery(tszUserName, &st_UserTable); + } + if (!bSuccess) { Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen, 404, "user not found"); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Announcement.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Announcement.cpp index 0f1e9ce..3721652 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Announcement.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Announcement.cpp @@ -23,7 +23,14 @@ bool XEngine_AuthorizeHTTP_Announcement(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIN AUTHREG_ANNOUNCEMENT st_Announcement; memset(&st_Announcement, '\0', sizeof(AUTHREG_ANNOUNCEMENT)); - Database_SQLite_AnnouncementList(NULL, &nListCount); + if (0 == st_AuthConfig.st_XSql.nDBType) + { + DBModule_SQLite_AnnouncementList(NULL, &nListCount); + } + else + { + DBModule_MySQL_AnnouncementList(NULL, &nListCount); + } if (nListCount > 10) { Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen, 510, "server limited"); @@ -32,7 +39,14 @@ bool XEngine_AuthorizeHTTP_Announcement(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIN return false; } Protocol_Parse_HttpParseAnnouncement(lpszMsgBuffer, nMsgLen, &st_Announcement); - Database_SQLite_AnnouncementInsert(&st_Announcement); + if (0 == st_AuthConfig.st_XSql.nDBType) + { + DBModule_SQLite_AnnouncementInsert(&st_Announcement); + } + else + { + DBModule_MySQL_AnnouncementInsert(&st_Announcement); + } Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s,插入公告成功,公告信息:%s"), lpszClientAddr, st_Announcement.tszContext); @@ -43,7 +57,14 @@ bool XEngine_AuthorizeHTTP_Announcement(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIN memset(&st_Announcement, '\0', sizeof(AUTHREG_ANNOUNCEMENT)); Protocol_Parse_HttpParseAnnouncement(lpszMsgBuffer, nMsgLen, &st_Announcement); - Database_SQLite_AnnouncementDelete(&st_Announcement); + if (0 == st_AuthConfig.st_XSql.nDBType) + { + DBModule_SQLite_AnnouncementDelete(&st_Announcement); + } + else + { + DBModule_MySQL_AnnouncementDelete(&st_Announcement); + } Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s,删除公告成功.删除公告ID:%lld"), lpszClientAddr, st_Announcement.nID); @@ -53,7 +74,14 @@ bool XEngine_AuthorizeHTTP_Announcement(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIN int nListCount = 0; AUTHREG_ANNOUNCEMENT** ppSt_Announcement; - Database_SQLite_AnnouncementList(&ppSt_Announcement, &nListCount); + if (0 == st_AuthConfig.st_XSql.nDBType) + { + DBModule_SQLite_AnnouncementList(&ppSt_Announcement, &nListCount); + } + else + { + DBModule_MySQL_AnnouncementList(&ppSt_Announcement, &nListCount); + } Protocol_Packet_HttpAnnouncement(tszSDBuffer, &nSDLen, &ppSt_Announcement, nListCount); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); BaseLib_OperatorMemory_Free((XPPPMEM)&ppSt_Announcement, nListCount); diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Banned.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Banned.cpp index f066df2..20ae19b 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Banned.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Banned.cpp @@ -17,7 +17,14 @@ bool XEngine_AuthorizeHTTP_Banned(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, L memset(&st_Banned, '\0', sizeof(AUTHREG_BANNED)); Protocol_Parse_HttpParseBanned(lpszMsgBuffer, nMsgLen, &st_Banned); - Database_SQLite_BannedInsert(&st_Banned); + if (0 == st_AuthConfig.st_XSql.nDBType) + { + DBModule_SQLite_BannedInsert(&st_Banned); + } + else + { + DBModule_MySQL_BannedInsert(&st_Banned); + } Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s,插入禁用列表成功,禁用的用户:%s,禁用的IP地址:%s"), lpszClientAddr, st_Banned.tszUserName, st_Banned.tszIPAddr); @@ -28,7 +35,14 @@ bool XEngine_AuthorizeHTTP_Banned(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, L memset(&st_Banned, '\0', sizeof(AUTHREG_BANNED)); Protocol_Parse_HttpParseBanned(lpszMsgBuffer, nMsgLen, &st_Banned); - Database_SQLite_BannedDelete(&st_Banned); + if (0 == st_AuthConfig.st_XSql.nDBType) + { + DBModule_SQLite_BannedDelete(&st_Banned); + } + else + { + DBModule_MySQL_BannedDelete(&st_Banned); + } Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s,删除禁用列表成功,删除禁用的用户:%s,删除禁用的IP地址:%s"), lpszClientAddr, st_Banned.tszUserName, st_Banned.tszIPAddr); @@ -44,7 +58,14 @@ bool XEngine_AuthorizeHTTP_Banned(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, L Protocol_Parse_HttpParseBanned2(lpszMsgBuffer, nMsgLen, &nPosStart, &nPosEnd); - Database_SQLite_BannedList(&ppSt_BannedUser, &nCountUser, &ppSt_BannedAddr, &nCountAddr, nPosStart, nPosEnd); + if (0 == st_AuthConfig.st_XSql.nDBType) + { + DBModule_SQLite_BannedList(&ppSt_BannedUser, &nCountUser, &ppSt_BannedAddr, &nCountAddr, nPosStart, nPosEnd); + } + else + { + DBModule_MySQL_BannedList(&ppSt_BannedUser, &nCountUser, &ppSt_BannedAddr, &nCountAddr, nPosStart, nPosEnd); + } Protocol_Packet_HttpBanned(tszSDBuffer, &nSDLen, &ppSt_BannedUser, nCountUser, &ppSt_BannedAddr, nCountAddr); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); BaseLib_OperatorMemory_Free((XPPPMEM)&ppSt_BannedAddr, nCountAddr); @@ -57,7 +78,14 @@ bool XEngine_AuthorizeHTTP_Banned(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, L memset(&st_Banned, '\0', sizeof(AUTHREG_BANNED)); Protocol_Parse_HttpParseBanned(lpszMsgBuffer, nMsgLen, &st_Banned); - Database_SQLite_BannedUPDate(&st_Banned); + if (0 == st_AuthConfig.st_XSql.nDBType) + { + DBModule_SQLite_BannedUPDate(&st_Banned); + } + else + { + DBModule_MySQL_BannedUPDate(&st_Banned); + } Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s,修改禁用列表成功,修改的用户:%s,修改的IP地址:%s"), lpszClientAddr, st_Banned.tszUserName, st_Banned.tszIPAddr); diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Client.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Client.cpp index c4f257b..f1d1ecb 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Client.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Client.cpp @@ -17,7 +17,16 @@ bool XEngine_AuthorizeHTTP_Client(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, L memset(&st_UserTable, '\0', sizeof(AUTHREG_USERTABLE)); Protocol_Parse_HttpParseUser(lpszMsgBuffer, nMsgLen, &st_UserTable.st_UserInfo); - if (!Database_SQLite_UserQuery(st_UserTable.st_UserInfo.tszUserName, &st_UserTable)) + bool bSuccess = false; + if (0 == st_AuthConfig.st_XSql.nDBType) + { + bSuccess = DBModule_SQLite_UserQuery(st_UserTable.st_UserInfo.tszUserName, &st_UserTable); + } + else + { + bSuccess = DBModule_MySQL_UserQuery(st_UserTable.st_UserInfo.tszUserName, &st_UserTable); + } + if (!bSuccess) { Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen, 404, "not found client"); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); @@ -63,7 +72,14 @@ bool XEngine_AuthorizeHTTP_Client(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, L if (!bOnline) { //只有bOnline不是在线列表的时候才执行 - Database_SQLite_UserList(&ppSt_UserInfo, &nOffCount, nPosStart, nPosEnd); + if (0 == st_AuthConfig.st_XSql.nDBType) + { + DBModule_SQLite_UserList(&ppSt_UserInfo, &nOffCount, nPosStart, nPosEnd); + } + else + { + DBModule_MySQL_UserList(&ppSt_UserInfo, &nOffCount, nPosStart, nPosEnd); + } } Protocol_Packet_HttpClientList(ptszMsgBuffer, &nSDLen, &ppSt_ListClient, nOnCount, &ppSt_UserInfo, nOffCount); @@ -104,7 +120,16 @@ bool XEngine_AuthorizeHTTP_Client(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, L memset(&st_UserTable, '\0', sizeof(AUTHREG_USERTABLE)); Protocol_Parse_HttpParseTable(lpszMsgBuffer, nMsgLen, &st_UserTable); - if (!Database_SQLite_UserSet(&st_UserTable)) + bool bSuccess = false; + if (0 == st_AuthConfig.st_XSql.nDBType) + { + bSuccess = DBModule_SQLite_UserSet(&st_UserTable); + } + else + { + bSuccess = DBModule_MySQL_UserSet(&st_UserTable); + } + if (!bSuccess) { Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen, 404, "not found client"); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Pass.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Pass.cpp index 94935d1..4dcafaf 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Pass.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Pass.cpp @@ -19,7 +19,16 @@ bool XEngine_AuthorizeHTTP_Pass(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, LPC memset(&st_UserTable, '\0', sizeof(AUTHREG_USERTABLE)); Protocol_Parse_HttpParseAuth(lpszMsgBuffer, nMsgLen, &st_UserAuth); - if (!Database_SQLite_UserQuery(st_UserAuth.tszUserName, &st_UserTable)) + bool bSuccess = false; + if (0 == st_AuthConfig.st_XSql.nDBType) + { + bSuccess = DBModule_SQLite_UserQuery(st_UserAuth.tszUserName, &st_UserTable); + } + else + { + bSuccess = DBModule_MySQL_UserQuery(st_UserAuth.tszUserName, &st_UserTable); + } + if (!bSuccess) { Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen, 404, "user notfound"); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); @@ -43,7 +52,14 @@ bool XEngine_AuthorizeHTTP_Pass(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, LPC memset(&st_ProtocolTime, '\0', sizeof(AUTHREG_PROTOCOL_TIME)); Protocol_Parse_HttpParseTime(lpszMsgBuffer, nMsgLen, &st_ProtocolTime); - Database_SQLite_UserLeave(&st_ProtocolTime); + if (0 == st_AuthConfig.st_XSql.nDBType) + { + DBModule_SQLite_UserLeave(&st_ProtocolTime); + } + else + { + DBModule_MySQL_UserLeave(&st_ProtocolTime); + } Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); @@ -55,7 +71,14 @@ bool XEngine_AuthorizeHTTP_Pass(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, LPC memset(&st_ProtocolTime, '\0', sizeof(AUTHREG_PROTOCOL_TIME)); Protocol_Parse_HttpParseTime(lpszMsgBuffer, nMsgLen, &st_ProtocolTime); - Database_SQLite_UserLeave(&st_ProtocolTime); + if (0 == st_AuthConfig.st_XSql.nDBType) + { + DBModule_SQLite_UserLeave(&st_ProtocolTime); + } + else + { + DBModule_MySQL_UserLeave(&st_ProtocolTime); + } Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("PASS客户端:%s,用户名:%s,超时通知成功"), lpszClientAddr, st_ProtocolTime.tszUserName); diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Serial.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Serial.cpp index 97bd0df..0e54d5d 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Serial.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Serial.cpp @@ -32,7 +32,14 @@ bool XEngine_AuthorizeHTTP_Serial(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, L return false; } AUTHREG_SERIALTABLE** ppSt_SerialTable; - Database_SQLite_SerialQueryAll(&ppSt_SerialTable, &nListCount, nPosStart, nPosEnd); + if (0 == st_AuthConfig.st_XSql.nDBType) + { + DBModule_SQLite_SerialQueryAll(&ppSt_SerialTable, &nListCount, nPosStart, nPosEnd); + } + else + { + DBModule_MySQL_SerialQueryAll(&ppSt_SerialTable, &nListCount, nPosStart, nPosEnd); + } Protocol_Packet_HttpSerialList(ptszMsgBuffer, &nSDLen, &ppSt_SerialTable, nListCount); BaseLib_OperatorMemory_Free((XPPPMEM)&ppSt_SerialTable, nListCount); XEngine_Client_TaskSend(lpszClientAddr, ptszMsgBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); @@ -93,9 +100,19 @@ bool XEngine_AuthorizeHTTP_Serial(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, L return false; } //导入序列卡 - for (int i = 0; i < nSerialCount; i++) + if (0 == st_AuthConfig.st_XSql.nDBType) + { + for (int i = 0; i < nSerialCount; i++) //导入序列卡 + { + DBModule_SQLite_SerialInsert(pptszSerialNumber[i]); + } + } + else { - Database_SQLite_SerialInsert(pptszSerialNumber[i]); + for (int i = 0; i < nSerialCount; i++) + { + DBModule_MySQL_SerialInsert(pptszSerialNumber[i]); + } } BaseLib_OperatorMemory_Free((XPPPMEM)&pptszSerialNumber, nSerialCount); Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen); @@ -108,9 +125,19 @@ bool XEngine_AuthorizeHTTP_Serial(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, L AUTHREG_SERIALTABLE** ppSt_SerialTable; Protocol_Parse_HttpParseSerial(lpszMsgBuffer, nMsgLen, &ppSt_SerialTable, &nListCount); - for (int i = 0; i < nListCount; i++) + if (0 == st_AuthConfig.st_XSql.nDBType) { - Database_SQLite_SerialDelete(ppSt_SerialTable[i]->tszSerialNumber); + for (int i = 0; i < nListCount; i++) + { + DBModule_SQLite_SerialDelete(ppSt_SerialTable[i]->tszSerialNumber); + } + } + else + { + for (int i = 0; i < nListCount; i++) + { + DBModule_MySQL_SerialDelete(ppSt_SerialTable[i]->tszSerialNumber); + } } BaseLib_OperatorMemory_Free((XPPPMEM)&ppSt_SerialTable, nListCount); Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen); @@ -123,9 +150,19 @@ bool XEngine_AuthorizeHTTP_Serial(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, L AUTHREG_SERIALTABLE** ppSt_SerialTable; Protocol_Parse_HttpParseSerial(lpszMsgBuffer, nMsgLen, &ppSt_SerialTable, &nListCount); - for (int i = 0; i < nListCount; i++) + if (0 == st_AuthConfig.st_XSql.nDBType) { - Database_SQLite_SerialPush(ppSt_SerialTable[i]); + for (int i = 0; i < nListCount; i++) + { + DBModule_SQLite_SerialPush(ppSt_SerialTable[i]); + } + } + else + { + for (int i = 0; i < nListCount; i++) + { + DBModule_MySQL_SerialPush(ppSt_SerialTable[i]); + } } BaseLib_OperatorMemory_Free((XPPPMEM)&ppSt_SerialTable, nListCount); Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen); diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Try.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Try.cpp index 86d7089..ac5b3ba 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Try.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_Try.cpp @@ -29,7 +29,14 @@ bool XEngine_AuthorizeHTTP_Try(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, LPCX int nListCount = 0; AUTHREG_TEMPVER** ppSt_AuthVer; - Database_SQLite_TryList(&ppSt_AuthVer, &nListCount); + if (0 == st_AuthConfig.st_XSql.nDBType) + { + DBModule_SQLite_TryList(&ppSt_AuthVer, &nListCount); + } + else + { + DBModule_MySQL_TryList(&ppSt_AuthVer, &nListCount); + } Protocol_Packet_HttpTryList(ptszMsgBuffer, &nSDLen, &ppSt_AuthVer, nListCount); BaseLib_OperatorMemory_Free((XPPPMEM)&ppSt_AuthVer, nListCount); XEngine_Client_TaskSend(lpszClientAddr, ptszMsgBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); @@ -43,7 +50,14 @@ bool XEngine_AuthorizeHTTP_Try(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, LPCX memset(&st_VERTemp, '\0', sizeof(AUTHREG_TEMPVER)); Protocol_Parse_HttpParseTry(lpszMsgBuffer, nMsgLen, &st_VERTemp); - Database_SQLite_TryDelete(st_VERTemp.tszVSerial); + if (0 == st_AuthConfig.st_XSql.nDBType) + { + DBModule_SQLite_TryDelete(st_VERTemp.tszVSerial); + } + else + { + DBModule_MySQL_TryDelete(st_VERTemp.tszVSerial); + } Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s,序列号:%s,临时验证删除成功"), lpszClientAddr, st_VERTemp.tszVSerial); @@ -54,7 +68,14 @@ bool XEngine_AuthorizeHTTP_Try(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, LPCX memset(&st_VERTemp, '\0', sizeof(AUTHREG_TEMPVER)); Protocol_Parse_HttpParseTry(lpszMsgBuffer, nMsgLen, &st_VERTemp); - Database_SQLite_TrySet(&st_VERTemp); + if (0 == st_AuthConfig.st_XSql.nDBType) + { + DBModule_SQLite_TrySet(&st_VERTemp); + } + else + { + DBModule_MySQL_TrySet(&st_VERTemp); + } Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s,序列号:%s,临时验证修改成功"), lpszClientAddr, st_VERTemp.tszVSerial); diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_User.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_User.cpp index 6654cee..81188f5 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_User.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/AuthorizeHTTP_Post/AuthorizeHTTP_User.cpp @@ -36,7 +36,14 @@ bool XEngine_AuthorizeHTTP_User(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, LPC } BaseLib_OperatorMemory_Free((XPPPMEM)&ppSt_ListClient, nListCount); - Database_SQLite_UserDelete(st_UserInfo.tszUserName); + if (0 == st_AuthConfig.st_XSql.nDBType) + { + DBModule_SQLite_UserDelete(st_UserInfo.tszUserName); + } + else + { + DBModule_MySQL_UserDelete(st_UserInfo.tszUserName); + } Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s,请求删除用户:%s 成功,在线用户数:%d"), lpszClientAddr, st_UserInfo.tszUserName, nListCount); @@ -60,7 +67,16 @@ bool XEngine_AuthorizeHTTP_User(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, LPC memset(&st_Banned, '\0', sizeof(AUTHREG_BANNED)); _tcsxcpy(st_Banned.tszUserName, st_UserTable.st_UserInfo.tszUserName); - if (Database_SQLite_BannedExist(&st_Banned)) + bool bSuccess = false; + if (0 == st_AuthConfig.st_XSql.nDBType) + { + bSuccess = DBModule_SQLite_BannedExist(&st_Banned); + } + else + { + bSuccess = DBModule_MySQL_BannedExist(&st_Banned); + } + if (bSuccess) { Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen, 423, "user name is banned"); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); @@ -85,7 +101,16 @@ bool XEngine_AuthorizeHTTP_User(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, LPC XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,注册失败,没有设置用户和密码"), lpszClientAddr); return false; } - if (!Database_SQLite_UserRegister(&st_UserTable)) + bSuccess = false; + if (0 == st_AuthConfig.st_XSql.nDBType) + { + bSuccess = DBModule_SQLite_UserRegister(&st_UserTable); + } + else + { + bSuccess = DBModule_MySQL_UserRegister(&st_UserTable); + } + if (!bSuccess) { XLONG dwRet = DBModule_GetLastError(); Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen, dwRet, "user register is failed"); @@ -113,14 +138,30 @@ bool XEngine_AuthorizeHTTP_User(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, LPC return false; } Protocol_Parse_HttpParsePay(lpszMsgBuffer, nMsgLen, &st_UserPay); - if (!Database_SQLite_UserPay(st_UserPay.tszUserName, st_UserPay.tszSerialNumber)) + bool bSuccess = false; + if (0 == st_AuthConfig.st_XSql.nDBType) + { + bSuccess = DBModule_SQLite_UserPay(st_UserPay.tszUserName, st_UserPay.tszSerialNumber); + } + else + { + bSuccess = DBModule_MySQL_UserPay(st_UserPay.tszUserName, st_UserPay.tszSerialNumber); + } + if (!bSuccess) { Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen, 404, "Serial number not available"); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("HTTP客户端:%s,用户名:%s,充值失败,无法继续,错误:%X"), lpszClientAddr, st_UserPay.tszUserName, DBModule_GetLastError()); return false; } - Database_SQLite_UserQuery(st_UserPay.tszUserName, &st_UserInfo); + if (0 == st_AuthConfig.st_XSql.nDBType) + { + DBModule_SQLite_UserQuery(st_UserPay.tszUserName, &st_UserInfo); + } + else + { + DBModule_MySQL_UserQuery(st_UserPay.tszUserName, &st_UserInfo); + } Session_Authorize_SetUser(&st_UserInfo); Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); @@ -144,7 +185,16 @@ bool XEngine_AuthorizeHTTP_User(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, LPC return false; } Protocol_Parse_HttpParseUser(lpszMsgBuffer, nMsgLen, &st_UserInfo); - if (!Database_SQLite_UserQuery(st_UserInfo.tszUserName, &st_UserTable)) + bool bSuccess = false; + if (0 == st_AuthConfig.st_XSql.nDBType) + { + bSuccess = DBModule_SQLite_UserQuery(st_UserInfo.tszUserName, &st_UserTable); + } + else + { + bSuccess = DBModule_MySQL_UserQuery(st_UserInfo.tszUserName, &st_UserTable); + } + if (!bSuccess) { Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen, 404, "user not found"); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); @@ -200,7 +250,17 @@ bool XEngine_AuthorizeHTTP_User(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, LPC return false; } Protocol_Parse_HttpParseTry(lpszMsgBuffer, nMsgLen, &st_VERTemp); - if (Database_SQLite_TryQuery(&st_VERTemp)) + bool bSuccess = false; + //判断是使用哪个数据库 + if (0 == st_AuthConfig.st_XSql.nDBType) + { + bSuccess = DBModule_SQLite_TryQuery(&st_VERTemp); + } + else + { + bSuccess = DBModule_MySQL_TryQuery(&st_VERTemp); + } + if (bSuccess) { __int64x nTimeSpan = 0; //根据方式来计算剩余时间 @@ -231,7 +291,14 @@ bool XEngine_AuthorizeHTTP_User(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, LPC //是否超过 if (nTimeSpan >= 0) { - Database_SQLite_TrySet(&st_VERTemp); + if (0 == st_AuthConfig.st_XSql.nDBType) + { + DBModule_SQLite_TrySet(&st_VERTemp); + } + else + { + DBModule_MySQL_TrySet(&st_VERTemp); + } Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端:%s,序列号:%s,类型:%s,临时验证成功,剩余时间:%lld"), lpszClientAddr, st_VERTemp.tszVSerial, lpszXSerialType[st_VERTemp.enVMode], nTimeSpan); @@ -256,7 +323,16 @@ bool XEngine_AuthorizeHTTP_User(LPCXSTR lpszClientAddr, LPCXSTR lpszAPIName, LPC XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _X("HTTP客户端:%s,序列号:%s,临时验证插入失败,因为服务器关闭了此功能"), lpszClientAddr, st_VERTemp.tszVSerial); return false; } - if (!Database_SQLite_TryInsert(&st_VERTemp)) + bool bSuccess = false; + if (0 == st_AuthConfig.st_XSql.nDBType) + { + bSuccess = DBModule_SQLite_TryInsert(&st_VERTemp); + } + else + { + bSuccess = DBModule_MySQL_TryInsert(&st_VERTemp); + } + if (!bSuccess) { Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen, 500, "Internal Server Error"); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_Hdr.h b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_Hdr.h index 78d426d..34784b8 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_Hdr.h +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_Hdr.h @@ -40,6 +40,8 @@ using namespace std; #include #include #include +#include +#include #include "../../XAuth_Protocol.h" #include "../../AuthorizeModule_Configure/Config_Define.h" #include "../../AuthorizeModule_Configure/Config_Error.h" diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_HttpTask.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_HttpTask.cpp index 1240c6b..fa73a14 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_HttpTask.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_HttpTask.cpp @@ -59,11 +59,20 @@ bool XEngine_Client_HttpTask(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int AUTHREG_BANNED st_Banned; memset(&st_Banned, '\0', sizeof(AUTHREG_BANNED)); - _tcsxcpy(st_Banned.tszIPAddr, lpszClientAddr); BaseLib_OperatorIPAddr_SegAddr(st_Banned.tszIPAddr); + //是否在黑名单 - if (Database_SQLite_BannedExist(&st_Banned)) + bool bSuccess = false; + if (0 == st_AuthConfig.st_XSql.nDBType) + { + bSuccess = DBModule_SQLite_BannedExist(&st_Banned); //IP地址是否在黑名单 + } + else + { + bSuccess = DBModule_MySQL_BannedExist(&st_Banned);//IP地址是否在黑名单 + } + if (bSuccess) { Protocol_Packet_HttpComm(tszSDBuffer, &nSDLen, 423, "ip address is banned"); XEngine_Client_TaskSend(lpszClientAddr, tszSDBuffer, nSDLen, XENGINE_AUTH_APP_NETTYPE_HTTP); @@ -253,7 +262,6 @@ bool XEngine_Client_HttpTask(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int LPCXSTR lpszFuncName = _X("api"); LPCXSTR lpszAPIVerNotice = _X("notice"); LPCXSTR lpszAPIVerDCode = _X("dcode"); - memset(tszUrlName, '\0', sizeof(tszUrlName)); HttpProtocol_ServerHelp_GetParament(pSt_HTTPParament->tszHttpUri, &pptszList, &nListCount, tszUrlName); if ((nListCount < 1) || (0 != _tcsxnicmp(lpszFuncName, tszUrlName, _tcsxlen(lpszFuncName)))) diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_TCPTask.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_TCPTask.cpp index af26d11..b4cb4ac 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_TCPTask.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_TCPTask.cpp @@ -61,7 +61,16 @@ bool XEngine_Client_TCPTask(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int n _tcsxcpy(st_Banned.tszIPAddr, lpszClientAddr); BaseLib_OperatorIPAddr_SegAddr(st_Banned.tszIPAddr); //是否在黑名单 - if (Database_SQLite_BannedExist(&st_Banned)) + bool bSuccess = false; + if (0 == st_AuthConfig.st_XSql.nDBType) + { + bSuccess = DBModule_SQLite_BannedExist(&st_Banned); //是否在黑名单 + } + else + { + bSuccess = DBModule_MySQL_BannedExist(&st_Banned);//是否在黑名单 + } + if (bSuccess) { pSt_ProtocolHdr->wReserve = 423; Protocol_Packet_HDRComm(tszSDBuffer, &nSDLen, pSt_ProtocolHdr, nNetType); @@ -132,7 +141,16 @@ bool XEngine_Client_TCPTask(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int n } else { - if (!Database_SQLite_UserQuery(st_AuthProtocol.tszUserName, &st_UserTable)) + bool bSuccess = false; + if (0 == st_AuthConfig.st_XSql.nDBType) + { + bSuccess = DBModule_SQLite_UserQuery(st_AuthProtocol.tszUserName, &st_UserTable); + } + else + { + bSuccess = DBModule_MySQL_UserQuery(st_AuthProtocol.tszUserName, &st_UserTable); + } + if (!bSuccess) { pSt_ProtocolHdr->wReserve = 251; Protocol_Packet_HDRComm(tszSDBuffer, &nSDLen, pSt_ProtocolHdr, nNetType); @@ -268,7 +286,15 @@ bool XEngine_Client_TCPTask(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int n __int64x nTime = _ttxoll(st_UserTable.tszLeftTime) - 1; _xstprintf(st_UserTable.tszLeftTime, _X("%lld"), nTime); - Database_SQLite_UserSet(&st_UserTable); + if (0 == st_AuthConfig.st_XSql.nDBType) + { + DBModule_SQLite_UserSet(&st_UserTable); + } + else + { + DBModule_MySQL_UserSet(&st_UserTable); + } + } else if (ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE_DAY == st_UserTable.enSerialType) { @@ -278,7 +304,14 @@ bool XEngine_Client_TCPTask(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int n __int64x nTime = _ttxoll(st_UserTable.tszLeftTime) - 1; _xstprintf(st_UserTable.tszLeftTime, _X("%lld"), nTime); BaseLib_OperatorTime_TimeToStr(st_UserTable.st_UserInfo.tszLoginTime); - Database_SQLite_UserSet(&st_UserTable); + if (0 == st_AuthConfig.st_XSql.nDBType) + { + DBModule_SQLite_UserSet(&st_UserTable); + } + else + { + DBModule_MySQL_UserSet(&st_UserTable); + } } } diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_Task.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_Task.cpp index 40e8fc8..d2caceb 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_Task.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/Authorize_Task.cpp @@ -52,7 +52,14 @@ void CALLBACK XEngine_TaskEvent_Client(LPCXSTR lpszUserAddr, LPCXSTR lpszUserNam _tcsxcpy(st_AuthTime.tszUserName, lpszUserName); _tcsxcpy(st_AuthTime.tszUserAddr, lpszUserAddr); - Database_SQLite_UserLeave(&st_AuthTime); + if (0 == st_AuthConfig.st_XSql.nDBType) + { + DBModule_SQLite_UserLeave(&st_AuthTime); + } + else + { + DBModule_MySQL_UserLeave(&st_AuthTime); + } } void CALLBACK XEngine_TaskEvent_Token(XNETHANDLE xhToken, XPVOID lParam) { diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/XEngine_AuthorizeService b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/XEngine_AuthorizeService new file mode 100644 index 0000000000000000000000000000000000000000..e4e0990bab9209081b0d00ece2aeaa90027cee30 GIT binary patch literal 811704 zcmeF)d3;k<{y+X(pjsW77PVs?x8NEVFjdjuxCEgZ6tGaxj-xgO3aOShlokVu1|ixS zqeZ7$*9oq1FDhe2(cnU>GinhXJ34CI#vm@iHRIOr`<(l}wa;=HU&Q%AKqthR1Ll!|C6Hj027BNQcp1 z4{ycKz9HrY>$8B%4W&=9Uy1l3$LF3V8`h`QLh&i~)Befu7VERfjKzNW@<+8M0cQN! zM{=WKeHzMs@_1?94?d^QH21SU)&0cSq-K}{kgCc4bWSw)%T$=3)_$Ut*e}ETWq3d9 zvxvvb`n1MVv{C$Z^LG4n(KhkN`o#VGydQo}Fn2SoPjL+Kr{bfg+5gS)%6Y%zPBF&= zKaVomus*HhO{M+Bxct&TJblJAKAvtKN_I4Bv_7ruIJ~ZQ=FvwTUN?JGU2T1Ha8%HJ z^r)kc8oi)l^bv9g(Jlx56*+avloGa`n!q#eolY4(BH4F>U z{P~vtiqk0W`}E`J@4Q>C|8e>Ji}rZ)nS&OT9yIjPh0k?=mOkvMUB^9j?=6QvH1e{4 z2lr@sVa5d$KKpp@>lg3&%u8#>zdYr$$B#YXrFnZTzN@0L@Z1qkmV9{P9~Zy&*hQ-f zRvkZnhf8~FUY<90ar@a5cl+o+!`?q|zqJo_9`M!1Ngg_+_RsCVF^rvaY(0zyDVI;$ zCAZ(Udv4#GCLmWm@BKEn|4^9QKiea>e_4{-XYHNapZQ&Gzl6phS395BEw^8$sejR4 zxy!$!8Rq~cUasRFOYL#wn3p3cNpqEdju!S@e!1qjwHp7A#;?)LW0$7CPiXSt6FO;g zwR56oJnzutp;uFXlct>uHTg4ClW+N&@vPAt_kCJea`o$c!d!larae>WwjfveyES>T zt7hDmYuY(QQ~q#`uO6PeJ?CrY@hi>vf2C>9ewy>{R!w`BX~yRQ&3rjE^%Q9Q`QPX6 z?i?G~;}bCf{DsjQ=roq05z5-)h#wVolx-*R*rGreDJ~ zexjy+uVy`&t-0>JsX2eUGt;>A3N-Z$)tndaX!1X;Ie#Z=+P}T#`Z!!uPqQY^XK3bqvnHQsX!`q*CJ!Ih z%-7wTarju%ocQozXpgAwz(A58=W*z>MroT^X)}QM%<>zY7>pyAcYq_TV z$7%AmL{tACHRHdJW;|cj%*)}L^R!!Yo!V0~4ySAG>z>r){{fow{W8sQKhfN${X;X( z4{P%O08M+&)AXxMv%c-BY0qJr`EAzJUqk1YgZ|>5m74LHps6RJ8UI%_<1kZG&pn#+ z?ifw^6Ex+w)3j%iX54<%_;;G~dc0=dpVE}yOS7IY)#U%vn)>(EtlLvH>&BUye!Z$W zuYb_Ae+0dhq*Hj%pBpvjb)n`yA)uMBS(-fAL6gswn*1!(jORE_{l{qXq)t=M<(l)i zOViFPHT@l{8UL_mJm1mG%YmA8c%x<={+DLlzSG=~U7;zTp-kA9-r_F5NZi>Q#-Z|G z!#I`hKZTbsHNBR7^!BD7a;fS2v%kYWgx$%08of^w^-Nk~mLJ9b39Zk<_vhp8!(L14 zr0^jZXV_P+v2>dM52sRW)~BLw(hPrs~F~sw%T+&Vm!`=QK>K2{ceKI?UwiS^nDk znyQML`q_rE>6DtLN!1IQ${HIR8dXDAWWo2XJD3n#WtICdQS`?_EK2518rFnE!O)sVGgK|NPXjMg1X642at}1)z<@8q7&I{E2nmOhvwi3x@CS%>Cne@|4O3S0G%(TH=s5q+1n$;?r z*Bq0ooZy4HC1-R>^SqfgG-R?%zi7xP&9^#IRbsfNH;5`HSJzk1ttoG4sH>Xpr|F$t zHD&4qT22}p7UkT=DWL3@wHQpPX&T?qSW`89e0in(K`b3*L31)nkE)tPYg1J%El*-; zqw#M#hQ=)zEG;cPVrKP%+F7(jiCmgEtD>p2be6xmv8t)Dy0&S-#93t()%1@%fy>Hi zM>oxAO;dGkUFjIJ*7}CoHC0qeO_?#M71MZ8r0lCZse0D=R*S5K=~tcmq7ii!N77vW z+7ta4-HAS^!8`@j&WeUv=hrly9-!5}hF0&B=nSk9Tj`?7 zRL!B}&2?=mTPQ}eYCPP08n^}$_P-m^vD8Akc9@MElsgsTDi66a(3D)w9)HBd z+N?|J|IwLx#5T{=Uw8qRr#-Zh&)s>oxn{!5dYTGaMH=RbdmnLuop@@llVA$1(e^1& zW?zacj-i#iVqBHInq)0>YQyWA^iBAMC*Gh*q?@+|HFPC2@AQ7vZ05S9`mZj4Vxgnu zfi7}%@0ER#6RY3gOPg|4P_Jr(d7Qin8SK2UsaGDZh_5@Rm)F!+EU2rh9N)Mo(9}>> zRzHiD{YC?QLXGL(n!3RFhIs+H6RvMsP&J{tsd_=x#QNGMBj=V0HFY&jH8k2ex0W~1 zJ+Ee))$*J>nvK`(N_n-FP2$q5+k7Tn8p{?^&!|8-UDj%-i&XEJCXv%Zs>YwKpyji_XMb>S)H1z6lH{8!hX(o$N0 z=hie;Eue1EWoY22W|PFRYv#xYAnT^hI`)5m(L0I{mfe^CzCL;)nOr4rnyj1ZX>(>N z=gOHC>jyt2VZd{-?=l}8ocG6^AdG(@!?wF0ET!YjxJ^SS3#+rSU<+Dyg za~EsXfMGTp3n!qthv;Cgv7|;}dTc-6E)hFsqxg_7kb0bR%ndHu|64zzcC(u7+Crz-i@Pm#vpxLg^&N-b-Yjn(a_+c|o|@l(={jXj zde$)7hs-sv_C~Y0;wv$=QCU-D)~#-~_olSZ-O~xv=mBhA&V6(PY*#AxG;et5d1y}U z+-7j-g}z@9_n-@MZ{?viYs-Gr5htg-k)PaL*HkN?%S3@`)%A1f z3rcI_ghln$^J?j#lHSbAMcUqybp^FmEl(u|DpHOjPPNI^BDr(!CKfw-HJ*DTzeJ)p z+`(WKeZNYBLoc|S7F8{D@%_E^nEp#&Nsp1=Sjacg^%u-Ds^-nAtEsMU4$wEQvx3!C zb85u_7S|Z_=!*yX+O4XJ{PFtGwAz~ zTDdW>$e3G0-K}mEVLg2}StE9sS2J$`jgTY?tE%W7r>vHa9cXS^V9cQ}jE!01Eutt? zM+?_H`J8Vo2#D7*a}0WieZDvh-Jw=h)igHNH&js*<=3+WwF??%jU8LHV8N{F`Z>l0 z^r9(HJDZ%2G3)%QS^o2@=FoR91frXCM<1kDYSg#NvU++%7qe}Bk4*nbp1Og*xC0em z6#)&r9E1)0s?SpMOcdW%i+p4iKPs;>_}y6UjpAKa?kyt0+PpTu)+R-Z_@ zfL)*USYkc_YPO1ZmEsMRX0x@VX*SzSfM&ZgSPPnF&pPx_DmVIQF;lb5pT<{Kjyq{$ zRq5y>jZ-E~Jc+`pBS#;l{yh4KQZuYNV)T)`g?=3P=@@(S5u?W#qYoFq`j9v1|Aw#( zrT=Df@YZ~3R++)u#g-xTe*;^#<2?p!;3un8_8yk%KDSqDH_HsJaqFI4Gwz)$7KW}n zhE>k|9QfCAv!;PaS5I~;^XR`{MfqiM_K}7f0f+hD&3b75H$HSe{l?SwMk`y>!Pn4l z&g2_^=6HVQdiqVNVMdH%@h6XdzQkefFXBg6Tt~lwQ(!#Awrg!I{YKGt#u|=ylkrgF zIgXouUrWDPG{ktBV)4iN@4V@t@{eav^Y@L?{NHg~Zm<^ws5$hcvw9DEdeCHT?oKJXLR{otpt2Q(hkcu3u zHt-+VJHU-C=6V$a&u5Q=@4(&(Uc}x7zAJkIyo9|6d~fz7xYgej`2Jiz4en&mfFH(g zG-l_si`@Z!47(Hj59}^*54#)uWOfhuWOgrjIeR(yH1Fhr6GuZv$mFxlVv)F^+ zXS0XEtJzz?YuMYs{p=m!=d;Ja>)GSr^VvJWo7lU+FJMoATi4ShxSem{i@BaO_)_)^ zc$nQ-kezQ=usgu5<2u1taCsN_b?k2N8`(YJx3hb}?_>9YTkY|KKf>h$;E%Bf!JlLg zfj`6E0=}L-2HyF#xn9M=A7k$Xf0Dfm{5kdnxK)1-_={Y=7yNbhKJa(gli>emPl12I zp4NCq<3>|ZjF01?$vm?#w#`M1K*9? z=?6cMJpf+H9t0o99@2P=#@jUBq4Ai;;~MV-_i{VCz)xpSfLF5jfX`y@1#e*Q17FOZ z1Ygdc0&inagWtrS(YVo^o&VPPTLAtSuBQn6cJ>nRIJ*P<0d^<&Ds~rm7rPt$Np=r- zg53+gp4|s-_16#ncP<|Q?`02yzs4Q{?_-aFzsnv6|A4&{JjLDx{yBRB{2TTj@Czu_6+zic4J|79`3+i06v_(2)u~B1bi2E2l(&Uo#4B( zyTJEkcZ2W4?g6*1r#^5y-@y0fdII1Fvj@RPv4_BqV2^=Y$Bl!J)9RPj{op=8T=r27x-c9Zt$bn zJ>XXTUhreNd^va-dnNc3b|3f|?0)bn_JGEN8V_l_MdNMYGx@k3;Pvb=@Wt$L@MY|s z8t>A0LgPIe@6~vp#*^Teb30Su*RiL;SF&foSFszx?0mMoK;uOkFVVO|<4%pcz`MAe zZt$nsJ>Wg;Uhs|V<>2qKSAu`S?gRgt-4AYjZ=Tly@ZYcpH68-D&fgaBLawI`d>8f( z@DlbI_+IRB@R97D;7;}~@Wa>>;4bza@T1w2;8uTA;KySd^X5UUmog z>FiGM3U(KGCA%B^Ty_t54Z9cI&t49G9(yHt9lH;_p4|@~U=M&dvIoJN*hAop*jvDt zu(yGS*gL?NvB$tKV~>NkvUh@C$=(HiHG2Zwx}GM%?R*2jhU-a#-@u*$zlGgcoSkpC zu{*%6<2u3b;qor<2ie`=53_r~pJ4ZbKg;d|x7yY^1pX#_3-~+i zG4S3W%=I%4{swy|_`le@z&~V9fLrzVfPcc}d%?e9?*sptJqf{wbFafT!7m;9s+cz%%SI@P76<_|Tus^{o@UfV~U+x9kbJ682v3-?R6D z@5!D7-Z@`_6+!PcH`pg{JDa?0Q@R;2e^BPxxW+qM0OYW1a>$0Bz6zDRlgT} z8ka8zKZm^%d=9%0yq?_;egS(x<3WvwG~S}|Ht@xK+z#-|*kj<=u*bn~V(-*=m&Ows z@6mX##``p$1pf=SGX?%2dm8+4_6+z7?8YV8`D}TC#)~vwqH%}Dof>z6_i{Vk;BT;d zz?1A=@XhSy;NP)Vf)5#Lj*Aa`Cw4!033~v1KlY%;L*Ul=+X8+N*V6`mD0>IEi#-ND zhCL2Gmc0|)!`=lxfjt54W$yu>!kz@T`kMlu&gIkKmFyYtv)PSMc0T*q9pH1>o#5xQ zyTAkNZt#Wd9`GgXUhoimIrydQmEgZvk&-Zv*dO z?*PAvJqCU&dmMZvdnfoE>|Nk@vnRl<>uD0)&NuLTxt=umD)tQcYIb93cD}7)cYs^R zb%L+s@-Fc8>~8QE**)MJ*}dRzvHQTS_V~d+;PL_RkJ*FZpR$L*zhrL#|CT)l?jB~2 zV;uZM_D=8#>|NlK*c0GZ{XO8*xO^}8IqZGlbJ&yM_3SC|3)s^d&uHAZG&`@XdI~gN z1iqM$TLOL=y94|hb|?5v>@JPFHSW>4SL5Xxuhh5?{4d;2Klp>}0r1D!gWxZ)hcw=z z@ivWjXgsFzxW+rdd%2xm;BT-ez?1Af;G5Zd!M|hg10Rxa=4BFmC-xM0340oRKlY5q zjb+*SZ=Jsd;0JL%Mc{|Bmw>z29pGcwo#12HUEm&eH~0j054e}z3qFP22X6J(4?dmC z2f!=YgWzYghroU8G4Q$Uaq#omJHZ3&UEmAZ6W~kOd%#2Nz2KL!_kk~GPl8{@o&s-S zPlI26XZ4SqMf2i&@z`oQgc z1HYH+34pI+4}z~|4}q^?kAYjqjf1b_@}1!8*}K4BWKV!^WbXlgi#-W$wI>Ds0hdpM zf6Sf%|CHSbXXnqC>;>T8vOB;%1?K)v@Ke}b;FH+h;M3VX;8y)!@UyslId~0wC3ro% z4}2lJAN&&bfX0Iw4{5wb<89!V@^L%BuVRmZ-^d;Zzn#5P<6Rn0XuL<`y&CV+coO_> zZf6Souk2~?b?h1N4eW;ae^8?Qca)YFXuL?{B^q~V+^KOFcptaZ4gM~>2Ry~@1^>ltiyBEBLy&U`s_Db+8*?r(wvHQW>*aP6#um{2a%pL;2fxQL%7WOvq7<&i!?d&n| zyV&F4_po<@-_PC!{t$Zt+`677!R>qlf0*k@gFnum0bk2*v}EVoGwcp<>$pzv7r49& z{AG4G_^a$5@VD5#;2*I2z^(T9!8ddH0QeW|LGZ8HL*U=Dw}Ai59s^JP&K$=$_!sP* z;9s+Mf&a*!0JrMz0UxrPdE8#`;p~0jzhh5=@6Db9KZrf8@r=fe*6h5p>M7885%?i| z+!FAk*&W~~u{*&}V|QuXt#OaWy&5mqc%{aD;HPst{ov=a2f%CDgW!wULmF?yM zG#=A;= zdj|YCb|aFVhvV1_z{}W+z`g7x;HR-Wz^AY~!Kbpjz^Ajj!Ovv(fLqs7AGn=w;Ae3? z0q|<}Ab1UX2>d+u7`S!ZIQV=n-wD2uy$gIXdjfnJdk=VoJqd2LCk1{jmrsLV&z=Fl znccWDJAZCtF95%b-2vXQhq=EK{4eY-@H^Pu;P>2Qb*^Ov+K3iU(@gj|vXxyQ3r^a32E^enA{1|o*xQE>fej0l@_?hgL z;4|5M;C1YN@F05td>MOC;~{YC{A~fhoa<==kFa-ux3R~-+u7sbH?Vht$Jo2T?_f`W z$Ju+pA7oF0Tm4OeKg#9P;9cw)@F&@gtFrSs!R`R>W_N=Bjok&_%kBpM2fGLSZFVns zlD!=KefCQ557~X-|7Q1tr`QAFpRfnPKV=VrZ((l%|AxH{Jj31r{sVgq{Acz!c-~&- z{B?p4WA6gro;?9>T~CwXcD{k{$n~VbN3dtWi`k8<)12xK8kqT;2tKAiEp< z5Oxpvk?daZKd}42t@ilA$8-4r_$ll`@JZ|;@M-KV;AgPMz#R^A9OK{zv3G(W#@+>f z6ng^Ps=o*PST5fSUdG-BK7~CAeg=CAyox=o@r=few(PvJ>M7885%^3#ZV7ljy90bN zyAymFyG!G4je9ii)p)taD>d!|znt6Y2fvOz0KSqv2)>Fvr12Jww`sgX<1vlLHQou{ z#qI0@f0{i3-oxGlzLC8b{9X1w@K4y2;9s++z>Se+9;d;7!=BN&u_8PFt@F14ypZcD z0^fzb1iXaZ0lpWz6MQ7Q3*5=>20x751MXt?f*;N91GoC?2S1L>2f#h-LGTIeA#g8y z4E%KVICuqnCwL`$7x=mC3Gf>B9&kT`8E|Jt^?Narrd(E9@EY*Vv6~v-9Uo z_5$#C*d5^MgU$V&;NP*kz<*?SgAY5ztj7ax)$ax0k;|8Z7qeG_@6GN5KakxIemHwT z<3WvwG~S}|Ht-|(xEisc{#03%An^el@!Xyo22femi?P_(SZK;A_}@;Lox9 z!F$;Q;BT=9H68-D&fgaBce$Q6@DJEKz*Foo@Xy%e;9J-`!87b#;6Jh_z>P!AeCh$; zjy(x(^*05+6PHhe7qMr+cV#!)v-7!x-2uK2yAymrb{Dvl-3>mP-2*;`-3#t!F9$!C zy%PL5b|3f&?0#?$djR|-_8|BK_7M0)_7?ET>}}xX>>c10>@n~&*yG@TWbXt&o4pIX ziah~tT~CwXcD{knjYoKhA$R zkIVOhH?#MFU(B8azl=Qvel>eq;~9+`*JtOIRZoG&i@>kpP_Kd@&sZggblzjgi=fS<_q6oHRtF9G+m zJHRKiJHe;2yTB{i-QZ`ld%%6{Uhp~WK5(nQe(*Xj9{>-q2f>@zL*PO782BaZaqwmA zo!~9(UEo)-C&1g;d%!!`d%^|_%+5O<(u?I9B)Obka zEgEkF|DKQA0lrW>15UWzT?5 zWH)Zg&S%RDG+w0f5{)}F?$o#oyqw$V20xSC1MXw@f}hV`4t@c9CHST6KJY8q{ooz! z0r1<|gBlNkTjy^J_}yGj8~A>2QXu^TsM=W~+X0sb+&6MQqf3p~y42LG1b1O5}c7u-0)Y+pI}5cW#& zVeCHe?b!X`1?&Ov9od86JF$nrN3gem7qhp4m#}w$@4+4e-RkK^(#@RQly;HR>Cz$@6j;D2KG zfm`kIgU{mf0r0u(LGU{E5O^bd3;06z7`XE&a~$K~hqHHrAI07UejIxO+^W9^{3I^l z3qF~>5Bv=FB>1`PDe$@MX^m$zZrqxkS5`d*8ZQDrkB?gdzL4Dkekr>XJi_kMxLe~M zje9j-uJKBZ`@pZ}cKX3@We?!bqF=ig8!FOTLXx#WqcK%!EZvpsjTu%}B9_%IH4t59l z0qjojgV|l+E_OHgQS2UYH@g@71a=>|)n7mO1TG%{_p%4UC$WdX%h_Y#XR^n^|HR%2 z?qlx)pTnL2pU2(<9$@bUZ)EQSZ(>h^FJw=F2ieo$i`g^a7qJ_$>^xk`UH~3uF9L62 zF9DCRJHW4EcY?2AcY*(z-3@*{y9eC5p8CM;d;`Cc>j{9bWDkPh$sPi~mpuk<9XAfX zipzI`|CPN9d<}a7{8{!M@V~Jq!L9bBz&CRFH253r8SsCx8!NN(=Y949@PD&Az+-N6 ze<%3e>@M*8+1=oevU|X-`n}+5xO_SI^X!%2FSGl=|H1ADf0sR=@u0>-8gJ2f8~FQt z+z#;1*<;|}v&X@Qjy30{Q{!D4PiVYH>hA0yBEBIy&SxXy%PL9b{}{XyB|En9srN92Q?l7 zx6a=d@T<9=Ht=iNJHR{GW8k;2$H7;!cY?>+yTI>fPk?u__kjPEJqd30HwFGAmrsKy z*fZeIu^YE%=W`Fc1N;?sC-_Eo7kD4L8~h!15BNvyUhouqIrt~+mEfPU`@lbE_k*X| z1K?k>2f@E)4}t%Oy#@Ry_BL?iSaaMvz=yKOz_(+MgYUrJ3BD717kD9i0^GWuCc*7| z1K*kJNrUgso&n#B-MAw=-}Ys9fLq6Pf*;J~UErhH-QY*Cd%*v|?gbyu?gO{l;|D*D z%Ll+uXAgo;XAgm&#ohvbE_)2zb(}elaqwf$#nN@VnRp;H%h!;Op2!8gJ2fo5njd9@BVSDz^(rJ!6$L~0C+ij5PUj&2)vR#242M;2cN~>3GQd_0Z#pToB@3LpWKV&!J+4=Jcdja_8><)16iRS)J@YC5{ z;M3XN;AgXYz^(ed;4`^=Iru#GO7Mm3KJbg#{ot3g2Q(hkcu3A0LgPIe@6~vp#*^R=aXVAsPqC-LUtrIG|C8OgCp(`lFVJ|A#!EEr z(703MF7PC`(+&PHy9YeY?gjsWy&QadkJ z?#<5U0J{VH0(K|(h3qcy5W5@vGIkGml-#$FD74SOZ{pV@uj*RlJ-JJ;cueDQjdy}Oxt(3$hqEWZ-RwQ!j%G|%Ll+a*@NJZvWLLC*kj;Nv&X@oW$y&h;n4O24*bBfvV=n?vvzLH>#qI$AmfZ>d zA9fe`kL+&nes&MIbv^Zg+xZ4Qkk;yWoGQhd1L zEsFnE@ixT^74J~INb#8BBNUG-zKi0Witnm;m*T~WClvpk;ysG*rg*R7C5rbczPsW{ z#ec7OO7T4uPb1N6faWTp?HbnBNcZjzOUj=#rIR(rTG4e zyA?k`agX8$D(+SMAjQiScPd_~_`!<%6hB09zv71~9#H%+#e<5EQaq&iXvJF;KV0!P z#a)VbC|;^~Oz|TWk1Kwp;+={grFfU(V-!y)ezf8}iXWqRui|dS`xGCmcvA6W6;CPt z2gTEhAE$Um@#7UY&L7DC6BI8{{6xiz6!$1zqWCz)9g3f%xKr`*in|n_ptxJ{GQ~ZL zpRBl7@lzBpSKO<3rQ#D6_bGm=;(oF~t`s9#_0c z@lM5?74K4fq2dX}FHpQk@u1?piZ4>UPw~ZyCl$X?@s#2hDV|n*iQ*Z>FIL=`H<16A zC|;m=Nbw@YmnvSO_@#tYu@wnn%#qUwPT=9DquT=a##eIt3uee|F z2NVw|{-EMP#UD~Ur1&buTNHm-@ixUDQM^O(M-`7LzFP6P;(t}VQ}M?X?^3)=@r2@! zE8e5{8pV4Re?sv-#h+9>srXvOQ;I*Wcv|s<;u*!)DQ@ulobAb;QM^F$XB96}{5i!- z6n|cEhvMrMcPiekxJ&UK#oda(ptwiz7Zvv^{x`+T75}^9m5RTlxKHty756LtisAvq zdle5VzCrPj;;$;+qWDI|+Z2CI@eajbS3IWpKNOEE-luq{;{Q~jsX`LMpmGLS& z9wy_JcAPKc6?VLxjF;N6xEcO((|kKFka4vg?;zu;cD$pE$Jz03WL#>;JIQ#Y9S@iB z2s{3*jPvZcP{vz+w)$Hnxe}|0U zv*VF6-eAZ3%6Od}?o89_*fZ_v*SO=xYUl1lkrG9K3>Kn?Dzy3 z=h^XzGT!oo)qjtS-?QU!GTvavC&_r79gmmsDm$JaW)D<5Oik&W=x$aj6|olJQ78o-E@Lc05JKd3JodjJJGm^}k%k@7eKG8E>%T zX)<1C#}zVOWyjNHywZ+m$asYvpCRL=c6_Fc=i70mjH~VVk20QW$7jiSoE`s3#-(m_&qybD&q}ye5s7r+3_+N zud?IiGG1xNVHvNm%TYh=96j<1#RDm(tOj91!myNp-Z@pUp@YRA{h zc)lHX$hg{$Z;);He5Z_8*zsL5UTVj8%Xq#W$7Nh?$M?v1svX}e<8gL; zpNvcG_V+ zJ6X~)mYc!eFWm+?|N?w0X8{1L=&L;O0#FG2h~#A_j54ewSO48)@#J^`Z-KZS z;wZ#nh?hXz4DmdOYal)c;u#Q6hPVvk;~^dc@hFH7fOs#6iywSO z48)@#J^p7zf_Yp6x%;&L4{=cuyGsHJ#&$gN0osGGT9yw{32S5C| zzdQdq+L}jYQ&sd0f;Vz}3soV$QQLGPl^UqZe!hElz}l#iMYKD89oHy6#%7v|y^;I_ zMGbVo9r}}n`-DV0p5;#}KT(z+bCUQt_-Aix+Pm)a6TRy)L%n(Hy&HaR+LbE!slu$F zpg%cB9@pAme18`@es|i}Xg+j?ciHjJP)Wnv`cczP)bf8*kgDC%-=CUIUxuyE-*OH0 z>>S$HKEBw0(*?9q{4j&|qXBXC7l&!b)+PV)wl?=tSLV_KuD7);ML#Y#e@xSl_n1Fs zyb-ab_y}r)xAh<1*6!4I^yX<K1Q6j8p@)O#ZZ~ zQ8YSIM%5O7LT%)FPNz56S@oQ2*Yjt!o`dXq4l(P=P(2UdY}a!=y$Q&w=XZ8JSE}{A zo3`5XJ~gkq>_gGYP2%lFr0hd)hc~*b_*pcx*PGYtjZiy9pDs1)NEOiwSDNHeTP` zY3pMger$%l9QKJ9@8{TcQ${)Zi;oobw=T)FHh=AHospuPzNd{OGC3pOcG0Gn#bF;1 zHAV94#U}bzyT4h?Wc&@on0B5q?s3uPab4Sq;?d$}Qg7=9x%X2JSp}z60ZliZuMX&= z*^c|lv)a)*IX$VhEJ?@wJsmSLIqi*z#?f)9H4R@_dGjYTkN2jpl)SCaQ0c#4ZMJY) zWJY?L+01d-%^Yqvvruj3FtwT0G(*%(SKGiem`yCmZX%^yM!eCJ^Rg#ZF=&T3PS5HS zHE)J!9*nJczeSsN=9Zg{{_r1JV_RZ2`eD-CV|zcHYPrUC>8BoQS%2{)*_5??G*GRp zUz5Yt-Xnr&Fa0~IHJqT2+1|*o1Dvu)Wtq~%`tW8#YH$9nS5dR0?IQF>qM{Pci#tE> z?=SqTEVn#SxLmw|r{WD%JR&RhM&wbvk=5o--KlHo?XNuN3ztuzyfNqRT#;UK{&o^a zq70iBX%`Kf)^F|@ExwSFSV^}1%mGQt)aGQ%n#G%F%@DJ==^ZK=35&{F!=H+lN5g6Q zSYuFed;0dGjG_*T4c=%}7K?<%_;5c*(ZUpA&ksiBXvo55$HqNQr*8i^xm<_@eTrW3 z(m2c&18CztznN@ zL9ZEkDT;(kC}<5&7hB9j(}6@i-eu1?#09_gjno-5|Mtc<@&9Ur5tGi@*YYyNSRFQUO=YGil#Nih@jhpJ0cGu8~F-R!0(#rSbsqES(li}Cp$*fbz? zj+|$R{~IU1T%xO{_*ecY(lnaiE7DZny}VD~eu%Z?BvCt^<@R`Xr@jy;exzLt3#Gt6 zTR5|M;Azd210OAZnyOIFL-F-HU7)X$73W$|=88F>HFNVMs`gT@)~@aG?ApYa@l=~f zTifntZRX|P8<`=Ns9ojdg_fv`XiTz}s6c;l+$&F`INjaGT4&tcI=KVR2%45B>7=Lo z*E77)vd%RgYJxorXHkujV!1}qHg9zJA+lxS_C*eIY6o$Nj4tVnOzw!xxS8%HV%|tu zd}6D-r5H<9ZQe6`)4+PZ2W^#iE!d6KsjO}+{ZxE~*51muIjQ)k+A3?r!p0kjs6Wadees#&=o#rq^|r-^r5W9yKG5|X#HVU z>-W&L{!;pOP-(sRuAN$6Nt(O$_tI1hwEli^?nk1c!8B(r-sozx#oSb@mCYa1cIZu6 z3v|UJ#wC)!E==Pr>M|duUKF#^T_%2Kf^K%q+VjtmW!lYQk@JAJ2Dj7lvPrBu=GYp| zN7*}3hzRX=;)|qEd z+sTozXyv3?3F^#i%SC6_%40<*x6v4g3auHHtJLJyb$oLC#1u4b1Zr| zFvlU?9IyCDTs;Q5{?BEi>r1How)%bd2WG#i%g@Q3W`ub1U!r7-M9m?~56Ep>oAd`o zu0--LQ3{$#6sCG|E-Yu$kSpus(oY@vVqpo7r?$7QEfLq4*40JwqrE_WL=F0&r6og; zgcDk$UyCQhNST8cjuicfi_NmNqPS6b^(l0sbcYWUfgJrDH^+vU{%F`mW!CIXh3riG zn8s&Lx7;v-Dmj)4P;KK8CNOvA=lF6J;;`beYEPMZ!WOMr$}E zKIOmkx~nz3oWf0K$_sD)?2E-K03mBAv--`qNZZr$Z6;^_ro-jB(?kV~0+C3#RtAMv&Ze`& z6z{BF>Z)iQFU)l`$TX@ST_{I2d?S4WAamXe&lUUAY!9S%1?6+kP9mQt9VheID_%ji zuJ+JJYx{9Bh`Q)wLTlJfA8M+nN)z4T>4el^G49Dh(~=Ss9}V}?y1J%_(%DYjSHy-$ zSRO3eF1CA@KC_cZJo7R2A!;P==*<^y@A(aFSsxa^ac4yG`)Ey|m1{SvD9v3NWqym? zzPVW8mu(KMl{*(M7r%>0Z4jL+{A+p1viFT;FW%i!UP8g{%id2fdoi!2eD_FH^qNiw zQH=6MbeF0XT@{&q%0ES>2;_p%)p8SejY|B%e0O=qVj5jKIr>+deJ*~0?#+~yYln$x3y+x!Yq-~~lnCc*PlEzGpo9ZHUlXjZgWvYkN zOPVmX$JBDtO443a`%Lwb`bm?frc4cx21(PVW~8>Y$oUI}#7Aq`pk8}h+Y7{pIjP;A zooSOb#oeCYZs(Be&J4QE;`gh$QsBE^nF15u*j5U-#f#QRenk*c;1l|7QzZpviN;2Y z7n9~rfluC~dg$V1robVE;;rpY)L;6tBrJZB7L)n=fu3wTlb8HsTiuv1)|yEEl^2Lb zwq0ZiU5CA5E~3SAv%7M>*_DT$*L7u|tgcl3R!+<_w0w&T!aiahh=#=xyvtG{ah^TY zN6Qg?dm+zOZ^Sdid^m_xH9VD{|a{beEiFy8osW68TAwlC=Nvw3Hcz%f-K#m_H26%eE8q!;RaTls32#NGCRRhhO$Q@f-0HLk<(&-kHNBR$BAE ztwEHHnoj8&q6yn{DqZl_ho@0dx>Ai^B(GE>X>i3}R(hLhyh>i2M9IzjLWJg(hQ z6z9`iynOCX#YHlP*2>Y(RryN-W~zQbMIuU+?-zOt>kZKlUxTHo6O zIp%hcby;&uuV2Mk@Ce;x<-UyXw^5y2dbw*XljBUc`eN$F%AoMdv*fM5oJ@JEZ_cND zB3{}n2E6ARS_f#{is@qTEUkKSO=#Ml2iMv@RBpdhyM2hR(Du+;nSh1M zU!xA-1pM@C&a9y?Z)^0wqbD~z!6NxPHt3f4Bwd@81?f9;Dx7rk=bnlVI;jVi_`dwC z>!*FuG_Q^73Drp}kGS^sO- zp7>gfRuwu!<%f0qafMk`Eea%w0gcO-uaEp>Ex*wwnaQk6TtNOv_! z`&2+gC5>nZ)-7A+k7qEp^qP_vGHfnRi5Fhe{C$;YbJ@ZTv@BJFO`oM==Q zu%7GXy~VLqsrE)}AeVm8i-ezh#G$tKBH>Hc{$R_L+7<}hDk(?;{{0a;;gwFFYIgFp$COSwL{F@5v!9?dlsf6^qJngw87cMK^}Q*Vy^(V=18>6U zMcBYg-eu2)`iqY}m|E4kR=i_VUwhH-ebH#i*MjthH%40{@?ZIe_YMj-?M-+7)T=A# zf4C+R6{5W1&F|)Qs05W-h#mGKKaq%Scu4M#ZoHV4_CD9@6YD2d0S>Tq{Z!6oy6byTiv(KtCAt(m?$74*!_3evGyo{ro!l z@x4W{);GTL-sf%ozI6zFp*V~ZQB)wNm_GP-0}5oh^>iOXZ%g)}G>$}Np-BE&H6rQS zMOpefU33J$#TV<-Ci*=``V|1t%pLweY$iQ~Qg^tSL6MJEGas3~t!Dm*R+vp6iwdIc zVwfXQF%h&li0{12N3S`rSf_ghoo?l#O8FL;zrQM^b4FRyCd#^s-_!jKsYZGhB-{?CL zYbDM4J*C&4gEV!}koFh{7u8DTzB|Ks)+_otc?579<)#hp&l2Bs#lBsMe7^ZiIs5}MWXPgJ1Dif z!v=?x^d;7h(XfMlT(g`C&@GxsjqcRG)I(ZFWsS0q!RzSV^k2=>2#S5F38G?Zf~Zt} zA;!PTHt>a5+PpLsiB)q59f}swd|HV`DDO&X5&e!@;h_fDt+@GFQE84vbQx`k6u&^r z32hepd85N`lo>Rzh#oEuNZ)pw?K2BmUxA6%TJznVx>Me&%N|6cgS$NN-Iv){dlijS zTQ`r5w3~aHM~bYL6-33jduP4iUH2Y+i@3!b*@5mgX_#aUw2sab;~X`2q2V4cCRvU% zt*K%*$I77a%2P!WOEI6PMCH7uiut8MO!>?;^-0~DdJrXi)|xtS$zS?u(RLznCybPd zTOi)%w5~SjqqY6VO(KY<=>w9PQin>&TB7*}$$OEoQ|ube-`kAj?~c;E(FI_QC}&UT z->A*voc)wGWPLgIu-HJSg{-DsY|s93>>7F2${pd$u|C?eKD?V~Q6&EfT5R~sFc{ESlm$)@uSFyIf2^V*mCK&lr(!o%q%3=<%Yzkf$JJA0JVj4!q6*4mx_qR? zh}f^gUZ(GL#5yI~My*&NHnxf{2gLk%qb}URaW>jfLZ<>+Mj5eB)-;7=~qktK$GozpxtudpJ89ib~EoO9|8MT?w z9cI)aqi}$}T*yA><4=nYh0}vJTy1U$h@|pRPwb>xC^lFl5f$5MArkx3>LltH19s_J zSw{Am!Xp!c=}9mu3q;JpFfU(k(78whw>&0C3)10}N5$CDC4$r8P5C6Sm2^1#b#dT! zIZcuL@#oMl*YvOElvqoZDJfAW4_N#a{SVmWeuQ~jbkt6XC&aI3(EBqnkklog*eJUs zyKZfexiHM^Qh0-Cbu=8KU9!I|J@P5qIod9gBodWpKK*hI1?GsH5JR#bj< znBKgVxxJeQ-fHd7bmOtr)>dp(TRWHjS5*e)c7Aqimzu5JP21YMtk%9uC#^LR?P4NC zDvQMCC6ea*_oL~e{;)W?>8+KVlJ3;mVxrU>FgM5?FzAvg)&p%09R8#@j4lVNpO8m) z49bBFt-o8#fuY=GYgFTui(4JlpTt`nI|oLbrH<;etFm%He6de!^tw)64%{dDWamID zeTzuz#MW})b~=DK`K;D{PZ_?|)}Ef#+F5^8TRShiwbz@i-9_8lpTrp3t$mArMP(Z~ zu*Wf!0}oO;$^p4ZQ(jbxO4J-MH^?0Lk(NEWJUX{g?FA=MwP%{u%GI8#&BJQV4YJxh ze_6FVolVsmX0`INLDk+%ce+`vH8;p=r^srzlCewZKd{ng>_c6&m7YrmW$ejR@76MQ z>O)p~*|Q(8-xYH@y5KcH*vX<4m3ShSWeADUHbl8TZL`pz-L^Q)!GT$YV8g5 z#52&^2d1m7eT*toT1&rCC|Y~YeY)13lGWM+L~FO619jDu1DWlqK6<6dIdGepC^ZMn z4KfE#rbYZ0tXko@RP9Q$T6wQY%gbq4t+_!~`vt9NTTQLKS5up`sa5`{7{VN>^)c1E zwbc6ZUUMX^$-16WajU8I>5J-Q85QbeJxrA;ll6`{S)KRjChJDgCp)!*^z^rl)Vc;* zyNPZww%XbgvRXTBn%dg4vs?R-+1er6)_y9+*lz8M^j+mPQfvEplmoX=IhvUcPOVc! zC2DG!8)Ob_ru9qYzyw>qjR z@jBUFUVbcBNA*FfOv!<-%~8GoZe0#sC;DWMYLon~aH}^(S3zq(q72_^Ymd!p?Ubz6 zR%W;M2eY+5)31l*z96Q=7~8E~FTMuc`ttIAfO6mlDn~Qp;v5(+Dxn;pWY2nDHn+=E zNYXMUQsD{tj%`ocky=Jck^iwA$go>f70rJ~HZ<%pqgTvrUKyDWvmx5cel&fnlXkKW zYCda5+eO{t#hLh^HR{Y&G@4<7;l#y9QfYZ4+He(ZFcX&_Qq2vrwMUq(T~1#dP#fVP z^+cX}>mhXv-DGWbzOE2YIN*)6p)5n;Pk)yREGz!xDPrv2(V~e6f^&#Uyp&Cs3Wr#2;o({IR#|CVqc0 zFxJFx&d>QyJw!cFUQ;gnw5Y%M{+-1Cu+5M3mU9RlU%V=&_uX_}=l^h;c=KEQTy_HP zCHr4|gPb4!Z;}dxS?|xNEGW_~mvGgq*s+qUBuvDssHoVO z_pQCZede6W%z%0C_kPd+BR}OkyRE&}+H0*{PMPlVwg_=(YOPIhL}D`NURAK`YfbTkUVFZhc5GZZ=wehk+9o(KD@lhUTaVoZ;_J;7Vi-zMnF z3O2=HIloPyzPHfsa2bhjBTs_UWU{e>oiL-6r0p%dXRkH6nWpjzc-SOoqQQ%vLZ?TC zYuwRn6LfC{7o&!>n0Smj@a*M!XXCux?eQk&9)H?ixj6ta-i9Cna9()Nx7Oqef7-W5 z_Z8Nc2797|u;ru-Ov#crJmz5r2zhU62EI28{Syi)S)BoJO0XSYGx01-$5)mR*yq7} za4I@ass=nObgEpXiZ%n*wgEvqus1}XYg;ulIRVdqK}M8ai=kMH=VnOVOuug)d(wihuCz9=M8y_-tT!$0HN&+JxFg!TvX39f2w?!N6$se zz{gid3m^BPZaLpWUt2esY`SAnbyj{xZb_-v=2-U?>0w$bCr>kM@$_;leut z13dg`C=l=P%SQ%I6v6@T7B{h}n%GS-iER`OG&h7qDmC&I2rI<-xow-y19^3n=WPepEN7MD$8@N^h+6b zpc{ux$jx_1_Sh1K`dl*nx|}j(!+=4nC2672PML*(AGk^ChpW69PLeKpmKu_;I>ea8 z@OZ4mA@y=B#W=$jV|H3tjBFn7ipo&y4ODVj~z`9fbm(pVVET%HV1+?2@39ZA|Z_h9wx~?hbn~>F#)EcdmiRWp}k7 z!%-l?G@*s}Ufg7GwjsIiFBV3lxx<;742-E7D$wCP(0r||GE`K5DU$o!o-k(A+QEH$ zcefR~+o8^GUEEg)6>){*H1}J3DDKa4lffyyaPM`J@kyT1`4~+G+@AyPVfFhSjZn7m zudO~ux}eqn24i$sJ?@K2KhG?3XvxKH1H9>U zC762mIdyqc!<3h?-FJRv2f`k?M73!JVV_7*94rpWsSd+P4tBKt%$ zBer5SGD%iU2z*e3+S{~)+?7RRk&8TQckU)Jf#9Eug{h+DvZnDX@Rv!Q5^z%{B>bw0 z>)8`L+$YuJRS9@6RFN?wp-{DN;P+e)&bq3^-BbPE4B=BVsaG@?$gq@n{=8g<<9sRg zd*&ixhPiFIOC_Izc_?bff>|kjdLY5=Ie5G0H<7CO@X64$zeYJ;S)#~?NC7k#@&s_$f zEpKsCtkx8NpC3!eex&I4D!q075#0GbpOeSvZnokPr5JIuE2L|`Cs`mY?0j3;V;!tb zaI^M}X6*(iYc64*FW367J>f8Mv!TM7x4UqL{oJK=vs^dP|7oJloJ4(+XQqPdNfb2v zpb^#09#LK;ZZ=akVS&z;0OHFjoJY|3GHHx8v%CB6b@%>xvDCdooCS{R_mqidl$#a6 z6`XFi4lGs{2u zrGVa%HZ;pdEmkB13x7zvGQuw{qBBtNd-9hmrH${)8INeFnCGD5mcYJ>D z3{ha``{Z9w9`zU9-?}YO8WMlo(M@r%T_7y%SxOTUT$V`zg?$rqt79Ori56kMFN-B? z53*MKG-g(R^KT)g-}{ls>i6^qT{W$3bQ5i^i7s#wb;u>B^;l9khWU7{l7!igVRntk(1$?} z{)X*(I$R9f_5OZu5ADaJ9dw^|(>+%L$H&Z=MI|ZH4nv-`v}dmul6_ezDZaJ)-Kcx_&vvx zcw-Vj(@ngiCVs7xxGMmy5-XGq5ZaOW44e4c3pK~fFeeJ<=evocRK{TcgAUGJ#0QYL z8nIhY9knlW(}2@R?ph}e*J*4EO`{b?Yy)IWZTVsqE}z9^%NMuf>It1GmkadeHe5cS zFSp`yvcBAm%Za#b`QkoYja65BaFwmDq+*u3l2fc#J2$X!KA4i3G9cxul#IcHRAhP` zYg>mOz@UY5%gMP9O0?<a(bc*&z6XEGl49UQ9fK^Jj-b=_UU{$;T}DxS?gGm%Ofr zcf~9j-q&>EQW<_28}^pMmKXnha} z2%+178x=QD%cBp09qbc@IFhG|0CY#ET_&o_s?$ew$V6s*xKfOScT8qem%6Bn&I09F2l>E~G z1;M)^g5Pr?0vIOProj#fzc^Yy2K@z(gk6|(?(NREvWijAE07bsHf3nab=SS7e&d^; z_D=|TSNtRjzehgXkN@!vcxO58kW4q_B@_3c4*tiChpHv597p&e?+8>=y}Lg2j`ml^ zYwzp}yqsj}#^7cDj}Bg;_9_@$_*@=yjxXf>RM)|KX|9iogXf@()VpG%CGyJx_#f$G z#j9L520X#R7_T~dxX<)WJ>d4BoLWa}0!%>Yfv(B}MY-rrImv&(0FKfk**+C5B3KSC z+K+)NkzZ55H|Q0=io!z4RwLp5wrx2K$wd~7y!C@yV{b%i40V=A)JcF!!gMkrQLm7< zP*+-mkK|T3`NZd{z{?u-{#P3I<@g_3Jza7B8cHg32|lZZA4x#T;i}}-UM1UmorR3F z?GO(Cw|zR<*@gR2nK{rDf1icYtHPI#=e2W;1MqIv+FH*82xsxT@p?KY&r(R#km*)xnEoy+q@;m*ZSx`e#f z=z7rN#Ldn@(T1YmbdgclO8fHb+&^NuVm++)9QGA;2+g zy53S}y=Zm7Q-Pz7gCFM`zV7P`^c3=@t7aRvegW}IR&Q2NwgylVcme-Lj8$f=u{h>+Ne`Ll`7h^1DhzJu@RywQ+**I%GZ=2UKw<* z)N4sXkCtx56d_bX@@-SP+Wp7EH^j&xug@CLVG?QG~_9={4@D zW((U8@lh-n{AIe%YE=hsi=&188qu%Vzv@-uT%!$-=Nv3T^wv!=j3-RhxCOkkK;E%{ zJw>tLy}`MWb1mOziIVK^JZ;2E&elP|$+$ke{Ta36GJB@F zqM&{Ct$nqJS6hm{kSpl8+zK|5`KzR;z4TSMLBMKRR1O+-266!z-^+pg1ojwLH|OG% zG?)nn)km+ppN0LFJ!~UE%rR_unjal{mp|mtjceFGhxN*qPEAa;O`9qO3AZ>(E)Tm? z&U91@1VmB{hluW9EzV3&5N&qHA_~u?Ns+2>*0#cZBU?V8?+HfOu7@JyMz*ru8fhEP zb}z=6l3#VNiNiFmY_CoCs<80yKum}5DO&iaoSQC}@H<2*+h&{LR1Lz(7)EjP!V;wc zu>|;_r8OknD|4xaN5N;Mt-fuV;rC3zLrhq-pXTB_uv#n#6!r-~Z4Vb?Mc*!d9r4#x zyzh%9{($CSgKCdA%Ei7I8t}3nQfc<*)T?0Mer3D*89Y^2FN=!qmmkgQZ)L*LjkD=oBqaVr@v6Nb;)RWw4RH@_7TN;0wBGmXoslW@5x34Lx7O)?y9u_y8ho3Spi77dbQYO zH-Uz9Hrz`}<1GwU%+LZG3oC)?$5ro_IAhQYgULp6&$sPjY57rDmqW|NTFX7zDN+${ z9p5Pmv4ia6s=6(2^FkE5RyJ2|=ebL#+UQiiPWg1|7M*IZQc)JctL{VZSno(VjH^_Xt?XLyV+xdAcS1}RyS`4v z#~`?YW)LaAwXYIDMe<-NSl*nbVr@|uAzipZz?#@hFCr%5ZZLY4Joh5PC+y%?&p;Am zC4Kl;i!xAIG$Snjg&EneI`yjx5sL`b(ky`U8RpC)VhNTquya+%EPzG-_5%19tiSQ& zYRJ;W5mh}tZRWCwP-7MFUgNf!lOZy!<`i}&8gRc=zd)q2?R%2k9rjE^jM7uTqqo3n zQ6Zc?SpdRj!!u;+k5}h&jF~^68qKD_F=pc`vFIsVZtN*W}e)zDSC+O8l$U zSow=wD*0L+KI&lvsqZF(a-~X&p#CyN)$jT8B(=t*h6)f-9T6Z2HKC!9GXnS|&-m4( zDWEF14F>7;cN@xYNq&jMS=ys6Q1-YKkx1;Z3iB7%-;fv-W&O=7s&TD!ZqMACATA2> zK!0t4v)~C7^w9;q0vm(|>`;ip4wd$ub{PIWntLaUW~D+Qz7TmlNsG>NKoGwXhK_0v zgU6Uk4PBLzRi$21X(xh$snp0-sjaFsS}JXFRBGI^NZ(FW*3u`Ce1tKaz@!BGvX^`` zNR77Yv(=UT0Z{={x{SUE{8&m(wy zoV+cD>SSCV(Ti6#vQcBek7}19Ln?;n@qov$>)-BX@M_KA88I1L4EqQ(c#lWq@!X|Y zDoVnLV$H6sOPLyDPGEx?A^&QrfPoYb3oqH5LuAhFPpIA_9%M$GS-bFzwesrc>{G%MZVVS61t zuqBkyaR2y4FiqrCC0Ig=KXz4#yWiN|y|QR;T^f=VN#h4h*I0(4#HJyMyWh|h^)gh{ z%j1^^@5Cjer#5c)T4NZ(aa>)#_@Go!(Zla~^Ejsxzks?NN}QyX`0f1;CHf@Kgv1=} zdcN8oSc4;$`xKj4|J^0*Izpl@P$BWbDLN!hgsoR9y8%U5oO5=lGofCBj_|zyiE4Zh z+V>gVCSrV&(JR*Mk-9D1>=R#-{t8to^ecMosuFi^+1(RgjH*jVvRq?CI{%(5bfna# zBZ<4W#F(^dC&eG9mt{)SlUg9EkGD`;DmC(W&ZCWUoNmE#)iF-kcuELLohCyQZL7IK zY(}Q8hb6#ZgUxYDlYHkm=>j!QwfE|A8vS?1X*LM@J^c`lux@}KS?EZHSNV}1C&_Z@ z7h}|1=~hZ?-AY3HQRBKaBrB4}Z!i&jDauJh65>Znhmnhl^xHurjvpO|1yS7b$yFN? zj!)q+&hcpuk8zC83Ozncr^Xte6Yl^oGDSew7$5g-jRG)wa7%VfEg|oNA4xA8wtoVW zSh6c9+X}#v9skx@vImjLCHvJdD;)OilQsd*0G+ZvRjIx@m7r5SbgGq3b4qs235bNK-pjpg0w83y35WMKeX~WRz$8tj@h7vJM{qs zZq7IIOb3Qlq(X~5VkiOcql{p`iut3@OABOdbsgLH(86A0KO|?We$O+l?YUpk^UiP& z>~VTvuW<%Q*W8~f!r60wi#EbrnTX+6g8?7?mhz?`8@>) zJ@DouIRK)+<`7H$BAAFG8Fx<<9-UfuPfBmW!Q(3Y6t(M7T;Mr@qqW-c%!g8zEN!&@ zha$u|9IK;Jl=ssj8P;fl?{(oz&PEpd&T;Ym+oK|kZWRbQguYY@UG0n}E~9$~ z{DqBfzE>HOh!Mr;UX!}?EZ2AEx=m08(u|{kk9#J_(_;9@|A}a|rRZxhK%D;|^zr=1 zn8Sad-eOg*&VNkyAb6|JF4&+Nx173E3F9;zxN8D6w~X%k0783Q&3!G~c)w?VD`-xe zj4&HEoBu#p4h?2%4L(-rFdLT!10uZbwu4*Cu4g+;9b$I%d#;cH!lw_EYSg#0VMzh} z%%_kGe>!{X9pKt?5-OLd#(0((B(Md$w;7&9#wExa18e!BJTrI<%}suOS>?1WiW<%` zR8Qe=t>xZz0R6ls2d3EnVlO7Q$!vEz-L01#tr!1&vGg)=yi+fiA1%MUKr6Tgp^{dh z6oa5}BUV5TD=^uu5Il4?P64Ggo#++xz6t+Z!Hv=lZaQh#6ey{5M;92$lX~<@ewX+& z7Csx-LSB(0K|F)s!e~Gd*Mk_glUqR3VJEj~ecUxAmOgTBRr=ts!kl-MjHlC<-9fNY z3?kmFbAo2_B4IL;wRUdS?$WGP6*yS)NuF7nzmcbhs&@8~$Tb13GB`l;Rpe7sxhYVQ z?-#hOOt&o>i6DBqbw$3@$DuJpVmW%Vk1UQr0YYK|riyqW@%RGGt_g|qgUE3;(yRy_ z`aP%Pk!Y9U_JN5y1`692FzkKrUQHgUh|{h0!np0w(^^S&<-k!w;+|V1xb4)zt?)=? z)~6fK3}pDsrM?AqlrnOuz57&CQm4{0xnlBC2_`QX=4KAQOW`kZl~j$L zgm#=F5mN@&^Alc6H+RIv@xnHK2go~Aw?M0I?&Mgin*!ct3f0FKy<5sg`4$9PID1>G-4n-{2U74S*s9U<9XKRyR{s~v#y0J$5ma$6s5X14~y`uAK^m|^N>-8 zXH6n`q#`_P_*kVTo^B;Jm+G-R>%uYOS=HLJ&O(%f4aqYmYJK3cp{KFHC{{JqGbVK_ zT#GQKE5M_KB9&9F_;s2TxX))?FdlUosK-^#EbI?pS1S{u1mdo41^ruf=pBrJY%f6@ zOP;Z#6d74N^c;SKC`cKA`8m7IH=zOyihdC&E>I*Lb(C#g4T;qR>o04Ma|c-DXsjW6 z;U|!$ma7I4LVr$=Hs_t`SkuH6deOZ?)$?-GC_=vgVh*c#S9RzeerGJ9`-n`o(8nAu zLYrY08)vBa5C&n(oso=7Rj7XIOYJ~jP!-BlZXn={lX@p~+KmSgN=|Jc)XpYRggVbH z)F)b~z#R^ue3EBI@^)bcLe-`;LvA=Cghq=%a@wVKz@|Wr+GB{G5)r;=Ag5hP5FHf7 z0>q@vPqZ?hJ-PZ&+`ag z#WJ&s2oRoCPDLDb7)VeF=}o~2Vsx)KM|5V-DnBP+R^djsOl?42vx3YOD@K6d=-bqL za}FTN>vu~9Q9fk&q;V`6UV@4oGJL0HxaW3<3_i&-_Hd)37ccPZxa~NVR{Ka|f_QaToW4F!-it!fE z1F`mq8x>Z_`6Qm&10UL_;5mWT|59uQJX^kkX7rCTJq9CHKf~k>`-uqfj*yuoN)LFi z94{J;b{^MBS#BB#_d~t8p ztq#^)>$Lg96l=cP5nv6!O9KPa&%NSVEp;s+M=J@x9e11wK@IX-XxqZb%`AuF>PWSX z6Nm}bn=y)UrSfX2lJ-ZD>M^%e_;QCR{F6L~RG5rpN|2Si6?`pQOQlk^0aV{ovW zEs=#rr@zpc4|KaNuAN%}_=cD$VEZ`fEZW`oS8q@XNOBL0c3tUISUmSYEEdWsso%5c zPw6b;Ncsm%l@2=_tQoq($&gR?qerBpW+?i-p4rzq@Ab&n+MK^h;=EoCE5+|WtrrP4 zjQ&Ctw>n!v*$_ZUAPfIGZ}#9t7QB#+%*J2`$CZ~TXDgZ{Z33Q7I#r-k9dxQ#rHUln zx?f8;@jB5*k?yZDxL=YoZUIHj6sVB;C_4i>JAKU4-kgfg|GC`U5|O3`;9_=%(Zp@?gLD95$E@>mXwr-4WDhbymxe4Y;w zp}1&JLyEzFcQ6+XCLnNF%;%MtfXfv+1u8{Ln`2R04v~{FgTUlCLuf$wJ{UCx#41ltr zE%!TySr}~hJBG36kiu_=;Qi+pWgs@Jk>FOcx3q-v`hbb zy{KLno6swQ*rE3=>_4%Wz5`A4hZAyfg|8{dhZBbBOZjlZKz%9SLrBw?n{jywF7<~K zE>KtU;e<2Ql~io2uJGQir(~~Xxjvf^TCKDh@ZR7aS=@Ax=$?q&=zegl=%n!V?AkQ# z2TGUF)nZYdQ&+k`>8b||S#*WFj5tA&A%l`-{Ls_wSU_q`{Uz}zu-c(Xx6609;Q*Sv zPoF}c2Z~yKr{Rj4JXT+dCJ)z_qM$#pf;1bT~a1% zof0+EIK2cfapPB4QA96!MEk{N653o=!d&njRzxgDN2w=)wu_#H%@Bq@^#?GD^*(vx zPu!{JKZLZtnXl9z@D{t>>LhIp{bRb-W|39)oWtc1Nxuaq!t|1SrvlZeXbm7VDz}QM zz_tU>IHm$`fm-mKz|VCQI2)REDX>R>p%Ytyvt%gB;wUgEhmd|xqdf<&z{PHFO415! zf!yeE>0Xgl6nKg(I1#Ej_)R6>sX$$zEbuABGKovi!2&Cb%F#mXqOxeIeYM=adYV^= z^>PWdN||4;P_$jjcj~~JAJx-KJj~GRNxLOzJKtv49$ko&!H0b^$N;{0I;vezjY>@JY>p*gB?Dv zFxfn$=EtH*$U(}lQw2J8pH3C4R8iHY$Q}O0V3-lzz4dR00?gW{U~+KZpAZ>^p~m zJ9MW!jiGqsiJf7>teRQQRchz7HA) z%A^203ZaPe2!Nh3ZqlYMrHDo{3RE8#t1B>FQ(=51!mY47DbXD19=$DqZ^c#E_tbYYMdZNu#bcfo&J_V|)yaowv9VEtn5o+}V!5)9#QGO~ za_UyXPkB|21!d}1$--CLhdJ`NIXYc)bYx79Jes4V+75c^E)Z^@oPd!ykS#g>B3+=y zu_L0c1f_dpjbrweXcBWA&xaf1H&0&1XyJo5c>SoT6kWJq&^k#`Pz6TJDX*>(Q`3(} zzAfzGcth!~NYr2((S!k*gU$n0$?fIQjqv=MGR#+)zZQA{EhSEOG%%e+v#S9pk2_42 zSleTmzSkp#ls>?6Y*_ zi;bEQ(*;Vzd!cd}u@_>E*vekE4x)Hof#^;v)K>GKSH$P+PVrl9u(TMGBS1H-`@I)Ktn=uW?9p}X(eHpfCS(O=LjahN z@o$|8c@i=k`_LxfDO9#rR4i=*p1XCbRHr8D)I61nvgdmtP0hA1d>1*}3Vj&8?6?rq zFQ7S_+4j2rVlBFk9lO!Oo^79#0|9)4`)hEh9tc)~;cxVVo+93Q!=#AyGLl*Y;}Vn0G5uA&lpD z#4qedJAjYzBAv0Zlr)Yg%?Z@~;OE1+WGzGf{SSg2^Pb}MZTrP|LJ&|cQn@sxIt zY^|y(WTq{z9bT zR$S^y#Cii-Q9DVK(N!!z;FQt56;DT)j4R$E?5`l+%m0;eQ2fZmE#2W8!VtzGVka%) zN6z@*lRUGV=mYLV#M(?f4JdO5*B|siz68%eww6>EsA*sl0-~4%j+LVu!ZHjsIg6sH z`7lMl=Y52b2u+p4)Lfd{q^9TCnmQS)j<}l2mm^rb8z#<&bCN3P#@5s~(1}A+J(V!t zr=0=ICwWFw?L;G@DIR{$5Pd~cScAiP?nVn-;5OJtJC*SASgvH+ zPN5#9`|UEQK_1JkTeL_#ETHqt3RFv{cEsHNxcmS*$(GHW;zjRe6&bx@-J#kl^0=?Q z!>O&k(2GM`LqszH@8p|ALD8Nc*qfrY6?Ky}IQbyM`!;xd$UAzm^s=EBZtEkYCo3rH z0w@V|!oPJw`VeF?q$exiF3OWO0nbG`HA$zEbgDq5qJ;GSLK|>#-5;JO0n>V%6*W_! z#(5M>TE_W&I8kNMP*9X{t}M#t)h6`~i)toilBDX zdtM(U3Ab47mWOv)uU;k`2Sh~Js>tkLEyDqobrFCqE=HuQEEYfQ6J_lNulE{5W%lH);6wcX&e9J5)^4w z`d6#^`1M2K0z)Ux9!yrJ&NivusE?<=q^1(0Om&R?@8?b(=eXUYgU||icgJ*(4=)2% z2`2q@*fmCWo#dBD*i}aAGO`A6en;3X1xN08ER!xpW9(*7;8&i(q0kdlJBb~hp;dO+ zm3kuZaZr{DyC!3j_^!(&-4oPu8Gv}!_?K*j{GK+Si53(;2)m+W=%f%jaRidfwWeMf zBg&5!NS+d*L{q2B>~9oO8N5L9m8J@WuqjaP_%TAVXzE8ryr{0Gn#iEW)YLvS_j}IY zQAbnnUUyPdr}MfsH5ncsS5xm}4-8Fx_em5@&4*4Lnz~ABYVPP*nwla)iQhs| zbyn0nyE#K{=#_Yy&z>%{`_gcy+hEeZ<2v%M+2Q5RIzDd;B!xVzt{bv(1HPxh$&D8GzTsr2DBVoW;lO= z$SX<(v;T`^c5PQ-p{S}(!4h4N{as{>VqH)Us_qAA#-X5agQ&bw%b8pXi>`${v`ZRs{ikesAeLdOZ87`+vSTpS009Xu!lNUb-t(-1}bh=0GhTp9VZ30u6@+?0aSIq zVy7}Vv@;rO$Khb%Lo4EW(oZ~H|1e7AsSLI?1T@c*)n0j?@+vYcx%XjE;Evb~!b0_2 zeJ>>EQS6IKORL@9FjMsr9+H+a?Z@+mk$ueJ(ChSme?Yp!Fx~tCMnwdITm!DcEId(&Bf{iDj#Q z>CvXGE^4A}Rs0$wTp)!d^30nOkI%N z==dbh>~=eK0xh$csQnND2@k>V)>xF8a9cO0RE+>cP#N$haKaZI{Z{%JpIjogdUAn15TmCBXc91KJLhTD~Ce?(VwA&bFz0pm$!l$ zY_4#NjmJzx?8;#PGc)*{V$VEZiJerNgdG$_Q0p#O%CVAY=;3Ast&#PWIHtJGN81Mif_iP8tBG<;%_oQ zVL8T&jfqm7d}|vh`9uU920`O8TqFB`zo$VohChI9I~Xq348L`QgJGZK8ULIuqa@p+ z&N7bvBDKf{6DLT%aH*HZra%q-X4ta~Jzgg;g1J`;-=8ZCnpK%u)*WEz6BLj58SoB@ zBj?axuIv!smkCL@O8hoJ0_OzT*`aP9z3F8q%{RZsDp}8`xxreS7WkuUiUZYLa z-X^(z1!RK=5$}<+4CpT8{b+_z->_8{QTWLLKuOtp{OjB)spreKBNGgPYmZmO+M=Me z!9fqS>fQ~Fm#$HOa`&iQtqby`MFD7SR0J{B$%@$`=|1eKQVlv1GEsL#52+wp87w?U zD!kqbYhVj2RQGB^*d~+k%wdeX=BCAR74CGM)glONMpR*MI{uO)QSATUgy3q^p%fMH z4t5)PYo!?PaU?Hdxj%KfN(8hw9qJJ;d}~j5gY?SYl%*??O@XrXk6?IW=@1O3aG#@v z5XVkVmd)xiP$s#MQF6EjYlZIo8zkS~+!9m6$+4=m+My3VqLdFm^OwcZ!EdrX2&hg- z#_wtRhE|CBguJ5cUFf#nlZDNIw+V8iTkpa|rIP3muY}H)P5!8JTb?{sgtS_oZ2i>o zq~Ck_y?v)!R>xmzuLsx8;$&5xF+@fw_zGI<`ba_T39l(4hyFRFfkPTNq=7>kIHZ9? z8aSkZLmK%1vj!Si4VCx<`}OYEf3P($Gi`u{{|BY_NV75q^dEAymC>Wa;Pif}{Rd~t zWuNqZ1Bb}Pz<%ip`=<2hFC|t+N@|D9fdhJ`NK0I&^h+JkKRs1lrz1lytiJubr}s&- z%a}|D1zx80?VgsJnr3QRgVVZqNKaFcmU@N0=+SFH|GxUNXZnD&p8bcY^30T;DFf2g zW&ez{0V(QgKw4&2&w+i^b)WR!X;)k!msa=me%6(l{rg$n<)0ya`&gM-1Je6lVO^7+ zVP&NEum+{4ruD}U;HIYI-?U6C75@*&OtFUa7;tq)meoC_pEaO=|12vdwJ%5wNE?)% zHrVRl-Rfj@wl1_TvbtDZt;|6nCjWOl-|BdQ)v=S+v9s0jLaXCNR>v;Ta*zJ~QmxdK ztF5ebh|^){cR#sZy3@dBE)mHzWJ=1%nr}VJ~_Un`0H$BTr8`8u1Fh8b z%-&Y_{wV{XsFWTM2O3m==bkqtE%(MTxj8rV7?(S0%#9Jrb8nh34i8OPR?K>Xa>h>> zGcH%RwyVdkpLzS3{1Kxgt6RZkkJT(Htt|@d+OV=_&iy;ry;!~U+29M0C+eCL$LHLT zo;#-Jn6WuG49FQavfJrnhu|I*o~e%2uJ5>!6UXL+TVDx5ZXmN0?B;*7y=Gpw?l9Ww z(97z8BRl!)5c99PbXE2A<<&Fqt0}9fUbC`#`jge`3#ym-V>Xb72drHi9^AEVVa)@@ zHIEe5EDTgnU*e?m{rUyFmiw#M&h%-zgzAFz->;vcvuft8s-Cg7x_Dak(q+{ZGpnb~ z-?d=s*9G@gKXG5pqJ=xx1Zrm7U%hfcb;Y!u>lai{FAr|mP`hqkaOF}|8t@wFvN*mT55=i}e4Mfa)YvgOx%oF_^~gvWF(M}~ zUs)DX)hi#ZDSm0!Q>$QMr%!-A!LX`}9;esLUvAYUFd%2dZQ3yFG_ILmR$K58e6=R9 zvU)}lqmXu@Zl{k-terhSxN4PzfJnN7GaY;l&a6ZE0BjA;40B~!QQFtcTvAiwuPH9A zp1wG;?_T-&d5+$3dX$y*w-qBq3=dJ;{|((_^v}$4Fgb2QP7gJF3v7!h0AxX-BdI8#oDq>7zh%oOUK>JLQOONnK`*5`%b`(ZT!`3rvmP- zXV+CP@`F4g>VvffQ)mZzDyp7VRQ=4nU9+DLu6l`fp{-$8`4q#^p?LF;k2fyU%^Ei0 z=Cs=+?nKz{!iwrg3c8&>AyFHyx^kOPV$E|)Y8IAMmpr+1!+f#Zxi2JEzx3R$bu()V z7VKL5xHiFR{4&{#MJP_(xu&FM&da(ixN;*FLSj_Lc*Bfjjk`HVt;xiWRRYmy>_{@= z@F3k8sRti@YS*%Lwey$S9wp7OSUj|j|A(*R9Y&&URHjHV7a8BWac=&)>J4SVO^a$C zcpNrSJ8xahGmm1@OwXuRCM|aI#1t6yDbhSvdma8{vH5WM&NXXyDWaH{f`uDEz&5e! zqUUSpJ|mRs@=+(=YZ@xlf-s$D$x~Rl!W*iW-mhbGV$Iz0n&-=Qty{Kh-81!|Tf1UL zaMcv7$ZHCwAa0xaedgmei>HboO-!`QE{1nI0z77X6&hmb=>oK-B^fKA zbSi4nIqteN=`7RT801y? zXZ+*W#Tb7z|6P%mWsS-64I4Rfe9nXkzA+Pg!-wVO=7g83T!qMX(zcJfaq8gLA;Tu- zkG4kW?c;=;@neRKwI%|sykQe2SQFHFqD2-)jJ!GL4l8$D{+JOtR{r=qtnoRwPRyB* z@0&P&tZ+Iecf`2yxUD< z+WDp6Gx*~3*08)W*2od#M&{U(JE=#ZulKo-ci@0NT6TTPXHVb~zAv@Lj+u~e-I4?O zNBW>%->|V`$K4){Uz;BGGFYd%Rd{F~_&;DC$jljk8{8`;FYkuT{Be2Olk|DDwrzX) zUt3U6egE2X&pkKF{R4>(eaGCAb8h|}c{vm6-Y<~y9qBOna(MrtPSX|R;#TbwG;_<7Gp=zEjk1nqs4<|1X^4jf9U(zB@ z{nYL}1zS6d`Zud{m!1#UZyh>D+4`(??JUuB96tKqk$LM_o0S;CA9Q;yN;DRfAaUsE zwX;2;#n;K-rDMkAfbDeX*CtfI@z8QO=$O6_U=MnKtX&;j#(K*il@13)A6n@xkvdw9 zqYs>R>{>Tf&g$nck6{&Y?c3R&-S1qt4tLz(VmsHYfW?`^-S~b2I#i0jcNceT;>%N) z4jID^xq9Yf;3ttc2qRfMc)B~+`f-=ljCuTaS|2!m#|=AZ#W17NZWYC$GdO2>=C~0z z=j0!FwBn9eT{>|_EgnB znsMpLQuTmC8At!F_Hl;rK=D}7Q70MniFl58Ab#r5Imn^=8+2Vmc7S#VJycQXOfSco z-p=*q!Hu)bncP}=^q_QAqCV`Cuy(NR)In}y?fv)5`PsY&WND-*tHFsL7uCv4KLk)S z{qgDtr|()fADb%97xS0P)_~g8Y=hU@Fox^TKjYVVvo!pZ8Qr)9L%f>_8oCu)^;oYYEs=b9HVQwLX-!8VXqlGK#o z)@_M%k)2(vCR#H8V=!P&HF$*3Mp8mkTT(!W))D=T-ms^Qs$j^7XOBh_QJ5 zz`AAJ$T6eT*^qD4xQV$VeLPVzH&|25;f~BF_T64d*h_sFq&Xi_r|c5Jw0pb43l_!Z z7(Lc`j*}!w=ul{l$<5ChpF3=<4<}r=<&5{`j2}M^UsjFFM|JVs;1aHVaT{1YpP-&q zaIqz>nKy2NFK^iRVYlE2OwOI;C};eb8*#qIzk}}wXMqtXMTvN9qJvKdfEaXaxi!lS z|N7AmeP>1j3LgECwI+3pcs6e%o+qm*zaN`?2AEj%OJ*Z7nwFSf)Gc_4hs70$B&*~W z3htAsM@f{#2TMmib;D;+Gf{O?aa{V~ z=+K|TTf))xv;VR3asKBsC-et6r`BiF`tBvU4=geBx_Y>#rhI+% zdQ9!|e4g9_@J*PQmp5)aP$|Tx4;tg^B|3fk9srKX^*v7Am&BqWDFd^5S?MNfL-`W5 z({$91;?LE^4_B{S8!17ZSP(CKdp*!11gv%=^oi`b>abJv2k_7BzJ<^o~1|E`1xiHlHRVvLnZ%TG;r7Zx;-4kDqBCgPsmDB3%r9 za(`>a%emdPHE16@m}k-usWDCZawpz0Tn0|=Y2Jpru)~Ir#g}XjlD~+KosXu~OI}S+ z%PY62OuSYKiY>o$zptl6X{;XTVv%|>FSahU?Lq}=XB1POQ*ri@i3C>1ThZ|G3r`!`=>pzVU`b>$!jYdT#7Eyx(cz zUvWF*ekS7UfFFG$nIX?t@h>AKv+f&BCL)F3*>OL^ZI_2916j1(K5qO-Sz0(JfqK!` zQyh1Eno$=W$9bJ%O!MP9IdRoD?r!sKGWbxK?JzAhzlZ$mAMams z&Md3%=uV_x8FsHH!*;0`5PG7}w|KO9{J(yS=Rmh~T=S%ZfAyZyKY;&3e)f;|GxyP` zejruf(~0hR-Stz+I?mRyU%iae`)b$C2%RM-edZny?nlTAQOGhcNx=a)FV>;U6A0D9 zMb}y2q8?G;?xPO4Ekf9EJ-m$35KMS0Cv9sJfi)s$}+dtml zMvTuHhI3eLO+*>Iu-{PM7sYePT?aM5uR3UeY>I)b4o{lq#dfzMRi-i4fNTFYJ zmxG$b+sBW|&+*}zfAa)=9ed_8?dsGW{ia>5UrW(FCWcRirWMr|E)Snj;lW|`cVK#) zuv0QJaG)nMBd+Y{7wY;K?_(&j6+dy?Cz>ySEXE`L5_Oy}Atb7|9n5W9$IA(kdJoUn zTIpI3Y6q)n)GS=Vj*9053yQFt=3B#c6cR%p4!VC&9vM$_pC)hoxcqS=#;IFZG5Wzd z#m+SaHILxM>J@l}8gaDxnNmHX%D4{2oqzs!iK5K&u2Y%)#0>eX(@w8CNL{r%*O`@`DlbDvdCy6& zKXg0y`bPH}@xb(il6x|oI@D^Sa`{R*{T4TE&LWukPlG~1r ze>sn5xuaH3MA>_3c|6Lw>W$#X(2094s=Y&#tWSHrST^ks`NcoqFVwl}#JrKRO4iR9 zUTVK}>3qm8e9jreLmVG;u^*5#HW~5R0WN3N*W~1}6!VP*ce_MqE0a)d^nxx?uh-=5 z9kt-&OF%2C)#o;3zKBOpH?}{M!KHNd!F@u*96a+@qibG@A+voPd*EZ_=<&g+4g1ch z>)6=cF1%i5%b5@EdZ2>ueW|^PzO|XS>){vVGb)>A<8f=HLp5o-p39S`0y4ty`VPWf z=TT!u*f&DWi@(wJprfPXn^^Aib$gJUuK-ssm3v<R_p@-T4v&;$EHozjkZ&nhWlP>xF-`^>!SZTyBK@ zDja5&H#KP6=;9=NJ~s{g?p(7!Gy~UJTlR-u0FDH{1$_Pe{h>a>IeHnlYq@X z+#lKrZ1nN|P~%3Hbp!A;;4WY)aQgQBp^?CKz^T9z>vObk zY*~*1PXm4cOa*?k1MPv&R-rwxSvA@N13|P0-dKzF!0z9oy~ncpg!YFLfx8=oLVbV_ zH4cTw0xxeG3e5o4v<-z4@$+AKC!!qaI|=2$Abuq0X_P16w`kr1UI6?S*b8_B%JYG< zfwO@h0M`Kb0bAiWN7~@m)Gh^f0geL>kzZE>P6B=doCj=yUm02hTn79cI0rv1^CxgE z@Pq`=!A~q+0=x(~6!;vl0N5J8HdGFr4BQM{1grvX0b2OUz3+fN;8FM)wq)SBz>&ZU z@FPT1fi?Ic&!xckZVrWB2OcvXasj(d424?bOSLQR3WYiWlL|wjEMUu$P$(aG-vf{r z_{_th(0XA0BJd5I4crTCEyj(%26qmy8cb@{pzRS&6Xb`@@H?8;3HU$n-Tk36q(W-b zR#GH2Plyu&#Li0NKC7zNLS=ykVvktMa|bz5sS#>?*(4E^iIG52O4sSNQ_Fyc5b# zg1>ZhmXB7&ihdT#&qH}E`uQlIi}J?sH=Dmkf7txbM)_UvyIAyJK=}-m$D;oM%J-r? z7XN!uemnd)7X8-Xs~F|Sh(FuZA0Yq2UHe1L zj&_vyDs0r~x1$sdAuDqHiF$2*-yd4+qBBR)k@6G3-`qdJjUMhsd8hM2A^A}ryL^ylQTkuV@^hT!!^7q4QGPkvd!6Nd z!sVYIp#7gHf6f~UO@}?${WqFo+u;cqzY~rPg({r%8!l5Fh@LM&`O_$`JjT(!PoU9^ z#)Y0n&mE)ci5w$QZ~M8iX) zb5K6e)m|HnjFZfdZ=w85XZiKIe;@J^QT{&4?{bz4kGF(*%s`#9@nd(xopl;sZS$Ci z^06o%<0{X#%S%!IBFcTv^1)&H6)bP>EWaUKz76FY(LPrB9+YoEc{CkKpRF*Lzkzbm zhdqvZ>W~~A|4`>u)bSkdsMF}rX2ONE%R>1w{5<9JuJRR!oAP{=cf+q!etVp={ny7y zx$rd`?d6Qk;jy$qI}lmP-udy{3cZ{ ze2zqU4b~;+$UJU*FAIFOXl~0Re9S<-+EV-qohzO`tAvpd`ZUT*XN5vX;oAJQ!Nu#y zpNIUGk_q}LEfP{&a4``INpL&#cSr+=H1Pi=4J4mHza$zjU4N41(xg9(NbinF?~h0y zs}@sOPf*wn5$PTg>FkK~oe}Bz5$QD%=}#ikzec2w@ww&c9FZOvkb!4wNB^)L3t#N&y3Sgz(f-K8-T<$)Ch$`BQ6DeX0H>Su0_T=1>2N`Bwrx{s@*#N%D8B z25ZmP`oiRAT&~lG@A9QOjjgfzGyNN6w)ICy%Li?#ru&)Re3`BhV%qSvhv~O3(dEA} z{h?8WA^iUk?&G*bl1rjxClfP>*~C0z0kM==POKnqCT=5E5%&$&Ik{=PqUn`=Im_$q_W)QQ9dBg%@DY2YbLEKE-Myw+4 zAzF>tKhZ}_A|?|vh}pzEVga#~SWc`UZYFLcRuT6Qt;X!1=p!Z(lZhF`Y+@dMONr&g3gTwsHewZV57BDE{)s+f5;2*W zLChxR5etZ=#ByQ1;kQfIkAGcnYfKuMchNQ z64*b{M@%9n6Eld}#5`gFv6NU&tRQYCZX;F^_Ykea*gw%nOd=)|Gl<#5JYoT{lvqxz zAZ{jZBUTaj5UpnHpXehd5tE4-#B5?7v4B`gEGJeFHxsuJtB8Au*5T}*=p!Z(lZhF` zY+@dRuDH6w-Kv|dx%zZ z_D}Q?lZeU03}QAhk61vAoWBk>osef{UU!RxJ({nU#MZkT3fC*E979LIK(i6zAO^~7?vTSlxPt|L|w-y?ob3=)5eK%>83ng0jT`a$d6Lp+Sw zirAXihIkUuJ$hJdk=|)6Z%<4lCdFuH=v>6|i;2m^p2WVy4B`M{7I6@92=N-?P~tFR z4skT`W@0Y!R$@N!cA~LM!*3)S`R`=?Da0b;bYf&XlQ!)iWW71W1;odQPZ3Q!gQorS zEPsi(p7<(p3(>SQSRpqL@b?mNJ@Iv-DSw0M4~btAYlz<;B>u>H`-#nd*8Lw{Pdt|G z&LDOqrqmOAv0Z=S5aI~pIO3hesl-y^!x3oox0v~l5tkF6AwEl7LtIbXOx!{=<7Uv% ze~abYh#wHQ$7pBT?_l}Y#31oI;?Kl=#NUa36894=b@R@$8WI~54N1v}xa!^)4fJC-x?05=}dUrv0@nzkxWCcoQ*~ zXxbU{{if~zOkyIj6Va4+V>*r4k2r{U!$IP3*2^W{Ni3`<-p_V(h)ami))UvT-6rBz z;`_uM#BYduiPrC0kB3K~(O*mEA5CmSJdt<`u{|-7m_)pgXvWQ;p??X>lZmOsUNPF4 z_WfC&NgP7Fo|r=%O}vRXmY7S-BaSEL6Yn72Lo6T`5~mSMh%<;YiN-DszmaI6Z2mqZYBPQ_%3lf@pEDov4&{I&7h(GEz9>1_Y(KTXlL4oSl;L_J&p;)7DO+x z4e@y53B;3#K4LrKX~eUL9f(Q93y2pIyAm%UUQRT2Y50vqBY$_+Pbc;z4j@LhGilTQ zYSz1+IGlJhaRSk_Gici1#qxWJQ;E}w4-ic|gIyZxec|QARAL{ZDIdV}b;MD`T;lBq ziFdNzG~z?VhwF)p*={BAW#YfOiU&ABK9MiaWiP>XR&+;aVRl6Mmy8~MwZ`9%p=}LyoXpoypK4QIE`3LoKBoU ze2`d1oJV|^xQMufxRkhzXzbGP8;M5#6|Da(aW!!*F|wUWoA$4;-WK8;#P^Ax5luUT zrv29}-$neE_#^QbqG@Nai+X4c&m9p{iG7Hsd;rte5l0boiMJml-pP8?hz}7Tt|u;L zyOqS3iT|!AZezQTiB-hi#9xUGJ@h|f8{(-EX!Lg`^UonB5jzvR5|fFk#9qXHL^Ey% z4gD;Z4XvWQ;q2IWT9-jo_5yVzRQ$G@qWqDhok9Y>L12Kts zKCu(=LSh$UH{vD46k-~&7qK_7AMq+;7I84q*kvT&CT--uhV_RLbBH$)P5nqT?Qdnh z+lY4(3yFSWtoE~5K9{(V_$cuSVr2VyZS}YF-ZJ|_$~1V;?Kl=#6O7p zi49KFhXA%>MortEq8`EjTe#Ak<8x9hOvtBOoPGVs_@qV_OLtH|9ww}0# z?KTm&65l88AbvyKOSDeWdOSP=js99P|7cDv( z|3j=lpZEyzQDS5}lQ!+2WWANd=ZNcwuMtf`TlbW)cSxuO<#9-as^VY50vqBmZ#LA49x_IGz~U z&ZJHIJ6LZr@jjxTIE!f788q!5X8B^`QsN5YN}_3JFr$MW-@(M8#F0c(eiPFZiIa)b zh%*loA7Z^l#1+Kn>xnP1-4^1z#Q)Y4gKYObaUZeKxmr&xiN_O9BPJ0qjzFWo%bDMU z*o)YgcolI7aVRmHIErY-&7h$_mgRZGeBz`S?M(Z7SzbsiCO$wcBhDi(ATA^>B9;>$ zB`zgCNqmM_L42P0BJpM7dg3Ocu}i~mBpUf&W&M8>|3iF_7}?IGP5Vz+?@QuW#NEW7 zh^C!E)BX>Zhlq{O)ArJg*n()<8C)YDxWL~g;_Jk>h^G8KroSN85Wge-dXV@#>ow`9 z`#p--ww`!0+nr17N=&aOX0Y90Vm9$+;_bxyh%<=uh>t~}(cd!WKSit{t|q=r+)R9( zxRv-e(TtlxL;nMoZzq0EtcuajwBN<@-NZe_UxW|JdJoJ(b%QoHxiBfXS04sVrODEVq`m$HtkbbuP5(Cp z8;N6yB0foc zxt_S0?J9}eh@TO65q~89NlfUh^>}my8vPy1{I*0N@pR%@#3W)TVi)3NL^Ey%4gFM> z_agQoX2fV`+7D*=wZv@VDB>-|JmPp_KJhl!UT%xf{ z!*3)S`4_PM65`{;6~xGPCT-e3%X%*o*AibNzDYFg44U@uv;1S?=ftmwHAK_SV0jm9 zH_M1m6JH>j^0iF=i}*J2BjS#O#IIQIJL2!eMqM=@e;1pw-7&;dh#l*RUD)n&VlQGQ z@dn~e#C&1_(I0_Ee>0gsi#U(?2yqEgCcaMG8l#vC4NWTL;R7rm-rj;FQV0r<4kNqJdAh*u_e*irQtUcjr>Qk{&B<; ziS3Ay?M&LVKa2IwC7w^bnAn48+8H$Md$YVhF^hN&@p__ZXE5m!t&fX{mk?8lru<5# z2NJI*jv|gbNF2|4lZn%bv+9X++3pGAv&2{GiCfw39pZN4*TnCMzY`l@s`b~3*fs)< z{!V88sl@ig4#bYcF2qZS$;6&SGj0YA{XQ(uAZ8JV#As*Q-@x(_#L>iD;zZ&k;+@31 ziIa&1#QTU-i6z7Uv6MKAIEOf&xRAJ*XzbGP8;M5#M_K<#;xokOh>`6~+O&U}^)?b; zCB8{~pJ>_{H0?iQ`3~Yv;y1+ah^C#vUYBe8=}*ie4keoM;Y{B`yp1@Sc>h7-bk>_g ze3bZ9J#iJ=Z6yAi_(?snitTn0_YnUeHci(0I*ND#u|4sE2sHY;i1`;2lZk1>bYccE zi#UXMJ<*JtK|_Be%SRK(67yoTGwp9@`CY^U;xuA_SW0||IGZ?!IFGo1xRAJn_&9Mn z@hRd;;r@pG#awTuLk5Ai4BFT~%7e-cAP zW0!{CNHp>{?5W59Fk*A!QN+l0CT-du$9g9b+Y!$pUO+VM44U>Av;1;mD)CBUKjIZV zdUW%(A2@tsZvI4H$ByTAIyb39$B8Q0aq{`+pPSU_EM{AY=tB#oKZcWjf__D1fX*}= z*r@AYceVNG&%-C_`cIi}3E4IEg|5H(6;r=wqON}(KLHd`o&2mkr2#)G^jMOvUmf`^ zAU4$W=M|g!#XWWXp61&_5gq9I#|KUQw|ndQS>{_o5%t%jxS{nJzJ9Fr({6;W-+!Fs(j8 ziS$!UoB9nW>-vV?84>9#nVyff^7l2<>T{7uzjv>@{Vzwx;@hk@6+{7`fR3+JpGt9pQ2(j8}xWL@iyZ4 z-NgFpGmLhv@P)45;5Ji#TtN4)KFb)cW?$+0+dee)+s)VY)n^**THy;_e;B@ks_m)8 z^SZwJY-6~ZeWmNyE->{6ysYc1&o|n&!WX*!?jKD3+t%y)>NAevYW9_`|3^O$`KftT z*H@o)v}=Vgbo~pTGWEy4q3f&9Jcg^;SGxXpO`DK@?`^ui`s|}!D}15r*N!yxH-4z= ztIt4&tJzn&{;{u{`n6x_`fFpvud5NcJXQmx{9c!jwX9Q&r$mcP*0XV)-q?fRuCbat(*;>)A0rtI&r9nBPc=%K zj64rn9oqJg;w<=2!%jzCDcADF--ex!zD};24Z!tt6UmTEkvPN%u{Dy8+kfy5Bd?#`QeK zR+Gl~+*-r=ZB?Cn({Q~|U(d?Lb@}mS0z9O3&$XDZX!vR@OO{h);6W_?&jB z_)ezo5V)Jjb;~leUlJlg!(jcT9K`%JVD(-_0*z zpDQJC;b9_hf~PT>H@`?FT6uneF*Wa^5^X#US|HI?C48P!Z$je#V(&em<0!JW;pz$M znJH;B%Ccn3V@tMW8_BY4%R#a&=YS(P;~+FqWZrNIw1ykOz?au5fr;U%vk(|1ff?bu;9%Zp3Cs)swkHB( zOYerCZQ++u(7f@*yAfC&{(!zs6t52n|DL{0lE7i%W1A3|EcJ0@coJ$lZ)zbg#LeLw z(ZBPiToMA$GpW+w)zd><)aZ;61xq7JHpSRx97EqZ@a@+4M1R7 zy>>6HBrUAb0`kaP6OzX6gM8EyfpS0XVs_%Yhyd^gFs_|2$k zB}vB1IlAO0fFve_4>n1r1uJoxKJF%&UL-GQCCLmqN0QEfBxZ&$1FEkG?5qTD@9(U9}s!5{=3Lu>tc*1!GfK7kjTsR zM3GnO*&=u8{Y74-w}`x2UncSz{h-Ke^=l%p(?5y)yp+`xEci!h+fd4{O1HF9ep9+b z|MbzQn_gDRX}IYX&IFw+bD-QtO(*n1{Udm-FP1y3Bs z1e~dQgy&Pi6Gt)px9IU~tV5}gRx^1FSqcmr{&Xs&2XtMr<_J}A;}Pgbtov(H3ZpIN zkY7}8Rg8gbcn%|A@#a{=(aRuTj`cqm^H#~oyd7xw>ho|ODOqqf&clyZBYt5XFF4gm zMaklXjVtme7?0u74$Ou*OVphX=LOQ1TY|ZUS3L=2}>&92L2$Q^o; z$ep@Pdhh_)4vk=xV}T=6Z$ogPwMYPKBX&hzZ5LpqX&q5 zT2FW6I+4%lGaY%I$Y=GFj{HRAb2_>=(?6$cMLw@5IPyTqQf-xPrOdTTucgehN}r;v zwBjsBX_XacJ(qT~;;i4&8Y|9vEv>cUlCHNEmvnusIMWUI(|))v8uNnX{WO0C1-pC=^U}Mx85S*Df%ptQ}sn6r|DfH zXXrkHo2d&aJGE&3N)2`zu6c7E>@-5JV87|qsuNQvN9oQYN9(~N$LM`Tj@4^Lj?*WK z9ItnXoS<(JIbHuv?9I?mAl!dOfl?LY^L~jRMYER7X;c-9LZ!1SKF;m>E5xYb?*yPe zAh-BZgyy`?z=^rVYQX1cx{9W};#X>Lv3IgMbFOHpH~{yjBf=vl!*1sp!OOvH-MOk2 z|CR;2A(!`I!uk|C>vQ~5#m}Q9JMRYn<;O-r zwIygDm4k5^$<9xyESd4d;ruQbPdc9-wBJA`-vM+tK|Jwh@-+(5`GTNbI?sUK_5(?+ zTp6?%!Y>*KqpFN0$&Qtw@}FV-{4QueKG)P;lAxb}R>e0_H7nSSJt&Xy`M+n(jX`@P zZa5e*m0;ucIhY4K-x{=6^fGm~Hf6^co4fMhRjTuyLAwhsFR|4hmE8H>p#2W!WJX+= zN}#&D3L9)M73?xdho(|C>B-Y52kVuP)%7cImshpyzHe9As(00!)9TagkJ0@` zL$yza+Ikcjsa8(ERoB`3plH8Dq62_A+{H;Q`eY1;RqOM%LT%}{5|*kuD34{e^0ok3 zum`t5RX1L@$|SrNQ8&`ScDgWd<+>HB>ekOugS7e>j;CE^!Bb3m=Ux4b@_i^iO)D=& z7pS^-H6~5*2iHjihcT-!=nv(FyoXSkR>4d(cGUwFKoYSRjz$+*a1PD<;nAQ`PJ&{3 zS~-I$AD>ccl&hdPD6QPalzUE#80CpjoR(HD1Ziy53+v)au^M+mu`8|Q^;GrBolQo0 zFBA`@l^>!ms^0hs4l(8HP`sU17W9Ym-A^!_@M8WNihsIFonH^-A$b?F9SXRWRnihKz@>+&s=rp?2P#dBhH`2qpx_@9P=;@-&~QYofcAhCLWL3oU|(7G zfF4GDB2=fjYW=%4P_Hw6BD8cN0=8uj!C*to?{VDfVsl^Y4t1VozlI_`f#{d0Vh=Zt z=DxuTpv1Dzg8mce{*k5U?ORnR%RYG)ZiA6U2@aE)@eQTV~AlF zw05L2GP#9r!()!B2Fsp^UVS&v3xPbyMKiqvu0vIChebZHIi>@&;{<1dsq1)hUC z+1Kg+0PS&sGH}oxJR+mT^DO&Z+%7TZ1AxAFfppYc34*==tz2Tz#gH{P(v{%kAEnt# zEPFH>nr4RsG}Q%q92MYB%ib}^09OHYgbVaID!|Jv`$Q;daVz8%E->3sLGQBceh&Ix z$UW`RDl{8SRrOoT{;`uW`vE{-xj>Jj0=(X`-#^Fz^D$s`#bJu>aa4deS@z)N1~>$u zsV*?vQ9<8k*|+Rt(5rwvqCHxLwhe%zcUktPS_9k)&~IFz$58>^k4}iuffaQJK##dV zkD~&7$g+pyk|*#TfWC5p*^UbOQOjP9Ih^Qx%voJ=v}^h%4%tsy_SRkoI0T@HF3{ts z0H4K>0&BFm6d*o#YFDEIe8IA>#3f7MF9G_E3(R&@(63l_W0OJO0pw%t(JE9w7>>Sa z*&8bj@Ew4@aDg621^6e+J{w~o^N(Smsld_BQ2~Bn*}ueKOW**2Cc40EM+Ngs{-#$fXj$2!r{RzCMLX^ zxm+7#D%@Efw;rJt4X-!D#(X=}g1F?3xnrO#96TFVR7)axi@g%zy>9Oh-K|B-VP&tU zFzh66D`LF4J59DV{*5+rMtuj((T!}nvKLq4{A7D1ZmACi@&X(dPgLV?adVrz(EbH_ z$90If2S;E73|l-ig{k}kgHj@SM*J&8H8PMqOE>mZ>W>J2!~|C|f!GUQfgvfmHCF;E zyep2-^~HChid6VM{7?SAkgi4+uwaQ!i*f&vyvzOqGkPCfP=j!o+@(@FjXxOb`|OQ} z;1(UKS*}`&o0QZK+DF4K@drVDC?Q9}9hH27c|T&mk7lCwm(ZM@GN9x(D7kXb2hH%@ zK%ceW?PDOf0(Li{VyIK&Fc^B>j*P~O6U4qwjZ~3%(doJ%)Nk5+?)n*2-)5?l2g3Q} z`}W_*nLEP*+^(15aGX4lo_=D-An0U2Xhu>i_K#z=noN4{2i#xmli=aL(9cg{RHp~n z0lu_vPbjq(u}7vfCSgtQwHSIVd`F;8hvwo8t;KO&)jWv)Ty34aSgGrwzRw3DmuPZH zHD9V(c|_#Ajt-NYS6YE>M%l;8#}Ii6l!-2Q5Q4)L zzp8R69&=io@C%T|tb<~BN-6$Ze2JiHHlU0Xt;*hbj}P_AObAmNT-DUMcqnN75}7md zSm4fRk5yH1+^WpC{@&HJ$mM`s@4`3)s?J|x)Jrb2D*EA94^-w>REA<{j?NWhp+C?{ zpo@Lxr#}xvR`M`QH)AhhZ2D!=i=$HIop)inOP*qt^~XK0tCutWQ+gK^$yH;=pmr?- zKHa(lUhn6E<&6K7{K`wNjw~DDg3q>^aA$U^3zj=+{!_--cI!)&>}pppC6kiNw2{2f zvVTBjZ%2a12olewVnR@60wJ*G-k{)DIc@! z*U=IuLwB~T7f+4;CCk39n^IRocUOkq_$ouWLB40%&*LI}2B`OZkWx1Wi7EG?)hItu zMafk8nP<8dy)Nbi>^``3YXKeZ!re;pA_oQRzr)#mfLi1tx3Sty#xnx;)+k0m=(f1} zg@cf>ryR2a_KWq{DHwpOT#$I@0nH28XU)f40Kii&h&efyuHl^Vn}9t8QSSio=M>01 zwGZ*hMDnVD-GZ^_d|<+GJAuQ~Qw-+DfPKYMgXs<^^l-_d#<@gzlQ3cZt6NdOKA=M0ydboxI69yahL&8 zloNxmq7HdE_lIIIm6EUC(I5F9&@crftQF$plH|;weGXcXm_<026U*5`$)lCznn5$u z*aboRqDF%`4Y;kun)2}BN^*J7{wu~wnz|at^;C{7hia3WkAISf z2krYY*U{+@p!#!K%?CiqR`!)xM zQ?G-DLG^6V{unm}^sXyZJ*bv?&D}l;>W_lA$nXYrHmcQ=)VZsYtXe8K-ZSi ztK8;Gk@RcS+WvU#hUjBlRfvzKl0TufW|;|ZJ5(1@ZMqmAP9>KQj$uf*LVP%tjEC%R zP`kwJ#_?ndYrN1UOt7r+M@()`g03NZ>{J8%0^lE*z^ye^hv!)XLt8N*(qdr`rMlpd z+>J#7CWU5T$YEA|ZZ(2{w1p5KcqQkD>?_c9h?xuhq7+6M^@@;v6rz~N5s=4HZMrL; zh$RmW*{{Y;>hqwwm}=A6MSXP0UNpy~z6Gkg(y4bXLF!XO_T>xA=CaPGMj`1 zvn^!LK=0!S^ELIjLpEhFqnThX3fX)58cZehJzb0$%>;8*$UYn0ly*i!KiS2Yk*XEr zRr21D{WmmEZ@dkY>kbiK|?quWu zKMdKk(eyO?CO{u&03FOXA)Alci3#*Vo8w3~r@4$wu7R-q1}+~0`vTPD0;R0Enk_dx zY_G?-x;J!lT)nBUs#fTygzal_;n2px&>!t$OkD`(sIa|fgu$E({SFsnW(dKY9k&0u z$Y5@V{wWtD^CK@;(_KS?-Wj&baTzk#_ksL}i}uu)0B;D})7BYa95*YSaCp0gU>*qD z2lq3WM(9Vo7|GRB)<1^rMJ)!nA3&>Ipy?Y2m7qR~a_j)g!KvnW=(oEVj>V?kjYUB( z&9U1ogZ>?m_hzC!W{=IW%NClfUk2y{7brfOx)zJ)=GbpJKK=wyr{1XoyFhQ}lO(^* zv1^t(<8;;20NRlW^wh1OKg_ZJff1Ya z#!m(wbBmO8jPVPS#8?|7&zDu{sP=T-Be1E2r_>SvR;EBI^x1w;9d6st3^xvK zg6iCqI$i0`pe5+jZM$D5gT4+(`OwlGcukV*?l0-CuQ2v>2 zD(LTRdkCtK8SDabw+}kI1O*ZMeauo!@*3cub&$j(?hKP;C*XJaBw;VL z_|GZJ=7_zc!6bPB@W1#Zk-CYzO!XH$fUEucMMb zMC{(^h0OR~fSxCiw-KJ-@YJbXzT8UYMC~2J;0;iJb4@Z66{_k2eIja~j@Dr&x*o4w zaX2?6eD#*>9JM#$Dx$g%R1I0`UQv52E-W_rB&eoSZSGmV$4!2+U)1ip%sjDK4b?iT z%^eS4xgDEOHyjfEwWUqd7YD-8ns`-)ycBm3gjPLw0rqGz_n5Py#)sN zCP1ILK-a7T+!VFXZZ$v~lUo@MQPZ9oyFNBljzUt<5Z7~ekt{yFn$V)Yr#Z|si&4&lhhAsX`tO+Mb~c17V&VO;LO_ky}H6S8p9 zY}mfu-X8;wH72DqPuNr*og49Lky70+mRYozuaCN4VdZhI$p2Ff0?%0XPq}zTfTU;Q zu*M-D>o+)4#eCz|eTOAh@~AB4cTL@Iw&cSmll+gCU4l!9$)C$eZZW8e4`qtqS$X`> zz4JTF@UPa}YjG#&f|=B0n9s*9-KzukGpJ3v&1%zXVfM_r`$z>}2ETKvz}F zFP6GrYRM-{#r$ri`&CvRTe-+5%0a(-VgvFrwg(=(9Hm}=J*;@@oCUQ~WI1P<2xG51tJbG9JYns@s0cR>!j zL(RK=Sq(XSUQ_d@zWwRLqPOrn)v9?u*PvhapkL|BzGKj@_T7tUWq-8@Rl6XNyBz_p zOt6G%Cx05skXRBZq@;?A6^ttS1F}!7%IC-VT)JT1%tRN&5xYjra3O;eyM(a^72FI9 zT-IP>?U}f?u;L>wU%E5eT}xqc5sUfv66~wR{FFbjFc{}z3ND1O=#2bR_RW}`6DI`X zTs_3a5svlgxSkS=gZcdSpYQDCvw!pLzkMVox5Q;Zag*yOB#Gpw>@F*y`&}@fF1$;f z{Nwv61BiTx$V4c-C5cgk=k`VD9*HZBHLkwMPSIoXL;%JIxgtZ>24oj+$xK%B5rI6e z)i9+RvR7wBJz|NAJ^C{6n8l?VRtrk5qF3YAIB|s3J{NMB0_+{2>c6PEQ7W5jJJKp+ zIa-2QBXO&&d*GUnY`y&@y)84v;bIU0DEn)SM2Q!_6VA7v?uzGsRAFA1gl5c^7yLa( zRLJkQf`|J9yKpkDSi*YZ=udbr7_xY#<)(T#Smb|U*Inszip|4ew1bz-I>Z^zIFDBD zvlw3VYKZZ5XAtr_R14)=M{;Et!<<@1&%(d54YM$3F72{qwV9?@!?c-Lmp0>q?6soj z=sGNNR8#r>VThk%J7iy@n3rY?s4Hs@JeVqoB;;l-jF#5T`pCRC|pWG#$?5 z@OgW$k%MO8ys~X1OTIBa6eZ93v^x|>j+%zV=^E5%>ljS2c+$7XcGgDGb@o zV-4;WVDBP6fHJF|oJzh8HvXE>=T`t)7P3#kq)iB)^S$pvL*JnSD?5km^UKiWNc zG&*D_a!kIjLjNaX(l$en()9@;yUQqJ=LhI*w3pY;#k4aeWS@e8hgFb-zArHzJ3q{@ zROQT&eRmH$PJ|0%p`V<>s4h*YWVU{n_i=Ud_EhE3(wONQFFjhF?!k%Q?H*mx*r&n3 zRvLMa?Vsu%hoci-j@au{8tY@KQ{CejR!^#X%-G-HUI6wr;y)9p(>)F*G}S$hg$+V} z#1TRlH&C~GOp4(v5hU&cRW;S(liNKWMBDOXh8CzMq|{m6}QkZo2cx|0A zaXeJNOsTWF$M70cp39-Xo*0(L;+fk$ma|Z)?(ytmljRFQyh%L0Hh8ytyoC#qu76E^ zYlcm?du&={>{LSElNgVkRQI@}&Da?U{bXX&zJ*fVYHt=+~q$rhBmUJ>7#I zDSKK7Q}D8273aqtzITk!qjAR)I{i? z?#c!3U;63q-Vgd?ptBuy$%L@4JGv({g!#6|9|+D{E?NXXbKEZB7GjoO_oW zK83b!IPYXQ6n+n7?+U}4u&N)vcY2=jYszunSn&zZU&nCSXFx@On9^Q2A6QYr^M}xSeTJ3JA?CxC zIBzN9je5=;{HW|R+?;Qv%@OAOLEyfjdt5O&EC|?G@ny+!+52 zWiTdjPa~MqfD5E=aT&%&mGjY3yl}`VArnC!7j4=XH}iWlE1xSjxmwe7X*+_7srx7( z(f2W$|5PMDh$QEsV(Y@e0^ay@L8rN&-wwS&**EVGz*i=*8jI);fpm2JG2qwbnj7HG z)X5#PShv6G4c!#;Ba16SC5huu0EMmF*XX!P)aaPFo66U?K*SwA@t=yEj@q*4vikNh7HY?(EXbKBGmbp=Ev(3|jelI)>aEC^F~rvW)9AR| zRdmXpg??JM$kY>8zZ(CVrl@!z?JM&PX=-?fusR0>GkOCtJ$B}7+>oR6H0k_Xej~- z(R2>Kg{ii_Kmy6|uWSU0b8kitwc&ot5h%%Lhi*`LT)`z~$%d07bn4NEiUu zr5k`u4bpygkYkJUjExJ{#RrV;^HGU)=LK?SK(Zfm5xb)+>s18ZWnC!fEZ4Og*J)Q7 z^-d9N8!mTGXRFHI<@NhW7Ye54D)@B49reS4VrnjqPnSxSmE$=_-F00kn3`+my?KlJ zw}N77E~WS8eFIDTTo($a<_ddn-lBe{jDo2rxTy(NWpi;0Q1@LI3Px}}emZaSAkJXE z5kV7t@RN4Hd77uD!_Eno+<@|lkTGI9<4Wr8vgE#(Pl?hxr!#)r6MzRSx$*sr51{{3 zxTPu^q61U#?LyhG@=A<}V7Lj-!dRY2*j+l|?f$C+@wNZN#D%!Rqqkt#=r>)iEG~Sv zxH?|`sVFHY`t6&~n5k6ppNhy}G6@4qzbT?xO%?yC2$9k8RNX93KDlDvjFHiajJ;iA zFJvtLsmP5?uxkxeCl%2;m(&|obl+ZxJyl}4u-?SlJ5Y*#8_Xs10i)%g473rh!;f*T zckFNY7mNT?t}}jVIK+13g@ABHO!L0?C`o} z2<#_;IpMokAh1vZbHhnmTOxsZ;RvlQmB9Qk*TXg}m%xH>l-5>CV88GIw04jL7KU%9 zwY3shq@s&vA#}7fBbTR3pEN(%hAj+1bzJFsL`S%kJ;KF5F)mz>%s@wycPBB%MYbmJ zkBXR_@g<_XI_fb5)s($|0bD!xU$Q{+HYY#%P%(fvs~!qM1O@A z$}ct1Kf2M;?=gzze;_uv3d{imtMV;#`@%(GPV^UOzWi@Y^n_Hj#WNM*nlt+?rki1& z?DJKYnb6n+9SalY0uZp`EC5%PnOj=U#LB)KT|NKufXozJX_o!uT?%dg3iC~V)L7s; zw6p~$i_h^ZKL2s!Bp0Yjw0V~xmx6sGX6^ic8bIER6o6;=Il)pqR|CM)0h#l-q|GtB zkcA7FbX?(PqK6!V`>gzkiSBV)D*`n^E_gF7A6-<2m;mn;S99;xu? zp*c9;BOR1W>!fv*y$Kh8{w1aW^6WX?UJ*V8j`87pg#TjfjWKpudA}Fq3)dLm^u_q9 zGIkOF@yToKC8provZ2(LFd4s&5q2^VWAfQpglqU>d`BGPvZdIQ{KvSV)W!tDcWM#7 zJdAM7+qnKk1r|z>b0<1c<0QlVR|QDpaq$ySBRQjRg*0v|Wp65Z0@;0#&a&c&y_6bI zmv|Xb(O~ir{3gJkp!f@29P6bjW)%a~l=wkVtzJ}P3KdlqoACH>!2CpaL`8#}*L!Tu zOQAxlg3nI}9FUkOsJFeSO(|5ds<;F53m;gE$5Dl6AlqQ!j%qv~D|}&J4CjSM;XJ3X2-Rq-<{H#j z3yR)-0Ca_IQu;o@4nu_&w$;(=vhFCg;@@4(C+SIq;_ z^Jt`D8jVZ?Kox$AAG*!yoy$bKdINsD*0-^BV0Bh}BhoWFjJtP3LxQ?27N+1&c zHM(O{FA3y^Z$21-S_ve=6Hu2;y(Lhrx|av{3Y5V0?zzGK!Sk8HO&D968e?o+6@TLp zG`^gNtoRFklo}|3NI>-o4GF$L`~(gB&?sMis4(A1H4T%174EjkQccYg2!tO&^E97uij$XO zpAd6LrFBnOvjfpNNd6+`z@|A-Q_Jsm$Fck zR6xRtpHPp>A;^mX^i|IQJtD|1+zJD$@X{g3em4&_gc)t$ARDtS6u$(GvLMJ-JIIbV zqu;g#SzpIS;vOE;~yj>Tm9Aj%lFS>83`lnT$q zb>DP=1g!A5#RwcIfj~Ich`>P-2!=~wv1zRYLg4~bMAJG6gu~y}A#kt+a>C!?#37I6qBpoMyp!AbG}C>8d-(84}S~gKcX+$e_bm?Fy}Uukp8BK zjK4BKASM){ZF{gM2DVL^@OR|X$hQZ9ZLJm8;&$5#=P|Fqws{rdHUx8GCfHVS8K9Q! z1Xr)#uZuDHMdSJ>+;V^P{|C8p=l>?TGMbg- z%7t`{udzzePgPK%_DQZhOURYW+mS2J9=aaGp&?gpbjg()U2^5d?ql)D1tuenX>#SR zUUKEJDRSij9&+UYON%iA{Cnieo&SgA%ANn0T=_qZTzSr(BrcV{@xhto%F;(kt}J~N zeT(GEgI#jv!7jP706DA+@Mp=Di;_aFTx7_ViwwDPks((`B*~S#c1W%~q$6_Wt{svq zOA(CBUhfw5kLJcAkXmNA9pVE=KrUVD>q?O2^L(gCyBgL&k?yx zuMv5bK1t-&`U;WP=!ZpKtKSfLowjiA8!SkZD=(AqSEVPlGX9&=og%+2{YvC_rMHRv zzVv00Ka>`X!i3uqxw29CkSiMnZf5bq0+pI3S2hYCa%H3NAy@7p-{Eycu3UaNvPh9D z4}EStZd5nNhC1ZR!#w25y*naTZuTQro{Lf4kSkaEktUO6;l_VQ3j_@Ai45^2)pFUY5N8txn1H6pj^KZra>e<1Q)9YA7|D_4m; zPY)A$zMd=cSNcei7wD}bFVvTayhuMN@?!mw$V+qx)kbpVej<11y+!WSeCQA?y-c4Z z@^XEp$Sd>%B6sNzMP8$G(XUCa+$i#TJy+xndV|QD^tmE$*0+efML#3*R{e>{+jJOL zBFUALBJa@6BJac^3C7>0yNJA74;OilUL^8feVoYq^wlEo*AIz&K))yQA+0dn2TLE; zNs)ihq}UIZKBAY2d{l1{`Ix>?h{$L3 zR!3eh@>#vdk$)EXoYs3Y{d2mH$mjJWN3MnJ1ajqVlpt6B9VN(>pQZ%4GRx5kkSj|%kSjA?%fCUce9LI~1#;!xBAfJ6A_wbNMGn=oL=Mw! zBAfL=B3ty4B1h;X`=N(ixklng>jsfybc@KbdZNhj`aO{oG#By*%O~m|L{8EXv9q^6 zNy1a~*&?TE{;Up`Pt#Y6oT2v;+)Q0e=|ir(iv0%U%7s%XN9ih&qxDdcWArSMWA(uz z$LW(rj@LUyPSCfBOp_}=h43&Bx$>eEx$bc;Y zfpFU)S7zOMdz?7P+#kHdLe&IsH21%4Z;v zORk*GCEp=e-o||M9dc!s)sQO}cR;RuK3y2z0lBg$i#s4!Hp&jjl|`9(mcFAlk~^ofqil?9vdC0CaI zMHWz%@FiFF=z06rj$B#v?6E&Xt}JEUnW_EI=7Jq}@9v zR~8^0^;Ux9??Gi#^(g7za<&P1D)?!M&8 z*^YAUe3c)$a<-!a^dnc!%-V5O(0=5~nP}B9xpKCnTsvRoN3NXhr~v)Ql{2$;92K-5 zxpF4jtaSG!SI%~nOX92i$d$7l6`&uva%R?!qk{G$SI$JMj>(m?9p&2jDnD}NY)1v? zN3NWiwd1Iu{m7Lw(W>AO+&}&dx$-10x$-23T$xvH#JwXLkx8!H&=I-vZ;^`R%J+)g zU%w!7wf;op8f{Id{s3Jj@<3fL@*q83{JJ5P7)%Qsfc31fO=0 zTzM~%N9i#lH)(E#6zqDUUM}(^eU!+P^>&e`=&MAYs_z$hx_)2enfeQnTeUqCpH#H% zi`#yOT)DT0T)DHCTzN7-;t;y!Y;xr#uwjuN*BXU02a`pvoW`smCX-w_pNo`0uKZv4 zV8mLML9QG%Hu^e-~L$2J+KsLGZwM_7Dkt;9f+rC7lAGxyR&Z< z*%7%i4XAwH27z4pBUY7x`j9J&p-Mk;<+K--e&ot&bx#kuGVcssa%JP>f$+tTTv-g9 z$ZD0MR{D`EOF=3hUsf1)(x%4b69k}FH`yLCXWOr@dV;7bJ6$A?@w4H0$?!F8KD*Oy#56RWzV z$(7k6F1fP6@%>Y9l3HQSS5VPm8D;e^dnc6m)O>d1ORj9x9g-^>b%*52M%^K~vQhIHjxV{gs1t7$K%Gsl%qlShf^<0p$|hHK zK`P-(u59YHLvm%4y)U`4$Fk_N$(6-&!k1jxWXeZVDRN~_c-t}Vl7cuOnaaZ{kSphM zuIZRunOJi#l3!8}d&?U6;p@+kE2rJ&W???$%4v%P_>e27Ep$w-Y)UBH%YNj_QbKtm z=1Z<@QYUazpY$VFHmQa1*dbTu=;4wpi+?hkWRNQpEJa4!JThw*w>O%B~%6eF@qjS0>seR~EFVz69uyD--CF zE4x4y5{yHxOpHseEErFH3D6-|CeS5U7NF@HLK5spt}Gb2XY^PUv>&;08tpObkSjB5 zms~mRqp54L=#VQD=#ndE0=<seS59YOt~LQW zT-gWhZ81sbkSjBtORk)i&eLp?#35H^5|>=r zCy7%Ghg_Lxms~ju?P);Cz#&&=5|>nZzYm z&PtO0EoyRc$d#GIC0EW$lKw?%k~rkbOyZI&OA;4o$d$XL$(4z9$(02w6_oxb7h$(F zxiS;D6;l_2T-$dx4>2P*Tb zKIuoUoMqdC_9IvJK^rI9zwjF2G8ziGa)Xd7_x6x0uh@yNo|RSRN3Pt$0orJ?$d#!v zkI>}f9fw?bJYsv{gC-$YPD56xw4zwkSmva$(6g1jMGc5EZ{V`vJi2$BUhdQhg5+txw5Fr zQ{>8=FUtAChUCg@m%gK4J21?Ah~kqe?_iL zcMVT@ z61j5GzeBFv%OO|J@v#BuH4IESI*<&4MVRS^Uy1EDTi6P zDfG%Q54|#1ccfLubj(Aq%vB%R`V4wyE(Z~S%Ai;Nfzd+VBxl0B(4Jno3r0_a5-y-M zDSG9TTJa{|L$7SYf6_Z8{ylBhlDx0YT9Oa-R}%k`mNg}^tiz>O-pnkxo-R$VEFWKk zURgfA2EDR;eC^OH_jc%&JK=qBnTK9^H_SYOBT&uj!DtM<^6Q9wKc%s1MeU(i{uZjx zFejlIwdEB*=#}M%L~)v4nXp8!A&Y0Aov+7R?A8iiiI%*t2EDS3KPIivE4Ko< z0>{B_TAnF+s0(^!Uh`IQnqHY%p9{d{gtJH%&kVh?43H^$dksz48Hk zk1wyV4)D+`pUha!ukugzcj=Y+7`(qruPh;#URgpey|RQ{dS!+(=#`&D4*w3l@@zPh zqE}vk^Uf)Hq-_ zy)xUnD^z__YBLID&@0o#80aUZFe-yynI@J&wKk=8O#IXzkJlY~WtQg`&~GD#<*|6C z`ffol@}pN~mb{UE0Ec*O@GgIDBFDJ?I`r=oleX#d=aOETc7B9DiuUr_N%7~BUYY)P zhrW&&kDU~MF6ouoTI1Q~DU3>zUYV_*Ow%jV(%#cG9{II8-Gd{A+dW9H%uSxQ(a2e_ z=yng%D_@D&8&VqUT&h#uqaD36aWCO`gZK*s>U58G^vZ-NkOk!6Fi^L9kY4%MNZb{w z9#o4@ZucO)GCyY+0oA0GI;(q-UYRDALBBeMNq3Le))^BgKy^k+oz*=^ugvmX3H=Sk zusjye-0sniUYS{P6RNj~r`HDWc8|C4$d0am3w@|H!=~FkNUuygU7)We#$zYdJ?>~T zc1A%zg_yK&8T86*t(DLpn8KLu!PfV54|W^vbtUB_GtpJoL&hr(!+y z%CS*c@8r-cf90q5&?|F}PTx_en1^0@uS}I6y|S!Y{r`|&Syr+Bzd)}nt7<{7EURik zuPm!-L9fhPG14pZzKitAyuTv7vaG5Fy)swT{x7|9dwS&qNv~XF=#`5My>gL5ugu$r zG`(`1^va{3$1|lk|3!Y5UYW}_U3z7%-Q;>rGdQ^P%8cI4X#Vq|SLTvV!`ZkUdV_N5 zm6@1pJq;_cSg^hH%3S|x$sMxMdFhq8CREHh4teR7xlYvRn7F$t$fj530#Yx)rB|j$ zTvciu9hIV2W^@L<^1a0H;x{|JFsLF@U#+O%6umOnp_;;HK{M!;eWYa5ijc(do z1InOR<|0!AFb1;emAR5Qs0^vYZloc2q_ z8gijB^vYZ&>{WT_mAP`*YtTcl%*Di>R2lTjOWkB{!&;03>lLP=gB*Hgp8vh%vIm%w9YW-rB~*1 z@N7WLL$Azb;+`B>MwLOY%=P1PajOh^WiBUAm)POq_0lVIoq0RMUV3FNKyL@|(kpXi zx&d@RugoRu;sZwaYF6M!KVxE zsMGYyTpph;m8$U2D>F4$&3p6CqF3f(dT-t&PIl;(nVM_ty?Ki|O|Q(Q_ujncRv@*Z zS7z$9Zt8S>RtP3dugnKOX$PEU_0lWziI8!@bVe_|GM^HqbxvpW(kuVf2QbW`R}M|V zSF0&{le9E}i z;#}<=&!kt5lU})Vie8!PtN)i?S^b~UE5|(a%3Po>ebW438|2U{Z$NZ}i`j)eXWm3cQUFOPaT^vZc$&SiLaV;+8GF77h18T`sz>*Yjy`IWi!%dz3% zSLQ-62fQEpOp0Hb>%yF9FTe8SRJ6r2AAV)7A2TzW+=&}@WG}xm7nYfOTKQF*!LQ84 zX4%i)+w&`PDO%csgoI zby_PhHNiYCdNXYw^AId^37iw_Az0>uxO6F0FNa_`j|=2X9=#lfZk zGkHdebuf)s|C&hA{6w7f^ERQC;a@>bvd1{Jc z`OQsuGdny%D!rVFV{kswoIi2`&c~P4qp31zm{&1=auMG=tsAxMJ8Aso zJpw;Sqo1wEQ-|o^kH({^XjeEIi&{9>(LbY*xzT0E;hBE48mUU6XKaQ`(c_S+D%$%f zJgAGl1>?!+U5M`%y%{#UN5>+jI@$&2HPM$g;3anS2BcjcJqYnDRL-F&{eZav?pP@P z$M!4o79-Pf!C>sE{ggh@)!|6%Dp|Q43P2VpZZ0M^6^i&J>C} zifm4yj#tx8hHLYz0UtzWVdm+7JhJ~N!gCcKg+dPaSOTr#ZfN2GpGaVH_|iiW_*4SB z_1{qo1O9B%So%9A`iuSu9j(>U@xu`MOhOYaUCz*7g~WD-rO#rz&m}a=Qib%Z9QjIn zk5oA?)6f?Ix+=Os&`n1dRv@>Qi1De2pMoZ0PAYX*)wN;Z94jA<_W|OpvTQ;#ziN zA?S_@L3h*;bT_34x(79!ODn?A9W@NyV>$<$YR90+i8;vpJ(RGix2}QbO7DweH1&}H z-WOhjI%?`Gp-4dQLiIK66=UgggZf9LZ>p0}UQpjkWW7{IBB)oN-LpKR~a#T7ySgU6KD5I8r_DaCE6>QR}L@4M|4v)T%xmZ9AH$f$H;cI)fhjWEKft#*Wh#(qIDyJKA7(6l18JUzU!xM`k#R=!iI>K}P z-2%1r&9EvVIr)&1#1)9bSmdBe_D2;BDRpAsc4B9=z~Ld4cOZ}WT)=xFV-+n#A+6}* z&1|%XaUBGs-BGh4m2($xL%IdthGj`PwBVXEm72zs!=O^pt5A1VbT@ihAo^$6ibR(n zWi+}77D04;Ezm>D0~JWnb@j0B*1;Ie;`6Y7TKTXZ;R_HO{`?4hLff;D-B*RnpdQvs z0+H}k)atNW2_#hb2@F=ldgttqG%EZCM!;cxOdEyAFwj>5ox^jP$h3Mg{3ZjY(YuA~ z7^s&X&^`PCoE+9q0@dMzQQ~0@5~vAxVW7X}kkdoutfxbbfd$AlLcb#%7P{_iuCtCn z!7oBg_$fe|>m$7U&4AV1PXfts5ScVLI0IHSvTyD$L(k^$N9dc)jS@IDd?9jd9v}nH z+2JoR;x!N4i*2(#{2l{?Dmh79pmL5xj?GPh8oI%pr(K4s+if)u`H^l+L3eB()|o?= z(vowt zEnXh`7B7!|ONz(7mOS<+Ex?pb9{V6pgvY+6F=hr1^4PZwkN^e_64|#5ln_YS_X@QP z365eCQrWi*jdBPvRQ4^yBw(oQTbdB;Zilx75j~3SRpquuv}nLuKFMrLu1s z6nYkAkLdStnYRoN(a++b+AGr18n~Jckk`Fslw*rz_AMzgdz5QjVB~%%Aj#~1BA8_M zEt6u0>`QOwjYeRy1U74u*|+R%G?pfteajT1vNY-JTU82JWG?>zNK5R z3=NpD^a;4ZZ0Qr^B~oi?lH0e82(n}2uA^ubLSusLj`L7qVTAS#vVGe^Ld4gyAjpOV7dpIlMqdgU>A)8-^E3s3D-=MW-2FBqPxw0lo4lgo-6}WI%IZ8g6Q4 zb3o-Bi>!v12ChZ*Mwn$)8^)EE#2py9t8TzhH{6_7AB*?F=Cl|Yk2I$doQ^W5XB~|x z(wshrWMj>Lss0GCAjUqO(n0QZLRCN z@=i3kZS(Qu%17cq8h%sJ~=Q$;}iU5!SPZ>8%LPn*~d#2ZJcT9c(fIVMZaL48}t zM0sBw+_n?ts2h41M*N(U4>dj{YD^hQgC>P_Nskqd50kn(K5We01S^vUvsr`Nwr?ys znMP-qb2bWYd-h1F`9Vk)4c0j|U*EZhv3qH%ihg7rF6hKN=-{>+HrDTP04JwBor<=% zR>_7Y!EM)VEO`O7WbH3^LcwisLuu-i`AD4>sXV&c@5jyfk@ww^O1)KW^6Kwcv@SV0 zRg|#}EJ|S8>fB0L9Xs($bo#)y6}gY0D~z4TsRvt_sD3xGVP>FPwK%3OcTN42GBv!P z*VOO{DN|>n&kUbubn~Q@hOc3>1h%zFHp7oH+02mI%3sOa+VizjJJMSiCnYOWdCacv zz0J5_^M~O-YyOt*27D@v^3S?tBNE63HMqamr@@m_KCyU%=R3udd{2>lPtC}eaguK* zl}D5PE=5rqx1txH=wz9$(N|JgHr9KyY#i^+vT=@EqxGoK$}MP|~1-LyE z?jjnX=m<7g|m?ct5NtkcRlMtjFbsnp8-S*gKoyEjU$R&Hcg>`*0tW2fvQ zw~4`RZ)}v}UX47W!M&a0)}PhQIPs?OL6u0KGrwel+x}}~N#D(|(L2hAOz3mCSfycT zMJlL7<(1`s$u%&BlE;% zxVRs2tf$*xzm)YvhV?{-^+d|L>bDM;dh|eC_0^84bgzCXWh$D{oKd$q*#gnIrm0P@ zj;{9h>gbWC5T;kZ4|5oOzcTeWn|B?S0a{dg^MY@`4!` zZ7}1a4W=$yY34;p5)E$1$d_@FZ@J2&NyYmRZZWhujwgt+#n3rn(+|e)WgK1AR9_p!=sF;t)4VyK6Ai=h#zEr$AewixR7f3U?+ z<^OPtq00Z=V(33@i=kP2l6c|VH{QQGh+luVp;JdHaVCBAC4{7pB9dDS_1{9w>pXL} z7!n|VlnT&ii=kZZ!yCB_hyt_4P=VQEsK9J7RA9CkLL|2s>e1mALyaA6G1Q~OErukC z-xfni(!mx(lEiO|q0)9+49({B6TW?Z%TKF{I>K8cxBJ%sv7e)S1%57n~ zb+pBhQE-8(A_Z=%jXNTqI4LIJENhD)lfq|7!p^Oq!VUsF(hi)V#uV<+G0r5vcYfR8D((lgdV+= zS_5nD7DH+K1|eGv5#eqzl(td)@;KPY+G2=mvna3FZ;K&GO?zsdXNw{3Aer7`Na|(2 zXN#eARLd4aqEfm14n0^hE3qpIL&1`<6^vNmyTwpxYKx&J80qutu_#Gui=pEY!!3q3 zh}^2r7J0V5O5`^EkjQiNdm_)(3W>SJP-l_n=^-M|*Rw_bN*^Ke0)3{)3-v`JFVee3 zUaUV5d5I37+PK9~oyZ+}lE|I9P2^>Ii^$9MjL7@+E|K@^2Sh%g-xc|g{!!$^x(dU7u=Edlq{v5fo5)A?W|5ESUx|EN-y!k| z{hG)p^>-ql(v`SN;}$~$L_V#jJ93@KXY`qlyiVk^`bkHABJw#M#b<-uVyIT+^Lm0K z4}|0vLt81a#n82s*kb4@N^CL2a&U_wzT4pzL#$tJF~oZ17DJK_TMS7$Y%#=iP5;Ig zLpP0vU)W;kK9NoO36X>K%OZ#BeMAn^i$yl;14OpyBSenSRqThJErz;F{AgV-a*Q4( za;zRNa=d<5TMSiIwc=Yz&lW?UB2Vjc z{8Oc=EruqcxVik!a@5My7DF7Lit*!5kOn@=-C~H!{+Y@I$v4_+IN#04-#E4o}{)I`VJu3Vu&Ycq)K?V7^3cNTFM4VtvFi@Q72mr z2`IhAP{MbMp`Up+x`ADCfOF z`<-D*(fEZp47Mw`7-DTSz8Q=dUINxwZ)LDHk%EM=Je}qG4x9$a<>>t=Ms0e7~0Bw|l!_qwHXdA*1YIiy@=zV2dH6>|l!_qb%qTZ{PhSfKMq4g{}55keI83)Lrv&wIaAu-FOKeNS zAiph!B%NIA9d9v|W!r=H+hWKE?NkS60^co$Bnhj-3-sG!NPseMm|}^=^DO&Z+%7TZ zgJS&Z#bH{4j(RIW(0*GCiCGtI_}+ZC7|M2(d~?2A3}rhiK))@9GP8EdFKE9lhBDDA zL}EDKErzlk6`Hd@8lAJmaby z!^bK=S%q>RImX#yh}UAoy(1dpZZVY0a`owGi=nHLidzibC31iLtjN{+Ly>Frk0KAy z#nXv9Q1=yike(uPttR1Fu>Kd9prR$5JTMUgz zZ86mE_Wpq0TC^Ni`aM;Gb7zYoxjV%cLw}i$F=i661wUxufLfd3MS&rTV@vXV8>t{n71Gdwp?pDl*OP=((XLuoH6{I(cMtGj!) z7~-8_0e*>;;RqNf4}_K2If7DHR$lDox__$NxU#n35Gx?2oM@sk~FF+`;yqLejZ zy?nM9N<&ydW;s=I>RjI~hBC1#8ON>4eCzLB&Aqz2#gM?{E~_egiy^rcl{*z_j;ib} zhO+h9TMUU_9F;1s%HCo~^l4h>xUX zQ^uHQiy=`-$)w~mZT!p@L;nwZ?*U#%b*&B0oFn-hX^xsLOU6Z(dp9nUtfOPgaxd6m zswuWHZrF4Kb|{W*OdOiQ7#xZL2Vw%@(g_4YFDZmx5<(iGmyi%hNGPHF@4MEXJ$sIh z$j$xk_dognCwiVad-h)MTD#1iJxy!9gL<^JqZpFOvW1gzPyvdeXevqnqd^?hfHy5S z`i(dY1Fi%xEx_7w#whGbr43sDS7U9x7WWPCfYfV*!t*JH1a1e(Mdnis333~UT`lEP42hf+0j`mJilL}=PG|EehHOp7QbCF# zg7mGuQu-K*p^H##DTZuqo?;Be5HUmg;LRO2odPl!6=Nudh_MtyVn@y-#TbeqVl2gw zZM3P&Pz(`cDTV~2EDE1uGS&}Frn)XhoHnc|KSWy|V0*YK7!ILA6hky&#Dyq^M0*t9 zr4*nT5?v7%pcoR(^8X&ikQkCzEB~BgNc+Q=D+MWrv_B#)L@}h=eEn0uCYgEw*HbP; zZ}vr;0c>WlI;0pXLfO@$Ogyam~g z_6Wt0R4Om0KrvLxYfZ-#L&WN$T;6pg>@6Ad1#g{Hp?6VgD&Cwv4#OW{`z-9RDvZMW ztO686kwpRuPz*&K@0empd)Ohxko2%)iXqjm#7%uciXqh&+8;wP#MQ%63`zUsx)-Au zBF0h-2}V~lv12HPh_Mtyg3;AXFot4?7)voE7+tAciXmbw#gNk;mtu$*OEF|II-%vd z6{8p;+ENS&+FpzhG7ndidP6ZpprshHK!Y(9L&R8$A;CoVKrxCT0xiXm0Hv=L1u2F^ zuH#kLh6WjmA=dx2Swk_zsx8G()J7d^v1llU2(%PKaiBYxqGBk9r2j+U6^qTe7j#Bc(1v1& zXiG5^RiI~^01d?uftF$@0_KlIA&MbE3%`p@xbhAuhFFKC7>d_n=!2S4sV8x*~I?!OTjfUhx&v0{QG1Mk$6WZeENDlTR_k8V$3}npEm(yeVgcEX7c~LB1X= zp_?%jLquDOp#o_4h>4z|7^0q~7|PRg4x6YLiXp04ilG83rW=N0h-gbOl!tZ>pj2Qe zhNxmGhD1dUp!_&JHxxreTZ*APbbb#E#Sm32#ZUni(*r{>M6{(C%0uV(z)%cP#ZnCA zsYK6mF^VCoSc;)M73qea7BWtTVu&i1Vkl1~dKQgQ3{mCz;h5>zqRA^0(~q7=V-!PF zu@pm6iv=phP<=!(M69J4608hR^dl!>eMB)t1xqoMrw|>y`iNqP3YKC>6e3v16hm^W zA_H%m;#KhDRy&FzG095e6ho{ez-?0%Hgl8gQVdaSDTef}L&Sz+h&9iG=3dlh4PQYq zq}u%CQjlUudSbgQXZ2T53<;X2j0-G8F%&oZ6%<1PcD2~=oP6a831n8Vh z{6JnmFi1U(4-^cW^z|{GcP=*VQM7b*Ofh78WQctVQ49&j8Z-A29a0PxKuiD4AaqDE zBzjz^zJg*X&$fduL@`tVt&M2^!K>Lu_0Mn|hYH2ez#o)j+3K^7v96Zv#D6|`esv*= zp(ZZSD#@c5qC{Vz$v^KHilH`?4uVag7>XcE+ffWrrf=B13_nD*ITS-R{Cq@;Azmvg zU&8}6{NM5poVo2;(7or%Vg4ekNilHk-*a5|m2<88+3Q!D* zumu!Da_f`f^Vra1@NYIlNio#ppHU34xgo{SXtrV5S5XXc?t~OW!-@7fpctzBH=!6> z{_jRHRHYO{8HPJe?Z6AN%I_vK+cA*U@S4ylr~IO&fg%PQiXnPrnKiJfU@B0qHkmg?tc1ro{fqIg> z5vV80Tfv7?{&pZ9C2@kG^{gUJFeLwajkrJZuh$?Ll7GE61VaN2!B8!ZShYhibU)1e z2wS2T&jyt!!O)8+eJzyueMRgL41GjVi&4}yTR!lEU`QS#I!6RUgbl$xEqdKi%Btb(+jT3%vDn7^U{!LD`=PV;8)>4#5!7DGY2G zHkG!JU`W?9UPpWEvk0viG^&)JJO3HM&{Pr()#eclt%Pa4unhE8WGudedr4YLG8 zdY)yx4jjaMuMS*tq31Sf*~G=3YTE$2$(nyTVnA79DuAtF!T+SZVe^=a*BuW z9eyE#A>wYwb~o`y2$Xjgg$RZS`8~EbEYvc{kYMOoD1QM_5pGJgO_o811VcR5y&z&3 zNfGNR6eAd-iAj*p2r*uaV2CCbLv&;)HYUCtjgd73L+sBtAm2(1`{Q%Z8`2TM5Uac$ zhzE%0NGjek$dF)&^}Y!CYs5r0ErU!iJk!$7XOO3Gyj(jWgA56VXr~_XVZ=CgT!JAU zt*MaD4l!PD5)AR^_qGH>8Cse~f}wS7W_oa?u+xJCLubLjRvMWDi*|aDU}zUgZwe*; z-V}$^qaDEzanED>74ZiM)J%_d1Ve;;fvpHrT%mS)kYMN#DEES>AH~upJ3UA+#D8WO z57CTJoHsp4FhmnPfmVc=XnK%fh$c2bbap7tn;sLe#<4%UAis$i_Q&U*ogVE7hFInE zK)ggeTdjCIJxDObdOxDPEoReB4-yQ~P7lZj664qjr^j83)y_o7XA={(Ek-cJqqP+B zRUt;F2amopJ=h{IwPz8o-%FBpKjW1Ec<1`)5)APwtCx0{V2Ib;{5t}dV2Ib^c5;Vc zh}Y;y9wQhU8W$BJ7!se=|BD1e;=}sCKrkdewICQ0pIQ(MiBByEhIlJRf+5~_kzk1T zS0oq`pIQ(M(Wmx51Vil!hE{dMc~qqYLsd#JRHXz%8Qwlb1Vd#c7#jZ^-YAvv=PL<@ zGIZLs1Vi-Pq_?In4whhu#rLzAKLrSe=+LS6^SrxPlqDFVGCe(&7e_3_2!`nW>B}9m z%3OjWdW4EO(;$~%h+d*9qjEp5GU$nrCfgF31X8wx?xQZi5)83L^eNSb=0buY7RLyN z?jgoLq4>;tX&EnY{V2K^^d7^?cy1N!27^3&9woeS3!OABXqHnAo1qE1wAzG%xtj`@Cu^7S7%aqCF zkYmWK5)4)56AaPKHXj)y7@~h@UQ2zkSD8;RL=WAlwF-(64AI3@0cs$hV2Ccgjy!ek zVvOTRzk)+VH{a-qOpm2YFhuuXZ6Z}m3_V?4f+2cHOE+T#L-d!9#>K>wbO?s%M;#50 zkvjxK^smm>j}Z)AMSwh^%bs)M@yNOaLv+oKs)`c~{m#m`SAbxMe%z`o0GD8huH8-( zMIIv_F_V9df2;li#Q?}nqjpG_G;&MN6VF9hz0b=kLuP#rkIFe zh%bJk2AIR@5)AQ;kQ&j+xE%ktH{x!;hVPH~mMD^$$>-P#GQH%i;t>Wh5Bt@x@YHvPX?g)4TdV1VjG|1VeOB zmpLi-Y~BPzFti%QX}Yot!BCkH49&y6Ooq>eW%T7r3#||ZWwOV+=?q^g3~tWg#X;vJ zeYuo%#^o2HXP1`7_=V``Wr|&Xp)YK4=|8ZFR=lZi!f|#P@FAEoA-@ov!c4KtFEk@8 z_PJMpUx=Tw^nxZg;?>1KrCfd?dX?!dEpIKo7{3rb&GO&8tA&g4(yOAxFK3Q^Xpsfe zNS9xT4r)@|5x-CwJk1oqy#o9~bZIk&7XT3Q3(><(i*qi&(BQM$fa#y4!F>Xci$B|WZ3Bp7j?oLZ0LpP8>cl4Hta(5lGC>GHo;5%co=NV(TLOZoQq^S^W^e6 z;qt?Px>ttFB^RP=og5u6MlK}po}=TH=3C%0zI;#fr;M|)j1yMKh06HBwTvG;%lN6X zjO0RPeDhlN3u=&DXgsA|sK)<}>59}#dJ(x$8NXJS(QT>hasH58XgojcmhmUeZ))io zP58MNxEcS9Txi=8-y1WjXLnp3I{oA{e7BumI}#OkYWODhXLN%x{Kq%49&M6dmU!I^ zrO`2LW^&_6PA{(xQAJ)iLus^KP%pcv$3j%K*UeBG-7Tp4lhsy_OEBPdV{fh8upbV{ zOUR7Kl!jlEMcor{NJ{*1jV z{Q_V$#r+BUp=4@%_Mqf$F`ap^=L1x_M{-3^6n_iTVC=n;>t1{hweFKlPp{K1itbOm zj7E3qj1jsF&6L5};LQx#m-_9G)*ALD?pyXHW-R*>GaEzpC1x!9lIU3WrB0}&&9W~s z_fOcDq+MfSP}&u-FR`g2n+F-sak4K-!C_&+mq{&H9cuUXhKJ-v4Yk*!^j{!18Xl4x zHT3;}n*TF$qv0XBQNyUR17O7^H=5lu*(l^jXG0?7MvX&)iKt7-jT(na#*iB|4wIZA zH)-;;3n|<`O;0a?~_MbIG10I%=A#xuTxrI%=Axx#FIrJ8GJ)xlTRFc+@mQ zbB6S&X=dUgw4~dTX^1&fU1`oeb5_ZDJbk{I62)FOk{*rgTG@o6l4SiUdhT^Q95ZBG zjVWDhN{>_@>Tx}M@*eG?#(#tNXk4Gf@qngzjtsc6St);p9*D#A1eWgRk!j93JxiK* zmyA;WG>=N_SwhO6=FtJ?`$nPsX&xgPrTl4jDSw(9hO=2p`P1CkgNvx4{Aq4V+|FjO z=9xn?cH-=9Zp3Pn7bfIVUw6%Ae-((kMgu(>y_HFqA*dty0CkhVrL*Vj>5N zvnxxpLisab0Umq0bx#Ph5E*~6F5^$uW&Fvyj6YeI@h9st{$xYOpAp^qCH6lEtta76 z)+PMOx`aPjm+&X+68>ae!k=tN_|u<+KUD|A$%=$O+gQPE{ZYY~QazbS_>&zg8AJG! zZIB#DYep0`C!eAQ`F^t55}sAc_mgdrjPm_tbCOZMpX_+a7`~tEh_ot^?jYW%4kMjLwCls-n)k$wex-HRwrVHgwc9Jngx}R)F_k&(dOFYi*k?!Xlf=Tz2 zomF}cCcM)9WM@l8>3*_%s6^?0vU60VbU#^3_tT$rKi{FXry5{wZyhYJ_;*Jk=hFRT z_bi$Kn9}`Z_bFlvFmnA#_mepU`aj2GX!d{-9c&Zf?39SySmWV=X4*?zJy zwx4W_?I#;!`^na(WKmVNpKLeD8MdEnpX9YTOAOmjc4(5Phhh84wkA2Nah2<`0+mlm zaxNOSpX|O#9$v%tlRY@e18LZPvWt@(Kg0HuU6$lv#Mpka%M&|L&mPLQa~oFVJ(M74 zD0(iQ-esH7`SiLr+{E(pUYehP%XYDh{~}PvZ0WwZS7>>yihVm9dOmMKyi^z5oU|1A zQhZHV>~qgcbBRf9gj#N8LI4jF(1cR2bSUmMavP-dMO!Mo9!=o&U?pAfWz%P4{ZIMB zn@IiH4t<{pUmz6p^U}QN)RGWle1$MV5HOA=M3FhKmYfyiD}}Uz1&gg%Fk+WKUg|J2WB1Y5b+YpN!iS!=fkx*^@G{_#D7qn!9OUyoD5J z!VaME_%O~ zUl_T3J52TBeP!Di9@FHuOV;&bRR6Zg_e=Ktb=^n}UUyQukXOItwvX5J+6`??o~YUP*Yx@krDrPm?KQo~N|$_)*FX@Rtm#Esy5w8D z3MRIBy~r(+{Dj9Xu`PWRd*>%heeK_iYotGKqdg_bw?EbXbQ6+~5#4yr1VzKzJ#RFT z^=Ig9g4c}%FMi4}t6aXe+nc8#pDy8jB?%Y0WzcoMq?Qu|W43nBx)H{*88EG(Yxl4Q zv`xm4?T|6-=4CiW-kU41I>Gc~T|uEJ(f;|-oqxMVsjW94;olx<{3n%0`|qsL{yS^5 z|IY2B{dfNAX#btRI@g31!KTdTt-v1L;XD?v} zH#+$N|E~tDHVpXx1~TbC;79nuzQB%efAEsJljqGpFbw#AHy)*uRT~2KCt0;IU>lQF z-wd?;tl(LZZwdY=>A68-9OdT)-6Y)_(5om}wJkVE((S<-NiPbvNP21TJxO;2Ka%va z;O~-N5!5zQ@5-QA(p|wGl72ThP||CHBP6{x*evPyg6~RtUGQT`uMd7J=?y^w&m_sJ z_iH##$*RBAES3D{9i)>ztkCl4fuZ^1u_TvMgjjh_BVtAmDa9- zZW!=?+_TfMIBzT+X9E5=n}GjUmEeE%Ou+vOv0wbtez@c>DC3&zWu1Wk30%+1uq6(} zNuvS(d#u5!VFLd5foM=D_Ifx0|8ppvWF`GJP$vrbe-I>xQo4}mVpk{N{|P8P+3Kl8 z1OA_j(n~^#za&!Bfd4l@bf*QdR3iy8%@_&N#V~Y^`ijaW+ zL{z|NcWgQsVxy}Q@P8yk*-)(iB;S=zwOzNSjv9h!KM)-lihbJi4&uKNcD<}}3~sVo zQQ)tJ{AxE$;R{9jG+7Ax|~e}Ti!fdAK_OalJ1;1DO^KZn3)p;sFQ{LjM3@GGX` zM&bzwlQnI@CX_JX|5{161{X?te(+zCZVP@Q=>@@Cl3o}jq0E5)y(RrtkdySH;6O<) z4o;TzlHhzvFAZ2(vSvr{h@_VV??`%iP&|$0R|KOZ-5Jc0^vYnVq~8fPOS&t#M$)T; zhb6rxcw5rzf-=l&2K*l@=}p0blHL-WDCup%c1gb<+#%`h!84NH5xgtu4}wlJsDEeB zN7B23@sj>9NY7;X-9eqC_XMqy-Wx2E^uA!dr1uBcN%}zWBS{|$-jMW>z@J6^9|e6R z{c$i^(w_uNCH-l@cniszM}r-b{w%mh(#L||O8R*4xuj17b@(R)2K;Z5^r>JUldhKZ z>EL{m-Yn@e!BZyvlcdiE8GOcP!2e;AJ{Qb3=`lzd@c#m)2>5>!Qw02fnkfSQvmXrj z&v9nJe~vE${&QRz@L%*0@L%*0@Sl1u|3bk3J0_!D2>Abyq)ow-l8y_0C22O;U(%M~ zFiCU4(UOi2PL{Ma=)-yF1pFT$<&%Tal1>RGNIEr`CF%5l|5KjqHY4~z(wV{MlFkZB z#LgbUX35V9wn;iSxI)rBgX<)n7mN_x-T@zn3I+T>obv_&|GUg#Iw|Na>ExhA(ka3I zl1>edlXP0}O-ZK*S4lb}xKq+7;Qy1zH_xlWIy1fOT>Rg`f-vC!LI(Wbff8>@81VmU zgzv9QM4Fmqq zL3hh3oMr?5bA75UH%Ns~vjP7pY={f1@&o=KMES?8OMZCS@~Yf`|13E%1bJ2T`40pB zQ{&Q5q!{!|8s!uCx|<4C2qif%3do3l2I`M{|QQCsML~F$HDNb+<^Zq z=|@mvE{84*_|F+s&hjcZ;6DrI5v%FMaCj1pI#&20y@-I2jt=;#k1{R3#qj zv5CxIPk^dw!2f{|jke;`Be4ejp9azXF|q#`D)Oc~0sqg1($T=2WN}hUg$ek70mOcV z3HZ;x`sJH}>=Fh1r{Yc6Zl{5Z*@Rpa@SnoRu{~>rU7~>h6uyn^y+{}Z{HL%OXJdd( z%~o788UuJj*-tQ-ewV#*uVEk{+Rki30u;aX7Z4LxdL# z_)qaSv2C&93KQ^O=0q&uKQXsqyUSuL-GKj3qWDFMIK#D}m2SZQKSB0!o}9ODb-Veg z&3J`Y)&=h@u&F+0Y&_sU2YfW-(~02}^sfpl(%OpLfdBUceJGH}S~T?yFhAh`nE+jA zfmGEf0(F!9R5wgSzE!*d@`o(O8uK0WbU*bET;GZQHISclfR;wMEpY<=cg9rjg-tss z=X$$<|4oqZVKGrl9JCYge;JVLJ3yO8@JbK{{HM8#0l(I&u!Anp1pFuPL4cmIKv_6g ztnpmxOu&DZyaUh|7RZLWgCO;rfd53-cEwWOG{Abk{0CcSd<~LN(Cg4BO4+8m2dvrYDzw{rVPb|=BDC4=* znSlQUcCNvLDK_o8(@+7Lfd2&M0Gelk`3)7c3HVR+Dj-j8kM?2#{|USRpzm0q(@@59 z2?PEUcn?62TcFcW0h)mS1ilW?Cl;9BP(ho3|3r7LMgOt2JM;|G5(fMyFbB{c7U(oo zfF|HSf&3SM6D`nbr~pmCe*(`1=sOme-%vrDfd53_1LWiF(OwZ>zk~t*349%(4=vDX zr~qH{Q|Dt1B(Mw%O)qTi4!r^BXE?6Y!ttWk8{fhvmr)_`e+> z=d7H;*D473&pR1!h6(u3$~53V2XZ_E{y)SUw{rGtct-*MuZI=`{@*9*;lcBgt_=Pl z>8ilri}E9aT1k%#MoM~Au$QDq2ggaeI@luV@xg79o)|nY>6+j}N!JEl=h4nd!Ei}W z4yH)DKA0!z>A@07zY&}y>E_@0Q^DeWaYKZF z|3ATr5C;6e2m2D4OS2;Q!eW zcIkx|A=tG0PQZV5a})$^p-|ed|G4Y~{NESim2n6)73T!}XW<6mwzkK*0snbKt^wp$ z3*!>#^>PCKKMRrGipo+fhohGh@c)BCawp(_Rb8kr4V5A9SBeeFba4|3wxod;Ia_DGvevm$zE52K+zAg5^${Kb{)XfdAK9x%5nWE|(2A;Q!+U zNz0|@PQd?{AbAIy&eg3rxNgAz&mgJk9ZIbMKN>_Q;QtT+v+coNr5o^nPXP7{LEZ!> z;QvaLo)AiO%~DMh@c&H6F0^uKsme{j|L;L|Ureq&mZe;gCgA^bK)qD}DPyBZ6Y&2t zpla&F{$#Zfd6YC+ic~BHlkvuA12`c z4gmhkf~0j0$OQa<0Dz}0h&35YZovQ70r+zW(zo`pfd7|5E!_tvJ~n5j!~*^kGaT}9 z79(>p7Vw{#d5|AsF>)rw0{#HK2&EO6pC(f1aYhf#{XcL_FX>Ps&dr^7@9_W21oo)UAb}7lmBpJrQcae`+>B z&|)q6*Cq9PCsP-URLo-FRuC(Ot02BLnfm(CxC21(QxwUym|(qLD#!%bB-~4d0soVjRwdZX zxVi!VX|XRvgDIAAt#kwaGakvzP*c_pPvsvZQ>!q&7DBc(lzWwK!2gp_yxxjp0sncy zyBMM?D3(eq_;LyX|I2u-i3R*8<`Ha9g;;Gxg$el25M%Lx{{()B?Mo`yQS-*yfd91E zbpWcvCbg?Y0yN-1Ei^$miGavLEZ{#e2SdI%#CR%RR+Ks!MXZDA28wmMR^qO`{@9|_ zi{;vxOCZ`wu}*dopHh@scz|l(3DJF#wj1!DtH%ovy%K8say5ws{3qs9$cu4@tbNec z%nkTYOdaGyEJjx|H{d@plOdmLF}hNXK@==Sn7b62S0sjen1)x91fCgg%{u5I?2*(^-bU5`iiUs^9 za3nxk3zWWAx&i<9gzO+I*YT=r!&sPr|Fm&D4KqgM#Qn1KJp z+zt8D79-b3SpfLs6$$#v;#4=BhD5&&R5|K6Y!tF#1M2Cn{)8<2UAo`z<=pK;Irc@&WH-y1pFs@DUc_$M|(vA zGy(q!+yc;5aiBA{f;IvFITCjR`Itp>PbY1K3HZ;EOcag7Qd8eAm8!zR!8+at&Knx* ztxgyLnt=Z_zZ*dPEs*Bp0so1a0QuY)#us4a&5Kd13HZMRfR!Q0#F;k%|Jk6^Ai5|N zM`yfQv?Tbu3HVR+%|JfY0XkAPwU~ha)O!m${;+o4c5d}G0=x1M8mpg3QeGBwub#Vgz z6Wa*fUKT3@6#dA$tyPF%v4H=q^Fe@qK_G7<^c{e0 zidV^xTVcTeKLGVNYm$}VDuEXR^_3;5b6P!*m6YQ?s~VfRDRBe-Q#=Bqv3X(>@Slf# z4n+GSnqiF$t4W<&nBM@(YHf!bYjX`?G*`nZb|AF z6ZNL}E+8MZXuDt=pb7X-v#$X3fdx7vDHhk4q|R?si>15coX4gk$)jkh<|mgh;6E*n z1!#%|I#mnM1pFs(0YIxQ&{pl5H39#n|3L0&kB$fYC-D0KJz{}QL;1-i4ERsrZvpzF z1v(8Cpb7X-U@=ac?%1^J`3)7c3HVR+SRkjgN9!l2FyKFd3jjLG0-c8PlS>%zpTNxk zeaix!h6>OG{3q}xfF7~H{DunJ1pFuZw?O`}Jz76Gg#rHwEFO*fKWyy|JwLgG0sjdc z2~evAIt>+|3HVRoe1ML!!2E^^+64S3dNYvUYLAWw{3q}xfbO?IXGHnQB@Fma;4cAs z%L1K-3eW`nC(y(4$0e}vp%=6X_)qjmAY0p`^^;Q=@Sni>03B|DPD9;*|F_^}`$mAy zw?L|z(?i1SXM@zDL-lj^bpYLNf$UNHfd5ZI{;I`TW9D8$EZ!2N=!Ui(>i+<;J7%JG zJ&u+}xGi}&NX;x!y|K_~wR$|Z?F0VLhx{muiEKM)C*c2PAiv!KS{q^i1;~Ez8qX-Z z{MO@@a~y}q0{-vQfZNWivJm=Roq+#;0{pM6C(Geei3a>nL7_7?k?1Ql`R5%I@P7*M zLm_UALzcM#|EGsCeZ%IJvvE^Rz<*vvYx((z0sncesCo@IreVPUrBFQ|n?Dov_}{^v zR~rWWrTmp_hH?m;W`NVTcP~Fl?ME$FbBaTD{Mu;e-46I z&SO2C0sn_H;D7fp;Qu**cG`r|>;KBI8_KZH>CpexVQg*~@V|j=Se_s7KSKX<80StH z@PBury;#71dM5bU1d6Nj1OC%lK}DsXq58@d75wLXx-OW|GY6NWbd`jjp(BGSJ(Q(K zRec{Oxf*I|YHyrdmE)7;{BL@CIYhn`60J*rUW9#bMHuj(&J=Wn&=@q^A@WkZlvkdX zD5sAlog<9(y>Q!BxhPq||NW=0ga+wh6TH+(2SWB8jcHH+2~ja2!g?)(?8c-7NPL4b z`JtbS0@8m#VP_5aU(Wqlz<+vQUlP(L<9cwKi}RACH?>r zI|2Vcg{Zj2DC(LmANUdQU!LE(L;?Q^8-lHY@S!l|bI+5vtO)qe^U#;C)d=`6tB>kR z!2d}=F2{D9)#aWiuXGXcpJ%+^g%<-2_|K}h18_Cr?2^wtIlXjwM8JRj&sMJICgA^% z0r`bhkk(Vn>%ui%1O7ArM{Iu~j9u{hIRXDEEyciAVpC}=1ODrJ#_MSJFyKEwcQWAr z%~;5o9%s^5Ov+2k%=yT4J7GV3HaM);rj>e`J`$$&!n(={`2S6o^6Dx--Uu7;pD)2j z*nt0%vjP7lX9NCA&IbHvE)4k3%T)Ojs38pa&#PT0UZe)KG){%E6ECTQa*e#)$)Y-_ zwQ(ObCJgvLAN$?IfdAvs^DyB5-cXK4NCN)LWo{M&{x8PE^vumV40I-?MGC${^DA0$v-N)Yh>Na@8Ec@?m?E!0MIzo-@$C@A|AaOz{zHra^o4EWDuT@TT)P^_y^EZ{#)Ooe=Q zi1A_p|7l_=M8||;W8%xvXru}F&;FbN`31zVKR)+tMEC9N6kodcm{62@=}2w$oj^QH zJV#RTHlllFCvEy~Ab*pX$fk|x&Vc`H`j?QG;&{1sF5_6wDM~TmKil6A@{zaMO%DeAr-`MIuL?2I^kBe$n%D%0u!3`PS zyCnxVWvXy1&6EzLOzAJml+r>@c z=S5glOoQBj|MU`78I}8ZRrvw`=|1WLY`}lEh(4v-n2BM)e-_6A{@+iGeWvl5_0lq4 zZoq$fq2@izC^Q!E-`)1}vur>GN$kL=Vb44!UMXRe7m}^$?xn%Zr_t zt&DqKnpLOv*%yEfemP&Q(T`h|1rP@OmqSkxcN}>v;6Hu7BbiwSx8fmW#BF|eoRJ=# z!Sexbz<++DcWPiCy;#71dXLM=?ZpEA)0tfD%6YANVZeX3m|o`X44>8)EknS60_c9; z4iE5*3Zvy^Pn_loy$BkG6{!^RI@lmh5Zce~|YSU-lt=kFsPi?x=yLC%M ze+~FgZF<YuvmV08)O3h)3dwmZ}>^ek7P$x;B7}3@Son*{|Wg2zYy@B?&&fo^?_~D z0!)cfU#~e4#c8^-r|JAtM#uH^zF0ZS`CM4Wvh)R&_@SUo_INj4&X)>dz<>I3X&`tv z;6FXPv@{m*pN?Lp*bVqkzb|9M3HVPhFatgWQzi`fPp2?b><0Xw9TxlC!*w1Pm(=g6 zH&5T}(|JrUXmTU2;riWx|MV);TUvRjjRpLtr&<1+ceQXat~X)8fBK!`P=y;|17PyQr-_!gl<7_PBgiZ6sXBj`ZmdPH!50+iQAHI1ldyyLSEo-B+nri&- zm>Q%W0{-*eSeib3W&B25Mz^K1r})FNHcHC`!f$G6emqRm=WP!J{4eT+N5+@d;{*PL zN`8gv)csWKPt^UcXJfyujLq-l2LGRUCd#K&eSj9EMd@c-P%yP~VjmQ+wA23yJwWPf zFt(r8+5uHS^&zO~YuL;HWK1ys!%8b$4Ql8i;rJby+K=jIar}OM4#)3W>?cZI zJOkrbav(~IN)AOyamh3IE!9!1g^skM+RGT~05x-^vETiYO}I}4b-)uq7QciHr~|s7 z6P7yQSC~tdI-oZsmO6kLOC7+Br4C3TW2pm}vD5)H9Z?4`7f}Z=XQ>02iKqicpmo)I zq3G?fLmRv~A$7oUc=Hlc2XNmjp0pPIcqh$FTX7$pO=JHcnT^F)9gobrlCjhQqGPE8 z#-WxrOC7-6KcNngc5OseGSCrq0Grx<7iRbQWB*$D8{5XeN#&-Ee>ZLPIr~3K6Sc8; z3^O11;Q4Z9G2_yX{iFw{_!b?4cf+a>#J&!*W9+AiEhv&^r14&2t}IBt7IZ^_w5zvQ zH>%+PzXHq5_fS^+Q=H)q^EI|%@zWTuh66RWVezn2kU2;)>EaJhLgrw}WQreNjm#mE zsVu(q1Y{OSrn>kMm~B{C&e7^tTzxz;i$qdi{0T*aI)-T6kl-U6H>F(|H&il) zc46Ew$r;*(al=dbEzr;|j2j_2L%T38M!PUBM!PUBPP;H}bb_s_^P81+;R-ZFXcwB> z0-mFWcA5bjD=$OBQY9O!(2soC$p~`4GqRZXAegpTs|4Jk9lGj`AI}G@lP;;X7z) z>B*B@`3_ogG9eA$LCg3wPdLMO&@y2-YczZZEv<6S-fQ>{S|%nYK-f^3XgS~rtO=hX zGv=6CQ@xh?0nZv;z*-JWb4sLxw{ef#a!~q3bTZ=yNwl@)V5xZv!o;79+#!;C!Vg|- zMs7h$CP>2TbQEm2EKFPu^J&)6P+6K2f`v=)9cUy77FHjOx=65)a|sr5F2O?1C0NM0 z1PeKrU?EqZ;we}Sv;7i}(kuxUaxTF_&LvpLxdaP2mtZ015-j9m1Pk9d1piq?f`uaN z2*E;bOsSqWzc~)Ijg^ccSjaU<4m1HHL9j518YEcAWlK0bO0bY?k&F^75T-z!nLfQhbK45m?FVK zE=I7>x&YlH!NL~=kHq?#n^nrAt^^CY*^*I$h1?!0QG$is92F_SLM~3Q&=qEdU?I1+ z4wfeb3ptlyA-8AIEvQrp7IOO(u>~Q)!UpR99Pbcw2bAbwlVBkiBUs4A2o`d2f`waY zK>EJW^qm9?xkX}42^MmPmawBBSQrU{g`ZM^1Pi&PRh+8G@f^r?mUF->Cc#3ki)55w zAr~W9$i)a2axsF1T&BgN7IH(AJUtA-LasH*S&e%E5-jAV zBsmui!9s4|BoD74SjZim951n-1J50Zi<~>C5`in=XXQq2+8=x(;&_rDVaoZ=@?{=l1#F=D=g-YmP}D`)iPv` zkxX&%rz4O#Rx+K6KOKb3ags?DpU5M*S~BV4dG*K~FPW0!Ut_(Pr;4ILu}}-HMsAtsOAFc1;0HBnaVD_d_U+1yk?KDlBMZ=UAD$|mfWaB z@G2(v_%5>89hV4}pNw3!V9;mZM<5$*{VpVbQCVwfP0}| zirSy7T&k2G>6r*@A9d9K09c76gv!pt zFj8X(qTDNe4o#mhPgLi!l+Qde?w(MLG=pM<$M{UjINyBg>##^0r8hDQ1j4dDUYa*p z-N+#_NjXFa_yJ8sofAd=D2GVfD5>W+1Vzo4tbo#dN=to;>DqdY&cu%hO=B_fQtQzF z*88-j)efVKFBZ(axdZd6 zX?C%+bqi(DffD1AWpBOIf#`n43MFv7E>=Y!uk>9E`{X~1ncq<+Lo3R*jlOhVhE@%p zhsim)M0=TB8Y*#ge96iIO{XDAm+^flRV-ixBX~E=J|EVk4v+f zuPYa~oaHrv#l4(Y_{q?f=B)2`WBC|Uy-(d33 ztjN59j`|w|9<$`O7gujXvZn^aUQ+MD?c#?Zgf zpdML~8H7pg-(>1~bVX)8+j4WyqQzR*fMbo3JJgo9=PK_ud2N;4_VX13&NNc2F!GnV zkK=S_sg5(cGJsvV%jBO~0Z`*bZE6ZPCh~V8nQ3O`MiydBWm z>wCxZajT5?_sMNzcC~3Up|baHOc0OAjCmglzEa0#b!pmzbMnpd?%CtaM6Iz z4L8huV<97aHRW=P4}zRUnKyZqD@t?owt#>L!<_F+Y#wEc(arffn9ZzI}@$CTjyx=k`Oi|1mQD4QgidBt~Q z#V?yInFEXeYalXHYwjt+<5ckr0W#C8A4Fzl@te48l+BbC<+$RTM%L^u6IqMM7XiXplY zm3*F?V}XK-^4ySuOlvVbH=>eHbMqabEX~cU$fV!G&%V4|{{uU|{qfRXC&XvlKcu<2 z6BB|oH|z{)ZrDQ7+-Uh(!BZmN61*enxxtr`o)>f-N8Hw6n55f+10>xZ953lb0i8IK zRhI_em2^k&kffIdf0gu#pt_mzD}zQ!cLg&g{cfEYrW&Y-(fram`LiKdJdp(obt{m-HVsKbQ2g8d8(=iPPK+ zN@2i+=0*jU=BAAT{@aw%n1MZ^xjBdep}A2FOLKEP1wwP90!wpq4h7$*exHcuhGTzS zC{SsP=BClm+%y`Ro2Cno#91)0Y$w)>0fy%0eC)?)ZpJw@H@GSCO4E3iyZ;na&wF{# zrMantsDCJq(cCnnwAD)bZos+Z(A*pV$pT6bhFP!Lp}9E@rE9I8N|fg2Y?OX0l=z26 zib`{H9YnWV@xADjv8yyUk3#gk6)&To0p35$ioDEoI5MQU zxdvs}ncAHN2Rbx290H$(o~5~If{`I)p2_?S!X#*JHlTzwHz!ECH8@|=^Mh+8-4;9| z=>@^-l3p0#D-iJ8gPxLpD`=MVqF{eXFAmm9dP#7uq?ZOeB;64_DCuRvo0480B&N~M z6~PEecLuX0y)sxV>34!nlI{w2NqTkgfTY(1Z%BGwP&%FZHw2?3y(!pV(p!SnlHL|< zll1$+ZIa#|JSpiN!P}DlAV|)j{+&Ucq;~~bNq-m=&t&=CK@Umq338I&8yq6(eZi@c z-XB~e=>x$-l0Fo?D(NG^7n1%csGCJQKMp2J`jcR>q(2QdO8RJUv7|o>?vnJe;8&79 z9(*e46G4yJ)PFJ5Sk#NoNM1N;)g(BzE=)Hc5U?aGs=dgB_CY8C)ajykMx{_6|BT-EDkuDOSMb zZW99DTqk#H4VH1?7&a;Alyw1*c0oJ=iJfjNo=jBbuAX zkZ&?HH)of@OFE>vIhZsz7o)_R6w=&Wh1?;Q=BBw2%}t}BxtVNeZgy3`rN6EXA0w6K z<_(ze-$kAN`}m1yZf2po849N?U+t|(o^lx838SbQk9LAo_!LWXL*eMSu#$lzdLENZ zRpPOjcNGUv{x{YoKfG*tl?>|G^WVR z0(1{S+;J;$X>KTcxe!Q3#n9XkRE(igOHv&N!>fE6A0m3*m`wd_zUQ%|o}e#*j%aQ; zgEB0yyqRExoScXo4i?NMSexzA+;HrU4(+J11uo5v*m7xZSa4~m;MKi2$n$u-Kx@+& z6wPJY6wKa}>9}Ay(g7ovp*3|&?(c?sV*0Lv=0^Hd?ax z!(qGln&nKn1q3}Kk9*KnX>sFc@3V#j3%aJgmx#5KT2!hY8u*}fhT*~9%(A*Hw zr!zW^O@>F0Z1%7dy}Cbl$2&>_CPO$k4sd90h*$>c5h22h(cDmcIz(q#ahajHkvS2g zxgq9eYa*E5ofqIwEQ=?_pj^fr|8D?2gv@GCwFOX_y)QwHr3~hjnmw4 zOh-aKg&0mje`i>c))u3=xd-S4Kpth$)HgsbopsHA>hfcB>D-L``4&jk_B1!wL4Lo* zSYy6}c4%&X3FO~9KuaUsmN+yw71f?cRwwPCoa^mqZpK1B(_*5QIB19FhSbETc7QgG z;FTbxxuLo3fM0D@*g+R)Xl@9+51=P4P!EN$fkI% zj}LB^^u*v9N!J7)NV+!YJde1Of+3Qg9JEQgKA0=%>A|6rej`{T>E_^kNzVwrBk7sJ z4<$V(_`Rg(2JcF`HSqVwQ$a{`^9W9a0blNmTh99Z@4~*Nx#`m#|NTO#OLOykEC7GT zmN*DDd_w#j_F^R~X(P?ea^ypr zo29T4(%i6I?@mE;^B39(X>NGvT$-EXfxHBp&mC`^utg}%%?&8H7hB>481}iRov}1G ze@D?chvw#Y$iGd6?@~eRg)}#k@rn)2%?~j|UPyDprlt>N$6_=$Lwn$hCN`~I2F0bh znFY~)RxI7^yJ!K1?BUcYuul9@5Fby-NobDO_px$Ff0BA*iAv9gtS#eE%`8{QdK^~A#tHq*!>(NaTm z!!GO&$wW%U{?|FIT8Tq*voGWag_s!4&Cw`5DU_(G9_zJntMxE{jQhuIt{w zhX*6vioY5EhI13d_ZNVa8Je4CAoDXsgfut(#$!Q`Xl^#4#eaqP6Kv846)Mfm84y^#*1!^w;^{?t~ct zNf(T8bf&14Xb=ZB^!L0Q{YHQWVryy-_R3{-y37%Tan< zDA6@bH4V+pX2{OBa%ri`4b9DWA-g*!*S5-1u1G_3^E6Pe7eLC`DALf}d;(OL`mq13 zGa5y=iH7E8FrX7G+zyh9G&DE+0JYE}w{h6DVncItJY<`!d_f~BcKTsxZY~DkS__ia zIUqxGb1wi-SP*M6mRy>fR{;292-3IqN-J}1A~has&qYux?t>E_n=?}sb88}XHC6y( zhCtq6F)|kwb8jMb_u-0}3;BT-BWIFgo=l|f#Fd$LRztqdVq|y}QBdnphA?7S> zTZz^FT!8!SkmiP_zK885ip5ln=7!oo#r7n{s_oL;u+eWq^v6i-(%ev7+zRhn*LuBPD#*~>ybQp*F_2g8(%g7h<2qq8uJAnMLMca#! z0UDYc0$&2?ofyzy49yKOi9tB#*rLO!r%{aNhQMI}HCdqawcMq-*#oiztX#*dt_?@l z(A?0*v5=o)F*+84F*G;CTnPD2i_t5DU<}O-F?T}#gvH49k*BLp*BH$W(Qg3xH;Z=0 zOUxRY8v@I5v$7jD9SfZnf-y8V#EgM_vc*WPPG1ep4S|OMw88>)ZU|kAp}FCuW&`Bg zErx5c9(T1UXhU;D^o>B?7e_m04b2U!egU92El}F1V=Wd9%?*KH0<;@$+ns}-KbWFo zXl|tcfX|4lI3p@(Lvus)Vjz!ekM?3THw2yq(9Sr}8Cx-HXl^(XcLMoSi{_qA+A>3P z!;y^B+^~*60r$Dpawd#Rb3^krL-9|@ql}f$h<2^VqEs)QSVSE9W-@F)e z-q73}3c&IZ;VTXewXV7e!xw8_xiP^AU%{R*f= z&vG%E8>$=)_!$LMq#MrAu2GsBs$2>9-33%Q1AYFOz8IPtsyq+)p9-kR>cStRVrXut z(rE-je~| zgV%ckZt>quUxO8#t=SIn)m9;b#b|C=@qGY2M<8z_^c{e0k5|r*TOrNOTR{EAnq(zj zjOK=w1S9eG2b;MmacOQS9tzQ@Jh7p<;US*|(Owkm4Z2Hn!}l>OAv%U)z2o60myqU$ zO+Evn%R{kmyDWpMpL6OB%?;6a0QqB!whOia8k!pdUjpbo3$$hp(9qlvnA#oZJT@Ik zUVTi}{NxhS+z>blpf(G1surN3xgqc%fR3?1TeWM}(A*Gx29OuGM|(wL_KA|zuBH0U z=oWw;v_Pk!{NxhS+|c5$0D8v)orVg~(A*H17=^B5)2`flfmOXlQN-+z+5t7MR~qK^vMIqBj9~L3?zZ=7zxQ z0lLQmoe||HmyqU$z@G#3x&=B76`-NHA@Fm6I*$pvp5IVG8=4!UhXI*ukJe94Az+c4%%k z0eN``Xl+FM4_+-NY`}khK*`H+9ES+a&43@2V*vZC+Y1A-cqd*?cz(4*bMptl-)B8d z96psO%}o&$DzJ$}U!hIqKkpctn>OGFK|Cf7In1TGnG(wM4V#x?<0c!L8(u{%%?+;= zm9OC`Hl(>(4Apb7`O{F3|849=G&i)8q0rLY@N=N58=4!cKO0l`nT=>}_>b-`&CM4U zOjWJ0lCNDtnj1D@H@=pf&4H?PX>Qn*1}m~OH=N>@=7vYv(%i@~8c>Jt&z1dlpMe)& z^5z^gH*&ItG&d_@Qa_G?=0^T?E2O#E1WAnM<`xt@h%Ip$M~iztG5V4nG&f?m+M&65 z1=6=d1()WAYF}V0LaP#2va1fw4Gs5zppO;G|63`|4Ta4Rv|8c#L#OHgsAYJphmhuG zNQ~y@Oh7}Lo9oK3&##G~xnXldnw!yV!;*ZOn+W~OVVpZ5&CPJ4y%^06Jrk76rZS)A zhRzD@X>RDcpkHQ69hw_DGMG|_=7w$!S{kFdp_fDCOCe6Z`tu7+J8x-7b3~?9oOLIf#2xC2@x#9o*(^sM+nj890h>Gzf?zIe)%+TDtN}2r7$wdL_w@_$kZZh1D z(cIAcB41$gE$HJw#>4CLVQ5+_3 z`DV;j(%fun!}opA+^A>CizfeCuv5xk4{n$Ajo{~!z7>2Z>Dz&LlteT)RA0|3;xsq% zuh)paBL8{~nj87oYeRE0;I?w$2ac=7E6r+$=H`Bw`4P56FP;r5QJR|sKqGink^srL31O|Zw}23VFR&^CVUVK`P}p5Eh}hlcpm!lwHh=x zvidkQH?2S}!FIIO<(?=1ZwQ(jp7Act4XfS;z*U5^OFsAH^wQ-KG&lO6t*_t$VrXt2 z2IM)bAg!mCOLN2gJJ|kA7`x#0b!cuVO<`cmu&H!BX>Pcvdl_CwEzJ!-caq-b23!W1 z9&OT>Ov+2k^!@PT(%kS8uo9;A!nz`d6LQe9fs^qtb~;OWb(J4)C>MdlpPHjzeTQ0_ z8@>`BdI}EO(aZKRGD~wKGD~yATu5`n%T(rPs3D}e;ngmrxtRoENOQx>T}X4Y7a9}N z-0X*aOLLP&&qJDSA*b3+r8AfFLpyco?5O)Q4!$WUxdd^s8y zS3`5d{(J-St;DcDKKH!An{ZS<|NXJj_xa{kk_M)25D~AwVCO`mBLOB(%hT{16yh26&}=ZdaS`D+=bGcLW%z-#o_cg)tw%sxgqX( zY`-G@U4feEajZK%*1-lLUtlYm7((szAkEGDQ0@g$KZ>PIc6vOV#;OL*@es`j#d*_% zG&eLso~RWeCYm0kxuJ;-5S<;0^QH%BZrGn)kl#cM`{Q%ZPLHMT^dQX*t9%}amxyPp z6>q1<@9|!Y^?pQoTg;}N9_tsXogR=6B*w85PLI15tDT9E&n6~nTa4z0M{6nMt3r%U z4<3DIday;FrMcntaVPN3_0grdxt${3)*wPqPuyPotcKUopNFL#(A<1jNbbvtxe;Gj(AK zb8~oyG&dREKBVcMnWh77z@JuT11Wn7*^X##GIZLsG&l6zq_?In4wmMI#rLzAKY27a zyz!?)r{2$Rhg?yX=7!4j^z?auYh*6XO;5_?4q2?nXm02cDk`QyF3kD4apXP?Xv3e8~U}nGUl)cXY&JG&e6(CX+*sA+t(zQ<+b5LpR%eWQ^v9{-HXO zwxzzuZs=mF05yP2N1nQNF~-r*+|bQ8dLq*!5z^dnw$uGr zo5>!>Xm02c9JMP(b3-R#SF~^tYMft1gY+AA4LUS8bR~AQVl+30TD54nScVu2c$8jg zXl}Uw??!Wzp{J`$b3+el>87Q*;keLWIvN*!vEb6&(2qJA93wY0H`J$pb-sR#=H@B_ zF`66td`G%w z8FXoG=nS3@aA|JnB;IZiel;GGua8D|qxZO+++K|4hR)>qgPRIzZrF5snYS~18vcWg zG&cm${k$C@q`4u0e(4I3O9O}BOC|9H8`9j+VO`pQ)jgl)hED88=F;5oz|pT=n=Y?Z zT$&qJOLzCE+8E6Zwdn;Pbv#CMLv1?8N4<*C+)$f7^KRV^%?-8bO7GTv3wx_HH`Jzw zy<4}4mF9-pbi8-#p5GnXN^?VP`r}7+>-pf)+|UGH{6q~Yqf2x1rviW`LvxeByM|eyx#^L?VUE+>OzeQ>hK}zY(A>3PIE)+bg5TSNOQwdI@W7xjOOM|7RwKBKa}Pspl5gR z7yP8B^p_^G`s>_4GX4%VhXm z7_cn8wGuxR1hU7w=?q^g3~J8cV^!xQeYuqW#HG2RXP1`7Xm04}Wr|&zn=fo}=|AwA zui{OKp+_$;1I9ZNOLIe~FjM@&p(y@XiC$)e#Xk26(A>~7MK5S_Bi^3ohF)cQODhkx zF`65Cn&rQFZ%=bWKeWh#X{1YYLkBe}?uh25Y+eZ9UICgLy0jU?3pgl-=7t__T0Fs} zxfyg;8!-Koba>Mv@6z1R{mqm*G&gjHi#p*AN*x3f&nM^`r!@@Pg58RlKE33$GrUdk zQa>Js;yHTZq~}~D)0rpNu!$Ye+|ad7j*b_jxsi9z(eX<2EpWh>?`i%7oQ(k|Y??23 z1AcG~WRKqmgB|?go7dnM)Sz!!E2Ukj#{Z6ypktu9;k&UkefR=?BM$g)GQs2gVOcAs zfk608EzOUIY5Kg)0?m!z36GEeBF#;V+UBolM*3C!boy7RZBk#um*B6av+3G~H-HPU znT}Si9qxH!M^w&1QAx6XJzm$~Z&*ZUvx9<5&P3r?(AgXhkXZgfXnBxVW$0|K5zB3% z<%rJa;C*3p@fun_=p-EKlDTW~va000)p);A^4C-F_OGP(X}GT}@v$G2{Bb>&nUW=6 z$G4P{e$eV#vSlN>QSxvTLuZ0!8R6Jh(;qD?X~C0>=GvsuArCO2--k&#|r9-@l8Dnn

Jo#{YJHANol^eAFgSJl%@zxL5Td*(XQLeUcfA{q%@U~SW+5h zEGZ2$mXzjW=vY!3W-KWUO-H0O%tfR$%vn+zW+GCW7t!dh4Jf)0&6L5}p!r>4equxb z^A~ny^aiy4Z)xH!0Sq&3#fAWeC`$mt8DL|BO#%SjeZ+IO;Q6arspG`%Ow?a>@ZXCI_y;zqz*sJgSDqq-m1ol*XiKvgVY= zq-l!gl*XiKs^*l&q-mPwl*XiKy5^L|q-loc42?(xEfQs*p#kPPvzz+|GIN=otO`emg8|uORmKU z@0UDyDwl&l;tWlf9Ey{_q-5a^KlB6)8Y^U`HrGvSUii(I2mZ6d+?|zsRq6ekkU&WI$sv90VW- z5>EnEcye7 zx`NTkCKR!a)k$wS_&@Gr_2j_FPBNCr|B(&(KhULViFpU1Z{+`|!jABNWM`G0jya+H zAKBTG*;rAAvwsg2_!R-JOmkG=SIonmgeCvzSLDx24yLK68c@~VI!vCBe`HOaSemFxi}I?Ck!2&q3R`j3OVpoC#f`xQ41!T(H3 zCgXekHv0<_4^Ue=z0h=;#2?v3V#=@hSrz{2yo4P@cXMd?rlz? z&S@P5@_uByNM>Wjx0YdWJ8dV*uQ>8BEP0Z_vHu;8QAqkx(WNKW_7o3Z#;^D*40MxB znO||qKwJQmV{yDH{fg5@;uCd}C&OUB;%T5;lbphBeg*kHrX)G<4#Wr*BLZoX2Xk>z z#pRPd@8Bel+EJ;B+_5N2a=g~1D<;La^6F#twKD1!ytG-C1B z@D;A|HY`;m`e7Mv)!p-OYERZ(C9~Lx(Gd6JU^50Jy{-+{dVX_C^SflQi)H+79WdLC z0qR?dBtSju7HCCf;W#$WraWK-ns5 zOU#HtF)g-YGzQ-!RNnUS*{9x1y})I65AEYU6v`OoHLOS2Fl}9`no7%5=@qLa9hEGb z;icciZ~9&S@ER^W2Cd3tQ2GC`_ulbU6z|*c&N<21lT3O-5(tD)LXILuI-&Po6ckW8 zh#;sm6%-Xw6cq)mh^QzEqFAtD@7NK`*REeH_J$p7?{(cXJ7-S<@ALUR@B7E|$CJ-z zGrMzNbI(0xXJ>cLTsIaxYx*(pn_LW~FBzqW5+If&Yj4Q0$hA%Ed^QRST{TFtPQA_M zVFW)0eJ5g{%!#J~)Rgu|*Q{OAl70-@bTyZ&m$W1=e47!}8C|n-NlQ(QXS3R)YgR1D z7gqRo#q43xHFqwVJ?Jd_v=&M;qW?rqE<-Q0xn3@LV-Eog%^wD>s;82@x{Xq&;t)*w|QC^e~i)=1SWnX1)cLrkivHn05Csdq#<`!*aYEWr@60ti|t z&*?f|7OP;$V8Eh<9;)*N^p}85{yJAr3o+ib6o&ndj{-n~`~02gPL5%J^`!h1hW*PX zwffL<(wAE;`6&$hODE-jj*14uK6Rtalk%(Za-j-r>CTyyFHQ#v8?#TKVJ5X2Gr$z? zLKAp%W_hZPrPN(u-xH ztdS0dkb1FWVNs-G5xNX8ctAut74qdT_V%GT?_6{>&(EHX^XkIQJTI!kd6%LGc|NcQ z&IcCU&GWrz-pC-6uWSrkTUX-KiV%NQnVg@AxkO~WIluG-oNuVd_`_>6@T01Jfnhl$ zx{s|u0V2DMy0f4n>K7i#_{*UpEwf-M&U601GVqsG55d#Z*YSGj#_2=qV+ha7qGmj} zQD=UgI&*OmXS1GwW_1kwC9LQuqSHS@?T-=${?ZFza9pdRigdk%@HETtmP2{# zPTlZmKq{~Gv*=ztOKaV@FTTqY-TEhJ=UJXt8D`+``~MdMe_19PFi&UZMbRPBU%@m| zX9?rHm;Mn7sH=S1mxBer7{CLQT@$?INrQ!#$glznLYhBTz#47;=2 z%DwER-_DB;!hau6PebzTj&hNgz6YHtyOUg$rmGxWbe4;X^d`sQqFOEz>DPC`MHjhf zojwYkE4!;)bV|>`1myoR@S_f<#=l3sKkdbu^iW=oFHLg9&I(AH=X5v#1Hbf9wCU|g z*}*aJcOVm5{4>Nk27UqVhk-vQipiohcwt4f{Xh&=d1?HeWno%c0a~drp4MxSM0Q0` z88GlqN1_x4{x)Rb&)Xjbe`P?yzt*L(6#OPlO%DFKfFX_H;D5=bu^jv+O-&O18v!eA znt{&WI-0v17xAz0???`<|KLQqfB0~W!G6rxfQ0|S4!FZX!q4(VLBdZPNy2a9&)2Vt ze5L+Y!i#jIBjp$CQVCaS?%j#zuhHWqyiA`Y;T3wNgjeaCC0wVUmhfu*n}pZs5)3F& zknnesaHAd~;Z1t1gq!qn5^mPZCA?YRB;gjlL&972`x0)|kdCl`nTfc zJ$d~{@%0k!E&g4?eZ|`){ImEi3I8fC=!Fk!sU-Xd`=~G>;Wq+D!rzAivc=gH18^oJ z{NpJQ5`L4yk?@~HfspVUfg|C+m;yc?yv9iqe%AfgKwzY$CjnAes_Jnh?)Ykdyh|<3 z>}W~&J6RI`>(TDbED8UmI8Pzr?;IlGkHm2+;fRcdIzz%=?cSmVGVm5{~BMAeltz1X@`fBH>?v*u^fLkr)#Gix9gu zkf^E2gocEFD@5C!_%Rg9>NO<%FGBRD6CcaeMchbK=d8*qyyoHhJ4pX<2+?m4%XhXg zh+HVGhr?8c=qP@(A9SqrccaKHA?h56%@5a$xzW{<@DGD%Y#>(5(HqB~_SLyMuMH*( z-4UVYL4FD`QZGk^NciVbywZuhoHx+yB;ntJIGpsY$B3gtB>b!b#YnGo1124X^;Lt; zP;&4!eK9|H3Bo8y_?IDuB>X2!xJq9t;c9)0glqIO5?-ReknmC+MPichH8B*TT7MdCETE=NqB=^F5yPK zNx~cTlM-&yUrM+|XQN+}guktXx9hPI-l-Q#c$dCR!n^go65gXyqjfD5<*Z`*A zt{X{szwRpG13EsC@ek^92_MqkC45*L?pPwPe! z?$Es@d`3@`@L5d`glO?|dYy#N>xU$KLBB8Ii~4T~U()56GLeM8gM=^Z!)-WE!d-f` z4eyZf75%aezmxD)orUQeN%)&f_?jMU!xIpag#QwTAmP8AAxQXlF$4)e%Rv%;)-y@? zS-&LVXT6eyU($huU($hupXsXq2PFLW_J&;`;eSHH4tl4A9rZgBcGgEoSgof>*hL>N zVOPCa!tS~e`(cQLzf$6R>q8~%qq|AiR}Ye~zvl0}qoo7%9tj8Pza<=`Gepl2yNOG$)7MBiTyK$Zq;4U&!*m^n`yt^!mi-1K{Dngq_R1vN?d$5H+V^OApjYSQ37M;;1U4NwQ;Qcm-h+ ze#SH*C^C#ycNeQ}bhHtBP!8h@!X*5R7)h`(J50jQx|w^Sd z1CsEwy+FF(Ui+|xB>cmMGwi5mB5YIfaDZ z$4h+y4w0!d2rx+v34b$)4t3(QlVU@{-w&cAQpD;7WaJGDk?>!HM8^ZO$l)ZHTuZ`# z3B)SblJK*vDrY&6MLY2xR=#cP43qG7MBPILSJH$oNfLf)eG$j2PFO@1w(yM9g-Q6ogY1tQa!%jM>neZwXiS3(ahKyT>DgmbN%&c(heF<;7t zQJ^OQd7?uzy#>}J;a>sJr4GoXW@mqSZ{?SwBVLAxt&l(AFix2Yp+hA6?*h5^0BA8H zY)OcOzW`mm0S;3@xz}rv@OOZGh{Gf;386zI{L_Iv;{a%D1fK)}2|v|c3HWB0gar%( zEeSt?j|23I1Ioa`Xv47*knl6+D}erSKpGmZ1j*l$@Dp892X8$%l9gcdCnHKg!cSmN zfJQoC$WQ@pFeLm0&H`w$1BMJ0pe5la@DhMFJ77&i1#L+;U};FU%MLPFhvg;DnLuZPhb~-Mmk_kLj`R~_=%ncV(^2GCvytZAsAEeSu-1$bp_jH6c5lR70J;U};Q zKtmibWT*fw2|t1S!N5WX3>hjwOTtg!MF8F4fHe&jv?bvu`XL}+tc~{4`1vIu;V1Aj zfPQhnkf8#!B>V(sW1wk(qgK-k(30>I*a4s+4p`GrL0b}jqNfA7ur}H&n2X^lOu~N| zK%u*G5I?Jcgr74RZ;&P7XJ&CXBkD>L{wFwb%VD_=J`f52tw==@{zoJ{R=+OcO#QWl zv$PsP`Ej~L!r8i|gmd%=36IxvC7h>MN;qHNCE-H-x`Zd`UnD$P*BMDYi}WE9F4lb{ zJVTF^@N7L*!gKT@376|jB|J~xB;gAEu!I-tPb9oZe=p%GopuwtuR2DAhu{ERoVQ;_ig zN*w_SKbtQ9KgU4%a=!;A*(U*cH4eoSuXBim{|-bvh9hz^6f2&Y!jzGBKd)kC&R#@y z4w3MGgzImZ;ASQeeE|u-TzCNq|HG&vFCgKksqv{SSYAD$(SOk2gV**JWq5VNVRDyB zsn`ERnEj}K%3Ms*AsXYvQrsqz+K})Qezl1l>xo=k&4!v9ql zSZ<((grAW6aXd<>D5}?{8dkjP$1z!b4Y40kB2^?-)Z2;~YQ=y3n{c!2f#|PPagz`U zKVMaf>Z5nyutv^?rIv)BMz(>ZH>IL~DXZ0F5+dP067ul@#;f-Po;wx4_}laF8id%> z0*Ogjl_cT67?NvKq>96(SM_89wIw9{+aP{oKagBY!v8vCDu;-Gguhu=j50|Q{^hXv zH;DhjA!RT^L&ARngoO?8Aq0mhetD9FpT%qqLC-)a_M0CQS0zdKM?pL@6~dGTS3Yb^ zK*G<+Gl5%G8|#%PN%+|!n*iD7U>pLy`oCb*tC*_lwZdBuL}n@~L$NeR{d#zBu9&Uz za?s}clZQz7^UH(uVyIMk{Y@BkE6!6ThvE))ayjEaFV~Xr_ebq21HMq*j|tX92bMGb z^W-fLB>cy8cVI)pf1v}*Oq%~ZqwF&E3rcpYlS|2@zPbvH>s2L5`2T{WxM3i53RJQZtCA%A2Laf*HrUGxlkg7*U~~ZTx`jyiXCih% zATeW>Noh&=S3q{DlZ&NBZb|rWhU}3Pxhb&>oPj{s`2Lte&eHyK+J{*xeE?&Oo&BjZpxED8TQ0B&(0 zu`UF%B>ay7u*-p%lhw3kI(qMQ5x*0nJ_F!~0A#+}8`67A!haPo@kY4uafEt`!B`T0 zVh(}4qr*sFG#E?5Ps~Wjk9HWjlMKd^@DsBT@-rPqs>fg~2|qDwA>ZgQtRgRMUsIH+ zS=6sH**qd2hWtrlYr$D~@dxi>ee7ex`l_$14<@)cpKYaZ=QO49_|m{S`z%B*kG8ev0Ew_)X8H4wLXx zc@;!0lHxE4KgIna8k!V`N%(o&9Rtzqq<9dg4A(~e4v3=o9E2An#r%d7knmHy5uzFQIzZTqfTV^L5`JQif_!p-@lr_mna5&?&ZO9M*F4PH0}_6w zUJKE+$YUh9im5)slz1v96jEI=;I)@lBY=u2|qFWAWv@=l);Qd;sE`a>H6io7I zk*mB|x1WP|BJY zCgC3r**GUR^;O;zbzw>PsbfCmr#p66vLc-4^a{<3#KS`t*X0(xFSQ36F*$DU}`$@tcsQAy8#ggzd z30ZJ{+)ol2UHH!?u_XLVlFI~=C?4ya^wDNmB{6WboR5e_RAl>8^-R(Xc?tae&?+kkbhB4ZxY=<#BNl>aD#BqWC1DbNid#U`wuab}@UzK>LUcIAW`Z6j;pg|5*$~a6 z*vxpivx-JkWZ%nzXy);2v5`LoZ2l6?Gb_2ErS`vN&KL%)z1BPl+G+GjV z0yFWsfge*$O|lhj)?9K4NcahC3s4^i3}r1qOTtg!c!1_PpvyX}){^iOeF2c`YNJz0 z_z5I)?^6yKGL%a$0SP~W?*sI$1BMJ0pe5laFugU3j>8narlEqiB>Y6T1+q_Vv{`Zr zNcagH56~P33>nHLmw<$yz~um4?tmdf1!zh53A`PkryQ`Rp@Oy~{6xPGICvXfva~!ayp@Oy~{6sGY^77i~R1$sy zZwKg62MpCHms|o8egfYD=nDr787e?a!cU;r21UoQ|E3qTCE+K!C6L`~qs@|2K*CSp z7=Vs-z>uL~68<~!$$cq6s~wO@?d>6y`5_YiEdbr)fGkmM68@c#f8sDsnVn0B#t;er zpFq|_Pc%hOMT-$(OF|_4ZIPzCOUJgYO~OA0@;MHZ)Ez>HNcfindEEif#)#SrUR}w2 z%e5XahxK@{knlIVF9#LaXvyL2Fzvj)GlZ%*M8f|a;6F2;&a6HoF(mvx5)|MNiTQ*k zKi;t<{C$8w7~=M+km+F({{Df?d|~r)Xk33w!q2B@DVL8L->96OlBirZ8+f9PKS zV`lh+`sjFM!7q-I7n7O{3;5Y3AmOJ8+>WG%!62_7Ou|o7IyzA)f3ei~dX>#CUdrFC zG~TST*~+E!`{CkA6_++@R*v;&knj)2hcEeZ4ibJD6#^3e*-&W~$3Vg_KivvQ_?JTx zuP2=P-Sa;{pS>FqPvMAM%i7|ZBF21V2MNFEEe?_Je+KE-K?1LcU#FT3*oSg3nSw<= zj>tw9Reo>PWXL0^Vk$0&ps5qe@2w08KZRW&=;egnLBh{U@N(GJ2a|;VV3P2cecuV0 zH2om!LO=r&{;k)(r2j(pc{5}~Ft;w4l^Go(;pavM8yh0w=V)kRQ%Lx^%OSa!Lbjxue{ZAPc{2hM zer~4VMhL?TbD5aVM|s{^ksR)r;^qjeeFUa$c@v|#{Ov#YO32Ut&2RtxMPnhmAu78A zxqm{E*nO}KrbA{)_;*t#|G2r;0ODUGvM?=uSp}Mj=P4xo+lD`_i9MdydGf^{zP-k{6NCbts91fU*CK*VosLY=SB`w03qSm?^Cob|87(c_jV*j zMzgMi7y7(=W#0q$eAJYuknnRehyc7468^s#Et`JjO!#@?dsr7?68>_God(5f@@6ha zUnL3u@}Br!3KD*^v*c}i{i(iQ;y=^dCETswlJE=tyM$kA*-?@t;b-!*m_;fHzx?zX zB>eKzYmo5EPp>Tre=|$MU#|;B?hpz86HxOkjz|UX1|u;f{QTwH=Yd33ia12VzYn7H zYMaoE*|NY75`KAqD|-4+{LEndV2l%l9fYGD;Ri#J;+ZF3SwX_j`w$cY82muOFQbo1 zJNaFdz88?k;F#;u^30P@x**}_9j}V`Flcsc2h<9)z6^jH31^WM&*b(p!y`!e%`aOy zo?8ZMP<8!p^ z@QJVjr2Aa%B>Daws1}BEZTPVb`DhtD1{e7YMq}AvN`qxH&0~5tRGSCutPlzRxs2u0 zRsMO+Nu?|#{QL;syx!qp{W!m$`MqXyN5U^MN5U^xj)b3A0SP}JQ#mgohk%5iPrHDG zzb}LV2|piq0SW)%FeV`3AA|EUa)_&{Q*yeZSkKicdfCu4pCtU$(**LC#Dw&ON%+}X10Ww3 zV7vw-;b-eN*o_4MPEWlYY8pZk{xf^p?!l45bq|v8uY`h2sAMEGy6!;|{!NJ87D&_) z6bIeo3|7y1G`S$nCka1sZ{m2L_@e}ByT^P&gYK~eItWqd-aZZkb=`v`{F9Kl0-|OV zi%qV3JQ>HRhSWVE8XSmgbPtm7Q^hpMX9bvK_aF&BRV;((qCi}udvwDX$MS4~d>b(= zkK&o@9y3^|pnH&npIN>M#K*+bYJ+#(gCzXScOT^GJyUeL?m-fM>M4i(AYwv#g6?tu zWTU4yiF^nBD0qeb%OHRTg?J4Kw< zfHb8(VhsuZTS07ygkSd>2>HtmxySwY{mDZl{Cq|yXB3|PYYdW}S;S4BEmB1!;eQbI z9t8=%?1cphzwB8B3BT-_1qnarZY0^y$5fgjH;^*qeo=b|M z79{+#mlh=aoOF_OU-qyfknqdiT9EL|-dd3G%ida$@XOv>knqdi zT9EL|o?4Lb%br@0@XMZBknnRVMiPF`yGX*%`4vg{Wlt?g__?R{|B~?6CgDGhB>aUc zQi?887|FY=9%tBj*Yd5E(}y^>XU4e!H=F-@@-kcEUd82sNceM>A*mzb=gv*;)-;2I zBjIQC6O86RY-Wlg$>lT9S<|EWocMD?rnJBOu{tbP5Uoqr|v( z8pTU5F7*{A;pZ;Y8ZR>jnnJ?w^#h9ky!ge;CrrZMoHBWVk~6+2*vy!@BjKlg+}awh z$bf{OGH!PjnU_Ms&)u&^yC}AmRg;9Ddt*&27=R<;r)F-LRXi~@mO{e+DP__*qz!p# zNcanClJIkzZB1kf2|xFT*05BGzJi)0{M@0NwAO%9Ncg$M)Bucvnk4+((i@Wdn?hDi9il{l0tg@k{qOXeC@F%BFHcofaHB>X)8KaGSxhdW*M>*G)ZA4-*T zhqM&a)6J$M_86%b?w3y1i}|piJvqG~0C_`~ zv(SylmesHKL{^WBf!vy%%*sn4;s40Vc;>~KbqWbT_i>xV0?^||LGQb!=_!(1U+x}} zr;zY-&v!Dd9R|ZB{M-y)6QJ+G45r0-Vma67LpiXFo*yRR=k9U2xxEw;er_gDme_vw z2}t;9F?X5QQhZipWDF910=WIW79b$uCxH9X4L}|Z#`^d7~N}<@N*Np zmE~6zBFzmA7_b_-uicm~pHz%^LkY#qmfPKv*?Re(@cwbjC0VKfe+sWwtYhN%()< z51`Xacmplzq|=9D_6`#Ma*T-}xk)EGU16Tz0Pk$QLL~h99v{Dk7$G0+xbZzi!mm5v z5!7l_F8QcNQpA5=Tn3Xtcv7|+Dx%pG@t+~#*ZnEFTfTg9$GjOM^+3jMm)P};{FBX% z>+wnR}N!ez>#C#HNt& zbEB7y4wLY6-gLEXAu$0eCqgALO~E%_<(x!dVi2?r<~FJ;EgXiSv5` z(=^HrZ>Ht-gc8K8l}6(BHyhioFJjk8EH}d?3*jX!2|xG7nH&-;aS9TC?vgWw;WQzY zgr7U-k}}itEfB7$#kqJG=bpD=AmL9#3I3-f{IMP@u;AY(e-A83A>@zXdtIEdv1iT#qJK$C zRBP-3bkR10#MIaf#t$y!*O!=o3eNu*B>a7#aS{$&&`e9hKLSx1(G8X!yADyy15}ll zX$kdD64c`s)h=y`Aq{NX<)BeW{(lCc{?)Ki?C%Ggq?8$6rX|#GPcx(5*{Cf132JtL zO7k);q5jc=njA*02~b5|rX|!rOHdmER7YgHJwTo54PSl|D5q50&wGr<^GaChzl`(T zOYe0ueya18T=YzDbQ&(cmW!q7*U!hrH*)cK*3XM^@vTXtvi332ce){R>8Y}E7UJrA zxf-alN_q7|>@p}Hsj@C+x*z3gwDRiEt`W#rYNCf1dy|UxL};qW=0MgPou72}60sxz zH}on4di!mN3+U}lAuPRpbK0|idVA_=m!!A<9hd(Ddi!=sdi!pe`TTFv+qX;7+mEA` z;ZYPcV=o?E%Bu|M?H_}rg7o%1eU!$ln7j~EES{>03vomB=4qtja-8mSXwCE%bZ>URGqw! z5rsR_qB4&~{ei~b#C~LB=a{{|9m~}H^F43)kw{U6yuFNq1u#Ej;!;?i@iaO_G^6nu zu-A({2wcZTkp_VFIY)JB-|;ffTZ4=ANjT}$K_885ysR@W#YIQWrcP5?9oOKhlU(&x zUaT{bog+sfRh&uV>|(=jI2pfrRGmBRqq3o>&Cb>J+3&opD01%HMLP0Wl{EwQb?zEx zw_B^S_MC~UZimqF`&HIwyy{-Y!Q^3NG++@fdqg%v*e5U2`N-o|;)C@V3~?t6>g#nL zBi-NJTb;+oX?Q&AOUx!ZkBe`HhAd@rK1y<4spN+0e6(D>q_W=b1mt+1%W_!}FE$6d zJ5Pwjpgzt#A;bNp9_IsU7|9RJk;$A43D{QnERP08_p zCNsDT^M~p-nWnYL@n79mF3{Q}`LAv#SC-}fVWuF ze|1;6uq^-8E#f8-S^leA%7tP1uMV^PSGP|aihSZ(yK$3LcT1z0MTX|T@i=73_Nwk> zRgvbuI-vPSsrp480H!Hv{udM6avtP^GT99b&42Y^xmcP-n*Zt{MxwIF^ItvGh*TDd z{;M6+e^WC3uckIK{Z}7mD$5h5|LQQ)fA#RR=76PTk?Fts@HAS0nrlj`|9wpVAAG*4 zJ~G2p_9uAduMW8Wvzm6qRY3NiMY8{D$M)ZpZ2yNG1qD*}3AXHH`>&oT+Ef?ybk2>-K4_+K3` z{$~|p?o(Z2ZWr82R8lHe*(!^i|J9A6m*a-WQ&}YauRb`++asZ}$ogO1J<48<=N4)I ztNTRR7ssN$Fq5qw6=m~IPRk`jd08hJJ^^D{2NFR7xjN(5BA9%&V)MM}Nn)W$>sG|-g|0q-<dL`sD)x|Amdcqp=*T z@%IA)pM;HlqOmtwCKRRu3!kR?YZm4bAo@mQ58F}?Iw0^!G88*go#e?Z_{K=hBs zuCy(G^?`tX;W9ku)0DK$cB0-vw^Kax;(QMJ8K}R3PaD7oP7NDD@zRSkf!`k`==5n+ z)WjzS+c!CYS(tMNe5db{rUV@c)Dx-Nns6uw+ z)S6V%{RBcmL%h-84$J?~DfoFnUhLu}rX6l}_PPFKK5Xe9S=M1vh@Aw9{nACHyo7uH zzVoptv&j_oGot3>_VxTFc>Njrh^ePPlhLQ4NZpQ!iOv!XM@gNY_7|eK7s-oa8;az+ zw0TPpJW{Yg!ztril>K&h)wxhP!l*okGQM1S{=Mg6ynv$$CRxpBDV@8)%q4|hild6# zQgUwS>F+N=Q$8eWKBi16TXe~&AqubI4exGXPZwd-A8cGssL2qKq&M_>tj|NmcG@F4 zn^7)0rB3CNI=y&vNaC&ek8^duK1Yp7rb3TQO~jPmh}+QT+Q!J{&r+Q>9C_l8%wGIc z>xWFkH_j7J1E?9zhx>(5E$F7AZFh6|k5O*!lSA%(YBE&R#z^I`bJ` zA7!s!8J#(l_@nLh+oLnLQ$F5ae>6IC2P$4ou-9LX&isJ*iT3)((V10fZ8gbW|1moA zR@Td8d%g6C%q`S6#a^#CqGc15wKEI4@gxZ57jxW!;YWBaTS79*Nmhg;ogq2iNj8Nf z_~zrC=Ohn@BqJcX-bvm}N>0Q>+2;OjGS+K#^CZ(6_eCJbUn4r(h$@-t!mr8bMqN=d z{HBsO25Y*}Xk4c&nai-H8Xb$8i78vsn@2ZdP58m}oueClgqn&6*Y}TZbOgF$p-VrZ zQC-wjk-NsIB92JdXXH(*#LHnPA8`}ZL<@g`@||e&z^TS<)@rr>G|Z7&h$E8DPXG{I z^Y-k_6h|a~%+Bn@&Kk3w{jb@r>JK$#Z*R3^vg|6ymi^n=nc`?9w=wV9=$fT-TFtWw zc9?YDTsRuZm$5#&=9k&6mRj*OR-7r0O$y`Y=KFDW=5E}Ysz`Ip#oab1b0&LPoeI95 zp>F52DjQ}}-Y-po_PPYOwrY@NZi@{kW{M+{@+=k>m4BkZ=JCbOy#M(4X!IPK2aZS@ zVa~i*9FfdIEdS=2K>lwn#8l5{#DiB;BtX5hpLNjja7#F~}h zy~9hV6Ovd}J*q4-PDs)xHbPXQ{-G4p2}$grBDAb`s&PW1d7ge7-VS017vsN|er_7h z528m8}7tZAQ<w2aFR-l4)nH0KIe3fMBcsKO)7=4vw?h>Rvpla`JTFImHU;|7@MF^Q z@}qwsdH20p5Ec|NUH2(yn!LiyL5TNa&!d;*<@#bs>^sEd6{WukNt&1bIke=}i8A|A zab}XAnKyvl=@q;!=VxhrF2MzzndE2ZGP^k5AE)CgC)yBK={r!v1?hDs;k;CwnG_xx z{~Wa&qcfAjwl+^XGb!wl!2-u)bY@c6Q7-agbY@c6NiIrbDhC&x<)R`+XC{T!a*>G9 znMq+6xo905g<3D{Di@t%bY@c6O)h%I+GOCOr(6t-4I7P%UUD%q_8<%_>@62#W4AQJ zMc?9oVdv!7nX{1!j1$rj>6%&91oVo%Hy~g5zm0Ovtt7>yc8amTNf8AVoRxDTsEKZt7FS)&e0`JAXytD zfn(wLx-D?AA=bSb7Zb#sn`3mSRX8z&t$t^0T5nuT%6tbG_s3r8hl|N#+vBm#ZE-O* z-UbSu_R{Ihq{x>hIb&x9B+YY%H$i^>K9tvIOG*EwRnmVE`4c3=>CD70N9=GqGw~BR z6JYNESm^oJA#=@$^lXe3bw(GkujrwO@Y(8R72?sP%y={@GagOKj7Jkhb{&MNYrME? zbWdYY&LUBapP-AoWk}B)OOGbqu>Ng>^t6vLfKb0qOwUI-=Yrf#6mE5e`O1MRjlJHi2oP=BTY6*WVW<8~q{93$6u74{&^h#d;Q9Mk-y~P_P z+*dqJ!as}8mhi9QM-g_UKaZdcER_6^K6*I+?kE0-jjG0GxTJ;Cdqk zJh1}tXTsKcm;z}wlZW^-VaxMpj!L>fM{a#7*+$>Ptoxq>fsvM$*HfOV+be54?#p!U zsH@wz#gA8^>u%$D|NO7+f;PyS;y4&ba9r=ur-U;b_I3gmgotyIX z6o}JjS3&8K8O*tmPr!Qc+rkIZ6#8vhnmOgvsrb2e=24g8318MD`<+bu++4i2lpXaV z&STFuLHzh^4lZ5~3d$zt`51j#;XbIw5h+@S(ulZ(UR%nH*OuWBjSj?K3B9(I8Lurf z5qpA@)H#!BjMo+_ITsRfK~fiLy#mQ_w!g47^0*$N%`Tx48MiI!VMIS0h*Wtpsqx#Q z-iPc9C;tQGvZ{^a7WEfoK4MK_nlODXspHGe^69!I!6H^b-rQj%4})3m(|L)Qt2aw{ zpMFxp?fL@=@7I4w_<-JVE%iL8-;?km{ilQv>$2+@|A_7);iGzngpcX7Bz!{OAmLN` zQ3;>c|CMlu{#U|hbj1dye^&RD@Hst3!sqoO3184xN%*3EP{Nn=dlK%{KTG(s&b^-L zU)C)p+@*)vaE^qp=nHLli-fQ0=WY0aH%C}eA1+)*$O(M7%$5^4aak!R z@Z!R7bZWNzFZo#$xbV8rFSdj zSl(Lik?>Icw}fqUMuhS0^c3{PwDR`)cnLe`#S(VZ%O&irm4wwgTf#27u7q86rG(w} zP6>PHWumW_eswMN_0}Iq*hhaQVPE~Lg#Gmz!4J^aNH|b$k#LZ{SHdCsPzi_XZW0dD zgCrcTkC1Sr{;!0G=_eRA?5ZDTc^Y<;_m8xO-E|Z8l!iU^E2xLGhQ0Lr686@=OV~#j zY-D_2-9o~Cx{rkY^+X8==!FuFkk^c~h9mU_xUM?=bKJufnOJ4S%y`5JCmrwQt3S~g z@4$#@(~mg;Uk6UxWG*|c>#aOK5!LjIU-IP4JBq$wRR8Sn@k(2@3=h1xdQs)9L*&Sx zABW^M6&Zu)H>)ywNG>9HCjY$7KOr0CMY84|q`Y2`4Zsn(6-HT6BobM>%k#z~`q)6E z?iKkjBk;^EibM+c;JpX3^8&dU7mwli`xjm;9t4`MNHzy@lYYkhW9Ewenu4Mi@i0?$ zBav;J4f16~{)Z_ZV`fEbP&U;t68Wx;^8Q9GeFxFcNinw+sV0#~;!q>b%EJQ!hfTc? z6Kqu#iCl?ZLUWo!B;H7*q(vfb8HpSLF_jO7SiF%?Y+me&uAPq4Hj&8Zj~Nvw0JD%e z7!@M!9EnVXm?|!UXl)?2D!9i=b&Etww5gPBkU#7&QmIAHGMm1U$ncv?Hg7=wQ4P%1 zJ}Q1lB=R@Dm9R8>Ax}eViz(`PsjshdfH^!8d92uA8bF>%#f*QaoAOSK%uJXnYkB;v z6Fjvb64`gNDMHKRr!2yJEfTrg*7>oMCe4>toUrMB>?ng3OQ7*Q92sxCZu+7z;boeT zF@3n{sTq4=!#323r&%*q-=b(r-3I?rNGV3#shWLi(wjW*QIVau1`)LCeiga$eG}o- zdS@&8JyH|WimQ6Gw4MGQJOW*(-`hf&PT!~iIqs*^w|n06IzZMHN91)HZSDtj`coSy z?=VD<4@Bw%kq4cA_~n=ZL$)N4hdTX)m$7FQ=rxe759B6&veQ%GI{k@hN{~+>@_DBC zf|+rvjp86iZ26r(gL4_B11P z4~PZ_;u@WPZHbZ+O@n+^fbq;dflmJrIvZ6igXp3_T%*&!gl7sXWfSDv97ZbDb^5}u z4dw;N->88JI{jbGj49tkF3w3<8ns92E9mq?_82|R5lIqbJN*-Pn?k!ze`-Hd1lQ?5 z&N30w>DgElHezIA&z^@qwgiWC`qgMBsZbT)j#Ifa5_mJe0)XoS&^->6dS|raozW1( zq^DVZ=O_jLT_@nW@cA=Ps1Z?#E?t3-2}0Ae-dZU}*;`OvT@SM#w8HjVYgxqP= zXF6NP6<3&2)}Pd;zvP3H!)46v^fqonnT&S22!o!Sd8KWCMN;);&J8Z3Z_}Rs)Qkr6 z|5q9D-j!2eK3`lo#Q{hR#~YCCTtT1{!?-*=zUHHZ3GgDlvAsyNUP zhq-z0;y$E?TQ}gB0Z7dq;I0i0q+#ZtKf{K~=)_!875~E`c)rT}DT8+E@m(~A*iwowl@aq^LzZ7f&8 zbVGTwKE`BB9hX(K7z)l+^e(5)&MNYbrgu5jA-nLcrg#y7cRBX^W>2?Ac8!*llwz&= z(6a$3uzW(#{ez2pp@MEmBDpsLY(&@j#q8v-Ao{&Pgm0;k_vD-cj6#b#qGX8p8JGX0 zLJlLN(7EVA8X1aKGcw~FG=Rs^*Inc8>DjC6;yr#eY9cRsSk^~?##*;iUUXDxIrE9_ z*nzpyXt{_d_<|Q5<3F?qyRU#$O#qR9UP%mnHhPqQC!XkMLbQr`QiF2;ypjuWt3@aJ zGtrecLcS%ycqQ4miKA2eD4xTQAojUHBB{OeRHvVia=JgZgYw=9WGL7{IA5VoLaNf} z%&Zo?jE%!^6`fu99(qAu2}RKp{4r?MIw)ruj!1&#GLrfJgXs6I5L+EcR0|Q`sgQ7) z|G?Y$ItbCY8scX#`bDqsr|!n897GEOu{U)uhN$RurB6PN-9OM2UExINaPOg#R1^H9 z?vygTH#x1YU(=c7V}vvDA~f#@MrKT>R!W`+aF_&V51A)9$d^wcS)C3g`{q=B=U zkBidR22K4oRcM;|gs7i)m}%yG;M5UJEdN5yyg2IrlV_Tl^g<%H&Acq?FOFf#k7S1h zBGb%buxV!NK=LSnP9}&a;Y_5N*GB!~v0(0o?CSl2%6p$u6=G&tF z^JB15fSC6Pngq0MW;l@KYpZ6wX=aeQ_vmDRaa6vkxIAg*d!znzG!g4AK@s&BWu}=Q zi24nNn522q%#TF0@=pcboYg1raIh^E^vwRTj zo0q*CVwJ;h$CY!k*`t;23S=(*M^n`QcM>Dm5=xr2dbZh=s73OS$inN3$hbaha+a2A9tDQr0Q9Sb~+)H&=pD%K^O5f#d&a40$$2Y%DaW>k+?|GIoArOq>*3m35SV?01NI62hG| z0GxbO!n@=(hd{%p5Pt6f?9g76<4$E$YV_#M`sz+y_)<)1U%E#tIS+Cl$V52(l?qogK2Ku>yz3$;)wL z349cw(`v)<%OegF4=VqC%nk*4I#3rmWXM=SK89)7UaNC6P}?0cWUL^c!tc($w@B`t z{M;dH8Y^&koh*CF!ZB*$0UXqVgL_eu1y^Dw*zO&RJQ%2IhYT4jNcf%n0WSbjtkFPC zcgT>jg2WWD{pS{W22hteq|4oQ1A$`#dBukoejA|TeuPia&;vV4wxY`aD*xk67Wo#C zUpU1fV+HxC@|X6vZJ_X=%*SEw_K>lHg!9RxcUYaxf$HgyHH{TGyiX=D7m!*w3ee+f z!@az@93tThtLjNJDqR4Ol-LxzH{DNG!vCa9LwnQzWTh9W!~EiI;@pZ3DET_-X%?<| z73NXK8+YZ@SnC5!rhdysMthLk?=T}rcRuUv7idy4sl4l+DlH3%~CK|;NXa+KSK0dQfwzvGmES^H-Wcb97c68 znbN3HH<_YOZbDQS{Ojeg!DQ;$s1+Xt(d4AqPNs(9^Nyrm4AGfMv7JnvAGhMQ5M7%T z+sV`kIdHzx40&&d=#iw@PNp8{V8w4j^nOxoCsY5zG)es{M1Lm5b~5#K#7?I8lkIvq zY$e#qR0&%rm`qKoXCSI4a6l`|syEIcra;J5Zc%0c!DNbFx|xq!j(-;hnB-)t zZKaiyu;*4M4<=L6U82EcsuS)iV$^H+_qGGO$<#Z2Ap0KidnuDnD*e+HX`tS5$eP9m zlc`n#{AWO;Eozl5Ihpzg&lOSJ0H_uY88SAQOzoaykpqAlYl?bd;_3&)`ll1Q)gft6JuWh>RpEn85>Ndrp>a*Uw}$$8B{>X*kCf%4MTzG zEC)(FkI0Q&)7W4#H4|S^1U?M#2~M$tCnr;@@Z=HXDL|d)kRfA($<%T@s|9&IP}>|b zWNa{*x(PS3AYTOPBZqXk+ddmirrHG0h<$+4`ACf}?zzbnKfH?Kra-lG$dIwYWNLMq zMGgmQqCoJ@7?Z$^-}016GZ2bfGT zKQo!4jWU^HX+6!tHK#Z4v}RK^f3=#{Y?}OpHLck(y4faP&(NJEJXVj8aHgIi;VgZ+ zgvaSiC7i8qk#LTFQNrW(w-V0N@y*mTU$>NSp&lXONqVk?C+js5F48wkxL7|X;TifR z3D4FaN_dX`Rl?;u?`G;dPdAZph3+EZg?fsF7wO|AT&2%OSas8_sGzE=Rn|}VEK*2{ z+A8=);0u2q>9DKth4;@+%KNP~zBvM+u0tZ#9%o+R@gpFIZv?K1XbKDY$*u~%5ja&f z$>AGe!b_N9A^EW>$rUfXLi$Fif^P)=YPP}0%GJ<4&J12d_~Fpu+=swNS?8CG^^ z0)KR^ZiGSjS^6-D+C=<+elT{v;6#P|8dnA12%O6o^219Nd?RrBTsXfUF5nx11@LCk zuX#QAH6MO5K160egI_Ntj#x7kD?IT8dPm~goCR$#{1IEin8b~dPCM}n5JdLE5xE<7 zC_>CClfi6`e4J3;5r{n|6>~qWj?F}tiCZ(73UhQ;eqws-#mk{%OkUz1{|3Z&-;R+;W(Zu97YY0#8wGWb0+i>z<_dmzre7QgR4%85kZ{Sco@p{k` zaN;WehL+0v3K4s8M0V0{o*BDK#f5odWlr0+NWhE4#rnI>N_>=5B2IqVVf4jrJRIUx zS)$yFZOXyb?L`{8yx607Xe90^psDdWOYy&CB0h5^9`v8W66p-+nMYlcxfH*I9?TPu z`bX{s7YjtIomfg+M^ZoO&$}8+M$mRM#J3aj8Y{BS3(Wc%|I}BE^chHA3KV!UK};Oe zemQH(Kwt68(5VU8gX4EXMNtVom?z%#-+mKax*dMwjl&ozR+MawLi}I<@++|x1d%u* zkun$~>A^g)+wYKLmPCdDGKw0Ek+WfG;%on)d?iJg4asSgih}pq3?>tLFi(8vkHS#2 z3i8VXj8{Sr=80eYDfnQp1+n)85|gkIJ(wplmB0Qj`~n2BcT(hvH-OjZ$pk=6lz-uH z<$VvpKl=gY@YYUDYLeF;Mrk6_-^Fw?F}Czc)L{|5m?xSk|H(T&?_=2A9#6kb{EPfF8{gQ`I$B zU^qZQ6~{vJaY34=0X>>0W-I<2wR(SYdNfZgR1@(P>?kJ}W2FHa(4%?cJayzh*wy9a za>jpN4n3MDX7v4pz14s(RIimPZ?gl-8UK0ms+^b^ufM{9SF8D075$F`i~0QL8D*EL zhS%V$zmv;{3n{sLiAY?f{7YUn56_~G&?=To$s3jRgk|^+cjK4f;!SfaYx}rARi_4I;UHNyRy4AHn+!&y| z)*^dc{rfL=xghqbKw?HRlN654f8=-bcOd-C0mNPdctiOeet_4m z;g3Xa1?)Zt{gEwT@`ii!N-R&PmmqxK0r*%8R}B1{e_aIBPefpb6S6R57aW{_hhH_R zQXmoz#muZOdN@zO!}+cXpt=JwC_tH?Ohox>iv(PpS3C^Ie@sUT@e=}&l9n(a_&Be^ zqhCNP0JzkFqOrm z<{xs$j)!cjOMeI#{SrN+GqFU(8~;>Dmb%nNIxso}U&xtwEhN{vv^jKko;a>`pHonu zQLgGG4vYG~Va0+NMMoqr5-f(uSF6OV_5+h(cst*@!(bF$k^DihDHYcM6Vsypn%hl= zs-O#|KsaovL_PbJyinMGdE73Ifa$`_~K^8}X4r=h2+mWc08nVSQc zhpa)t@%as(05uwjNhv5VPS58Fcs^gd9e|S{JS_lt(e`MK#4AyMG`@3-37125HRV#p zar!<_d>Qrk?LyjZh<`XpYvut4uqWzQV>+Z>gYfMD;Kk|vJn?(f--vms`X2GWI9Ze* z{u2L2{X?I!U;c9NnW6}X$ykbkAI7p!d0Jl2v%Mb?b6=GA~Kb(!m*ABmfYwR#Gtga8%=K8AbpsK zq>d;TXA|Sn{L|hx81*Iq?*|~y$fu|Ii+{AH{|4D#l$$=x)!W30Y5u2Q*!0ES@#8lf z_8t&9+@K$fI+UV!fUGO!COv=0r=H{%rGn< zI74rZ-}H!0xjpc62OOq$2{I2wc1tfR@ORVvBK(|I;N1Zo?%?j}Wsz`){=nBZ_nAN~ zNI_Z<{GpH1RvrD3T;o7;E0_{X#*uWt;j32NcA%bgNGWk#vlY9g`&;Aa>2E{$sRI}- zO8zZvf(mOqSM*3J5;Y)3LrQpvC~Sa3J$M5fGfBe~jB*Km!06??5%{ zP2d~S{r3v2&XWN>*TF;eCP=tNANG?~yaA|NQ;^ogC(`{3_F2#l0N!w*P`!ydI7WXS z_pI3Y15o=M()1L1_)fqx`iye(U{XcBFx|spsznC%kWPWaHF`HZePkBf2hdTe@Q`Bo zM(^^C&HZ?wPIpMrY5Jk)gmd(pF$jyDR|2)IHZt59B@Mizza2c&Uj+W6)HI=*6*%0Z zcf#yOve*Y`CLTVflwypz2L<^?%)bo_;DT%lROeJ=&H8|Y^!xv7rv;+`<$i3Vm}ll8 zkwfST<4NW2K?t4BwVC_{-Dj^9-tm`NM>L`gM5EC z?j>oJcM$zm3P=eue#c~F3@7PzeB37g0+HUw+UiBWKN_-=e1BHZQ5!}$MKJb(ND1JIBg+C98uHR3>Py(2I#T- zf!8broTc{-N`4mbR~#UXEd{)#=iY6zxD(J9_5%-fNHGiU(uV|N?`OdOv!67{H$~I% z$Ho0wZ`yoH`{B1}d#{HE)+cZmo zU$>t$GV1W3O#_$dKL>Si5Ae^sG!Cg`)G4CR^u(ue|B=g07M}q5mqYKb-HYfoJ@G}{ z|L7N!q)vZ)6vh!68YEq^9gFBUJ@HN4|GA~)0gBZPqKLufad~zo~(x^>Sy?e z;#-Z#KY{Ga8gh6~KL&ttfsO!Ua` zuiIqH(;Koefjs%TFZY#MSxdly`Y|6^_&h+*a&Y&gv`BbRfBG|vyc(!m9Wqp>yV+`1qmnWD=RFr?m*9LiNiFL%RQ_Z zUeu4obY4st2hm(I8vW_ zn?*hY)O!wD(^!GSllrg!Sop7irsH8$qikjcFwrp6{{&9wg^Mhm_ms*ylVc1W>` z|2+9+Kmv}{4+nBJBGjosEq6#3%Yv@Z{yX^Toq(g@c3zmG`3wfZ^uKqT;& z0sZa(aPy!K83W(yhiBV_{!skf2}iOjtTFFue?dZ`0uHFE%0Ws!i zKuX%Tt=w+3ep@9+#!M9~)Yh${dCll3}MLm!&S9iYEXvdYhT` z+k(0!L{;I;E?sSoe1<{qTgd-P#SA7USe9Zcd}6lCQrE784sLVlgvi9UtQL^wcRT_m z^<=SX1g?X{su55VELJhzEmqw}CBb497gvMDsvdacjt6oX4#g9%7T2#a!5StIeZgXtT)4%m8&H0?SVdFgb6Buov1-pC4}4A7 zkA%ZyE|n52R-G~zvm%JPIkA*BSgbm=E?z01?FfjECS*FSaf?;E(M*&sfMju?z%5qY z!kP*et3El{K&}PsMyDuPtcqjOem`QL3X~|ZB3P`t2?NMm5Pgy=u45Oge#Tsg8$0$v zOkY3N$l18UVpS#r8d(ZSf>LRLS*%r)iCwJXZ@#rvws{&@EOC zjbJYfWap;H6&K=@i&e`f;tLo6x9$fNELJ@NnbJfAi&Z3vb&FMfFbp(0eF-uTxv8wDK>;MDcs8kTs8l+pSx}d&M zxd6zsYon8kRotM!7FrL`W(VYN7TjW0y;kV+5SbsB$#aL;8V6mzMgHM%{%NhT<#VY?Iqzx9U?#CkAXa|-v{&R~}y;eE!YDG6*XF0I^ zHje+?V%0Aw+4W8?C6ki7#j3wh;j58=bd{z-q~va~s;Dd00wMbthv~hG(9Frjs_SC- zc>-j4cuz2LDZczmR-{|3YLCXK1hjo^cyh6-%UIYl1c<`|lv}K7kic&N5IZ-Jn32q^ z++eZlU35)#E`)0wKpjfPW4R^144X`iv1C?4bP%KtG zH51Uk0V}~1CRt6%3Jsfy#j1nzfNue8Z-;l46^3H5>Sr1}7O-g!dOBOcOUuq#o(EtTLGsLTi&ZPj?T!2u zWIqH-l8aT_v+TW_fhT(|4wF7utU4F<#T&m0k`|Qmao`1uRc}|A#Qh){;?f3-RqrlF zeY(Y}OVFIesQLJ}h+t6_ELMG(1Y@ykT^oZ@*8zAF!KPHfV$~1ztTK{#?{LbZ!D7_} zL@^KbA^z>A+@uc{s~#(}rT!PP^dp@-SggAA7%OiGS!GflELNRYX!ZAitY1f1M9~P@-ahNz0!sP)VxmcBpn@C-a`0Jg_Eml2-PRysHdI&NS zx0;ND#j2M%k8+Duf1sj?QD5TU&jHw25-e6dnM{Gjs=jz|6R7H8Os~Wdsu;Ui#chgI z+7;3PM6l#Wr(LWXInF4V2R_$zVLBjwT>p*763l^(ZV>%|;%?IFg2Qs5suvqmY>O??S0&s%^8JmK|s#dsp z1@tfgucm;Kk1x+HR-N77!oLCZPX~8TFN?%t)e)E!iQ+n_nhG4IMoeKPcPv&_`Uf z<{eXjn&XhnAh}reanLH~BKnFHkP@U@tlE+d!?pr(SAeqX0$8lt)y*395@a6-^5jq; zjbY(ftRjVpl;KZ6>)|~!)NHPmlc{Y&ELJ_%%O-4xM8o%!Fw}suHiE^fc|B~JnZTcZ zfHXD>ELQQSQexYcfNt9lJk*qu1s1Eu{E(D-ulAHwTmxz1^?MJSgg9XwN29k_yPM#Bf|*) z*)&+Js)HG<Y%aQ}UlY7~Epj4BX_*;Yq;X-%pZc zJG#ZHP4!HYUja|YNMw3`66hAI4jOJJcMXARN2E+~qz#-s$;B%95!ztDj&Mq883z9b znCoG&>O!=XWOE__Ck6UEw^(&XFDqXK+2u9lSgh)MFn*7NuLSB2$nK?FULM?HRl}*~ zQ<2&Q*&E69!D7{?7@NfIA0SHu*p$bW+)UnNUl$jv-soZB<$$(ya5tzY7pp$Qqf`_R z1Zu29I>i==#j4dkEpk3k%N&wzYI6@3tLEle87oLER-Jo@ zMJ@npg+tafR^V8y+Kp+OD82#EyK2Lei&f=wE%GIx-gn55vB6^137Dvg&fkEFO%Ey{ zWNfflbw&$|tN^OLL)J7lSgd*g(`!*Y0?j!D7|-5DIc5 zPVRQdkg>sHRZc&P+zHet4q4OKV6o~0ZQ*|bnuRyr8aG37v8p$OVnQ>Vba2R!v9eNx z#j1z;TI5KeCOc%vSV3a3>WNtvc`8t=9I~dd0>@(2&}s|c0_X#^;byy90*h5YbhOCV zf%?=TL&gS+RlD#>?uwzf@BRiVdqz+JrU5Zh*tHxiR!zi1Vl^UE6;N#)lEtzhELM5# zENCbIQyj>tv-6K&v1&QSR?&GHpz96*56?d&Ar`9!X4r)HAkkwkA#2VWgT*S1>J{zp z0Pwv7C5;Keu~^jul_u~w-nbj%Fnu8vZiW$AtYU4t?Q*hM#f2zOvpV|>XpeP+Xp6|@ z^YQwGP_JKLPp(*KPfiX_{vXD^15Apd>$+=tW@>hNW^-Z}c83L)oOhQD%aU_W3X&0! z3?d>bV2*%dMnpkOh=Q2KtcZ#UQN-7TqL?tgMwI`YTiw08!23P_JWqF3-E-bCm!fFS&qK-oh8S`e_e1pa&q&jLUi#WIK>>Ja1Q z@m&~uSRnt4vyqBJ)Wmo^aLt!^{|n)+ehm8DXnYsW9umlB&Q(OxcqyP)C*dipsbDRw z9_Je*Py zFMNvV2Lb-<6Z){~q@0FzG@yG_Ad3;$O)d^o5lqCeYD+;BzEGA>R#Olvd=k?VlHxa{ zEyE1qG3F=mKnPf~PQrXM;^!~b)*n3&4J$#r=0vL1YdK2S(SD?svhD=@phu~)a@){R zp?yu1^(S-kDhT^Ll9FnYrBr*Qtz+Bp@*7D%fbf@3lG-w)>9&62VV9JN$ygx{Qx~i; zD^gI7)?JE~$;POxQh+^tg4h7t(`Dgd@D5ocBhtua4|_@ zvw3_M$Q}?V9w-*hHxBIWw!RdPIFh8c;SXiHkN_rnO(R z+x=?N_zuX=er$v8v5(=QWk!ykfq#NH+??=@1AB0w<&N`^uB_tP@7cO}PkgTpB-IwD z&SXnY^7z#;dr+Y4@k;h5w!U_cA*pF#&LUg#CCjun9%%mr*QRK@7}%A*HiKh{@crl9 z_?v-ksf^EMT>EcW+GDsqima=bfxTXda~anT2KA%(n=AO2z`m=*xr}SagSx?fSATdG zMnW8J{h>}98Vqi@waXvS1CxSZosk;=}6IlOBoXfm+y`cW{4bxYsX~1Sx z;$QVc{6;~&?x>4j4D3oDPv<)a4ZjR^Vc&5(#9Iilq7`k;GWgG-qaonW0eia|uEZAe z_$a>JFHrizwQN8>B5$7>)DQPpLRWtx&M_~ZmB){K*!=_T->hU$4(h+~%`}o!{n=Rm z$Kh5G*BI?Hg1X&cS6eS&1Be^L6#T59cK$GlsMCSX_Txu>WNt1G>J9kDow@+>tG&1; z^M~9#AiTyw>q)1 zJ4)d*#tp9z&3nORe-Gv#)!1e&#@-gvuj3tS>0{F8VkUsY)Q4O?Jehxc_O6hw*A$h~ z7L0B_i+!tEy|+IM>8|giTE_q!?-8uX+mP8mgmhEd?3s{XquP^dy36xKI?238Je zEvr*~t&(B4L@UC&-mBpE0(W9{zOUNlkIO-0^i!dqZwH?blC1RkX7D(22MBXjXz0@* z+z4>JN5Fo&&jPzfg>K**d^;e2#>14UITGxT!}@AG3#Rq~{M09yO1lcvL|fz0Zhjf_ zH-JYyf)(l48`?ipp)3w=>GLrYz+o=s$orV_+3mHy#m0^g+DTUQvgC0;`+W zwf7<7a4^PKV_E6z-bE67L;uB7tARzp&aaL~61mE1SWktT!wp;q@Xl%kHyQbI^66SH z#rx@jC&75jXNm3lCo962P3`4c-}(-6^d)FNRij#wf!BkuTI&n9fuJz~P3I(3dReKl zln4k79|&zgCqWAdGzMNq4hJ!1KT4BNs*R59R;{OCCKKonaICLH>_uiqhP7Gi!RSr{ z3&2=eoh7p(`Peq+fHJM-D30`tqC2r>WkHaj#gtggzqIK1(GBrY}UFJog+- z$u9f_MOmr}4&@?JZ8Gd-Do}9~R>hFeAtrVk^6Ww@RKUih=`V;wP$7`oM7*6uy%_r@ zJcW5MuzEgzPi6c|RiF*7y!OEQ`uJAhN=R2o7VRrlU>05z8e5G4tAU{AwUXy1nKSK`fn$#72)Mv}xVRLQydkFrT6FMZO@>^!jeC&*;hegiM|+V~{k z!(Zchw(B8Y4UGSmBtKSU1|F}qpH})p6gIF0a{gU1c_rPlpWlrWzV3YbUQ7d+_}d`x z&y`VN@ZCz=cn6PdtbPLaJ8`M4UN;@a*F)9Z2QmLU6O%Cgr@>Lvl>CsUR)L)Tq$@KIlBUkTYQ!nR25xc zE4`;2y0(GwR5g|rkuQ)R!FL6}f|_>#e&iF3h8tO!UzC21e|3HV_^(GW|0dGgqEl{I z5!$v33NjYsF-071MacKd|5CbWGqC26m-?80$tLl!O>@ceudG%49NI0lQS;7cxsOaW zD$A3{al;>s#9gKK>8C)4c}TKRX|DWZ4D+*pjXGp30usr26`gaV&S?i>fpbVDA~m{spH$2?y_i8u_|j zqkj73k4!Qu9eK{hVPN@Gaic-cp=OzMa{#42SaW<2^BHf4uU<5+gXwbPOYyI~_>p9! zQ+wHaVD=n&IsD$|`|r&}U=hSisicS*@IK%FbqSzV5Z~-U<{=*M^ZmzAKTQx}JK&ww zDf0RL(}Q?3#*>?7wH&Ta)Zd>0&HUsI*WCS2-f%tH|K!cF819jSn+=9)iBwbr_$ohn zLp=_`lYjCi%Q4YUsTN%^c=Au)e2N+AB|e!cn*{w&-n>}@E9W5GK~fp($^YcdTYXJF zclwb3$r~=u_@BJtN{|1^8(F3)F35(SM$Pw~U1^rG@aCE2Pf&Ssvvd%}H_MM&VXT0l z501bktS$N!IlftnUe7Eaz}-o82H^Q#4BssOLbEfXx*Vs~gs)_2J+s`YO)}~pKo9t^ zYnH1qqhr!9<9OW%X_l-B%VC2zo|BH#h+4QR%eNz)+RJ7yg;}1n27b>h(>XnKAWp*( z=Geb}AnI*f5`nRuzW|}3( zaNjKXTC;DKm-JEAazwr#hZ>Gl)HCo^nkDr(1W#_3SEE;B^q;ClR}7xqEXRI2_u8GSqqvFmOb1HtufN^hw5!bVTKVyb(-O2;sxI$ zy4e(|HSmqCxYDlLhw~>izGV0$m1Vt%n)~W?mmq zMcf?)H|*MCF1WKc?Z|RiCyiG(!hrkRZLq8C579Q9T@b~aByDJT!C%X}02ik!! zzQ*swvM^Z*twg`u_`Sv}a^Pp3G=9G^Uk8+$Y`nj5h)L!iydG-R`7!R!6ynZ6YGs`J z0bQxM&Fx%z<%Ap*b15f*?Fg5HJK1bU`1k|(Ce=-t9GVS+W*#uXDc*L3Z7a72%I%JC zT&cz%#kTvI`>aal4mRfW$z<;H#!<=Kk+#SjVtnyGVsHfVV$|Z8lKV-0#&{=|y&T9% zDu7c0uL5!z<0`cq*&1HT59HNCLj`;4jf2$x+}H^w^xHTL&Zh)ow1Cr)j5;>}U+O>% zW7*>a>2wL5?L+aSaX`~jxW(}*O66^$_$in{WzP^bcUDTrQ#vbc2Q)nCOJhUYLE6zy zUXJ$rl45>b&zwGhNXe-HGHaFMj>y?#?c^;;&RzkKxiRJzd#E||tOz924)TaeR$_yK z5T9nJa0}%!ikZCGLOHf%G_X5t$>&fniX>>oYE1!lzn#M57ZQ_`OoJ)1^b!d3gQ1lP z%W~+C-P{2&?lju&JV}i9eS3q@(~j>V$l{u^RTgmG5LEEuz<%O#5%%G>E!i(C$zl7( z47{S^e-MZHVCC=bQz2R`)zAH~rOav-8!i4HLffRaxkYv*WK_rb9p~(aWm{!#oqaqW z`<1!PF~#AY+HQUF>vP%LOubw|G3#52&(zEL$X#qduC45QOyn&-i`8V!ya?B8UJK>4 zya6Ve^NN#>whiX&cf+4MW@GLzoXLV8axM_}D`%s)haK6NTlU7@Hx8;8J>>%AfxBs& zEwzI+|8~qiu0iFPeOyDzk$qfwcce)@r})`YT(C{sJaQovoRxy%VUV7%4e^IU(`X!l z-!>wz1{$gtV);nThIokwslNqZ%&24ZJ}xR=1?)x-Hv_c1jn=etp43swi!DJOtM~6V zJoPllyBWbkkD%zY2qpy|!}0eomd^jr$*)g-bcR@N7UU($V_Gzo47vc*SbQo)xnEr)xf<<@D1x@*=V z$}h+T;Z~rQ=-RHk$aVRR&8CN2;NR`S;driPVyy+ckZ2An0TIpTy&7}~0+~|06|>$V zN^2lHae1-V6&SvdP-v=1t{nTb1O8MPS>64pvF1-hX zc8GT>nsq7N3V-h9Tn=q^R`Px-`nCwblCEDMLS+rfKXaDR>b4Ur8Ihvz?3_z6Twl-) z1^mHIW0OR7c0%Boo%jCRC~W%0P>dsR+M|foLNGhHt4vuH^rI*zsLPKTlDZ1aYkjuO2}n`R zpuXugOt}zW-4E;`;*vFk*A429z~$?Kdw}itaMMZIoP-qNUegmVx=MZq;SY~w8N5|c zj{`1B(l5cwSU4mRSIIHdX;Istj^Gn9Qm!^2RFK4SDf+BD4yZ-H+iic8!tuH9qE5KS z^@f}7OpwlG6lUH;vDdJ^D)5=0$K1qMfp9ZPm3r-6EJ3fJF2RT_)vyDEXO7c!3pMo* z>I-0zQj8Bk_~JNCM{&EVXh=~1=LPic%*DST1Yr)Qd6LRd;WUV(LlwAhg)&)mqA2VogWESI9M(sHhn!g-dn z9=D1l-Ay1pz$nbTiQ-$%`$ycwcZ2XQNtJqi%jtnRn`k-$!k@=!@+@aUwlc-YKr0vE zsH(}coDrX5Hp^VJ1);M?vcz&|5LGOPRZ_ei6E+NzA70^&goE_RQ4pPlsOK_z(mkjE zZ;;%Bu~1zD@vR=Dk_C4M$u|mtZwI#1!>bRH@`$82NcP3$NS^u}rz4Dz0bPnde~{!P z*B>Nh#l{;X50v9&3C6CCtT(}7V$FX;~jWfCK>Xo|l7W00JQ3r$@J z&RRc)C}A{zknDw_LG;`Y=|d#4B>o^-x0Zol1M;?y$`D{yfw%&hJM=W9gh7#Su5xfJ zU1Hqd&NA-lZkVfbO+SRt8zfgw$E|IIn_LM6@`|E2NLDn(Q%00>SyE2!Ao)grcj%Kr z^0FRP2gxbuV`Ko8L2~06RR_uQMw^f~NOFbGxe6(GgCrLUy+QI-fZiaFU@depi>(1nSzL7CYex ztaubH;SG`pM`Ha0(y<<*E+*`EbxF$+)$i&$bT>?OA?TMg$`!))y1IX=b#*HS7?Ro! z=3_qF@9M74!9Od+SMLDZPh7I*cXixXmu;_p#_1mqKd!4goa8FWxf+8Y4p)f`q8KC_ zL|i3pfK_<-aa~<)v?*&qjRoO!l2|T9Uu9SKQ?;({V?>e6uL9|2Mq%bn6u+xW4ZDf& z0O1*uD)stZU9GOJrVl{);y6uSS9i%wSJS^BB%!6NYVx|eC+p#<0p_9(2n{`w>FQ_@ z($(>~Kg(ggb{pgv%UQgpisi6R@hzvY8MMuZrn9JRHgx-zbLJ5200Zgu9-POTh8-n zba{on39vREew^hzHP=-#1cXr@sdA9~V2-O~KCopTew^iWs_T~PdJt|WiRDuCRa(w7 z)hy>NbZe6N-5|ZoD6Cf##kZVKaLGyuj)3qdNtJqi%Q+9zbkUT71}wl)Rg-5qk4A}z@>Jv+tefEoltY)I z&mSb^+h*QBN%?4(H%NXyP+193RZpCT__68p2TA!}kM~b9_z|XQO#duUE@1=~P0{y% z43djq1AGrSkNYu138VRgoDno#o=<-2WVcHZ=D~yg_m^R?TNo%9|u|atFzy zuew8@43Y=&&q9Vp`6sy*xvd-|bC4?u$v?@z@$48w-XO{Q4bFC?;0=JMAt7%7oD6?% zmrX3yS;_yB+#o#_pQ2I?Q6cy(js%D-=nOHnfN)O9#*V1#9a>GO?o1tp#_@)m;| zdxF0EXWV~b?7cXB?8m0hH^wU@g1fBo;vrn76a-P$OdL`)Mc@BnjGyqrE(52hA48Nd zns1Cj+^H8m;~||&B1_^MV;t+&g!z%X3w*S)IUL$w?gzXR1S8~47#icV=*a1=aNVC> zmp3n(PD8*m#&@wY#k(XQL$$d>CgAXh#5o+G}2KSaysBKwe)StClU5(ZXwbwnlYJMRK zcsY(h2Vyw_b<%}+@OeF?_jri<0|S+nwH%cfD%bf)nJb{r0p8_NT(rBcjZTKEz@Gp) zM6?H0XYH$jxV`n{-KHD*2Z)WlnS>46Uw{0Exs#O-q&88BTcxXDgIKYFK`c;CvJ1F+ z$OXqLtB3KYkkjn>b-A9%HAu7Y8ShpT(%spVaz*m^_0o9P-oW1|tN_lH$`kM>PX)d# zd0q%NcBZ^I-EHu?xlR7311>uzBwom$8G*`^FB5+b_mt>tOT# zF)maGn-7R_RXW&wV2rEJ!RCWwTx1S59}-&)H`F4I=~ZsV7z_Rhwc)RkiAlc|dY~=* zd710zpVl1y{LE+RA2|c}xEtrbPJe7D{7q_nLI3(`@HedibF)GhodJKd8d!CM+=jnp zjs29*$c4XE9!6$-i>W32t@H3Kh!x7N4}VEsg8moKdM(>$L$ek7YAXC4Gj`BFG6sJq z<6lLcosIu_@_XerBIir;`{Z|_e+2n`jsI%$`x*a|68KLs{=Q(goSKEF+$?7g$BMtl zLoh8H*R{1qW;q)48Im%N*2BRX2 zI?&l-1eQZGb5NaD=^_{~Iqh6LUXFdAYlX9A0v+XWvIlluvx zJ@#8eVExTKso#l7%2aH{0w`?BFoR{@;$e*3(n@u3!IrEE!~$?hFFlSBOJZ@pHaY6= zfmWXsihnTT*ms!JmXs*D4YZUT{|=C1(9%+0<*3_|hK6+~S=DbA8EPyv46J(QX3kS& z@nq?~C{%0|t8b{$@RhGYd~$!tB*w&JJ6MswoBTy^Aylo%_b^v3`Nv>|9%jXckA!%f zsi&?KOa4T$TUizhePbZ@dyc8BNn}YY7((nBRz#*PZGRp?+J@VFip?<9sK1SvG?Bz+ z(9&xIxQiGc4c4weEC`qFvHK*<*f8dFfl>7X3Dt9|L|b=qWM5KdQ%y{W%uU zaC0}V0E?8zR~KcLeir9z)S}r|+fp52Al$Sut_Qr<3)BifTL*!t1cKp1kd!(Sh=c>k zRB22CvGBX?5Qs}4HT(yRuryf$nc)HG7E4nkkQ;87jX`QY@xAEnOFofueu%I%s1+}s0_jw#n7=9YYuenXjay~FXG@*t z-{!_LwjlQ-<2zB*lCcuM1M%bH$1G&NWVC7Oi6lr54=Nm;RR z2|!Dg+=;!_$LO;(Q;ZGe#ecps<9~HRd>9e?y+id-Hv(H zd=R!PxtW{T;8lX;Lz+0g10z7mC6e=U;*}{#CB;7I2)wrGnnsbptJ{icta+5!M!dw= zD;JuH_d0B%L@UYqO(#>lq6mbTAv|$1LI$tIR73dCC&-m%lCasixX&c~;^hI|`xwl( zO0EmU2E%0`Q*L+5-O{R2KLgkuwdgRj%{)lDN*CUcLzopYfUwjEleKCbtcln!*P_GN zv;5c$x$uiQgc<1yKemB$QxJPgEjkq3>&G_A1->_j4rA~3V;lHEmiFyhbQt@vAKNGw z_{|(TjIHnRa&F*Jd5Ha2Ejko5CQOeRBBVZR2gi~I}9IIAa=XqfBYqigvh^d~HpBfsD z&OAR=*Q$Yu$$m_S%6g|hrEt~lK(|pgNUp5ksqPgBlhq&!(#I+H%= zG|T!6)PN9AmKJ7DLJ!G7ybYLn%*|ewV5@&j55`2DLBpq4+R#j%AmM z^m1PsTaQwdEi{+RW{Tw`SE0@dKqDV(a_$2Xy%_^kltE3O^9*GV!Y-muGG#uV3*EFoFsS{wx0X%WV{^Trgh}rJ27TVM?TxMNn&4Vg*VkjpsfTV z;TOjv&{+bh;T34RHr*wV8~*211bRpy5uQQ?Jtfc}ynzaONuWjeSt{r)fwtkv7%|)Q zkwAI)jCu(4l|b+C^XSsr^oy|2gTpT~&|d;W!gXPQZ3aqUXgCIQZ8KN`!@@Oi#kUzM zf#KnJ8w7?+U_^M%Bm_>Cz{v2EQxF&{fl=WEwT+j+=x~JECQ4uoCd>#-mcS|DBx;)~ zfm6dXscn`7#)coIw%HOGXT`@2M`)>-*-NNMxn|5i%vNKAfX>Z+8)7|W6HeS8Gx|8v zkJ6|66yPL5@$rMi(QpgMQqWmDT$_wirmu%#Y64O5@y~$6HShLqQJGokcDx+|YFr3S z7ylj?U)FXRJqP*H*eAUp%{23I?hk9ovER^uS=mN>t}l-NjX@ymOVPp2V_h=1R+ci; zFYYDlihn}uX8mErFMDD|pQZaFOR-NFZ?Jiei+j$R@t7BotD)B@5CSTh1>k11W=hV9 zgcW-dS8CSAfDClah;fmj%41ei=-3VO!Ade3xP5J<1~-Wx$APfhWRm;Zir73k#*A38 zZJ2aq{bLAM`ULtcJ({I>yDkWC1Z2qOPPne(u^?mxOgwIkYs7ud=?QVfh}&OQjzC>I z&W&=7WyJaRUDl0K!`wF4m6mje^k$K!-t9^a)LxGPv^Nmvrn)AL_E!#usJDuD@I+Fv zR_rCrkFxrk4vTy4nzG6yNGe@MjaKU>g7uWtd3-?_{yk#C+?3bVa~`^ftaYXgvh8kV zlSR4RZnOnYd}t=R2q(>rR~xc>s>@55OTzWKpmtI$%_UvUy=)z>S4ZyvG0I&%qfRMK z1R9bO72cmfHDBP+d|gHJZfTS^tTj(j+J2OmhaLbl`W{c>eh~Aex^skMi3RQGT^K`WR1?H6$7p3ZK~5d_O_+tKak6W~B8+U4=eA z56@h8N~JA^^3H+3i}7b6v+c^`tf6^?INX93E^dNuqG@Vdh?4BYMNo;Ku;zHI`c~m^3`6b9Qcn|Bxy$MvT!yXnKyTk6 z{XV>lFyT!2)5f4iRN4TvPay5cd@R_d{jwCxJZXiWQUIIv4-r(&`{q zR@#-zu^^UqE@Bm=HAHn5rhNkCiL@smubuV~bQYy`honwgE%@uE?OTXvc+(z4+{tOP zAfIA|7NGR)M+GiK9wq-vDTICZA55|_BT5=eG~$2#At%kXxDuT^X^JdhLm2>o1#mbp(us9(To z43}*G1CL^xs7#*jMYCI>(wD$&oqL$f?{VrF+ft1se7V?!uhRf`EUwNmntojmO>J@+ zKh$QRvN{&l>PLBc;aM$FQpRsbSa zD3Cy?EWnuEkJU03&?)Cx1k-+<3TNHb4r3SZ$*{bX;0xCOlySNi>95{fL7DYrq$F3GoJPs;wD?&OB%ac zS`<;sKrpPdKXakW>OSjZgLN(%NlbUa(skO$c%dP6!BVcYsRbq9fu6cnHM|opqFCKK zz39eiynu1O`H1>%t3XUEbT?Y1bMpX|byA(XsKN!fV~s%T(XhhuFW7ReCoIDKMtW82 zD`1Wl^afgA2X8le?bf%!+nwHE>wDnsL2sz_L-6*bH{6=9iuIybTcO%Wp>yxRc}Qeo zuHCuswyw&Wu@!Uei0V8zR0qEB3^Z!zAt|&xEBn|D;14Zk*6~tCcxVc+evZNJegs&5 z2?SO48a&?Ec|a0vC=$s2{7Ya1B@_!}e{&e2Vc~zEB{g7$9zvp>hX;N{P&4t+tatDx zM2*~w;n!E-)bRnFs@QO)byk{a;iMj@qfGD8@-7-u_aU}irXj0vN)A|AsV_l<&gfEe zX%(K12~>HuE1lpF)0WeeUPM=7rxl^Q30k2i zz$>pEP@rC~N^uSby5^@|3s0CYig&FQSc1d1gP3E!HBKz#|s!Vk?wpn(KZ!@Uv+G?YN5Rg!C0Gzrw&23w2S6)o*s znZ$O?a4K3wjXixh4}sPafIaPPgiwiuA_1#!u&sT7F?u-=w@YG2XN3dp5oj*~6|OxF z+d*}ZKp^}wF6oMn60oiCSCbKH8ZnW+8jnCT38?U|=xr*ROBRFSuGt8b24^6hNcJI^ zS4F2FvzcjIeIw<8a^yX{AH76HS69`Tb_i6M*ix(>fdedHFi_FkzKL{NK}Daav4YVR z2=tYJv4Vnf#s(c4WEN0)SQ@Dq5vaKx3f}DnU}Tc1@PkDNj566**>&3>G+IIt zm3@ChgvLk+FVB`-q$iBND~9huNFM!iDm1T~Fv5t^~s2zv?3}PXao;i0wIF0+H}wW^;iAlEMeZAh1vZQ7d#FGFGuD(4U#! zjSn((%g^Qi5*@~=V>_Ho*DJm5QH&c(P7-9Ns5mt<|2fT+;OYYyjB4igppL%OaSC-j z&zM3eN?d_CL!9kZGyxrI$JF(}iXKEC+R1q9V7}Gacr(w%SYW&nc)J?!)k~3O<9!>^ zx*6~CH!JGck2SYmTJ7s_Mpc!-X&WstDo_9z}@Hm#{1MfeABj| z9F;MHi=nF>KLDar2b3Fbi%f?%*GI0u3-1fxB{#Smx+ zCU}B15F|k`-4m>XAPT`ePjD9m4g^a)!FCAZ5G?luJ0VDh;8IWU3Ir(-to8(ZAxMMZ zMo;iD1nCfL@C08&kO9Hnp5RvqG9h@-6C8seJ15D0))Pb@#{K!+B>Sz$O?_xSH5287 zOIl8RA2&K1trZm?-^`6Z!4scPi9SspA8m;8=@R`9{>M0cc0w~4Wl&FqDMWeFe1IUz z*JGpfX@2@5x_BY}E78}G-_3~LPV!cgKgDIGdoPAQe$_$WOfo4A>C^lkpTm!qM02O( zbSY1iHRRPB<*6aRIv3@agQ7Q}nWNWY?xy*Qp~IIQHQ(ZN_@ZT$uR7Mn*ktih1({_O zTAI%TI233;=%D%FbF>$F6wT-5qYP?3Mz8teg}kJq`Pf&~-V7O^7K}2e`4C~WHf0@& zGT5pGiqySc{C4VQ*BJX^Jx2dj^H=+MNR^zpKxpYsXp`8K4{=d+(HXZrU|AoNK#vtW zb}PgKjQGF4IDYU=UN`AK;(~M@1DOfom9UQ>?VQFdwlSr0?aPTlOS40W_rvVIXR(m_ zRU=t7?nIe-*%`m082n2xm9TUL4gOt@Ka25{zn0+pM}DNrKPnBjqcMBOQU=3h9;l8> z@~i@*sm2%7fr(_c#WHE~nA+P6WvAd{U?#^cpWC+g)yl~#?u zXo9|WhIO?mM^my*Ic|q-^-fAz1-lsF>!?zWW-Lb}W#tk)>scK?z8tU42UDjcqoJAT zE!Ekk9D6V=>{nCDv5mMXN6t&=$KI53yiKWOJc4PWlHA8uZ$MugQbPEi1UZp~m0^VS z?>zC(S&bVm!ROoTjD>L6VA)TAElJn70tPbRyu3S*)^c1EEr{?fFDq6Pme`|NSPWnY z#aw2nTqm;{q@0D4g;MS~+p^{pmy%bhqdB+&dk0g_ScFnn$B(b0Gohllo$>=BuxQUz zXG=z7PyYwkWFjQl`IQ8=ui_tOC4Y(K-z=$8FjKntmahd{AD?S)`>{3fqjqp{)58?|zT?UAz%l=PIOSif?v*K@GiIK=$leblB zI($E*wWW9udz!2U(=WzQ6-@bc1-=ADY2~OJzYrDD?Qx0lqZdKR@NSIirjLOqB*WpS zys|fFPla|$eRNmdDV3&>)Bnd*AU^vS=q!^o$20bSAHvDB&zw|c4NeINb`CK)iKS}( zV~USNRSh=9zTVFdUNME#^fKH0{79^L=RaZJr%3^J`4M6-_P}DoPsZvGQ_RK3%99np z%2v>SU^Zjh<&3K8v|p`nqvChGGbi&YH7un{(z~= zXvsu>ip`~YA2QK-i8T9sN~uGg$tGsj&Gi}AF#I7`$r|XDB*}WItU=e9Q;vlcJN!sT zWAOJ8mVB;~d}cO8%ue#U^J|27Wg6Vv?>vl4Gx;r*)fPEFNCG`p{8BtPH*9X|Sg-?6 zLrRZiSmIi-BXLBVX3AKD1SVtGSpypxf9NRe;(6mQ`5OKu;*UQu0QGdS_%EkQR=CyPc?Au7Or_oGi(+3Up;a@K zFn3gnuS0`%7#I=pYn9^jzr|&JMNq_Fd1ANL189Xl%LNKN<0k1s=OCB;_6wBjL00_7 zeYmhEh_tmQH4$Q0tw7_CG`X5niLtROubav)Lns7VTAJ%THz+>Z$i}+?kq54X2fvzf zhKhBYAZ>K&HvC<|s2o@`-Ri(68DF5(<>LRd{M5R)PT=M*!+uwg23&3fpL^8fp7n^) zJB(kXNP5Db{x%Vb&8^(>ruO9u!qa>fMzBO4&!5c-f0}ir*wTvnrFH`=4s|R#UUD-nw+e zD!T)@S?H=c$5(R>)x5bE-=Kvk>GwTYRz_};_IVQP4I}Bn$4G*9E2_5FJa&GM(e<$2 zXV*312hY#=>Q3Y;$u226ABsA>it4`^s{6YM*7p;<3sR}3+MWrlooQJwL;BnKN?0R& z?p}}E0ljWu&1kE`_S5mc2c++~+)8sf=5asusz0$D9}Pdx=se=aG7TZ52KR z(bg;8i1FhWTEV_@zd5j`yzt?NQTl#zn;Pv?c;s0G2W0Zrbzse4tL#hEZC^Jjbcga& z>)vNl|G#y+HsIFn-KK7@3%GT=;rxt)tlOIcrf$p1vhjk2n^8oWNVXuq$gg6AYr&8@vc3 zbhFdc&rUl?{ph7s$cy}EaVJh#qux6#6>$c{;vB@z`PBqQ1o|1%dG)7JTef zlfPZ4bN=X0dB*F3vqo%#rad7!&e*DN*h3*UVc zjA;q3UE6COJiD;u9fVKM<(%4Hb9hPNt{g;|?uLI{Qg|a~nSmK@_>U!p{jsDLm>K0r zV6VCK?84dTRRd?Z;nioK)n^4hxQVPK+1sPY1%BiIonz9zRD!rtU&3A^GpxWna_iP! z^PeRnqjL=f*S!1+Z+!&GzMI4uiM{5=v!P|`g6ditA`xo&+12vtl9BUWN_8#2x>`0+ z%f2(KYncx%w<@SfH&X|D%@<2Xe&&)qJxiFIOy%mi8+t~rJvg=S~qMG#9xDSv}$xo{Xrxu*S|@9F9>I1?$+QH zO#4qry&a@}=1Zwiu77bSShuT(G4PH6r|tHD4Q4xC&=b^t zIAZcT)19M)91}hxfu$-H`8F3$K+l~HC#aVUgcH%+Jv!WB05VZ8Yb5CDD*Qco;bw7& zigTJl6#nlp`0MALNjMOSkA>*8+7LCUSxWdB^uU3JnQP%66b#Lnv&ahHk12AXQFced z7YE^QQUjwX(hD5|5}wi=qNe%X2oJ~XBv6vxm;QA&{G}P==#LJCzbu1um+Xww{MXKbe?uPSgCpU$Y9jPfZH6M8S)r6743zLNshV(9H0DSIc>dpOsW{r6$;*D&RM4mBFiGiAIK z)fdi}a^<)0hlP0UMDoy&h58{oIyFYkR_HM5OlM`yLmu_*oirvk)Rd&6a{tSDNHVcn>JGrO13{l zDEtyCFczwjk0|+fX5*#Bc+1EgsJzf!$alQ8o90#q%92>%NGOQt@ir1j4gCaTinopm@y!Dn`&kH@ky!Da5qR_H3 z1o}#SED7~NO~(hM^Fmx6+6McM4@}{8yfRdP-XK0G@)ERNfS0ro7?QFNflEWnsbEaJ zFX~`*=ptt4)SOR%+!$JvgTUAtUn8&~)VVzZ<0LzGhstp|#!pLPt3Mc;T!Fy&=pzU` z7J3WT9-kn2dp2}eYXl}mjzGbSR=7?V{MXgeB*XS3fHY2SRR`%s9swRaj(7KnSjbD6j|Id_VCv-6y|w>ZCu zd#jU)-o#GZ;FOBH(djMjoz4hxH#?_`dzZ6P+`FAS#J$IPUflbf55(Q#9257)Y*v$< z_TTIY?dblNy|SF{AKB~0{WJSlasSHRA@1MV?}~dgJEf~-B_>Wy*{- zhj!J0d~951s$~SSPD|CeB9B3N6qj~j1k@>k^Uj3TXHAG@VXWa*U)O`JysKc1SrcOu zr{TF7NIUyT?eiIDa(q255h@u8gfFiJPGK&yB*8QEq83=6f^@MT&mgn)=~FE0a!9Z9 z5H-Fs;yhgs?QjpE9X|XN3gzluq^;@r(*bC&4^Lt2j4N}%Sy8XPWz9hN8=(L78KU1X zF51)7Fk(=egTqvY=*W7n2XtJi524770hM`hK(6nst}OQ|J*y%9H3J&q!HOwbqi9Q6 zx1_d0Puc+jH3#@2a-?2Hk7*3}LH%e$)EeQ-e8@_E2Q6b~4Nu(+89d$dC>Zk%F7B+s zk-?}CR)M0>%Gr>K($-Y9%Alm-t=-Xm?FMLPmpkV}VrO6FEEIQ@vs&EM&RycJab6Jj z8s`gfuXQX$wzJndHO0NoX)Esa&IoaDa2AVuqjQzGH#s+pd$aSbxVJc8io4DUpxW&0 zTb-uju6O!~yTO?t?j6obaW^^}#ogpQBkpGBkhu3aQP{Pey~SxE?p9}nxDPt>#og|# z5%(cyySO`?J>ov>92WNx$L_`Wk2(e7KIXI&_i-oGoAM`|d~u(2I*9v}bE>#IopZ!} z+Sx4bGtP73KIa@1_XX!)abI)_`cThHP8V@sb|#3s%ULe&E6xq#?sgs%_f_WuabI)( z68Ci{AM+(Udymsv+&7#-t~*EEH=V0ocZ;}hIj_0yH{!nSB=uwbx19#!zT@QJHWYF+=0$!aR)n%gg3-Vr(2_=a}&!^qm#qQwOymLGlh0jqufdD zPq(X6Q``!tjkw*Mq2hLTW{cayxj@{W&U$fsIXlE15LBpdfvF#HvU1)*OV%7}*Y1PjCKIff zI^UXRFP&)mr%cRKg=y#&vldx1?W5>&*m z6B=&UrUfNap7sDG+icwh6AlUnkZiJj4aUKm58HZ5eN%U{Jv~O*xT$leSv4QGbuC<8 zqN^n;x#mt=e}*xcf}6YuR;~Te!S=H3TBS~K0NpaD??Ae3oT+e&n@zziuVB*CxtPB4 z!;}SQ#-&VIUt{W1uuT63WruMb!4X)D7}jZmEKi#|0a;c-G)@W*!PGe+S zuwYi4WmU;5!OY+ma|PSBOfwPhgJ>HStYsG3PMtHwDtP!u)F8FKg5wPz%-|+$1&=?` z+<=Dwd|L@}2eyKp(=ljDesG;ca2T~I+$^qOVf+PDrpg$C#x8g+4@@$e;ArJDGp?bU zmv-3(>;qs>CCFXe3U>F;HsCY>vns(gjJfBshygDEa9JhD9We^_&Pm3XGf<5i0Bo)V zc|8@p|9F`JcLI2!68s8vQSjk0WQZ{j0Qj^Llye0K$rP&3O}=2Fvr+LaN<}5w9;+S*^u)9j)#42>bpgN<4S*kBE1Un zK0>r`lhM=!c8eKqiJfc^J4oYS|08cJU@9MfPV!B@Uad|Ip(WY1DiSLuUjFxDv_ z-t0yWO;D}(5;Ca;AHgz5K?|jO!>XSIdn}l1H6^xqgH$bKKp-~I<%GEp@r1C%}o9UkMQWMYuPVG1bM zy2;59r6-?aIIV&A_BoX~slpzibW>FIT4>~g%{l*r?Ph`_LBZ8Z-!{n9@>EwhC&OI(2WgK_l#YYh!4erY;-T?tF0bd zq*r`mm5d7U1*JRTk|*&qkbd)t$7fX7yOf@eF`Voaj9I*Gd_vQgvCDo<=~eX&u`Niw zePWf23h^y;DbPlZ6G7s-(+M>y#Jx)2iA$Em%R#!$Cmx?sVZX0*t1`oW49r(fWLv>z zZIIEAl|C!q5I+OyC!bg)qeA>#>DA~1nSK-g^Mc! zQMz8aVNV2e{)ucWZ63O(f?t*H*wb_rYe1@URd(mH$}yEL^T_VK&{JB0EG8E5XGHC4 zqO4DI;+D*EHM|$SyHH+_Vkdnt<1cXs1ESCoVx;F^g@;) z&A?HGa~e6J=}hImC}ZKuICnlmQ(7G803G9Xup?xNZLw|uqise&3my$m?9fvYZu)3T zU=L?ZhL)zUquWV5l0mtdohBx<`k6YyUH<~Iv=y5!_uZ-RU!=QWO1%Kg8*wOltg?GC zxlP=pFNSq&f#4||frU`4=re`M{|TK^YU0Y|-ykYuAaS+Rs@SqVLijKv+{p-{FSH3= zQest10#;~qGD2H3`Fgw+dK%}%1L@3aWC9D8ns*xJABiXQPZ-e~;esl~VN#b$$?G{6 z@Y9+bX7&Lz+=r#OwI%lRdMWghKMU{zQkEb)R_#}r_RIPZnu+M;KvsJSESUx+rj~x$ z0Xa9+xAehAhVn3IPm(H%@>;crq60cofg2}~9v~uBB)Q1jVgvqIbKUg_pg*g_wa-B2 z6NmIKJ1wzH=GRvQvCy10R?hPHB_-*x9UF+d#;l zTn65iCvvTVWK31Ys9y?Ai);jCt50JWXx01`yxhn@|v45+$AniIV~~g^>Oj>WTk8dkeJrJ8){b>@)hba z*y@#NT&sRNRQ)~bwlFLJNCs-S@=7sUDl4%* zcWJ#}m4Z}^qwGYol`6f{qe^!ejmKa>7~+wv_5wYtYQcD?LORbwOrK?9zM}L2w8TZg zR{OZ*)ZqJ+-clRe%>sL(8gB9`UAbXmpUQV|k-iDm7bjs#-54f@+!v;!{9t7yyz(>6 z%37?N#c)73!ll~))J{I#ucWHX(t!R2nH>t&IG?$O)ov0V9MG$h&;tTn>EmNdk#LoA z3=imco8h5L5bp9xlDjIT(E)w+7>orVyzY~jlB?++jv2QFbX$l%1K~T5WLE8iT$xDR z70?~g_goK72-!}>QN>aWXInsTnrJu;ftUCku|>mqDxjY@-Eal~AMJDGN-~^10sSaO zW~MbC_%fd()nhnmwqD-LaIOQs!RN4wtl(cT#ze8LvnH4!@^RqLkRxM2kV_?r7Ph_; zX3a}`%#CyoLd5D zLr~I9S>F=r&TP>iJ**0Hxg;^f*4Ll~$r*=ZGPxWrELmDf%qSgF$vwr^H@7mJ%fMSj zt|<=}R}zzL{R8?*s=6D;R>GnxDDW&>j~iiP?*g=ku!+s(pTwEAegD~Z87~d#X-Am=rK~g@Ec2 zmU>NH+XwJrTVD=iXb*7@FQ)Vzc)OnXPqv-`(>ev%1P`}TJKPTFchuVHSayT>93KjD zX)19Htu@>XcxwUOOxTzh7pD@F+eFc&s~{Jr63IdR2Wpp`XK}pdaZN5#xZhr4QmcP4 zxVaGugSz_wL;MNkqm1C!8a5kRgg1Ftp+ls`^m>+63x}j`G?LIKI2c_Hlj6EnXA&wk z1i9dq7!%Z+U^?WC0zS^;SO%UF)MrD)G#0~MM%b7uSHu!?gL;3miG3ZQTL>Ft7kDXl z!5L{{?*Q~fW$ex45&P1h-gt`XJ@x|n*o&=XGzki4O;8Vp^|2TFoj7L5rVOSx6VA;+ zy{EC^~$&1o(plWHKOKg8ujVq=iXe4>;!)nUtZ3hDXiSNj1Q>Eoup3d(`^59#}GVNl0h z;7fgusSDwp9nyO`8_u=B*ZUkZLI`JdNdGg=a2^Hzy3djEk(aA6*PyUBgmf-0L#BEN z%>VlAD)lAA2Sa+`979aTWTggf&pU;0GJ zqp54rcx_mJ;^y%fNHrRI1@?(mjZdQ78`gCvy5$GGSM?}WYE;-e!}=jNClkP&cOu&g z3UOapzv-IlWgxAuPOMV5!u~3(|BD`*^~OgAcKK}jjM1iC&<7Q~sDL#Y2)032lc=M0 z8afWz!S~?(MU=w8n=uey^3awP}t94ws;b~ynE6+cX>J!V8RTqjt7IZpu%H(3)FgccT8D`^&2Up2hdU|Zt+zzYBz+#PBEpRTwKxv0pQO9v!eW#6 z0W^rPnX~+jNq(Yvk}jNNR&1sNnnT#kczDYt(IrWLKERaZ5X^v0yldh`v$t3*{CMQ&T379vW$j0X^nEvZY zdgEk6d=R8(ePWf2@|H{DK$3nRtxk;}fb_Lbtddb7{*$CH#w9{x0GCY;4pa2wGb(H+ zst@%v>=s~_pU5`1oDzjmT`LXJO zu`x&;d}5W13UO0ZC-*SK;ULZMiN|MD*xRG}Bge2;f_cq}Y%3_l7o)mjsv+J7(vv>1 zN{#ZCOJZ+SKiS<7-vx;qjhYfw$*2&2i|XfQ7~(%5rK1ZxdD9C!=;;3K4ZAUz9ZqDM zTTY2=NB@9)u&|Z+<7*Ir=pGwc#S) zW{|e|M3%_hAWvNHXsg6#OQBVi>?^7auzVg{VL7}-D`fv1bLPd8;~uR?jtHTL7JXu*3Ks<{7nQ&X^j`NyljfrWg4~ z+9HE>KZ;!nYIr45t@~MH{x1mA9O@oy%xVa8y{7KxjaxDglRv@#R8{w#m|?$Hh5deG z+KyrGZ`_1zOaC?wRg2HZuSI}wCa87+_|mwQeX6^qJt4lVV4$RD@)`XP+Yso2q;Zx8Y12v_?cTu-Uk(Vox#^PZhN_HUm3*WA%Q6+7Bf z3*VoRD3YF~YfS-$9qpNggT&;-`%{Jx`3k~xv!i`7{hB-4r(#EYYUA4%$Hyq@+Z%+Q zHs8pQcLRc}naQ?aEzl@>K-;1$JJH&jOmtR(JepSoCTpD%Kl z0`y~>CH;rcHmPjB+ffM_%}LzRKJ{UF?}6`p9FJ@6XrGE5?U^!P1`&d#e@7pZiXH7) zFMm}M}q^%l3uL5pQ^Kl@^{RqxYK^CFHwEnW=<8LIbyupiRTJwz1=yqFQkXl~T| zJ0Xng64CV8a)ZCPbDsQv%XqORxMTa47+Nu?ElIBrMT$O4R#}V7^LQO9xm#V_#q>TV z?t}v)e1yk@E9Gbx<{(wSeQ8&KVGgPFJCt&`lTNjM=h8vQOqlEK^}Cb~ zhd*Do=dFKMayyhf{B03{C0z$1a%BzG@~0v_xjpYV{F&@^0rJ6yNag2e~Wng^;fD5Y>oq1C9yUx&EFq3{c!zH6Je-b5CCKcHnq|{N_UC zP=amiZzYv`kLP38`V|{-t*Kd`N9 z0pe$(1vb4{QQ9c-dOrf%o+|RxNH+ z&(^PX2v;Ykr&cmG_2eGB%gSBz;K1*j2lw8+3<_3JNg6cz=E1FZH$uAALsT|l&pggy z^?2sNjd#i0i{k_G^M&e~$6Qi9^H>HQr2LB`*u|sz=FumLf+KP*Ky?U9o_zD*p1XXQ zp(CJP9(d%^gaeCFElee?JP7b4UBop^aQoxXXTH_qtE2VP806+NDLJT}4T=>ohjIhA<} zdggK82rMKc3zLD*@Hoai*!oq>gE_MFz#vQldp2@>Tn~Pg@iB>eHm1(6%Mo)2A$ja3 ziF-Dt?#`z4T~DewnJ_h()Ri-WHwyWJ`>!X%pG59bmnCzq%`v)iMqwo#9R=w8OuqEl zs5)dfs2`JeWE(V2mUm$rG)tCuRvWaA$vd+RN@AS5*$v8K$(SF}A%UzeRhcdiC z+%~cQ$KIE~Nl~2bch5{u&rHqi%pUA6*D@T!a_q9O3+!+%_kG{UvD_l4ph&zy4G|Ru z6cvq8Jc1gH7bX$~)R>rfpvGHcyz!1vqr@YL|L1wDyQg;-L=(-I|MxM!Ur%+_`_x-U zS5;S6cfF77r7f+F%U;^jOkDQTmiCOxUfR;$aoNKPmzzX`aAj|8Y2Uc)tu3vI^Ue`0 z9T=CrwWWjNvbVN$a9sA*mJW@}-rCY(aoJN_IwCH6YD-7PWlwGCs5qx$!P3!j&bxx8 zW8$1&1xv@pWlwGC_&E2}hRNC3zF6B+sBMY!#@dF$EfBVEqU|Ou>WuTI+E&68+-o{? zEPlX1Tyi#c=+yWno|Ch&Ls{c}JSS&khw{cbCc}d`@6z}QhA%0`dDkZI@|>KF9V(jy zh$(D`^QtCIcz!>wUWcBAQ-~pFV~5`PoT!J%+1R0vJ||~mhrarpoQ)lZ7Gtb2!sKl1 z;Mi`MO#FzZxMvw*ayE7tsn5yT*kOh~AA$bTVPPYf!85{N&cXSj!mca4=dqkeV^@?x=M& zYz#s$=eLfm3kLi$a5NI$j53)ai*}nFjb-3yq>MX4C5n@w0H!x(;Ao_byF|5&ky{(N z3LUh};bHBe-sEU314ko+?f2Wj1CB<{*15!`yD5Dpy+%ap ziyVz*;AmtxccIpMn9)$%ng|p)8kw1Y5XC(mmG~{4o4%A+-6%JX_KR| z3>=LFaDQmMoSLF9mmG~{4o4%A+@YJztp?fTXe)O>OKe2ju-zRg$#O?0xOn0gDH_WY;z?PbErusYJOvgh8q2jM zlwyk%jpZqkG_zjDt+qT@JZb9^8=itVhsjcl6piJLl5EfwM$Q6cGfIlavX`YOO_5;W=i~%_Y>bHMPnH#8i~G& z0C_@}GpR=1%b8&G$r?cK736(&k}~XBX^244$c3Fhc`}|E5$4#Qz`hTPM&9nZk6UL^ z08vsjmc5`a{qQjR>sXe>KRa?VZS z^()bSzBlBcXk>%n?s4hdhHc|^RR)Si26HpH)|;(-n-q;@plD|iAT&KesxtV@)fA14&0X->f;(bO(a6}`9G@+fQCy65jxtTr z$k^O7?@wFAnxc`hxs~3Z_N^?frf6hr?y&c#En-d4$k;=@*aREJQ=1^Rrf6gU_v2^N z)(deOqbVAxf(t*{3^=QKq-ZPyMI$GmToKYrbYomd87LY#@8v2{R^~Lu&)WiUpD7dH zKko<7?Ga3=imFv$lz~l5J&T)SOoW9Sp=iw06pfup(b#!d>QeN{C@C5{kCmRqjqfIR z$IG7)rOAoT6O#-XO%eZ$hzusfF|c$VC88rJ;-3*AGCG8!?XvR89rJpOjFO_U^PLiU zDMR^ZL~dgQQZ#n{VLr8UOT89FC$>ZAItk^*dL3$$qOmh58rdY@WU&0vXGFLUKf%4; ziI4FYkw5X4q0Kb?Cq~5DipmIgS6ie&tkCA14C~r9@Mv>R5sMUv6@A6#Qp!3VbyG1& zJjE6%5Gw|YCvA}ev0{jLO0BI_FjPDh7AX)bhKZ-zA_Zc_aPibwq(H0~A)a9tDG)10 zigmDY7AX)bMu}&&ZI!BIJIyEf+O6@9^vMn1UIfn#-SnQ@VPL-u*ilK{wPSu z8E4ZuTvTX9lEY+PkbAkz0(1@|N{++i?Q*%fvrC8CFXMie1jiw-J2!ec!TWH9lHfRG z@ISraC^-(3Z%Qb4fjMAcjU+e@3Ff9SC-@^=z9cvf89dYtHhE@5xaZ7%neo7J$om*y zW$7Cl;f@A!945hW$O3RznV!<}PHfnBqp2ssamcZkJI(5^yi1|&OK`tQg5!`r?nBFJ zaFQU$VGH zj>jEtI=DAE4wK+Gq`FpT*TB;z$PI7$%123YnA{>#Zhvz^s|F$TG705oxNISeR-`yg zJ{jQNIGsW(G8`s{ncO9(3&ZL)Y!VzML2$@~xpOWn(=AW#VVy6Z3)D`juIRC0obQpV z!>x64bqxD7bp9j=4yi}ho_V5^j&Kz?!NvCo|KxpNf(=&Q?u_x;a1p~t zh{3QhsRO&7s?83PIcH6gHONxzRKzNY33XuXWhhU_?m~FWm{14CggP+R`~o|JXzaq!F( zPl0tm)K<;PVS$RR0u;Pzwn);}=ctmZIpS$!?If&LJf%iBm%h0HW--E-A{C@AWDD$8 zM2fbUP#4C8x-cfxg)yNnj6I3cTCo#bqrb#7bzudm3ngZ&*^DXFg|P)`wpyVsjO|1t z3B@|}gD^I`6ra(>gt{;$)P=Df)wppP6;&9dL`%g<)FRY{vCnaPGmXQ{?wVfk6-ZhL zz2H+QtkI%&B|f3xsoCOOROtYo23iQcAWwrWgkF%Rp%ym)Fqo%S3!xX}X}HBMgbwAY zZG>B*>begLF!}hr!Prz&;I`j$eXTriiqirtu+wYOV9GQMX7ON`;4@5s+|l%mG~k7qa(Qa@)6Y{H(w?bWnTcNXHR%~ipR9b&6nvVo`6MezD#fN1PzPae3>%o zK=90gr(8UyMQ*-KXUSm5>R$*?x6n1nSwsxDW%`7e&4QrO5!`$yGX3YOf$8t4A~#=V zfR4>l4GyHHqj;gfu;Akam#=_)c#PZ64U5ctnGxbyqsY&g8L1_vB0pnhlopwa%zT;A zk>UNAmqcqdpF%OvbylM2jBA0bL z76XOJKO@5Y+jsv6Z^~B%M7GqEMR%Ty;PWK(bT8E2y$-qPt-)6_m@_avg%y>>nU$Co zCc|qnax$^|JdE_}R!<`zsg8js8O-URVV`?8?t=ZplF(lm%$cEHUx>Z{bnoXyR5BBx zCnLY6oVBKxy~r$c&kX5Rky7|0`&c(!dB$AXxf8(ha-q)kEaD}SC=wm~Gol@lTCbl; zYG)h}^g~oj&oKhJnjp!DXktwmw#h7S(MjD;K(>OOpF}`=2b|aSVIFIZ!iHSH}CED#?G;UJu!9QDDz@Q_)2`nMMCZ7p>HjiC%h*2=B?!aT~D= zdV)MEjV6ds4Ej&67`}xBYA(?$x(i%@5iP(7S<^>q`-co=Gxa^BEqxYh&0zSF3v>)oN{!}f#LptVU+`?JN(54-CukLaTay(FbZ-w{LlQ=qw^m=%2ITed=%zkLowRf+M zkA~N@^dPzEaRfYx+BU-xDh_RW<(}2?G}M`POl$ZIi1`eNI00*Ru8wbIK-39Xhk&0m zAm#*Y+_`$$aI}w4p)neKqF7I^`i?!5T@owP+A%J{_#Ee0XQmo)tO#w|3Qd=x-pm5I zRfIM@diQFh?}D{D!j_;!H@ej#-e5FzvxB}1ZF&lM{G2)H=mb26fDh5g%}!3hiwGz} zmdr9I;1vXHVHABo4{h3mfFPB2E@IaXZF(C4r=bOz6;0XeLz_NCz+P0X*)_)A5Zbh5 zCvsPHw$5Ejm(sYBxod}k3>IQ^rF)8MeTq1}Gv_vEQ<8Fzu5ldwYjM1l@t5bSTJ5JsGpnlz*?9|<3j3kdKdyysm+>$m5)*<$%2#|-IW-x(?bK_xL z3Q`~3)EDUp^}(l61mkzic{;W2m_6}#e`~(&{ZCLIjQL+neK7Wb)Ccj?QQO~y`XJ6V z;e`l_5Gg+Z^+A7^`k=Fq`k?dN0z6P1 zqCWUPPJJ+8PZ~4NjyaXzfcl`)qduto=F|sqE@A)s)CX1Hp87zdd^_p`iSo^;4<_=4 zl>JhlXLv0i#&(^_ho}#*GLx&R4_Y3G`alczLw%qHcuL0S1gO+3^??@bhx$MZ_CtNp z@|#m1bo;{)+~L>6x;fMb-MWn%zY10AJnHln8FV#4@`Y9^=qgP;`~Cc z0rkPOgHs=L{0VNX@k7)HsJ%nf2j2Z(gYT63p!>L7m=@F22h&~ZgBc$6!2mz? z!QmeDLG}Kq54t(j2Lt~F>Vr5x`53hDYp4$fE&CekgCsW-AB_4Sd0^^;B&{DDjQSwi z9D~`xs1K6gg!&*^QUgr~p*~1HhSj`pKz$IW*`(wx1j7tjziPaDMZjnrn))Dl5bA@O z^{Ee%-xc*ig8P{cPJJ-zKR|sj_~6tB2|x8g!cTn=KPdG<=KG;ONNnkX3j9AteUSKe z)CZZl-y`)wg1hs+A@xDdL8uRM{+NNT15+R5&^pW^>Vren2WSO{s1In?{t)#6zBwtv zyK~_-;g^^W>jmx59HKt>4yg~4%Q1ia8tQ`~e(HlE`=vhU=}{lV`MGSz|IO3~18OH? zH~+z?4~Fs+%kPK!Ai*ufF7?6eI@AX#O?}Ycr9S9iTmdCL2)s1M|}@n1uIkaJ+_gI-@xeV}6=nEF7=zX|n$ zMt&3O1C9K~)CU^=O{fnv^1##wT7D4f0}VO|^??Q*g!&-o5cR>gqdutkI_d)v9*FuN zaRqPn-;DY|mR1f?9~^@U`&X$Ca$e3w?1NArXwZSF4|4ux>VuqvP#COK3Qe8ZAHM16ot z_@ARbNc_)JALQIpiz+xoeSm%;R*$*i)zB;eho}z@Q6JQ`gsp8`e=pPr@^b4C^}!+P zgYg)N*7J`|&*3OIM163G`T)k?@bG?!`oO(W%gF3?6sNZcWx{_8^?~=otEXpgI8Ngj z9UD*|)Y4eTzd?NIV^meHa;(RRbNa}-*{~GndyzhkiAo*WH zeK7yOl=>h}19S(aK4^U~>VpLhsSo=2sSjFrY=)Pp|G!foEc`C05A>#vZ%chp{U4-0 zkQe;loccgkSzYP_d0YL>sSjjH_ghjQ$nf}`Q6IGWTIz$|9`!-|TT>ql{d($yMF*xn z=v0ULpi>>{gHCm*4?5MMKIn8n>Vx?AMtzX2p)B>mFqisZxJ!MIvtR0iWz#V=>9s%V z14_&l6uY+Vzn=PFl|a7{^?^V=+xDbBI2n;W>I2D>XWPC3^?_uJTjz{A)CW}IQ6Fd( z!i=y#>I0vO15zI_lLw(bV3Hp7f#}@OhuPXx2-A)Gqdv&$^laOc`ha>o>I0u1*S38F z>I0u1*S0;W4|uga>I13d{ZJpoX(MEqOMM{CgP+!U&7%(W!8B;}nnxY#14_(U6uZsi z>!}as3G^FL9|+WI9;7~4jL07Kf#k_+9u24uBx7}(2dNLJ!lORWD%|GLfcn6v!fhT6 zs1KOQgHRtZNsszKbP831*E||fA7piU&4bhj)YG)a(9{P$J#O>ZQCpAtz^BJ;9;80t z)tV1IOK=2;*&p>m{1Ej)cWhTXM125Cf&ag#4;CMg`XFAH`aqHTpfC4ys)JG=#Q&F2 zAG9!%Ur&9|!Z-l+L7)G7)CZ`nuctmhW!=*T7Onps>VxEWM}3g|cc~AO|M#d5j`%O8 zK8PQpJ~%{u@NK9MFkl^!`k;kzi26YDZ2osrA9Q~NFMb^AgAx0uKIr$qm-;|)$CB= z|L;*Bw6?KWP>1@U^}j=X(C^=;K2RR@f#S2B@~96KsSgxicq+cCRHQyoTzOR<^+8`s z4@`Za`0814+ma&nfg<%mU%uE?`=LG<@jpU+5UWFdkY2BCUDl^Qh}EG!sPUtg!5XPp zoQxVVhhTu@1JU4`^L)B4a8V&6<`4{=A*fgUs2wh1@*OY(7a4Hc?{;7JF{BMCIowekju3hO`@=s?i`KPm%{L@)W{^_hG|8&-pe|kTb z{F!{rvE=VG6t@Y`c8|+p~toaY=L@lpajR+emrh4D7NODm@_BToD z&;_Gr87%v^f_d8S*s^~aEc>5Gwcmqf|E^OFZP|Z26L2j1v%ea-wCrCQ<9W!;rD6Xn z@xVHL8SMIhNc?}muKyWGCz88&FpN`&m`9lPFN0bC$;kJ?%=*90veB&n4Fo%8{dwIz zv;Op~$)#EUkuedNxwPs(N<3@KTpIPSYt#Q;s&Z`lvufbmpH2VSfQ52t(|hU)P@hRL0()J%6e)b7{|iPL$<}M||A9fayJ@H)OsOUYc`<84xisQGBgm_^ z%+93^|Joqy>y$`tzqDa22(tL~E%@(3at$r$cSm8xg1+)B=qt~HzVa;SE504G$6yTT z`Dbma{1QYo`3K@RXtp1t49%a0)VF&wdn87Hp10^I4>6cSo)OJp%;@=mfM4-K?N!jx zYq|!9XEN8q9+yI{t+K?L{1#4b@Zh&`LU;8BA-6*0Ctxc+nIRe=* zFU-q23x^ZsRb{qxM)bF=MXhShfk1W4>64QCAm;Q1!UDH2BD~Xz;r!lN!};$}g;Yqk zRwU0+8qV*f4d>^~1SnfD%5@tO7J*(4i$E1oSuMP*`r6iE4j4(4W)7fX{65++{!)f| z7tNt{q+$HNj$wRZLLfjJ#_y{Q;|ujcJ;V6Rrd$YJ!SGCIXGf@Sm)yMkdW;Z$!}!17 zRmU*?z3}=BHy&ugw{A?+ufZ?ZiZ)3o1s8?RtvV!mE8*oHPe zhujn)qN!PILz`YifEbz2bBxS?h5#{6pC98T4Q;v}iSK4^S~X_34sE)1_iCg48yj^} ze`KBGcPBUqVy7^VRgR*kpy(n7baMij_FW90 z_XZKO6nk`N6LS}3z-+~)1dI2(SGPZZv(C#PofYE}a@Q*_(JGE`Qr4+nR6o^=eW^a6wfGaJ zs-Ikbg?ReOC9Tc*vpG5D{NofF=i&B7bN)7RKUU27x5hUO{Iw#PDSq!a7RR`(-G9oQ z|G59P=KRMW(44=f6kIm~4-Ahr-i{g%pN=_X(9WNNs}R2EXteWK-aMS={7;$lZzNB^ zMqb2vr5f|Z1DNxl=riYE;hFQV@XYyFc;@^ovgZ7oM`AhV8*>fgF$`-1U330jeCGVS z95Ux`jh+Nk_WgzJcARxr5S{_znP&a0Ej)t?@5V@7Ydxdj8B%aBJV#h>E`Vp43^mKG zTd#Q|YFg-B>3N~76nVrLnUWR0gwXz7FnT_9pXRFn>Cp@zxJJ(w^7||26 zqr73?YR$*cm6#LbRA7hoI9hw6R`PbQbzLPq^CBNW!EcOk>wcz@V>fP!Bqr@iL((y) z`vJ`POB=XY~fGc`7w1_zo__7B9}=9QJo7PJM&^%XOSF z!KTeXU+u*iD|Dnzocb31uLZ2A4Zb5uRRoiJ;fcJ9zsbzmKXGDue<0uu8^)BWu0{X5 za7lx?s};)=%w40H$6)S{lny^z{XyjG)%)U}rvg1FKVKD#yFrzUyGczKce6TP+>6zE zaW7TZi+h>+jkrHn`^5c;D#Cyg%-yQ0#l1$26!)iUnz-B4k>Xyb){1+*`l+}#sNafv zqk2)?n^Yh}Js%dbo`Sib7S0#{zQVON^nX@(mAIc5{!QF33hxy6%fe^H{d-|vf86%! zTJ-OLCU25f+!1&d{RdJ&({qksD9*&9|4a(_py&uZi~h$`Ko)XG;92xPp8{zEt+E#V zS@$=&0xc~%9&z)F%_alk_HZov_i!xwS34H{ufladjE4Iojb>bkbL)4l@oYRZArCSc zpGE%wdp3^1G^o?hIZcj7ziCt(Z-m=TONiRJVx!4}%k9I)p&B5%(-Yr=LOFU@ z+Qt!JB!cJ}PrR71^J!AJ(dmb^!?QX3e}?ok4gP~)+ zy%$9;hbZHU1JcC{X%e>4276h1thqom%@vzW(U|75=-(Fs<_gGvK#bJObe~246%?=c zL`Kfjxa_p(e*?mBGN=gyX80`nvkFWG8bwSy9^QV)oGfqF~a3sn%2gN2(_3vn+}y~Mp(O%wMLb)vXi)JAbHRZJ{c zc$vCi+#joV#JyZusJ39?PgI4tSEy0qZdLQey;`jm_ZqcL+-udZ#oeaf7WW2~7{d5B zsY-EgR@212Rjm~FcC}gD?dlie-k}~B_ZR9taet}8LmB^0)l%FYs<*hmQjuW{ze|;f zd$;N$hDwmZcjB=++OM^aeJ#1 z#qFzFvKVqwe1PgA?m*Q?+(Bx%xI@%lafhmp#2u#oA?|P$6+I)>TJeuk zo5UThej@G|b%VI$RGHw$D^3N1je9FT?gSh6QJh}~8~0U<*=`!wsQgiM`>Ph>4p2SC z9jGRYJ4h`Tcd+`AxI@%c;to}JiaS<)Ec(W&J@8jM7X8n|hXseb7X4?^qW@(GF$TF7 z{jY^@mS@qw=l(4E_i!xw4|Xj2Z-ZgeW+gTFn-^@EYZz}sh4}%}H2;b}qv#2&^E8_f zY&iI!q~TlAk!`DaW^{&?Fma{U(l8M4v^8M!gs zXI+c_jB%+eGUbjZ8P08v@x-<0{||t66T}mLB7Tehl)b(`kkpD}(Vw6Qs!D5;*RE1T`N=r6kb7X2A; zxf{VKd9EE+i=o2^Ht(iv%G8Ql>(&+kc9^ z56a%d@ez)|iHKp$sbkUKPT`>*hsey+2+&c_w7&}DtA2>Oc;Yj&;^cHBO~$m)PZSQVHtAUOe*l$f z=8wn4F1fD>kVJIG(al5VUqCg#{asKCM?o+lD;&p|4~{C-!X*$KlND}a%sppEwD3m| ztj`K(f(g0g$)j@&gVlHq1UF=b>`x`n{t8oX3h#yBfvk|*l1u*h6*5HOpCEWWE6nWz z;cM>(u$YPp{sICc&nvWJ(f@K@hkWiRDS3NN6OCvCRA(2duWT>RqCZs(#xbrgApg^$ zD8uI^xNt-)#&ML3FhZ$H=m%kF?s~Y}2mJ*O=RZ+u>nT zevAHl5d0iPY~ebisXt=w?^^W#Gi0CDlXLp!TJ%pKiDDc&K3l92;>c3c#&@ZvKs-(iShv6o_8|XPe9^;`I-vM&yEU7l_%a1nXWyL!9FZ6(n zYJ>zcz_g3e5INVp3G(|qjHk@>p@*3Em$<(Z{Q{7m9{??x@aM#5(LWDOy*UnDK74blN{ak9$BFIG7!*l2PMDrhOr%OAL7jpnrNmX4GE^f_5zW6J68@PdzxYmEfcw zrP|9)djKvpfi(b)^MJmL3UI4wUok}kmjHC42lQoBfY+GznGjOr1#qwPfb}yf=xwIm z*+Jh6_wj~kZMCK3XQus6EZa)?0s7nn`Z78h*R1Nt&5zD(GiTyK8riz8lDg8={R6mtRU= zGVLEU)xb9Z`oshJGAh8=O?xB8K&GF-K+_yYgNzFBP18Q7l?HYPXru?MpHV@-Yubm^ zX!HUgS2jc&xyvy;`7Qcy2FTYdhjCfuD>IKX8Dp4Z(VvM$yctn%TJ*mUL$r~@a&5(U8cs0dz4x(?h3VD++)@4;;vLr zihI2JMBG)X(KzZkL3I-ML^V*{)6_U|&s6io{h>NR+_maLanDje6?dK5Dek%IHF3{V zABej_g~sElpcZ2uE&4xz9&^}N@TAj|@5Xu42)a%reML?i+^~mJ>bL0s8U}!maRg>U zhe?Rp7iSLUy1*MlvGj@1LL5HKTw<&vn97YY#=^{!J7Zzd|4+T3qt>(NKLo<4w&*{Q z7X6Qazl&qhe-X5FaV+{XT+dEn(f?EG2>1U23Qy|FOIQ5VLY%L)`(cuOJdi)eVe-Vt z_$>P0f`EH)1Xe+@$unJ;rZnQ8O0UoP96=eMMgLdee~%HaX9Uq_U5g4ltYsJ7@&$POI42^B?6y7ojaUa%vW zaz263KT#r8B)MpEQxM{p?4P2ud<4xx_ZEc$b1Sb!zwCODi-E=5iqi~h`HS4aj> zD*D&3T6H4r4+rkg_76K?DH-yaF2-nbAMQKpPwYEWcnm`5$*x34Y}@`Qyn;1HVP1MZ zBv;gtnjF`Sw!cOTZ*8u{>)zWSzHdK}q+`+lNyy9`BEm0VI7v?{Zrd9lJ$!~iv#mK0 z)8n!+YcYDNVT?D=LE;Qt4cvx?SffP_rYh6TzqZhG^=*LM=D|1w z8qGezsF$8+HtCF~9*Fc*REA=?9Da-bAMHla1b8LwlUot9H-fSC2-Sk;z zQ5W=JPcCQtGm?%){~@SdQ-jYncOciZJ+Ped&yc4)SoB}m*8^`fx$t$a2bP&M{|v2c zv-t^1cB3bkl1a(sw&Azv|1d$4b18Y-rZtAK%`8C1UV`Ku9J;M;z{NG%W>EDvm{;Pd z_V17sqK30QMQh1cV%w@VhVgT=8$j)GWEz5vl;5KN7yu@@Afu1ZqW=*HJ_Sg2In{EqB)Ri} z9E<+<0PvUxVoHuCzeWEy0Qidw(yR6%u1ut_3)sCe_FRf+k(TKAID9QdV{QxB*Ur_L zPLTKTFwzz^W@o^@Yq7?RgZyw0BRxrD_5|!Zac5>)D!LjI1@ed(7CoAR}PWqal zU5lpzim!p_22Y&wTlC+J;72KvdojWKeyKr@MgP|U_@EBRNck=L2hpseIGlRz))UD; z9<<-VjD{LpK~zey)N9Ib(VqrKhPg3i>@c+4vFJYwviYvuNck=LpMc=gJW+^CQ|Yg8 zwI=Bs-X#$IgkniF$;ByH^iS|!6XN1jIwxd*hT0|OejJawSe=WcW6|HtMraYT2aVRi zPXPXk5xiP6Dm{z-)Y#}Sq<}+G*BS}X7X6u2cL@6vkkt_4f>(Na$i5a$hnN|V*SZ)( zix-6K6A{ET=&q(%H&?ERrH={O&*kXYTOhiEV%^w9d{W4sHATn16QW(&*xTkH_PUUL z%?v$yJOk0IZfsNTCfXAJrjR`jt&bzj7m!*(GozX#wIS2A9>tM2XBO@f}7ee-# zLo|8^kiYlP-p$AXz7?`3V_rkGuLAUb9iW5xEM${}ml&%Zt~rkE<<#9sry8*AKcf2( zSPoFe14>y_evAHNAe-*Vb$yl8pe{yP_KjE)q>f`DKh?wNx)98Xmc6I1##{{fRUSs) zAq2D0vi~tlWA1|dF%Kj6M;QS4XM_a3)v}8*$}`osf&9!v`|3-8w_5g?qct!WGwo(L zbY19XA(;Ct`xwl~sH_|0gFQ@k*wLvv7X1n2cAzC5P`8a`jZh!?VLO0w@K$pMY=A>)I3a+^}71YV@r@-dh*#Q+rC-E}E(H_&h-GctFXcu4~bFVc34Tw+03#N>PGR^sGuE-{;Y)gKpxi+ZG;5)bl85(X{zf1x~eYFSGR(G zD{Oy?%gcJZ3&@8&G|zOSO*$6+S(AZK4-7Tw*0!CCfrFX(5I6%*Xui_w1|z`kw!H_@ zsJ<~kZ9E{=8(P_L+kVx#7=0igT?b!UMtIz$({ z;%tw12CWYchoWjmJEq zZvgWC{h;fYAU9&~ovx$22>3?_h~ku>ZNzSgI}a0xb;1S5p{ppHo%$u16R{hkeK1NN zz^CpfO7>Y!(-<5Xv5WiaD9ZsqXFpM-82ocvNW|va7*n|h@Ll_f!d7bX&xx`oVqa0A zqdWunhx>^lqYM9>D3?YWHNxbRsYJ^RqXdU8z6UgAbZIdeOGd9ps*lvzZorN8uu?(U zKN+`LyoZMSR%DSg7%c*L&3+%0hAn7ock|2<;2M^!P+ zdjWcyKu#m{8i1D-BgL0nu0{WMf%?=_$wY9Mz`{T}6}8XB)nOtz>S>Mh+Y zYM+K)L~$8JmG#8!qV^zkE?)9c5KW+1&so02BtP9bYPXoDS8SF-w1Q$i4Y{@z1-1GWP^Dr&zmLjzw0=pzs4t4T@! zw5YwYMgwEGxp6T?*Cel^lQdtsq|c4o%dvdLq$>d$=mC963-ISr`^{VpoC(kh59lTB zS9^EV-j2x$)t&?7Wew3rNYp+OwXd14f!hJP-vjzG%2zJw7ozsFxa!pSB0%qZKwm}$ z=vee8&_cIqfuUyjQG5cr? zPE3C-Ko@yHUq%HuK4zbWc1z&R0Nw8a>t|HZb7JQsSxb%GGl0H3Vf3QGnEC;Bs2lQoBfY-+CoWUA66`*Avuzp4beS6IQlhWw5Kwi`k zZG;5)o0vUdp$6Uz&~6Xtt5LpkNk190?;fOq&jR$82lQoBfcs+heM>aZ!0^W*aQ~NH z&>>}y>Z#G?K=y5j)~}q>h06X5^1&LN3eaK?=*uWykf+-!`!P(-ZpBS~4L}<`Afr0n zgD=0+8D-DLqs?ZFRW|^1hX-Vd^b7Lz#mY9SG-eOvuXz|xnKPFVjkhYBdn>8&OCXz| zCF-KrMN209Iq_NauSA@_UOZk~Cnql`TcKL1dn)A1JWN)%5B;gK`=PdoUJK-v2SDpg zG<@OJn-=}~uE)q>J$4d{{)hcC2Nl@zlnJPic~@a-Vwi=GK8TNaFSmbIfbU-c|0~nU zu==#*O8XsvZ5(+xM533_$m97EHoo%G%{r5`Yrl1D?L0>5x-b! zb(NW56EEU-E3K|G6THer$6_dG^=mUC*XXd4Lac$d?mPnbL|Hk9MSmF;tmiQ?Z{0I* zDOBp0W3cEipKe)v``Nlz{#r;PO&(efPv6`>q0Meb!2LJ^SFpBtW)hV8a@N5wt2PVO$nT{Ikb7LBeNUkdQF?xJ616d z3+h|+&!V60$hM==&voofv|;bVgJfz(AifzM?o2Q<0i5O5x9HE!3R)EVJCaW=O7i1; zZe7rCW@0mP5V}Ova3g~gI)|ala<@YzM?)QIk4N9arjHzcP0w8p*}W99WmW$@2mQuE z*P=f+Q*a}MZ=U+}m>06nNaHf`ypBbG?!KrWqn%^XpF1*S zZ$SOxEpjdTbFYRJ&FJU1=-dWmI!x)mfP1nmm7|i-MO*4E(te(vv;-dXaT<9}UUCE;(VJH_3ro)z~k^*3?f zRJ2O4K=^R5lFK)XvqY74*>k~?M+u=9wy>dj5ytXv<24xAhK{@mxy}ImKXf6 z=r7N2`M>D`?9379v4pk9QAKzMC^C6w$SNx=`m-OJ^0pcl{blsgacf^d>H7n@5XW*a zF3${E(uGBT_INX&H-ol|yQ5Z^^kx9AC7eYvc_!UU509|uufJ^Nc;5Dh_K^b&GnSFhF}>|&Loo-W|9u=E6UHJKt$h~#DUG3GQ#iD=FD?4(@r?J;rW0l(7wsxy zeBBv@dkd}#j3M!7n5#V-pqmR#`|5*sVz?GPPrr0&veiO#+ z&{>7ZNnXh2W)$M?#IcL`j|IwG$>+hYTM2z)0iZ=8`}ENo@)}@odr;40J1zSE4Ux@0 z==wNxo;;K7wCK-korb8RE7qe>9gF@{F$nSzF2>Me$D%(~%!lY`SL~?ZJB+5)A-m;L zU7oWbzknE)$K;t&%6sMCg4LT@C@#7;?Gv(J0-j0U3B<2)NUk;BGufUB>#Y9~@;8ae z>hw&u)1p81dNby4po0(-&D+MIp0> z>m;86;#K0AYmN7s2QB(D-7g@wYU=3pn#XB~#;lh>-kunr9=CbysMUG~Kt7t7Y~Dg{ z^Pok4UadutFLN=vdGPA{ng??Pn>HadiFv^i-XD2O_1zz1J8?x)E86gmc_&3;10*)E z8A2Z{WazVQsL9EMuE|(`&IlfD(F7rX+n=0fQBtSmaIVdJbaqBz#Qu)EYie}?H+`1X z6$MM%#qUDB2TMEV$X?je@*LT-T3Q*GJ+q}%an9X>rQPGXm`c;-22#4*FG`o&L+Nri zXt1G(!p`rTU$CbE_-WBhs9-2ZRv=(?5Qms8J9h^rK94UiUmtY$2so`mX3*Y zeibYo7neP?rQ_q=QyZ?p#JPQOKCY+{u5F3)#s%z0;adQ1-=yHjJYUoq=S>Ul;`tQZ zYdUl+et_q3j0qh&HGYZbS1iJLS>t^?UyC8FLwVyIli@*}|Nmvtf5`zY`sZ-^5aIUB z2shv+_*X-3Lc;z4Z@2;-q+>x*Z&t+HbMeR&ZbaJ$IcFfM{bSs^%bJ@>?%d>VP2HsJ zNHK!n4oL8Q4CWs;GX)XlB2;Xd70l(tpBp;$e10?J8f9-^48T4enL9mA&Tk!A7Yz7i zaXkU%?oT~K7VY-F_K=Oz4_UkkOB5$V0ZgyUCTbaXiE0_A*J&fSzD0j-AN2z~i~cMn z_mt|)^m8rxGuVE=4N|Bw<-uk*G2SzcNv{!+`l>;VmbKR??n15iFr%TiH4&)8OnHDZ z1_Q-EBXT~|nab*$pfz-)Odg=*j1LMaR$?ekl8gmT|kQ$P9bZ z6a>%G^~Bw;TDvHADyzOlf9{RdS3v_ji~g(?ZkRQBqHD}Hc^MXJ^{-PVjYFPt=rtna z(6VytTlD8P+xkd*B6E7IR>l3H^>S*8zTEm2{kcOon_CUChvq`nQCbzZm}-DlP~W0I zxAgkt_I0(0Tdpq$xA|tD$n=$n9fvMcHdk6ZxBu#FvcyKL4Q>o&N6J;^j^J#*j95h+ zqBBLrO~QWBtacDh6@}b4>{mDmSG{bfG(m19_QkS4p9#?<{d_ski{@QelVPy2fLqa# zjzxc-TV)+Fv5MO4orZO9Yj|Sf30Zp)Qm(`ku>$SjiHj$0J%wSoJRzQx_1R*0a>P?$ zjmG#|o)k~9l_`Wrn}TX)y^LFJxi$lpwl1;ZDTr@J3Z+)(`S3JKvO!lEIo#Vb4lKbdo7c3$J)Go*5DLWP1Yp{%TWh z_uR*=BMTrlow677rKd=`zVsfE+aZp|KR0D@VnCg^&M>%P1pv2es|?%>o>lJ5Mee{1 zrtB=qIp5LyQeYVk`+3|3%3A7?iMz+8a~rl@j^LmU=4SG2iJfJiN6;q9Y*Vt%UFHoG zpWX_9xCU_hc>_RxdjMemkY(n+bPbSOgU(uzV~exK#_x6|4;bC+TlD89c1Py7=+A28 zzIL5;SyIvBtwrtf^;#9TyJwR%ieF>@eV{oV#^x^gY{4DzZ;B{prnxyjTPmZt80#Em zH#Mij*xWPkPg}%4E26{L+)D3H`&O3r56$T?Hh0+j(-!e#MRXXO8}I#TPi=zOUo@w~ z*hhP@v-Mdln9qvnPz4u$vKeqLt1%XOPB&!&$`v7<1>G1IQg)Xq^IonJWo1rd{Jbpy z_n9*B{ct~k>PNa@jk;P{qwwAq7X3>wCSnJ$MeDG6DZ6=Ntlao4`p53Tu+e#}^ek?C zH@Q1r{)||6+=4n!OfqB~Mf@`&GMEgKJ@((sG8DZNJh<=z)?c7qYMX`zP5V}r6xv^e{+E<_yosZL9<{bvhpA57S?!!-T zXLsUL{6*wXycK8-P5+4zv9_Wz!rj%@5eTX1A;y&q>)JN(REsBK{bmk4eZ`ZqPDkBT z3=&VV^$$EyR16kR+FC#bL&Q^RZKZ;t;;FFirGjDNskY|F;TbNT8f)oc@Qe`8FzeSb zct(n){c+X<^o$bEc&iOAaK#w$Ot9i;4i)3XGtp{{9#t_xJd>;hT35v+@l3Xko(Iq2 z;+bOIy#St>;+bltscnvUz5|Q?v00O#?j*U4+@3CNQa`ZupNT76acbd81V^})J;KdD z32t1EOhiM<;d5bvVUY_`_@f{pXPiyva7n41W6_^`xy%9!4J7twT*>6^a{J-VE*)yW zjQd%#K+k8n(aQ>elqiFI?(ZO9{4j5P?Y3k_?nBFJa5DKJp3{;K>P&Kjngr{23DOnp+i=%T{zC&&<6HpG@HoLz z`~gii`Dj4ydEC_aMQv4{1*M&om~S=n;8uz%YT!J~9{=gzsTOt(C_hxPYa z^p71IMvOhuK)JO}u8v`!hR&b7T$fAMp0n30!d2h|7vCfNllOfIHduMTm*5Lmc~zO< z`@zId_{Wvk#B+?ny=66g4_LrP%&%h{BYF|8jYYVJFTr=j32s|TJjy?Y)lixc2;Zqi z`0_BqJ#V96(LaO|gkL%h`?30@_!cU{zwm?W5ilt42_zA@4}akYPDj9yqH<+?XbYcq^va#C$sTYo$&EXSt=hv(csn% zc$&bk{Uhh#3iQTVW%)cxwyeW>bOdJ-1)qAgIQSk%P1ioTDEiAU$1 zilm~g5vx&j{TjR-iJppBCDHaLVn7DbQ!`I7~x}ofC5YnY<3IK4|$Thi5hW-p`bIf88kNOx{+cobWtHA?l2Tg7F4Yt zb*_slFyanF!O4Q!>Y&!mX~$YAAj?!gIswk6NmHM?5uF z%ah@GS3GO1tB!@|J@MSD{)%d>d|$^g)fbHPXZ07PQe&!|mGFHazG0>+rtdG|%}_qh zROd6^hvGw-BwyzsU8%}`M)(;j`Y6DxHoXQ-XJh4GQ+pxTdHhtTr}MZ^JT;cdruDZ7 zQERNO^nBKojd7jz2Fvw%Q#POVI;l_Hq--Nxg0@@vMc`rtNjCB(8^##+4>CNkzFHwb z^7WPWcXj1y{V+bTE{m-K)Opoxu_2hYKF8Ilnj@Yz)=s2eRV$uS zBb-a$+yJu}VV>HP@j-fKx1yXWXeGk=5EagcsBk_+uV~GV^CT+AiVEjLRC7MGC+CBX z+G;YR3hP63L7II|SRbOo`VbY?hp4bVM9YKhbHe%%-BFF3wb7oe4_Zydu~ah#5F`3| zF*>l(-0a@ZY=N>p2T4oeeRvk-HCooL#N3moW=r9H;AxeZdR| zw>qf!VziMSg-+-zPUx~aybp_^B-##xgb~d<4%v^+Uc>ql-iK&i-iPjhM%cibZ>?@; z-iOY*6(O4Op)|r)XK2QU_7QgWv=P1^nCcFJ6Bv=$(O0j+*Pmu}b!Zx}qmIYUgeHvjOwv&x4#N8s>ey!Mz{Y9x_9+>@r^Q7 z8iQ2z1W9@v61$7giGdXKSET~gQ;tMe{}Vi2MdMV_=+wxxh>4UV>TOKos;5hh#7$ky z8Iq6nrVK{ahl}qKQ$1G=4yL*oG>ybQXlX9Z4$`UumgBL4;HFHW3^1rX3*Oqh;R zM!I8nM^jlrF|4ha5oel-CuDt$8p$*lPsFM^9G(*K#I2k9z|%rJDeL5Xc+%o2fZEo9 z8>sespubo+1GlJnuuG7idb{)&tRqAHaXIo(8KVbZ5|IBQQzbrdIh2C{qZOjM1Q@Iy z!wU2Sre~BM(`q@(G%~%!6R;i_1xau51P$x0`S6uRbfmZDz*8pE?)up z@EH4n$ACf48bt<-%t$RU6)7+>qr|tyROGfQ1xEFftQD z%mHeyP0E}cs71D177Sh4WWmU|G#IK)5BOXj3`HJ{OkE<33#dTKKFcZlf*gQmN2$$J zB*MtdiLz{#iOQN6;HNS!69$_qeCz|6Jm~|5%Y>n80J0+E(}F3jEqZ$ zp-6_2Dbl?IJqI(%OtJV9rXn3ire*L;^pcdR$cK^X5M=i##rG&^BALEHwrbqs$%v5| z7-Ug$cd4e5#)tjW~*Muz*ie&{hbm~{nGF)2(mIri*auyhU_M& zfXu?c2S~NK${b;yg2$D1vrt@{mtl!y&akEy!*ir~Ol$CLc$SJMV8yz^vrIfes}VG2 zjuKDE%4Mw_EgsAIq70s6#1po@z|uixxp-`AC9mWP@kFd~%;B-(iCQn9w3*|?6Eni6 zA!C`9fpc&%s@4U1=A48P^lE1Gn&YucHCe#X*ibK?08c8Pcj0?YHR)9Na%E`xP!C%@ z^TbyXP_LnJ_so~UZh1g0JQ2PE@tqJ*m(r&%;TjBLry!}Gg@H<>7GaVDYJXrDy;Hv! zkJFv#^+H$wyD*sdst!u49nRPdWqB&DUqY$kKByQ6T9>!T+nph>nQQr1QCu3$Gxiei#i8CV{kSp zda+`Kn|v&WNpA0jlHOwkWz!Q-?C$ZP5V=C+dnxCi5n=1J2cU9$4b^1{*SZM^AZ8=+ zUb7`y%eo?aC@<{{9j%WiW9E$5v$)asS|QP<)fL%2STS)O?Ly_W)3^LI-8D5L2D;x5SZYVba#*YS<^^+V}oM7wvs7u2ea_MugKuk3WVfbeab>97s$yMqRLM>7>gEgkfnT z!Wp~p$Mn_wF$Bz@3W<}A$Rt5avI+GzTC%&Eplnl>ED>(RNCDGNQ@~tF5HFto`=trF zO$wMk4h76FU4RiQz)iM~rhs{dpFDYQAXzvbqNddEjIS*~RWBclO9SWG|5a3Y2P%$V;?pYld zf)_icHM|YP_2?3yfYAXTBH%|DT|fb&13p7QgaI)pV9gz?;{^=B9vsQzIt1K}MrFpG zfQ@&oK87SQ=OWE$uvx1Ba)%EoT3^PhLj`HS(FeD}IG+^Eyyk2Ip-qqfYIVFFnzgB? zvmjZ4>eDbjm@S%eoC4yG)t$TkSnI)Rt^AfRG0c{6T?H?0UyYQuT&@wn##Q5w);Hq3 zBbwbCam)#A+W5=W@g-*=U_c%x;5zBca8b=6G8GDKdUE^f&XKKJ&wW~r5xS z7P^_f$rn!){oJW9mSQV4f$YkuKq-sxz5nws}suQflX9pfTumU{k^p5|uj z`K4?<$4@;EnqPJ_BhN0eEeSDnHJF~9}|KTM5%=XnC+T5h0EORc! zV6=&j6A&$GCU|c}n?yy=a!}VgO`~H^RA9bY$Qg^Yf{s@rpui14E9f{I0gX(>xh8b% zTHWz=G~+@q08~Ln=Z&}O#OJ$eS?fbgd4dRSdX{ZPucMrdT@OKKy^O)q!E6u3(hn8tEw}X;=E`6bqp`S#5K@Me_=JOAI^v6ZD;uBb8tRfr~7aR zoNv(#GNA&TU)oeKs|Vx!a(#Z`(Kz4QgyCZv64IcmK0(G3r=zyR-++)N!Pk0W)}r+X zy~f-J^&T$PW&ay0Iow#6_de8UxQQ;~IyBR8Qz=)|o+I(hVXFu~*0V-7!>FH%&*QbW z_`R^*sL^tGBD}0e^s2IbB+#k4JuqMjatfjkHnH=gOQGAqv;4ycUP=;a5bXE2ZxPj z1Vocvu}OW#WFH$1DKX8XAzw+1)XNkf8_m%apY4f^#1ptOWTV-JFq{l(!hoqhHX2re z$w0$nqv;MM?MV=mco4!M*l1QGglsg&iMv5<6nCS#PTWoEesM2QZ-{%LG7y<;G|j}l zNL7n_v6?LIC2EzpThw{tUaBq=_cC>_xIb2JihH>VpxVerQzq^eYPh&tRjs&Jt24yC zMqMNBwdx*mx5)x_u_;qj`ib*l1V|veEEG z0oiC+zht9fy^@Va;(?7u;(?8Z@w$HtHk#W9AYWjk*)48&^^mwd)HC8{)C6&Rs@dZ9 zQb&s0TdfkeuPR|X^s&*jlJEhlT-<@Gr?`XE5OIg7*TfyFJ`i`9`a;~{DlB?Nsx!nt zN}Vt6Xmy#mW7IZr$Egm28?W-{?uU(L0ox7OXi}r-_E*is9iV!MJ5Ws!caSc5I4(4^AP-1<8omMVMyW}JQPiH*=VMdjph=B82wx}nycWO;jz(l-ya)I zrNc&3ju zGBxtC(Yy_XAK(bALJVVO9X6T}E>04M$jp-o&`~uTO>2nCJ@J~XShLX#fM`M;vH3eB zWDM}J(VT-wM*?%ahm%xt95$K_5Suv;8x6~9Ce8pdFUv;5h&ST6jS4n13q7)IG!*_G z$D^JwFUv+l;a(i?WrbNb8p#iOV+4m*o3o`0D)6|({isYcFUv+lL?;|wJ!IYmXyKZT zhQi@E#%6`%&`dNN4TXzvEXxYBY%~;}iR0|7Fv~{6YTOFJwyco-Nwd*VxC?^&vqEma z)@(Esz5u~1Sz&G$2!)M?4f1ag{KFIGIBYbR@;c;kv#e&LA);j-3XVgnM_<_jfR+8aQwo($7ZoE@Yq9lXLp!veCpao;AXu;G0NTj}?*uLz4b^Q1{8}#x z3+M+rY%~P!0%(s1l!1f6+A5jLM#GRd0s7JdGNb-Vkn|lk8lnpt;i(5lwi2B5X&TIB zqam;lK%+gNFQWq7s@Z4=Tm;Z659rIN039|O0yhA3tp}{1Q9(OwG(_(La!*6F5t@w8 z0$es40^bB^p9l11RDcc}4S~r*e5#2<7u}ap0Xl3n1Xcqy+5^_lsGuD-8lo2gxvC-B zsKZ7>;0A!M^nkvMZmL9y95xyPcL4Nz59rIN039|O0$&Aap9id;Q9(OwG(;zhP<|W@ zErM@7RDcc}4T0wXbfpKZpHV?OY&1mg z0P^<@(RJBq2z(Wwk366+qul9S;;_*W7{eW}362IC6`;dLLtrI9!#rU9j0)Oeqak`O zkSiLZjnr}sPkuIk*4= zGu#XV2GC+-Gi zj>l7h%SLlQI)ckavjgWI8%@h5FpWW}pN;0_#xTQTua;cY#H?8Ff`4vI~l>B4wyH2VmSTvtV`DXgV~7avVB!sT4mO&2We&d15JU z%h@wg_Fvm4K|ArwAU>9m6ObLFP?pFzLP#J$AV3lbNnnvB4A>ZhNHR$n z1R{ehf(3eDGA2ixWHQ(W2QWF=VB-fincw$&Z*_I`>?|++&-uT1j`y72>aP2(>gww1 zFx`DWcd8R>G@4VLSnj0xFAG(0H(3DZ}u^oTeb4a+v*S9MoRdV&d-!lAiblh#uEBIY%~Dk& z8VyT7is>nuwX`3NhK+t3roY5yKN=0q=|1>~7?Ul{XE#wa8dlyHropk zmnyQ+XkLZj&k0db>qnyr`r=xN$@Z%sjfSi52~$6srC)3PXfzX%Ju50H=Z-+_HX6-d zuq}`5L9HK+=1628<4lQYG`!$#g6U$Kb%@z$G?l#8B%;w!^8ltNBCWQfhIG^B6{EkN z=}Q)Hy%vnX^Q^JuXW@j%8awvGNAZ|s?OG!R8jXfEFpBb23gQ|P(P*ey z4EwT36C|S1a2-d%^h26;xaM%z9z~;J>GNQ^BrYvx8;ypgZ-wcuxU@uwvC(LF_ILrN zSEACPTul0Unw790 z>NMIOKN<}+r@($`LK9z&fS2_KMnmBch{ijiY-_C_jb;bfc6WB|uclV)SsRUpbsPr!51dB(LNqoS4K?S&zS(K? z3LzRBjfR@rVSmzTA z)<&b@s(%a7+fFEL)V`J)Z8RDRzk#UBplE}g&>wtK#73i$?T36$vWVBCqPEd!s9p}` znzrg75sikz(;(WM6ncFt)!Jw@?1|ff$Z1 z(P&uYcaVSBP7%8!Y&06GGefb%F~vJvcBX$YN}Fsn8Wx!d`Jxg<;@@(KXf!Nx2;`@f zC?cETb?uQFjfO?GKz>(=A{>Ds|JiM^(P&uY1;{@rQAExz{AY{UXf!O+VHhrVm~``< zFqE@PQyh(k+R@O>cUpH4d0o{MN26hZl@K3WqCmX!n&N0QEU*dUt6YItmWW2f72gZd z^Az$nLZ1P+_5`(jxfMmDc?YV$yDGVoAQ6p*D>1ljs>5V&O8jUvG!KSpWRclMqv0;! z9;TgW=D``1`_X9lJZ3dahtjNfJbdL6MWbPpPl4&u$Q=I$mrk`oW^6PXs&9kxVW)P7 zzZKeOG!(u9(T7gx^`xxdMx&uHGXlpvChbXHeeA0F$|Z_ML*Yn>TAk2awFqrA8VdJ> z=ujtgtM;q4(P*eX1BLQ8XF~e+SWfPUtmMgf6moWiyJCx8;yqQkx;g_RqHFKW*d!$!aX56zzMyE@|8;zjfTP#Av(tiy@ra=Mx&wd zT8JKS!s3RC+D4deaHLhKkTeqoMFC zh&qmrHodr^qPEd!s2&34q_%2(PpItDMkls2`2yXLu-nEJSBIA&c6>qc|GP zR)}tLLT-_b0pmrZ`4#McavE2ey_YDCM)N6@jTni#*OO{#gx?Y`8qG+QndHi`%WO-$ zXf%spKfr0?x;?cQjpjrsFKtJyjcEJAtMJ`*`0@jVf@=2TpgDX*6h))iX)NwWHcvoK z*vX4V^FHK%<9f!k`_!V*Xv$Hb7L!=?5t@9wW24cuLO%fJ(Mid2KN`)9$fi%&f@(Id z)kdS?Rn$eJ;k6?727bl%ekRO(Q-wQZ6g?ADI1B3ue}cI<8VzfyrqM;C;p;#xZllq# z_;ZQkAs6FlH2l!rk4E#g6SJtUFvrI(z5A49o+PxsV!t$c|_ymxSnO*|7;_SaCNPdO4$f zZ>7;_Xe_`m)fp!u8Vx%ksOG*N#Aq~wcEfvzZXXuVz`ie6oeF6bjb>Xl=J_@e(P-G* zC>qTuwqf7mXf(0<#UUI!Q8b#NR0oM@H1tf+kTbdBXf$+IXd8`&t_%8R#*aorM+Teg zMWdlxgXSip(a_5w_N5SqV*U3U47*@O6pegIY8i%}dCABeI0O#e7sP9_VQ_nt#$X(H7Kmw!Gj+G#dH+)-jGo zLs@@JqbMJMibBo>@{|?PXm}ik^0pe$XyojpWtaaRTR#=b6_^fjWjPnf_lAf@!y`WI z$cuqSqv5JILU1|d+@z3ma(Lv2c(Tga}slTb(Md?V4eiN^YncE7JIOZM#D$qgIzQlS#r^6WXVON;ZhWh zhL@@8$FYVe8V#>@Q8b!qFhlAMA2v#VctcfnSd>iqS5S#!f_AvaJM3} z7>#DxRCpktgm!R8)ZRMVGBr=C5jdKYel(P+5dmtcQ`nz&9EZiLZjSkITR zXRyEgdZKV6j7GzHnqeP8jaN?;ZiLZjxVL7)J}=S)Js6FKd%p*x(eU;(sAf&G7>(wK zt#)|uOyPzHqtTp(3eI9BA!>BPgVAWNMDF#GCG0?RG(3*+hXY(InOy%1}Qa3ypjV6b}Jz(lXv$V+#kB722tD)p%nC3+0qT#`4G^~Q*oc512 z@$g_Y8dk9mrqd&H(ePk28g9>(uwPFNw-{I~t%*9_@HlRn*3%94{?vH&M8o5bLvyzgQ(8s1+q8jbkWA{q^SYX23DX1`8gCj}k8*az3+ z{qv(SzdxhV)P-f8F+}Rha+|s$DbH=@uU6hZWS__W%F+S1ivK2au}bou#$tQXXsYS7 z>7volbCcehdU9~lXqbH;v-z(m8Vzs!>Cmb7^P6B-m5WBh!u0eEd4Fqdel(iyw8AsAj(QvfW{a2gGElxzEp+|7su0%8%ItlwG8;yn)(r?(W z(2GVxS7NVJA{xy;u2|e%%mZU#F7EAZG#bwTZ;M7#O;1-p8Vx<9Wix{)8V&n}{?c*3 z=z|468V&uZ0e!3J`s)Path=Zy3Bb89`~#tjfSq-@v4GEG@6&4jdMYk zt4>6tp&z#v7C{t^Mt1%7i6)9Y5sijE-*H)c8uX*l&>6f~Q0YaZp_6!i7Td=@PvQqEqtUSG^fGT#@d@}ujnQZ*p!<0nK@^RK0{W$^KrRjJ{veaW z^(=};Lx*)~1J3Tn(P-$zZf$-v8typywQJMmk%}LUhO4E!d%W62G#Zws7ks?oiD)z| zP3QP{s}j*@Seicb{<=HkF~~5DM#Iu{rT5o;Bezzg(Xccufux9&1O8V#%9gP*tocDMS`X!t}(E78HY-%eJ-e&^j(=JC zCyT={C|ooedRPA|8cncgn*OjOS4y0kz0wsJt0VW5g(c|&S76~_Sy-CBeH9iCk%eV} zAB~3Y=`tqu2ip`Ijb<&fvvg(8()p)~j_cWlxR>el(h|U3TRcIE&h7H1qFNJOKd=Ui;lktf%%DeXj~p=+J&ogfj7MxH&#`zy<*z*T(s zp5?zPj>aku*eoCJR`G>vmCW(|VAaL^$0x5! z+?mgjU6E=&7cVLBH-vF#CSzvI@VU_bhhb-$A!=aFtD>3*1obxT%pz8hYK>}U*cqvL zQg&AumLG|={Qn+x<_A&x`=U+KGZjI-jXKl7W~Pqcq&*{BIWJO`2lY1U%tTSW>Z{g7 zs)nH6Mx9wMs^;@-U9Y3Z&W}{EG3$0Pm7%m*2wn1aK z;DW|T85cC>w^&Q73mU_v|0rk-+cg{&N>9W=W7t#|H0Cteqo6Uez9?u67hKR7s$9?* z4kZ^fhI=1DW4Nk|qE*E~VV<>(k688*-Fa`_9(%8meH|(VUdaw`o@aay z-&S+BtfvHE;cTj>1YqH8dCzSS%;IdirvzZ(Y=@o_fQ7R*0L!?!Wn6vz3jFdP-;lE- zF&bk$DnEx=_GLP#U)2azr`-E&aH{!y9f|edL9dR_+uY?gceVQcj_(%UaX6eDc1MW; zXwiQVfMtBIvi^`}xwHCiX&DwC^@AXI1v%*_Pk=Mg@GN(!4xN?}ve2AnP?eUESsglk z&_gYw336@6h0(HbYWkw1u`s5?CX_!r&0s4nV~4U?nBc2reh$jU<;z_}ecv6TW zo(x6Algd3%EhC;3`U>heNFScULO)qRAeDWw&|em^>C15OC=8H=s`M>~VPT*ws2_!Cwkk$EDMS%ZuvN3lj^7iTS6((Z)ruL3cv9HD@<$jd z8u6qsPZl)dNnr=IXvCAkd^Ksr69nnu&7;z?nba<%|H*M|{L9%T7n<3UVe_X_Q7Mm#AbBAyfy5l;#(;z^(N;nK2y zX9bLSQdnlUoe@t8drNH^@uaX%1veBCPlh7mNd<yVpiMDeRTvjXMKO6C+uqwsQV8oMq$KV{v zh$n^p%67zh<}LpoPSUxXaWVB|dS9x=W&(ac@n$J@ z0qrYMStxUtV$sI1;7O`--&64T?I*&4e~?Q4TF`&`l;%vFOULaVN>yJ{zzqz4#ecHW zc+G5iC=%xN4zj!=Nq~XL8eo8e!Asi~l(8-W1|}|$_3T7Z++^BiWg7Kj0-|29s)Jlr zvP}~8V#3~H`ccv((Ksd|8V8GA?QBvn7lSPC3?zEN6pdc+Bt^wt!RQ5(Z1jRRB7sIP zn55AQQh3K%9KGPcht5G}s>5%8jM7+tG59>Zbl<)4JNK|-@NpYEu6*N5cdZ*K(F=6( zSu9HQ0$qFzi(d4CU*5H@e!;O=Ls~9Z_YQAcX8T9F9OPlH7v6ns5B6aB#^di^ zSAQigdtt5GgRfC3IrPt=m9vFIe@vyWdzU+P9eq=} z{L%>iI2R6mt#asVl|x_KmP23r?Hu~rZ|Bg@`F0L{?f+d4{oJ-3dUVytopBrVpXJb- z|0##Q>wl6%kKIZReW!>+-x-H!kP6WIuNE+>ghO9{I-d1rP1tZI#!8mY2j)#!i*s8= zupURkK*ymU=s5HPd(XtvX{rat9QxiqhkjDTp&#UN=m+iFfb&p&WiK9J>Bnbdq1ImH zKR`}pLz*EA%YzPY?~A2QDXzY2nd;hSpaPBi zWn5=XP3jL=>hLhG)m7;(q?>pBX&&G8RFBGDfir*lYP7q0j9usTTo^Awth4EI6tC7W z+PU;cqp+Z1v^%H68Z1l@S#!G2fmoO*3j@=aPr||^Ss0n#6)&}`C(A-1U4yG=^%PlX zO^>d?LaQvy{TGKG$d9L*(IG=>h9x=lGDgXvmobWcN)G)n$Dtoa9++_GMaZj{2upD2 zO)3p3cX(~HaOi85Ltm>L`da1CBaK{ z{Ve}iNk7luAn6zRXC(bHPZzbG?Q!VUP=Z6R2K>OL6FF)^E2v($}+?LocOSU$7Iu zZtHYOZZv*Vk4Hw#p_hJH=yB)|pjkNdVhRjDS8Btd-?=1*zJ3cXiuK*Y9-~mn;LB#> zDi(3*e}Eiv=!v;c<6K=) zq*s}{B;9KGi3&ONX^d-f=!Zypy;&&fjpkrUZ#Ekwy~X@Y(p$}AlHO+Cko4!~Ye{c6 zU2sIE@^_fAlHO_f2?#m#c}ed!<0ZYv>@MlO<|s+;GyDi5mA~KIBk6;NFMw0|UzpD% z{iW%G(>^)$6D57bERpn4bBv^qnR6t4+}tARugtF{eZqVq>60dp`z3PdhfDgjnP<}j zBz?v(5K$`sjJaCUXU!uveM{2kOgY{zlSAJ}(&x=|o9>S^4-Wn5Ou?bw$`l;>N11{{ z&+W*AL(hKBgG0~$&4WYFe$9hJFXh0YmvZ3Hv)t(a0*C%*)6p()= z6U+ihCz?Gaon-ctbh241=~UB&N3aNAZg5@e;CUn7uMmXQaSXyL>&5E9fy9h&!J!B zIP{|}hra&BzBt&sgxzo9`QLKrr+6ItZcVLlyz@Bp@*18n`k?-KJfG;kORCpQY_8$^ z_o95Lrcp{Fe*#yilWMI3rD z3qW4YMI3r(R%-Kh9*3Tf_Z){lUQ3nb&=dL{R#^@`w-r8LIc!rq9C{+kgE8%J=*5_8 zheNN%b~yB6thx~QI1z_Fw=;Hj(}M(a6Bs`flW^#@nsYKRKKy7(jgCXF#&$ULYHWu? zuf}#b^lEH}L$5|UUX|d`tFeyTB^-JVNXMZUW0mF53tc@&H<=O~dMb6#jscdd1cyEr zoE+=zbLfle_SB^~^d;1`-*_b`$)T4b><(X8ibF3#IdRB- zFP9q63p3~9c8NJ};|Tr&Q<(_aP`?vIU5Z1WR4WvuB!|AZp#qHGQi4NY+)xpg;?O5o zZMR?4r8x9SwL(Eka_Ea2D!}+s9Qxvhim()iKDlb!P*IoS&?nV+jE#3hO?QQv;|A)E zavb{NhKjHhhrYO>A}qzBPp;ZFRMe$7^hvcsK}vGyiyKPJNK+{eeQ`rYSc*fRT(xbe zs7rC^lj@+H^pK`k!p!%&X^%P%eQ`rYSc*em+)xpg;?O5oZ5t};QXKlEI;dGwkA?z@ zI~hMcHsOp{#G!BXIrOcTL(d~O>+XogIu5$N_w=J zB|EYHpSE4D)+Q&opmKdY1VT>12MeR6jhNb{~$I zKHp%Wxp_B!uO`&_Z1d(CV#3ARC5wZp`Kq#WSHKUqi{;SMt5`Yof+11O)n#w;_YDdP zhd$PjT3^JWucALEIQ0CsE?k`8(ATx#J!T5g?Jb9XkmbgN0s8xABu{VLoXZC^`n)zS!~`=Lk|5YE;RqxjP4%< zjzdq(#(#}NzsC&JmFprT`MWY7;fn4!^s;v0(07@A7}j-P=6h@KA_T|VB1~ms=7)tr zb9)?mL3K5^$DwBh_yX|&RIuN;*Vt7mEy1Cein@%R2elLoXGODW<5LE~Pm1vLRg_S z!{asP&>xEyI}W|HPmIc;KM_X9p_k3?(QRM+Mh^L_o_o}B=xJ115nmz%eZPxsoEvr< z6a#8B)T387MJAEC$&M3m_yG!;yCmole?^LALHk0^NO(Rh#+{n2ihXHqH;1bLgeKG*r60+g4n~nokKEN8xdHQ&fM<{;RSa`l;yMP{n72 zci;v~5PnjbgZbg(4jet;(DPFcEA}|_B6j}*t!z{HF}6%N^kR}NlP#Ca#-h`@)Yt9M==>*qDSv zpA-kxB{}pmt~7u~5rtx$7ifSX8Ysc{^7sYi|^)mRQa zHI75?8g18QIrP*x4!vmDMM3%J7>v#RQ<+Z7^%8j}+9Di!o)s);eq<`M0mGWdspHVI zif`f2OX(r)aOkD17)x;IrDWCSQE1kIBl(s5w{YmCB6+j|4!y^$FU6tP?cu|fk{o*7 z9x)%B$}HPWN%xLJuch1N(5ty!4!xS&<u41 zi}W?wCJc4*))i?g52u<}wxoHjX`e&S2I{>?mF3WX##<*XP>MqzH+u-4XO-a4$2C$= zfyB!^y0=Wv_fT#7@lrF{-P&mN9LFYS}7 zNrFR9jpNXZM$cwGhn^b8p%;yw&3q0$HI73s8a-3B;(XP7Z+Yf#xF4m)ap=AFi00|? z%m~~uQ{y=FPNM@_u3HHXJ=KmwFKTx&3RGx0^b|S{y%SoE<bX09fw|oIyQu- zUW!968o6imY7})T4t=clseFN@L+HmM83KAT8Hpp@4lMM=WX9@Y-a_Fgc9QqP!e~(Ey z%b{mE$DuDO=j}ErVmb6I;yCmrirCGt9D1r9hrUSd?Lb+9<f$Z19C{XU9QqPP>=sxKJ=KmwU!*SH0?VOik%>d`zyp&W2k{ofzvU7fdKPgU z`l7YSX6Rud{bV`xEaEuyMMdJ@qPiB#p=Xg7&?w>17Zr(rk!lgkp=S}tp_d{~7|PkD zN6ew8)^X@XD;*U7lY_9wpO*x|JK6o0+Uwu2Ksoe91>&98Bj(U^4UR)E1!7tI9D2D` zk&bsw393tS=%q@o1SfVp7--H_WX_lhJ_sIxIu5G4%a*uJmZSPxIP{|CA>#{6ap;rP+8Rr7=taoAXloR_{23LQHF$i*zI7b> z;#G^V6o)>!YQNf29QvgCTR8N^4HaPg?<+DdmTN;DhrYO>A}qzBPp;ZFRMe$7^hve8 zaw^H8FK#Gbxs>G47dKRdr8xA-RojM&x)g^#sn%CcB{}rP4dpABk{tTthKjHhhd#M# z+fY%L;?O76-@>6UZYW>5l;qGCH&leBIP}R?+lGp|6o)>k)>lp?IrPO1ZI?qY!uZrB zubi7Fn9SbzaFXwa9EVoX#2uzEa9(w6BHPd3W7dAufZ9s*AM57#iz#?;iHEj?C2rr--7bbn94@+ z+^iNw(0_y6N)!@{K0TA~b}WLP=-l2g4@*k+@)7h?Bbz>43k=&e#Uki=0j=koquy7A z)x1p9yn!F~5rTdRik^x|VZ0Y(E~w{|{N9@pOcu2m8teJesP`>lHNVr+;ub;A;!h@u zhg=Nm4`+#=h1LAfz1wSC;a|g7@t)x`CuY%5R#?L)E)jyBISpvCF!6y}UI5eRvdpvi zjDSrU;Y{`XSgH5rVKpxm^?X;;`|7ZoJGlOEd|KK2p)f1Er%zKJ?-crsn2zUT^3WUz zdbzqq2>O+%GLZLT#R&RiVaaw8qWsjlmq#NG1v2i&RCYf0O31m88hySF1ijST(L>Px z5!TnE0zocD(6iWQn7*O$64a)jS}B5_73b01?wHglpIRw`p2jgSOmN2WK+wxwkKw)^ zOa%R4BIvtD2>O#CErpaPp<{>UkobtszL4n;^0Xi2Ak_4=;_g*xd{Y49UR(6&@c57^z?yH@6%1v zbRR)azX)5qkD#ZUM0g9-@-N8v2zt6sND&LI>ahx2U=j2$(JA>C2IVxq6PE|NdlcIf2zvT~h#-le|Ag5B zxRW{Y-OawozVH$Bd7L{{#cm4rju7<6w&D%9hoINxH_Szn|E9S?(znbrlD=d9D(Sn1 z_qpoN@tb8hDG{-IG*^*C(92iXaO#(@u7RMJudXeEzR%4Vo?-u%j+1ca_7L=UqMG|L zm38LPpcX~Yzku9VB1=f5PSDXq(ElB#uOhRav*q1B5cKj3BKONtc;U5_mlDc);pOsB zOl7@MQOLPK9uXQ@EKiYS7f%WqpmWW{y66H>Z)}50R#yPf}SsY2RH=1EI9#}qHlt69)f-ya!-#e;cGPa=i~cNQ=_lK89ITWr|t$! zw^9GLNO@-g1pS4S`UrYTevj!@Cv}W*BIy5&!k@wP4b9Rf#~3Gqp8LA<6x>x|60@F# z5(s)$F&XyhktRqW=vl=QnD&p%wu)~?;f};2=(#=XU_YH2ZcoU$p#OvW89BIsGqKWWGQ^6QBh<3!N2o^G)Br^c(t zN6>R`Z3p|TNP}C3U3BkvcL;jJnx+#$|Gic_Jb0#X!-EL=lTpFxtmHA&=!ORo^qY~p zEwY49(Hsqrqx|7P1U+?6WBN7q&x_O!j|2VT@k7)>$!D0paZ)!th@gKFg$bB$!lZ3- z!{ec>hFWNWX?kQX8XiQ@vx+6K?;C02;XwpFKZW=KOzR_a(eNOGp4+n-_HEQ~dqU2+ z;jyIHz!-IR@8y;*?5=Sw&TDZSyN96XH9EEj6<;n!(RB^ua7yc!G!a2BZm>Ym ziyJHu^y04iKS0on8!Zs@;zkPuy|~c=K`(B!K+cQ%s)wK#w^|_R#jO?ydU2}-f?nKe zfuI++S|I2@#1$n41iiS`0zohCv_Q~{J1r3O;!X<$J#WQ`pyz!T5%j#jB7$DrX@Q`p zJMF&^^lcIJ%Xx;VRRn#lBIs)sL2r2b5F_X-iJ&h$j~}m<{FnVU1ihiZrbE!vX_Jnc zdU9|GdS>6rZ2l`k(DTNhzMOhLzX^6#IRrfm)5%l8w^BpKN6^#pGn6}IwfzHcx`xd! zlV3-429@e;gM0)%9Yoc}!o7kTg9Fq@(9?6&7dQkxTSRwKZD>n`pl5ahLH~1V+;5tY zi$PZU%SX`D0k!DIj7k#-`cJ9izaaY~uE$5v_n8&dAaneoU{}VKI|M!3N3T}DBY%ri zED`jy(bH9IK>|Tf$5(BiRBSt|7(q|BSltUMa0q(VOkdfMGumSb1pOaqlffbTkc*0- zuPH{*)5Eq{nLyCfHMFRuq10DXjG(7;ZroZGB@p!VE>(e6P>i6bH?L<;An57g8~-BH zJyG%9ebLeT)^W7c^H-b6Ee_C)9Wsg{k;9xO-?P#9DMxCqwOa%|iyc*>d;&p#DFyNiUFM`4^(f~G zD_&^DsveLA(kt8F56hZi`avj<7G82T&IMVnI)R|43%3>)LB*cCqVVr!6Y16MZKBu{ z2zt7E$7Stl@GSfY8FsS*8R!RIEU54h^z;w+)*zjf@e%ZN9G8PTNFeCxM;>pneeClj zexMRT&rPI*d7Fw)=nVl7^c2wZyp142&{IH{bQSQ?hh0SqPhlejJ$==s4LG|OBk1YB zZfy+%>QUy39!$97=+drDmq#jU-qJ`jS4&U#c(uS)@%VkD2NRa21AM&U*8Iyxnpv8D z@$ps#4Z@het_KsArn|hqZVy4v()6PD*X<$bS(?uE{<=K`JxkN)-e33Pu4uU;=vjJy zS32&`2GM-l$b?n!!B5-(+vh%lo==3d2|5_}!_)ByLC>c|vCR%fA3^_a3BgE3PI6??=iNilSMZU;h+S*Rp_)q*{{>k&nRp2Ll{E36 zBIqk-<03lZmKq-C{H$Kjkri{9d%NUrVlMwFg1%zw0Wh6h&)VrtucnG!2O#%U$)!)d z<|YvIuQ6Nx@is^i^p$k;u1q56D~X`*`t?eDt21&;mX6i`LeT#=5%d+y@SAVs4`ese zGhN1{+_MD}EQ0=EWM}EcE(rQcLD27jfn@l*u##?EF@nBQ5cIs8HhiSiuTX_M?v5$C zaVeU-;sfl?+MDI_L#HmyO(5v$<7Kn|u>|6LO4OgZ?20dN7PSa^I)GU*w7k0)G5x`8 zwvV8n9%YA|D}kV=-LErDRR%rUB=^$_&*gNrvJ=$FB*NbL({bc@q9^xJ^h+PNVeAHGR~+5}6+I;blwNhRcY*|hUYbw3Sb4u!$*1I% zeA8EXD(BAQKR$V_e3m7MpfAwciN*L~jD_dL2>MFC^{%AHQsoo;N0+_=-|1Egf}Zcx zvV3_c2>O}-6$E_~ijF?EhS;*CMMT^? z*m968l%*?2W8q*~NToZC!NMW3P@b+^g@r?9A)Wqw7#0qbg%0V@aRqN#BMX`I5xudn zRu;19h1e}Ehs#1m`u8{)w0u_o;%^&qpe?B5mUY6@%CH=TLz&xzZ4G&pC-SA6qhET=luoU2Y6#aP(z(m$Zo(8G?whw^N4`NnJRUpJJL-Wj^M1&gHg z?xBkpVv&^IgSb`Y8#mp*t}#LBy$2bV(#wj4(%aaK>Okq$8XkaRUvvg2y_)gZ{p(f| z%KIhs6{&6`^oR&LaajKad8^Q`L8>|EbSgHDA~{C72ZqL=3eUbtz$Ghrz7TM?RU#XI zN8JNG{?_2)!M{gG;ow&SZk-Zv>y&_t&u_nrQPyG70vzN0I6WKEeJj8_@Mgn!lZZyWraixOM+`3Aj79CE%i~K1Nqn$rXz~3(KDAatr(G1U$t` zW$JgwUg&V%p%@F59amt!>VHbW?e?D};9|EX2)KJ+@X$uJJb3q`)?3%yZsLdxZQr5{}%zbDT^C{ow5(( z9_pm@T>LDq-nsTSSU5F({CF(vSv?P9^6d2b6c&~={t1=~(?{UCRK2vzdsx_#o;nc= z%NicQ!Zqnu+`d%rUBQ#=jp>!sv9M1iZ&&X~Ka0^`y*$Iy;sfcc$6#Sa_Cu8UWzeC| zc41JH5h(G_Pc_3bq-In*1Y8-TxHgf1JIWDoN3|v3im(I$x5^Q4>y&_7rv%(OCE(U6 z0T-Dh;0}xkxU14QiJpM-TW(5)T&{#on=6ID9T*{SFLY&Q)$n)^v`jGrcMW7HqYT_9 zU74Ng`3}&QDTd%)1zA3V;J$^0?ECn)3tRRzWdnFxul=v|0(I``P(J^BLAYKU*vCWhed3CljTEWaG!wbx6b?>mhKosa1X}v2e5wX6jHw`1cFONEh_Db zNjpR8Xz(Do!(o~bnf2?j1`mR}0H!@6bIAIF-8=~HRAhu}VgDXA(l5Jv5ZtviZ*V3A za>H&X1a}+qFf+3&GZuRgTy{ao%pe~@a3`RWL6^{4Gz#J{(%a0RCH=YSFo)%DH@zgi!%UX+PLrL>{JTt(q<5RClHOzX zmh@h8oTT@eZIa$^ektjL<}FEoVZ!ZM{+Fhgqz{|vl0ITqO8Tgw4`M3+n7LTe$Iac6 z{>uDO(kIMUl0IpgaF0g_?s!R`HoMq#t)$PGvu%2Vq|chCZTf+v&zUMb!zKiGh@{V( zc{V*1X%|3n&tVD(?)6Lo!F`4)Ah_I)E`Z>&pSu8p%l_>G2rm1z3m~{s4iH=^2M8|9 zjr%V^aBsuqoDkdxB^_^`lC;JAPSOcxH%TX&eI=b_4v}=SIa<=GrWePd2f^(p`P0oP zNoSZTlFl^SOFG-|W2;o>Ip!lt=bEo1-QHA4Jv*57vOM2xlyrf)Owt|AHc1znVWQjF zbYfZpg8Lng8$fXD@hF54+@6w7HxnhDVRn;rrdcEDEb}8tXPe64duZ7?~*csPy z3&E9bYVaVqe@2BLVJbTsC4!|12yO;Drz0k@g~w5#MHPbEAEr^xd{S&y2<|MHc1xJU zUtvYT3=e{PCJG$_&G(&7)>3UDxaYteR$B-zw>7L<4`s&~g3E%}W4e_UT)-xbk0H1; zK7r{uXY3e5aA|xO(}%G!hTzheuHzHWsM=}^!F>ds8Fq{zxKxb5G|nkIo`Vst5L_DP zW7;J)#t>W@55RO-Y>XkeH2w(FhS(TGaM_Jl!muqi@_1@`@lM=&)A#@kkHkj0^C$$D z#+PAuBR0kmTn@<3VF)_9jkXZnOSvC9@wZFVVyit_`j6A-EsF z_Gyuww{H;yw;JcO&X}}3M{E*;%RU_i`)q1B1jEat73tc_eF*M-Q11ifVNT8RR>)Il zQz6V;dZ?Z{PsQ@NPROEdA-LDU{-D#i%0f>)JIs86>pM@zzlZX(cGS`cza<_7w_^jC zahP-i*N)mYf>(kFg3IbIfc$D#gd6A!Ed-as2OxUZ z3FXAWY&<1njTVB-ocAF5+6mcEzY|1lA-GgGcEYb7OmQdJ^$Udd(lEm>-zjW`XrU8& z4He-Qh2TR9Ep)=-hKkxkaH&23%A?z=g9HSZ!gC}@A5)uMPuJxLf=l5fh<0#7 zuc0Ee5L^oR5{l2l+VrRhEd-asGaQdWLyj(lgD6lAdMCcgCqEg5W-a1EH^l;NFe-ZbaS^ zg4-8w(`V5tSX>LieI2jU|Bk6_De4F*38!MtY7~Oo0l9fho@QTa(yMpHztoYRfz7C~@7L)KUig8M3#|I7l{uz=K;zG@e= z=d3DO2+~_?uylRHJ?Nq!eINce-_Vgw&F;+&%XRf2xWl^Pttlp5yL3ud4}v=%rp3-I zo7>BS;8K4W%tumk44M=4@*udho(apjQ3ZkA1_6Tm-XyeKr3%5NtQ7RR6^&q&< zBll%mq>H2#U9U@FvlN2+5lmku&AmJbF7FH*@F_-DOtz5+p`{jr%SMidWjd`=|MBcr zU5N+5-5vI&ktXQsL2%a~_n63{1^dMi+#kcTIbjWXUJv@k5Zs$!ez1h3+Cp$&fGw<| zB7)%dpNzB2r{m!~6wbiy@p`oQA25H3Nwz_a3c)=c#`+$35Q0fJzbS^`ax+K5&>9(~ z{rW{uzZinME6l5t5|&h5(}Kkj1eclXpgXIrHfV|=xZERKA-T!PcnS=l+QF&>oba{6Vf;-CDWsd)XY74=gjouAatPtG2oml4hFOXk( zfZ*;o)rl2?dxjIsoizUiTA4y{uXT3WGTCyuZ1@n|Cn%DZ%a-@+)`}hz2<|JeyoX80 z>RCMI`o$33FJZ~|jI6GLFz&>DWBW!B+(8gdXe$nCd6L#HVIhCu@LU5ml>YWlw=^IsA2=13q<(s4J=Q`tF z^qXiQxI-Xqb#m89zS2T)cY|uVQ*L6n>xwM|_ej{*JNrK4uwrjJEClyr2>#89q;;Oi zLU8Yg;29_4nruxz1ouq{{u+t&seJ;1dl8Cdd*Q&x9weeBm|cS<>xR3y`$12VhAqFHp0+@MxNvYF)9R?CC9=r(Uq*;JPPYQaO6%n!zLlP z)GWueKebYkJX!$+cTudh5L{|DU^<6d-5x$%i6FSF>RL=U(JWP!i`hbOS^8I)o~2n! z`w(0<`aPKb8k>CxF3s6K7^9eMX&-{i$_KzSEH?WPT$*RYG(R@`5L_O1`@wWjY~KDb zY}n>hW<0WJJ{jrhv6;_sA_y+cSHiT-nQQ)32eXCX-iPd`X_9L(#d^I|k%i#C0l|j} zQBdPUa8o$PRbaCH>O*i@V{e!S(k%U2<3n)is5>_*Dd&zr?G}Q&47Qb#J*e>^xZg+i zan4lkLvVS)y8x!kXqJ^$^WhXAxYfMYBp|rd`~uU{kycw#Z6Ua1ZzLhO6n>298y0ZA z7L0HZT-MmBA6AD+)~+>Dpb%WvFdoKf6vQuG|0kkjbdOf*-QXU@hjWj)hjU*I%)rt%@U)a(!YTBp(W_z+xb zPKW&`2~B)83K9@ps_%gEF{gGHBP+BJTnb-<=r0MO)mR8FHEBFw?}RDdoq8B0Ah;9` zhiHNm%C^=R?zt)H%-X6T*b%lpon8B@sTFn$!DStX!+xyOXkUoNLU5@$ANI?gMz0W} zu@GEp?t=Xpr;+QUoB;R_U(<4}TNHvz^}A4h>eOC;iO@oDDXhb9$?ll6FLYRl#zJtZ z83+3;r-@HHx>gIprI4QzAK-*KHU#}@A-KHMoCx~`PQ!Dt?sx4yQCkQu)i*-PVD?;Buo+ zfa(0m93S!aq$NO93&ExO1}L9yM;#ZoYq1bqmU{SdMUH{|Y*$2fp#0NeDryVCrFt8bzbK(D-U183WsyHZ z{!u$c>=sxEF4dJovBNQG7sbsf-U183Wsxb6FD_9e{wN-1eYtR!F^T(CVNxjLvU#x2Gf`#vxVSt zm(Pc37n=13{R`aWH;<^u^jx7&Yz~5HEzNqz!&fd51eZ-d9j2c|=J+?b9Myrm&S_py zk@?Mbde3|Zl#e;JJ7HU)h2XN<*C6`H3B8__^;-xog_R?4%wy7?MG#yHmqK)~6M7BhE0+j@OW}Hm z&T~Sqp(3;pTnev;=od~{+)z1VV$nxv^6`!(;m&}5FwEnUlI1=L zcXnjcCu~6#8#m38aCsHY^Ysx)xV%=>zJVLlh=jWmMbE|*&c%AdD=-)2BN8rasiHCe z6BY*vm#+i0xFzAT_^%ViLoNpSh=j`z-MhcW6)Figjt z1_iY~371W2ai)Ak!sQUpM-$lGpkqwJWw8(~ z%3vzHlA9{uTPX>b6*s}q*BRw|D<$F5I0=Sn&Nu-iTy{cG#eF@9B-}wH;dYBixMx5b zk#Mi8#yp2Z-`9t*xyrVEW5`&xVc%jBZmfQB2*-}9Um7xk>L5YFrDuZTZflE4xO7%% zOTwk=g1(vYNw{=mu(=)ymuExGO^|TuzncE}bK8R`_#Z=bJqd_f7 z!sVB5Z%3A}pO`%o?&mP2C)$E~&XyPaAmPgIw~jFhm$E^a#!@~Q6@{D&j;=@BGc z{j!zkb4$W~7?R((0@8Yx3Oe$ft|VM8{{_?EDdQ#ty*v^wt(EB59456+APHB`XS|Mf zi%7V9-AMxO4Y&+2U1QVNY|2Z^ti@R9{M|)(ZJ;DvUIGq6)p}vw&m-afh`GGF%D-T+ zBjNHP_+UrEl_f{Ql_f{Ql_f{Qm7cV`rid#H!I6`4&E?((TYFoz^u?uZ(ngnJ08_%5chOZLDH zD0n2?Q;>U3WC^#>JiwB0ufuseLBgf(c1-tD|5K6jQUVh07D{~*E+wyHde=!E>Xanh ze?#GL3J!ft+9roOB?*`Nx*4V+ky+0|2@)==m_^$vAP5-!*K2iV`H zCa%+=PD#RL)4zee68p=q=MrpsxB2B6l5km1AJ~UeFMJ67ITIJ3M%%aKnQn+zqJU99D7)YIMVcB;2jYy(zMU8)%M( z$8qeQQ`qE=W0nTv)8Nw}k%A?^y5-#`F{;(e$X>@pS?|Z|8EebL_mg5|}BGts}BQL4m_0cEc-cA#5 zYXYBy`(l(E@@7JN(kJ2mvy|N<;qn?C-%%t;xWkerl5p=rzo$UL6<=78aCwK60tr`q zW(SU~;=NmH;P|RK{90j32U4c=7iCKKP^R<-O$}_R5?@-7aK)DvBwX>O1qqioohcA- z#fKFsokY1TzO^9Xif=7QxZ+z260Z2xf`lu+wIJb&Z!Ji;;#&(6uK3h~gu92dcZVwR zsRap_w_+sW^1h2CT;5-igeyL^AmP%d_Fp92wj|vBNy4pD5^kN6aO;$WTgBUlEZsA+ zbig(IH;Icz@}9$DhmklyhBP$d+!%CtcVB#B(xKBc7`#;{qNpR`(sPsEnmVK%376Rq zGMoR3NVvT5r$eXS&u@ZVRgQ!!-k>v)&HGzx^GUe${tV>~S!&PtBwTugN)g*2pM*;< zQMIvf@1VArgiH5PU*Jf%Y!Q7*wJ{ST5-zh7B;5O`aldIoE(TfYuU7QvutA~R=Fa%zjPJIr9oHWlW^&9{{Ti$+Pf ztbz}I;s)5Kc|Hl3PlU7yGFUS{371caVw)X|J_+}4B?M!h#4pgsf=SO0g1I2!HdSE+ z)+q_MPD!|v+acl7@x2`q?n0XQFUZQtWP4mGN6Z&U?m;y1Ut1C`J?8Zs>636TWiJ0E zNw}+ndp^a8WuB^WXh371Y`HrprR&Wo}` z&fz+r#<~1YEVr;sSgUj%(+is1h_@x-(yL5wY2`<4f`m&?v*IW3ZArNFLyK#$jr2*l zbWoFQeU~7ILV|>wTNnvASAv8~mo{7RQf{0j;nKrRvnTo_-2SJvLen=zhd15xJ_(oZ zZ#H-AOz19_cLn_5C*Fvlza`<)H%`~ke**hA&)=%<=u8xs3n#)YoPdnkN?yEkG3K|IRd?8*`SXMx)}cLCZU#^B`e3q+ z%^fuqAAbzX)g!AS)qF92r{b>@Roh3Z0YT2PawmwY)mI%BsVah;W##T8s^c&5>N+n{ zl?OS?%3Uw2SAEspk*XocSyt|~qH4a>*7XH8|FuZ9F6hMNkD}%6bh&I-v>m%7NQJ=^ z2iKj1+Uf{a*0@tm70mgK_z;){tt~dV%ZK3tYEe z;JWn!*R3C(!nv$o;JWp9;2xnSnBw5Nm#~r@AqeU}!^tlU21an*a1p{O3S9R^Y)jB{ z`4M;l%h|A}z;!uW)>GiRoK5uT@gbdvSb2 z&h~rMqukSD&;}U~=^(eN5voqPKFGp&;I`r~_Z=((uB*ArZElvmKQC9-vipG;p}&M= z_@Ud+3|bbOzruhIaMt0i`W{*CpKRs3I9IpqnSBlmRbgccW4vXrEO+IGu=3xJ#?lg5 zdNQnh34PbHG{cu3Rb@ekgHdA&LuDfEzqY^Ro&9=mEG*Whhn0O>u(XFPWy8v!4Z_l%vQ!lYeb$Fd%Z_FRvhB<4wy&yzXm6=4 ztbDu<3;R@XL(?HTYem^vEbs(dva*gt6-zt@3LWJb2-5H4Twkb{h2tyFTZM&&4zk5z z{aKwg{Ck)5Z;1my! zfnnt{7%zpXDURw^)UrR8W~4Y4_dtK)=BBV~io17tdF7?tO?#!dBM;70PU2`@o?`#~ zFk87@GnQ7R*csW%Ap5`=oN&6L%EEqSzrk8}P=NJqIQ)0G2ZMRXrv0$x;vs5I#l~m( zp2+aEK$fqL%vR>{)uQ2IX7XNPFyYoz9f#>7C>TDAI)h9tv!4hh`{g+MjMLz;Hm!qX zf5vQHAnnhrg8@;Vv{;J_+7sFPpr%mfhI4Tf>J8nTQn9mRV99cond?z}!iCz9)zphL zE-rIY2mb|`BiX_mbafa0C-i@1^SWyN_fgNYur^An=D#5G7+bMcRllK1yW@VY>{MOZ zU*hbD*3Hfvuou+a3*j65C$-0`pdu6r^Lhu_5Zm0DwC>4D>!yGoh!z)=jTOxJqy^IL zKcFb?TImti8Dvgj+gEDaH&Uf---B)cfwujcIC~4SCw)~Wbw2J^EY(Rl0f0|Y0Qh^f z%cElVyg0}Z06z5seW)1V9B=PK2>_p}0Ptq!@^;F*dt5!?Tr8(L^gA0eY;!RcJG}J0 zrTAfU*fF@!aI?xcetOrskpckM#lK-u0N}d#E*3oi_?vgF%OwEd8}440vjA{bT)y$u z``6`qED`{?)^H;ft9KCqxMtjejFm)$S5#`o1IYLpGb(MyV|TARfQax)yxyxwoi|#q z*i)C>i*3bUg(g97tT1=LDcIgzM_xujAHREDF!j>=lCtfcthXq=&fvl*L^@wcO}zVSBWLS!_afQ%NKaVav+#-0xg4LtP9H*P`3P-aZ9 z8P}kR2R`&*vWdDC3%us(ec$J3liv3=D-WGLBDXc&gDM(vSAmmo5N7XPfw!B&Lw~VS zIw^SjAzjChGP=xL|D5vBbIL={DGxo@mWQ7Eb{=}}+j;0aemf66_kWj%zEfKsI=brP z&bY1nU&lkoZY2-Bo(<#YTX~!ff>eOsCl7t0@X#CE@X&Ymc<6&24}GxXp%3nj-@)=b zZt&kxJLhsiv(H1H8u8GFcs%qW|Kg#i7vL0CJ*|R|0v4w4N?~ETEbNi~H{9e@&&=Ol zj+>SAZ*enRJzD_etJ81eCaQX_oLttVZy1Gz?PcMJ^bf~lVV;?a+Pwkx3r3HZOUyu!O zr@Uyl2!<{pj{!sH#t??i77~W8`KK8PgBx-#&uhb zgfOnV+8itS*O<#B-Dd8U^jae!jO(s53}H+dI=hK5^d%FR{v&^EE7MQ&7fJeA{;!gL zp1(oTFY?bw`emMeQoWKe^Z~f^DGXf=4u;-J1HW6hCFWpGVCZ|&ATV?-;b7>8(;zT( zH8>dh88qC&^1WghI{SWGWKe74k&ygHF!aq8_|)9O&>4`pT^RZ|sJt?Z$0!SNR&NVK z=TYA`GACf@1>{b3mfq`dEO{{W-Cu#tv0YhJd+@oAMABKK9a?gt_;a+h;g`sbQ z=~idH2OE`up+5%G3(mX`OV`CPbjE^tAJ$KtLh4tAz|g6vLZywEv@@g*ABH{zrty)v zj0aNS!_eo!v|D5jSzoZb2SXo^jPOv{kDx~SWw8fCKY-@boGGY!9(#r`^sUIl%*?LL z*u#UNvkO9I28~-9FeJK%Jw~CDq2!ZSJq}|EF!UcFhcI*o5KiUKGG|D7wz)#mjpjZ{ z&oO_J^jyPW(S)HlqLNhpJi{Q+sr>nd0iRR(3k>5rr}7sXhHy^hFEZyzda=1%(n|~j zGNGg&|hg10*4Py(Z@;4jC5KiT9F^m_S%HL`j7dVx_%`gaXD*toCh`)rPGrVsqe}@?> z>76E+%jLUFUedeGcuDUuyGwenIZD#|%;l2aZ|;%wLG!Ytzc36ZOBgz1$ENZRn~9P> zVwOnys5wT`#|#6zrt*&)MsiK%e`Of3HI;wDFfMB<|D<8~Rl?92Wi^$5+AyLjQ-)7X z<)1MOh{KctQB(P64I`g2Wr$Nk&>72=X&*_SH;hi2%0F)yhLkXLh8iUdoe@O|Lw}Sh zVCdWq!qC~zgrT#42}5VU5{54207I8@fT6S8e+7pAGdv(64E;_?$D4;GZ86VDI>9WE zbfVc)(n)4NNhh1Nl1?>UIQ~2sdJoB;ZU#v@!;F)3rkN(`Z1b|DbIf~^&NZJ%y1fad zo*m4wvOM3MCg}omo}@dP%OzcC`iX95Q_Zvl44v^!2}3vYnNBl}l1?{_j+*K+!z_?= zrdciNEOVTsv&}`4&M}N(n(7k6&>6inf}x*Y4R}TbL*I)q^b3#^Z1-9j{PYg2YPcLr zOWMHD8(-{;gS|`Go!5#8hTdvn=vUUlkE^K_{}hJK0I1>HSZDZW{0kZ*82U_XZWWEw z_FEh5pZdYRII|(Ep~fmzKFz_UcI+WhJzCjPABHY<`7m^5Toe^h7&`YC;OFBEW2q8` z&cL;Vp)>Ak1Vd+Z)d+?z+vLO0-$jKVVk%pU62YDcFNN}8 zr)GI8EQX=4hv;l4WYM-T^lh-;=QOUe&{KOb^cSK0M>}e1gx?YmhF*(1$*!1m1Lat6 z14ADJ`&_4qTjHrb7&;%=9Mg{4HiEyn{vUhi0jEb%zwz0(+*|g&yZ3rX!sSv(@Ac9z zAt9XvNKZ&E1=1-Y1VkVqh!nvPj0%bY0Z~*$1^*NQ5m1pXO+=-46agEckpJ`iW_I4) z_ulvJQb5G_KA*kWncp*YXJ>b3cfPL&LuYb3A-~E-VFmp{14F0qHi#auLK!$1tf3el z44ok_L-a2zWI_FnAo&{@I@Og`7*w%k8o}f*FmeM!r*JexGpx{8P!V3PVdxYd4bf&R z^c7Tu28K@Ic8IRB!t8>I+Q87Mz75I;nyOU*hECzj5dFgneFf#Kj9LRjr?9jd@7b~G zs{0BmLIXpmupXirR+wE-Q5zUK)kj0Qxv5$OVCWQXhv+gZ^c9q>3lD});Y|?TV}-tg ziqOE&DSQs1e^_C5K}Bs~=v0^1p#IpJ9C{)wJQzBK^$<&GKB|2r|>z5-nK$tLAlVzgP~KH#1*eCwk8D? zp@E@OI0&N2R+wE-Q5zUK)ytqfzNxw?41EVgzO(XRPOI#8%6TWF4mL1!W~O22JmLaF zznwR3Db}m^cRAD3VYz!ngzgHLAEt#n9OYh#ScIYTr{u#OR=ND~_;82S?(^cVao-bn zty?;i;p<%f0(`i`dUukz8{F069`Eu8+`}C` zW85}a{wry*g~@pL+euF48>jmh8{*} z1vZ~%0W}^Bow0Cd$wh^Lp+7znX)LiY^n+ncXc+n!!qAU`zt@ceApJ?j5~R}WehfQ+ zp)=gV(ErRdJQz9;ogaq25z33PIot`r(7%s>Td{?XLBbCAbY(0I{T~SO!_fZ-|Er8} zIU`7V9t>SPDr#Wp{ONY(!O&UM_)=CZ07LKD4v)gvbnen9ei-@`m}XnERJYR-yi}{Z zGj>v^zT=p|rb=+BKr$+c9&&?)%|wx3ce3Hf2@ z4Gf}sorw>I zegy0bJWT+Gz5$^pdlnth2Sfh?EME^;9iHWW82S%jzCDM;gP}hRo0Fo#gQ3@s!YG%4 zp`V5l{}txKF!XIOrt!^BH8x#+9}Jz<>;uDS&nV^BFVlT6^jR<;6_hZh*7;!Q z3_KOO^P6h@FmxV~Dt z)-HSeXJP34sr3L1eUTN*9{*VwI)9wqh&2rT94nSPY5ohq(7$8tQZuP}6BznE6iLaY z<~|tu?_qfvo9?S;^PKa+(BFflqJw9(2{@TX^uf@(LO8UkI0!?Z2Ek#TC;&r03Zch& z7CmNZKDdFQp9R~6)-EO0b^}BI7Hqc!?7GG>lxwAdp+5xGi#e3iHd<+5=$?7&=eUCt-TpOG0ULeK>Yw3Ui7u{}ZMUZ0tT67&_xtcESw; zHa$R!QNz#~a{vs(Xq0?C82Y54X#5DLOX>~_$1dutHAh0Xf?8fJlm|nfp3xc@IyL8F z+fJ>n4<}bV7&^224z?fAEJ+1m=#2d_b!4~9fwt zPZ4|{P4-%^ua^NB`m+$c5fBAo=nAvRMc7Qc`eEqIz5`4L(Jbv6fT52-@I)`Bj2%H3 z`a;+mJ$n#_ej}<)82Wo7ZG;Yy z*n}Bc_%_7>FUZB@F(8UsV8W-RPetwxVjei%A6D_}pyYIJ%0 zFm!6phW*ljCUZ4X0T?>fKY{WWR&6gvMrdH@6g~~nYXPCr7#KP=p>8?faql_ zlrrkJmJ|&PoxO)tzRVe<_N(p>tK5Ve7! zQ#}#Nr8(5T11M1p44qLMGm0+)7@0m28K@c)llA%L!Dg%14Cz&-$DLno+ze? z3=Ey>SZ^F~Y?%Wt2h)EtN|_7{ol!_C5VGnfp&(y`h&>7`X$p4%pii|G&XQCJwI-?Zz!Q~E{uD%sIGP?L+=+q8`Zo1Xl zlgQUpJ{US9tbq8m91$`H&j&+igq;vyWg}!{0T?OQY)7IUWq1>YqUQ3#+zQKO;0SbPAt_=uIp1wWQ>4VCWRa`r(|% zrdyI%ACom-xp**i3j0IUV1>S{MQC8?6fS`17%Q|{`;#>=bgIvW@~chNDk90=pNL(# z0s|?8KZNKGEA$nVuUtGBI)%T3=rt?!6;y-yV>)~}pA z7&?WsAzEpLzJmH;=+|OW{4|IzutG*Pr$;sn{c4DQWQDAeL6G}k==Z|@jMdo0%)LZ5 z4EL?Sr9jgYwcm zYF!9{p|ct73on78^IeZhu^lZ3ed=J`ab7YUAps8hOHjVSEC#UU{2cV%2u&iASoG|f ze79pb=p&);1aqIDWSO6XKE|`@$u;~iG16=>9CThlYxw4f9CThL0vz;3hEp~iC1C0#!U{SUA{??q5$84fz5y@zc#jbCR~Mr*;nqkFIvYWyc&vMqgWfy9K|d2xkAu$NNAfu6EUw2v@69qS z&*q?K)W7Y;zTjDLjxRiE^x>!qmb3L`rqS7U#;*s=v+s^H4u7n|sF?MPdn@JsY z*70~t0uK6V4R|#V4!T}c@}%*<;9er(FS^%>`;z;RxUaZ>5%*P>_nCSgd!xn18v%$|ne-xoldlu(FG5a{^@4)nd zXVzo3$3d4zx3aqjVBT*rFC~<99Dx%WTc{Hfa=2$X=sXWC2VF)V9alK$!=XG9+iDw^ zdzORFGu|o7aL}3c`4C)6IjiJwPfjn(LDwI(`Z(yfLGpl&Af;z4RmNF#%|WOCMQpEA z#ww^zJ`TF%hK7w}(^jE;>+y`&QOiN+n@;l2zl~<0yV|(FGcGSJ6K3L{pM%azzzQU- zFRVw8j9~fs%C6)401C)ZUR~v%>V7VI+o}hr>yInK6hzLnkZ{oDGB=SN z^!Z~zye0>o2f~7`tMDX#6p~nnEp*p>8~{HDeG5X*^DNFiG<%@yt1v=a&@~aP)Ln<| zC)7V6Qr=mBgMKlk9_adv8CvobWY1cu1znSa{s3FhJ()fY=QkeYFHnKdlqzkJ}brfc8`P3 zEU$y&7V24Qt+$|Sa?qLYqp&|sO(snXx+Vvm>HL#+94~)59_X4Jbf(h|_O8_U((ypo z9tjfH)pr_rEm9(@5_%bjV8DNQ5?{iFudJvdU>?m-Uv=a9g8OyoMGXuAhF=(`Yl zjc0LgpxNsloBiE`9CYd)#P%5VH;dGCkG1~paVpZF1?H=TyGo9)N4E)&q>3H4arbeC4 z2-qi5<4ecu9^|0&Xf1(#rKi!|gGb-jJy;@TIq1ATUIM-E`k1^GMu5`?I_&_<8oyv{Tsy{mXc+(;GoMgT5!;1 z87(;IvWynob6LI$m+M2xL6>E<;GoO0T5!;1SuHr|vaA*ybXisl4*Hw8qJ+Ugmu0o! zpv!VvaL{K-d8eghIW0Kor-^??>Ko!7nz~KgSt(gg3l94G@E17fO*!bRI6|Z~2R*Gh z=xM`2=j}uM5ge~L*WSAPHObI`d!RNEN2b5jmF zSC0AxmV?d`o#Ppm<)AY-z(M~%YV0$OL$8WUd-*x&T!5POFr%db4*I)P@t=x+p85DW z=$$8eDaall6ijB!+;Y%aKCWu@H{=r-V#z_LjVoQnrUD#vE_~JHlY~uUWpmKEELI-{ zEwCJPrp&dn4tLDqb8wg0=ctf88UCI&=^Szl>CMAI=L*|wWq^aurJ-3RbtJte9CR+u z&6HM)0vvR%F4Y2^KsE=Rt9gC)00*5bd^1mE`bZ>CScWPuD`Rix%3obf)>tLG;KI;n ztuzJ~182&mlKoRKohc@+5B8f32b~FW$*?~`9|wIfP13NESAc`Q&_=Td)?t{6{|o5bC?W>~L0~~ZN_s+yM!{By2gm@fut^>~&ByYeSOrNu*X}Lb! zmxDA?fP>D3<8pGV00*7x$aT7z#*cX%bXJiI%$p>9Mkizp4mt%~dEP|eanLE?l5{PQ zOM@<&pM%b|>QV-b?%5o4u3tAcKL?$K<&t(?beU4|bI_SBSGs4i4RFvIn+xDG6%TOG z8Jp|kGqnnE&>5S{<^6g4IOvScRrLP6f5?$kbI=)^i|hS)i&=Bf8JlbF{dv!8i`bfj z&e%uW*qQe9bI_RtCw?*oFtd4n4mxLqbP;rCJZdKLxW$qCUd|F_Y^F2%Iq0wE5O^H) z4`7=F4thI`iGbTgXXB1N-IRl#ydj2Z@0l`b$2IRh4tkPP4*iZ0*!g6d_zw#wIGFf2 z=qqUAKg~f;9)gQ#zw3n)&BgM1j7&~u=#3J(lcD^lIq1o&*TD3-3Z~B0^xBj>q8mcb zkx;Iw*P#Ip`g07Hf4mJc9CR+~cHhCjxcn1upHe*Qez*c}PWlgub76IXgT9v>^yHDV z@rL*mIgDJHE`3rzuz4Kx^$3o06?>fPeq63uk55BKO7XeSWmtTB8vkf;Wsi5$DNZVQ z9CR+@(tPaXpK&Bhe=L_DF6z>u0S-FXc$r{72mL)8octH2`AT1wG`IlFh!>&DcpP-D z2Q$Hb4*Ga6*x{aP%0cJ4F?~Uk8}X(bbS@~peWDR0nEDg++ zZzj~oLFYQSOeHJ_oy+2M4ju=c3*>ZVc$=VNzvzXOr|TbH<)XQaP4_&xhWR<@$&E#b z@qlztuBwxxqXHasnS0J0uQ+FcT~5Bo`Ojra<@s~pgX96 zpM$RP^9SLwpitxd*k(9pY-1moCsfTSk|KI<*B-}Q-RJkFZuM$!%y)j31Q zIvr4}ov>&``^~7SL9}z%AlkWW5bfMGh<5H8L_2p4qMf@2(av3iXdgN`#O%wL<56~4 zW!iL<%YEJHmoUqD6;(Ff!p1LN_4=zPof(R zze<$j7&?h1TiH@~e}*m93CAR&if(~!SjW&iNJ%1ger<`PmPkaP#Z{ssyiVeF{0}8Y zEp`xbQlo>ilUfMVE)&@~XPX;VCGtaB^E zpPGk-OlfCAsQX+r`z4f2Ok9udrlOa^JnRthY^}Nl53 z^w7^4`xKUGMuI1tsv@TT&;(CL6{-3>EHlN^5UC>0ewKK)Myj4bx`&D9j!4z7QS`%g zoM=@7nH(WGHbkr5-hz*4`tYz!j#k}(rkT@|O+7tYbrlkr+k*`^D_Zp;5}4PQ%`iKv zdc;GELJLv9Dd#MCkL7y{)?rJNx^~+h$Kh)fZ2H#d$*k%!@qAA8z&A(X0}(GehZQ>7 zMEH=gSBYnKq`L923xNcD*9VWmPhVIW-3}v&*}(sKBsC1io7AhM9)EsZH*is z`U0a1^natN@jB*qf_NID%jnsZU|Vig(Ut5h4RH=#z}VNqGfoiabBS?^R$LeY*1^T1qKRFy(ma?rDPz_C ziipn3NYmkUPsRSgR-dMAmB?S)*z27OF{G+kySa`Ud|6l`_osmIjO`4z>L4BYFl*b1 zXp)Rd{^JM;PAUHdqO78w|1?cK_7!H_PRG4~wl`QPQL%U`wjMoT_&}ZU4{{|w>q2~h zt)br!(k}C&c5+k+^n0X%e!t`iRE!|>p>uV{bqf)X&FZj-x@uBCsRP@~5edUOqu?0% z{2+7+4rLM&CliseRr0MJcu_n<8tw#&G8L56DOX7%$VX}f`IjilLXfY$8;Jlx{`!~n zYw>IlwR36ZVmt&Mi|c7mCK%cAgq+f=B;CC4rs@dHnQV~ zFP*NY&HJUcpJHThSy_*aZ2Bceg+nHPk3r-iiFhk#63ER>r6^IvxZD6 zxLM;saS+NWH&Ed^Re|A53SP~DqMb_7sBXYNqQl?AgZgwqheuqU@A`Xn;?G32|Mj7K zWfFe_1I$N^4xjOCV{q(~<;$_} zev1JoLJ|Fq{&l3$GZ4_G98p!#Kha5w4yeGvR7F2W&ns$MaSr#-!4yqVyNYjPzugGT z9;IV$oUd1-)7oRiN~f5zioS|B$g!%bGA4T8FhYlAZue2h}fesh!P@D{+R-nVX>^VBT%bugd5oJ%&;nhvh;fM3G zX{q7*%RE7cA2HiQhu?_tJ)8p_uEWoD9~Arf?rY*+;O-Xpi*D60#@p`p5_g9?SKOWM zMsdI5^6R*8*(L6`#QmE4b8)}!{#D#>xRv#^U+xYO_eyuNxZiT;hmLPl?M?%Z|p4eH`DHVbc)oj``5x3we)G#gbI5i*4$UWweMR=x|9< zTQZQc}9tMLXIu>~D2=9SFWhYly0+oHoW>HE;( zR9JL)CXK2maP_S^KlT!;Y|-H~>u+wW$eyg)9$Sx_V2ciy*i28&@u9;aRowq`!#ER(4zCsWCU>~FH@nfv48O%~C+<((k>cL!E)w@P z_p{>O?p`hK&)lDj`*Zhsaqn_J6!&hob_&z^g*#Tt4d?mg~T#r?H=leqV~ zzZ3U9_kD5iciZ7Ejp*<};y&okH109tKIC3t-0zF~uzR0zUl;c`ZUXmiM2B}5_YrrJ zao52mI($1_pu@jM7wGW&=>i?jdJrAXb|yNU?Mrkx+m+~Wi3fDJ!~;5<@%98A{^Ri| z7trCii#yc4SKMLl6XFhc4;OcYyF}cP?pkq2xtqluBz(NvSKNc$5#mm8 z4-xke_jz$Axo?U)*?nK!DQ=OZGtJ#5{^{-)#hu}PP25A>tHqt=_7vS=ZaLi?=7 zH$aD{@v@8P@b==4cZZ34uzR?;6Wk5rPIS){_YilNxRcx)#Lb|??}guw4xjI#!xva| z_&7g0d|?xGcy%sx`1t0~;iOp$Xc7p<%t>nttMTZNsdvR`bIBl|STj{80#&#EB-U!D|(BWd{be%D0p~J0NgLWtQ(Bb4j zuSGI~>dxenIt#;L?eWC|Voq^2UhVo~*41&FLx+=aofjQ0#(d~-ZOnrX7h~#T+~d@q zP<$5}GcP(^Cvy?{a}IR4Hs(QxYhxaCxHjfNhifCxryS^TZRCQP9O!Uu%%H>BAuT#w zj49HYfDY#i`n>3HD)o`ggAUIK@}a{ev;63AT^6pxtUX5eiTvnr(H1|}3EE;O_B&L` zqQj+sky@*Ye~)|r+A1gZMc6Gm+-K+QTkQc(>?};OS#-GA*<+hQhf7^KOYMW*=0}H% znkCZhr(xXnPVCZS^jc$!4i_Q6pU~@(YsWjWHt2|aXtU_>U}7zy!*i(pMHYy8E_ArW zlXE>kIy@_FpE?&hJcrseM-oq5Inm(~h0Wm?=0b;yPzDY;?h#4x%TDY|xLsn%%asNl zEg$@s9Z3-&tTGbgqJqXUnqMTch> zRD`+E;lZp;K}DSl9UfF`jzdm#cy>WahN#Vj4$m&A2y>ysgISw`iaHlMJgC+jhn(o} z?1GXEkrN%BT~HC`LWc*lHU$-RE_8TM-6A@Cq8}YT(V)Y5=4x~}Pj*XE(BGW($cGO9 z4q_1WX$IjA$Ghi>yV1Q)+)eJo z;-2WfE$(Kwd=_;lyFJAHjN2gY>Fx}1&vciH`#JYSanEuu6!&cR3USYIZx;6p?lad13X*E?}>=6g4gbk#>m&}I_4{H7Ba2^qh4i}l+Wwrks9#`v@J8k=6xhQgT zLyz=Dtug3uYAiZj(vdSsYYaM^n&XkisWu&H9<4FxaB3_% zT+(3^smS~2jCEbZv8qP={scx8iw@_gVA$aO!?E+x>3N=7bU2e}1|2T3`{qH1OI$JL zK!;1r)UE+2*4q9)9C$8txFjS~D|Ksz95xh(Tw}&_p~H23IJuG&9j@ym=Jny&k#hj& zz$Ac0hwIpR(c#*h7agw6dC}q8oEIIg&3Vz`+ME|1uFago$%zgZbMZ4}F#jkVI}KM& ziwO_8aM9?|OwuvvaB3_%Tr_$#6OBQKQ)AKLqR}IjA01AOMTh&!<41>6 zW6|MOqdT-*w*u&Jsx3NP)b?Uzu;2zAPN7AITcObybT~B@9WI*8Jx~B0PN7AIi%{xX z?DEizj>e8p;ridrpu@$k+pD$#c7qOQ8WtTc8hva;W6fn?Q1U)8gw{?79DPdN^{5!I-DAd4i}BDy(BS%4ySMt z?tBCtE<)Wm1c99k9WENVXY{2g>RjmXjM|s1L5DMIiw@6}QMa|EXwcyl?nW5}9Uc_= z8&jefbhy+XclndB`JO?1Eh=h*4yW3p!!sG^vrUAL7sVdJC`F+~hi8P@Es+ZyE^2{J zONUFH$q{-}En6~(4rd+~9Ujc18FaW!z8Q45)o65h@pX+TLN+>_A{9V~vp^Od9xRZf z50=2H4LY1^iw@7B_8&2cXVBq{XVKwV@qC9(q8M~IqgZr!jwq%Y1|3fI#9js+o~8C3 zK*_+M!x_b*!zD@v9qy~SL5EXq(cxL@>>3z!IHOo}c#bHh1_m8YwMB<#sk3Wf(BX_? z(cxK9GS6}WbU33}ba+-2sfIo+q@4^poKY+~JS$4(Sybm@(BX{oXm5iK&x(?HBGpk0 zI-F4~I$WYyp(CS<4;@aeMTd)48YuHmPC_3#oDnQKJS#%x;Q7$uj9}5>5+NhYj}Dhx z6=`@|6jjWZTXjW=*sc*uS#-E0$xJY?W8$DLorry53>K_l3e=**^=*Y89Zs`Fhx^P1 z9nPFBI-EJENM3Zfj?GstInm)#6I*3DtMSD%)iV;Y$3g311%HAYJVA$xnx~9kmQoE*CmHyP$mKk`o=CT~HC` zLWc*lHU$-RE_8TMtzS9iM2BY=l&@TJqQkQbD#Bdo@L<-aprX!&4iBpJE2o_3@a%%} zl}k=^cy>WWmWWm0m(EpWS*y?yH0j5iL;mZds z`+V@%c+qfa?7MjX{W|1tVG9lA0Ie;T#a@Frf~^#rSo9Ry1b)0@_~GPwcY}FgP}1n< zhac?O^bDJFS-A0rAI__2HD4c*AI@t_EfdU4`(Vajn#Si;f(&9 zKy-&*RlSiJ=HQ2aXvK`GGYs&nWQR1>AU~W%8Ej3}9zUGdi)xP_&ZAuI@x$d9 z9aLM57Ym*H@%Qy)=DhRJwsMK{_~EO0_~hkSHa~nDECGJ_4-s$&Hi3FO+;gbWlkA;` z>2#~^Jq~Y7#+O}(XN%`xeZ`C5=Z7=ehu9)0mHf7@pC8VI+riM$8h!k58tY*gV~ym8 z%dL;gW8H)N@E!qv_&Jc~;)k;tJbw59HutjT_~Gn39zVP{)hfUb=gNdU{BSN-(58fs zAI_x<`przj#}DU11{3PzhjUqj4h`_bxym6wKYY2LAI^mk8fmdpitgu!b8&=8-Omr_ zT8Vu8aIT+_C^`7y0xOb#ndPMMR}jJQ!(HwN_~BfAp(%Ko7~Q5$MvOzkT#=DYG0}K* zj~~vp8d9|&KfGJ7_DJ9!hf6m!KRn^%hjSr^u7L2v6Fz=8*LGw~I^{$ap4AOMoNGR^ z?E!u`7lVjE1^D6QU}~6)>HD|N@P)o<%gfnEQ0)S`Scq6aQXBa{BZg7+VH~<`f&;LU5C}+ zgswWN6fdM^#^%n$yHF%^H@47$JR7v-@Yn+oJc-a3Jd4vw%szhjKWV~qfkf0}w!Gl) zI;O2WM)>&Qly${6fO4UQb5F@EYuARhJP#dtTitc69({cL@G(#>$F{-7<(`r$-LB)> z@{ITM!3rp;__?ZlqU(Mh@)zk9BISJm=^25bv`QhTT{BZGEemH#|Kb)5-_t(h57zg_# zPoo0-a3;|R(>l*=lGr@}tz!7$tk36Q-%btd<8V)P--e^|&v5+?R*IAE9zUE}-T=kV zsAo%Ry#+**AI^NAg#86-GHF^s^nrM$Wjg>R|6hjV~P!5KVqK zkJbd(r+OLQE1QyWb8;Dz6I5Aws$MFQKINF7qN-Glt_D-rqw&*B_J zv)4U7>+c@qhg0_`w%<|TQ>3PQ9P95Mry>nXKExKmq=J^(?m>QdKSVwdrp`1=nQZqU zKb#*kjDl&BXU^&#CaQ>n?6 zE#h?#^22$wR=~c-)9CKOqwnh;ERhQE!*@aNyFMm-{O}uSlFx1uK7ROPUZ{^Bp78O* z|CY<{2_HYaXV64`xU7W*KU~(rf*&qxR`-D)E^BGQ50|yH;D^gvTJXbV zEiHKAjl*%l@$tiDZ7ulWvbGlda9LXmez>fy1wUNY)`A}{Yiq#|m$kLvhs&B;@WW+I zZTD#@SyKysIB&(m-DjkD-xcnDXo~k&;qJ3ivZfaNaIUE>@WY$(!;j9(4|jR{kl}|X zEk8W@2&R?d&GExsF50yGaIW0sYE3;jSbjKzZ)Y(7W%0v#V>{?~{;f&0c zo(}JCjm^&wZ%>=tAxr83emGZzN)%HdKR=wSM752PJ2mBpbNQ%WVEN%J5!aOJ!dQMd zg9H5VpHgF=P#k(yT-wXe59cb>tcMvb4e-N1po;%g{0q#-&kyg8^^rOS+2ezP$&8s> zemKj=rLF#kd;&u(`Qfy2xvSVzfFI7)uR3)}*fdr)Kb&i0^-<6Q%MWMDTrlf!N4Hqa z&kui=Ht8I44C&3o59c!5Y-NBS&h?>LC3PgdCj4-&(9M)qivs*`E-}>toj^7}oJ)Fr z_Sm-@(T;r`Aue;7Z{~?iABn^X%OF@*#@^25zq**Lu}b*(;am}%DVIw4_~Be6>^B*H zI1}W$VSj?Nan$?VDrMnPVqdHPKb+j$?B-$^Fe-SIUS;^<-2bHU!(Fa)P5AiXTp=yh zR0+cmXS;B{bf#VO%tOM*59d1SOyd~4;fFIm*H>r95AegkNx`W+-DJ;q;_=8P9&NyJ z(ERY92eJzC!~bY)+*9(?X#svX*KzA|iXdV5;d1El2HjUgu?P6!T=SiYYlcBTKb(uf zvjqtsKb(uieL2W1M1UX8)#Gw8u@WUCKi{mr33h=`jn``F%dHeX`jLoI={=9$4+G>6{V{?VQ zKW{N>emG-u;k`fad2JC}^TQdN>+v&r>+`|S4`&jb_{kK&%;x#|;hYiDiRjLF6u#T@ z_~D!-%GgY2^z+02oI~L8!$Z??`D&RTp78O*x$xb`4^I#|Vff)QXyQK=m%+rx4_{3a z|7m`B!p9Hiig`!I$b^p{ehEYQPxHeQh9AzHJju1*$sj*G*#~oGmLJa5)dha|Uh=~eK7Kftr%RvI4{RPk{CEV%xs+Y_;YluB zkIzC!5*B1K$PZ5nKb&{dLWS&BpTawt@-WwOX|8m_#}DVqE*%=+hjXEq3HI~DKeWLK zA3vO{z>Ihix{SvU=b|tZ?B|D1@`4@i<=}_&RhGV>$&GkZemGZ^>04TPs15MLxza3q z=DjIDoa@jsDVRd~`QcokCc*jm;l)^KrUl%~!4Kz>Hk0sTHj3egbA_7@4)DXfo!bCS zmoOK+=_8-;@x!_N&4l{+;am)tsf6kl!^}bHqam)1(>ZiIAG@WK9j=noW#w&x3h=|Z zaxP=jJx{J-etvku#}DVyIypKjzz>(X=gjena~3$s$@e(_CD|L3?67f8d?xwAH7R?1 zKbYhXGA23mntYrwgda|8C8P1{7(>v@@WYdQ^_}FxrsRG6XZhjDYY#vQe5V%Y%R}LZ zPsza#kCUWV^y~BSl6FG*L&ze2JN^~@@(ctVQqvdBRCMz^>`#%bi;iaa)C#_TD5^!` z15Yav?BF<@TLVw8W8aNRc%6@Q{S#8Y)s6^1H4R8$Rq z)p}2rP!)zMzF1USukfXHk*A8N3PTm&CaP!ss+&AjrK&Jg@$ZPL?n;x^yQu!to@$G# zr2kFNKUVv9!#^5_M1>tSX7_=Z&%=IA{Sjbx3Z%PSAl>Bx=`I&Yclo0*M#}}#U9KVB zW4fUI7_rl7j3|)q@|AU%5i1u+cey~i%LUS1zN9-wv2uZQmkXr3Ttm9Y4DO{9>3=a3 z5lDBrhIDsvhG51=^ipU z#Oy1U<9TstW!kj6*P`qX{b!s05LFc`YoMx1*C7b~;VRwk6|3MKT5UobO=z60KXr0? zSmVWwj=C6<=x?wCdNcP`3Axk5mdAO#RC@I>QzockE8IUJPD5HBscRsUBelC!6@86S zSB91$EKbAJbh5sz4dxmr&c{@Bo3^1^>__7`UFzG#b|Og?y}T zqk|X0Q!AcS^!u0(ukRq9bo8?o@YIQ?63KQBoycT=gG)wz7YS9-jbV5W5)YDH22WS< z#G~K9`CQ*kJgMmQ$HLQHJn879I(T}Br&4up6Yd=vFc*`|sqldCkC?%ayTCp$$-b&e zet#T1gTxbYN*?VA-(c~@L#kJ#KKv$QOmY!CJi&KA08QgvR{aR^IMI#(#@3G%Pbm7! z>9C9vPgq4?Spi?4xQ_J7Qh54`$BF(8CqjKcDPSZzt{R>pk<*b+T$oYyqa!S4Wmxr! zH-u)R=+P%}n_EB5B((qoW&L;^o3)x4dV|%AgeHf-M{(cdVV{zGkkyOM9}mw|@oX(A zM%SyKrY%m1i_xZjx;8l_vv7LU&xp&x3?VgVR`^b)_TXTIAEp~iMgO=SzC$E$72Uw( z4vicMS)`;dkLBSJmH;i+Iql2|^+qpoRzjCRov^gT`7O+QbO=u_PQE8(duk{UZD>)5xd#D{+HM;@+f@u6rHxM0-R#CRlAPRU=H zNE`7LJ0%yh-**iEYBtU*r{oM=2kLuF7En%)1(efc0p;{qKsh}YP)?5pl+$AY<@8uUIXxLb`COE3 zY~x87fzv<6pfmPXoOOrRPGzWOm9y}&dNp|#4p{uu2E^toi#T6vC9h-{UwbC$jeX%< zyc8Q(RK`43Eow+v%0VE!{l66aM&5V2)jf@owb9 zVTtrZsu-$bXCtkVujsUXl?iTO@SR%ybSC%@OyqZ3{r61pau#T+R#z`X+8pKeZIjMr zH{-pa1p_INaF+_e2nM@ZGM&~P=Yoe z0<<|B?+ym@fH=?cpOh?9JSrTKFsze`^ZF=g^D*h7FP^FwlD)|!vLZ?wC*InD57=i& zJ{7nG_znc^5=SM7HXp6g=7T88LYuGIbP)o>MdyD>=avo1b}rqq7|*B2eiq+Oun<6- z@7f}0^C{Z-=Y1Dh`|tD0nQX zQ+OAO)rTV>ZUVMmwxwbPSn5EVYsER2ZCN`7cYi-d0*Ua2BlKl^+6VVJ$Wy7`Ye(?l z72VE3^{VxNxZ^D(y&0XsscFNDZe+)Wmu*qg(huqg??`N=79&|LtM|#)jd)1Q{$XS~ z>8U2^KOyPQGwEq<+3O?B3zrz)G+cr7^etMQsyqjYu-tM-+DW-Is(<1ix#hi&_qgTt zxE}Iv+QT~26EK+Z@0{UEm1%ByStxewYWO0tlX3E5(ZmUGibmprG;~lEhB@ep{@eyZ zeKAuI>Z)&`|Ben8>elu|nnTfI>V!RI3Yo_;;1F%25 z^6Lyga~<|aRD7HJm6#m~jjX(d`;+;;cXIjl+}2U(!xA zTW}8;x>WCf=@{%^-j?AxxaDZ7zoB5MGtkoGX2mRl~k`!J4n^jWmN z=9bs&A8vVfKev2Lfm>cYI>Bf2hUmZqzVc`g&*TEPJi{#?&>81={QvNr9dCy{%Pp5a zia>J92W+F}DefI#gS{8AXSwAf%)u>Bg)!O*x4f(_JOnQ}%F+>jomLi!lw$}ei$}&y zk-$-Ky65GV58Qav1~o>0(F(sp^bYQf(_^EfkaYLF+;WL>NC`&?0L5R&n3SFrJyu7_ z!!4I6vt$|qQQEghl*6J|AWBVvTmJWI`R3!(!!57jh127f5Bkj^=*(M_gHBlv_le}- zFX6gXHMV#c#*4h%@*#o|Uy_cEz`ETS?ziK(E(vU#H)g8si8w*38dFucT-CzV#WSn_ zGH!V}*IrbeaS$%wYYxWiE7arfUR@mFqHD!j5A@NBPZGC0#m`$>$t|yG!Yxk~xaDZQ z0=Im>aLb3jfQPo4fyLoA{oFe-LWJA&clo>$ZZp7rO5B0&%i<1p3*2(F%K^=E%LmUY z!zg=5@p*VC%E2uk`y3u7+pbMjeiQZ#w|wYZlMy_$xW>;dAJld&Ubl{kHnfggUgPJM zr}+AITyxy=am{hd(_GQl{+MtqeVATbIJX3kxxyW{@Nt#S&n-`LF>?ED;n-)2FfL2Hz5PcyW`#mxtWIPwQJlz^@dAha%DYd{YPd|j7-u~Kf?ALe*W%H0v zu2JJPer|b+;pyur2195p9)lP#gJNCmJ>{0C2jHfy{cYjcbGRlmtxK5JUU18cKRMj; z@hx-9i~Zd4Vn4S$MQ(Zd14rN%k$B%gdYNmX{L_Rr~zw7+W~y7vz=~`?=-iTvk#0>e9AKeSpe# zEJww$Nu@QLcG$8_s`f8!F~>x~co=5{1?A*4)xKAY14qS5Sl4&vRt3RDt#R8A8P?o9fc_j&i3zsNIIMDaR>Xk zr=`YHss+U0?eZ1WAlKkBA;mvc)byfxf%t<29Y z*Y*~;)c?STxwKaBOI2&0stO?%CMn zhb~m4d2V^hGnh_kiCeBk`MKpKd(AB`X@Og=?K!#SC40>+m&vI;;g%N{xaI2UgS^{h z4fzw^_>M?y7J474r3G$zjMMCFihbdhmlU|=c)Zd-FQftI1#US8=>HtIy!b!QEibvQ z5lv9wmV1vSoJ2LC@B+6S_d313D^mv6F0+FCXWFU2Emv3d@tR2*hYz^=XLRfS9gp=u zQ!(T=h#sNvWL(GeGk)etSYB=wxaI22zFq_QT9O|h)D^hp>@A`G___z1?nJhY47a(! zEswpqQlD+T2H@Q}Hr-IXuQqKYB=Q2cJoXp7j$x0QJrM8wvFV1Amxv5j^26SBUESD2 z-SLBf2PkzKL>E|LX6Pz#%h9*&nW!wc+`jOtKLIOy_^t=PZ;E!@|J-uRK{f|zp3QLsoam#D= zgj=5Gv`eSXq1Z!c%^n!AahepkU*f(5$=x#dj4a?5oRUiWCiE%zni zb&n?8au!l^$i42-gj>!mEw^0K6wbNr9!{oZg{@}K4xqlbd-}D?&jSGk>dgUnWkE*zy`*ZP7*>kks-yX*P7`=Zd z^^@9QI#3n8Oub<@%%Og&<~V$j`e}OqWDLPQ7wY|~SoGa954XI`3AMq9S{6$0Y|9nm z>0NmCO>x>I!!38oEg!`-oi6`1%PmiRO1R~nRocbFK%X6QW3a39(&I%PbV?D_jxds za^NzlJ>{0C3*2(mHzDXA6}_XgQhk$};}d-et=ZQVPdv)66Z)palZrkz9G+tFq@(Yy zf~Q10mC+fv=jvN3o;K0pSisRYEuQw#XK<Kks(n#1#WpPjO$qwZaD_5yxj86s=zJBdgc00Dz|*_{kWy7sdvdO zpX71N%hJ)=7|YAju>&y)-tS4={q&ohz65t#pE7Q_%az@3kX!B+xaDz@$L2@lGjTas zCY}Y+stR~kh-YCmfjQ&;M~P=qbS;20{nv|Uar8z^di38Qo+DK=-12^ld969EI>;?| zZ^zx9aLZGCE_8$3a@TUpQ=C-jRN$6JarKUU6_Z}238#b<^G^b|eB@`bjIT7Vf83(e zxef5_6Surm6K;8@ec_h(yL1^!bgMMiUUJJ_%Pp7Rq;f5{+$FbMeyCY~V%a6PTz)aq zwcPSid>v}J<%Xb_;g-96_3d)ml1py6OK$lnzSwp7FN<3~>Eq>=o5BXU<(C^GwdIzJ zDw|t=hhIf*xu~+a`OEf-2==@BNvZZ+C+%qJtTR5<3P!Z9xuj(MqY%u9u1UMd{(Qq3_RZ8_!_FrskG zOIOxm_N!Dl=B2_hFBOh?sc_6og=1bS9P?7mF&}L?=HFo=!Z9z^9P{oT$Gl|r$G|aX z_Cbz$5{E%t-C*i15?`RbWFLcqFbOF+A*{qQh}gPnePmne$zZhmEw*ix^pf_<}>2t z(5vKybKp5tL(rWy0zsdtA?Qx>n}{)NmJpvOJITKQ`8w<{@lAJU7(Lk( zj6RbwJ_a!QGpKqz`O-u*>F5ZHS*gM3KVkm)!RV;f#L)D4s2;)SDeUA2qbCDk^ke{x zo(zJ~yAX`tnW?o5M!y{;j3f;hoh1Mmy$iwU7cjmbjGhdD(USo%dNK$`??Ny-LAd$B z=*gyF^v4;&fYI4i;mZp~PX@r~$p9EV833av17P%I0F0hAVD#=dd}$|X!00?Zx;se& zMrW^XaFPa$&b~Mw?S;D*fYEt)8zV^rM(2TCA4?iAI@|BmcyeqVlq^>*!vjLT2y#%{q$KfGRJxl;=;`0yWowgoB2zKc<1_)N{v z?rv?d4?*i5UZbOoWiWxzD%Ni~g8ORq+)VIVWH6#jNC4RO;w4?5=~S`yx;~O1{{`{mXH(TYeq1C>s55>Y0Tt@k ze>3iX4k~71f+8QCL6QI5W}3-aYVAjnzf4i4X{46=FgM`{O!~UYIc8U(F~$$u#=BT%*s+HTt}~ zDf+y;dGvXC^XT(KBhfX-Y*Izn*5h8NXEpLwMW4sRbEvm4#>@YE(dRScMGv<}MSjuo zdQ?j04A4|WpBHliqBZFA;*Se`j>DP@eU8>A`g~Tr9%n;S^!Z`K@oe5Eq0WM}cl~G# zW$Zh>f7M0rMS6FdpcIFSc<*;Gqrts2D7(oL=f!18J%m_e3+VF#`Wz?3^7xxL=kHcU zoyR(=Bz6E9=Z8N~2TQM#{;fct_qXWt{;fx!7hCjsxkjItYxH@!MxU2!^f>~FKJStj zeLf%``n*eC^tnXIg+51=Jm_t3pbvQ{YSz&mMhFTVbe-gQSG?$bM$3f z+!auT%eJ~-5%=>Z{9IRlroQZaSAJ%`>;hMQX1?r;uKdh=*>+ccX1;8PD?ck=w$qiL zl`s2>D?ck=c8M!LD_{0CSAJH$?CY-ltbExw+)9il;j+u!A>v-?P8RoD?i_KicID^g z%f9Vy6aRPIE5yCVy;I!px$^V!W#4yqi~p_aUrV_^-RSdy27Nxzpw9=j27NyGe*}GA z(IWa>D?U2(`P|ZRfUkc&JrFln1dck#-~*UV*g^|A zhYvW|JzU%g?gnuuy8Hp^meA*eeCYE9OXm($ZI6spFKqi-s>4_Lh}GanpD%g}cfxJY zOjW8OxzOhW4f=fCUZBs5`387=bLjK&&7sfBT7y0>%a1-UYYqCmtTpKKveux_%W4~1 zMxU3p5`A7wY)V;v^m$ne=<~%#9ecEDe{(o?;54kjW?K6TeO}T!^!bsm4F`90YuT}l zxP~~9G+sMk3vI@enDbfuQ&l23GqxMIhMi&RYt4K+ZOrG!UITf5JWPiN%!XasGWxv4 zk3KK)qtAd=<|x^(B~z7^m#>d=<|w;aP7^9KCfsFeO}QV`n;k! z^m#>d=<|x^(B~D+q0dYF=<^DGdfzPid}vGP^NM{ypO@?b`nPeLf*4`h1v0pBI1X(dP|~{0gNd^!Y@7V)fCW&r7(3&_kau(I2nW{U~*CTYPS! z(dT1ZM4!vu>7Jp_2k$BReDMB3pD$&_(ruS4Mx}3wy*&kQ$l5721e*r0cZ3cL;*<-(=0?^Y`HI`Vjn`3&XT2W`15_S#@9Cc;*VO)Snxnh)m3JI$ld zmrcPsq>ev`t-{y&&cR;v&`!k0xA}Y#H7+0eylhX<=fxKw?Ev~*N8g|5^RoQt^RoSm zK9`yEoal3TIkwm6bD3ms8GSBa7v)2r%lB6K(C6~KRX+6ja1VW6yszl<<!b%Wr#;eNx2Poi0!I>dkJdV*dcAGrdp~H@Gsv8IBJoRoN#5 zeZFGln$0S`I9$TT6kG_Q7e>lC61%=1ihf3@$jOlY_vj z2k`|t*NXIPi^b4u&z)#|r*r^7ekFp$_5c=?9Czh9<2wdp;0dQ=XrQf#pV4-!AHrYg zDE`RM=b0ADpwAES(C3pp^m%Dc^!aZVD&P!qq0eb?o}jsVtI+4a7b!0eEuzmwYT4FA zpFfMp7JV*dvTW-n=yNHUjM@S8Ig_yHbDf08wr+wx_a(s(Y;&T|SxAjO@6M}VF7!FG zwCHn5vjy~dCQZw>Ci z3g~m8kbSi1^HDj`=P8RmFXpU3Du_N$S@d}^r~kVZ(C2tB@X14;kMN_2{e459 zcWZ(^@3t@K^HKYbK2KTnx%{kE%A(IxM4!uVJ%PO6ZAQgk-w{>Pejz@f|GHd zk({v^^FzruF_Rlk{`C~Rl1_F&;gU%Q`)=}20AQz*%TGg2$ zpTU~l zyprXrLB7%wV^z@;Oz7FkuuWy}Aupcd37)uv>gVy|2iKgA(4+w4lLCxS3NSt? z!1$y983g&3dI#Q1(5 zF@A9WXPJs17#{V9rR~;HRVGf_WPKPg`M~vrgsKb}BdoXvy9WKM} z1nx#UT!Y<-+>Lg)9=nHdx2VHy*qy}Pm@4XsLo#G?h}ox?-UUmmuSlL1g?@ zkj8nird)x;d51Hse)wEeV)}_n4I9y(hg-Q}oMXdAO8=SfxJRQ-!$!qT(R{PSbuQLBlebLOLZ#Kup?j)#pu7U#N(&L5AuPEFFY)iv07 zu{f^5#*4{ugV^}a#KtdWY6crGjisW0T#w`qiS0zvD!KuQ)*l*qA0>>q1{=>3pyfIf z8~=C}qM&k95x)hoU{ zREF;9VdL3V;WOBHsdMyoaFFUN;!+Sku#Zwf0AD{HpA19tzbWZ|x|g5Qjq{yj%A)S&*OwDVd>+55{DOe! z|AlzY?HChPVlHl&hQBSLW%x|rguctr$0fA47wT|N#W{M$E`@!>p_&yxkAi!Vn8Pcs z{wFONdl;&bZM13|RnK8CbYzd2%SSWvPZR57w=mcCTK^sDdA-p8=v8sXN-R4YcT$(h zXFv~7BwzVtKJ|%>KM(CQNfYW{v#Cho6S4DQTO##}EcVjYrr*FcCSCptvS>>ai>VTi zpwY(6k_bZ>YResD+#g4qFzy-OS8ks34qL+!2`kh|#d#eTuKm~y*M65RkJMTs%7`Ic z`;jxG40lnKX+;rHt^{D;paJ$TP?X&&ub_IP48Z<ixRJMFujs-)icWZ}a*o}4{q)OOr| zFg(2D;n`zIi9d|B3-7ppc6!EXNG~e4Y2h7znw>U?`-$j@P%ll-fzpY|00sa2^Z^&b zANTwV(tpNpFgS^%&gDSTEz`NJ}t#i_slYj3T|2cEk6Mx?wMM;FmjMMid)82W) zL1~n_62I!szk4w*qj}@%)R^eb0owO$qx@c*k3_ z(^sAd{{dAzqry8boRj_Ol@q2)i2k~UGVJ+ITd#gz9)V>!IX-@t&H*0lVzrsb!b((=>I)AG~J)AFY^ zPs>mL_tNsGH>KsHsYuIrTT9D#KQ3B64l8N-RV)}EtlRMJ1JBKIq2nFDW3k(BXDLFj}lLP zv;;Q<1zJAZAQvrv<^y%G^eX8Wq~%K=eH@cK(nrw~e}MgdmX_bo((*;fi>U}JRGedC zQ8Di7N@tgc!+dzeJ!$+3DAJmipVqYew5H{!H7y^3&C~Mx?>Q}BqU;$hU!vrqn^*8}7B9aRlrPA9P0K&*@B%F#!&=$Dt4TPoTekcJRX(%bEX;kN)wFb&swMVea!4csw?N!U|-oLN8vcZ^~5cX3O^(Q_jW+%bmwW!SwQ+ZSly4v=K{ z#J=oDn{fleFXpfD4BA?a+Y43E#%ar8cz~hh4=}X+fvutC5Bj)i`4y7ky4a@v_{JBv zTAQ(j=CJ(QvLUu=rBdf1^vj;bS(-5)7dr^Y;To83ux6s-P3%oEwOXlrV0zS=S2A|l z`FNbFI^&>j_*f7A*J1s;RY>|;(Ht$m;)#h!Du`RH+8$fq z19wd@&GF0*b5ut(Ps^X(3@zW~M^)jf+3Bm1Bz7jWWx$-AwEXJJE72J3odbs=(;nZL zfZ?k^%SWRXX!-kvmOr>a%ipiG{DD4N{#=iiKQA{efBsXrR0u79u%YEw|F#QG_5+;u zyjBd@Gg^N2BY4Vde|WefKjoC)OW%81eraoH`K9@3`K7I)<(IaGmS5T$T7GG5L(8=M z()_gi>L0V|W`{d|Z9JNeg!|I`wEWT*X!#4WY5Ar5iNe`@R> zDDA7*-oz$Ee6_G8TE32&mzJ;1`%KGE`DytnKP}%SEx)WeTKX!-K%6Scp+d8krkTi;fu)Lqzw zTdZWsZ|(1Qhqdu37@o}-o1^8Y{IvWsuGVOlmOo_KCRO{Fws=7O0O^k}$L}j*)9_># zOO@>dEkCsfwEW^0X!*r0(DI85wEPMj>jEtwjZmQF7ijsosN<2bK+DIak9UZE{{72N z?7U9;!m@v8`K9|#%O7fK`EG%hUqT-HM@Y+0an-3u%U=|r<(IdXmM?dwxoG({j~#`? z&x(!3P4-6A<6>+MchsOgrR5LWKeYVC|6y9b+y)hB`51*-L(5P3Y58t}mj6-H@>6?4 z%a^CT{YA@{%f=^$mS3EomOrd{TE32%pO&xft)b;>Wou~pTG?t^zLvL!mamohY5CgT z0xe&QTA<}?Q46&E;sP!I-wz!V5O}f2k<;j49)8hz`KZdtF8=)PVA=yA zpA?MZBgg)SY5A%DJT1TYx<>Sa0xdt-l?$|doH`qN7ijr1#>l_SsPU1|^5x}LftFvO z<>SOF(DLyGyGD;kb_~Mh>4ao#@FeqV0RsxOeExi^W5*-YPy)e^xUuOY3bg##WPFCn zZ>RgC_l(4r`N;sozkkY&xobXRTE2bZHPq7b-Q2YNBQ-6*A}=jpTlR&Pzoa=@zMDlE{A_x8`> zqq$Chah}}(LN1bXCbGjfa_=(yQ>FQ7`K9@3`PKYlsna(dAtP4vyOmDgc7*s+y%C=c zce>Mwvl-Muwbl3xzjMDy_-sdJ&U4c8<>lC3)AD7K-J|7K+c;ZkQe+OEx)WqTE5J(dbE6bTkX;Eb=>A?`7)*J(emZD zPr9xeieZ{KtQ{!TH@%WM+|#R+WO(#w`4t?`yM8XV79Zo@3CSZi0+Wzf`g6#=qvh9I zTE4q?wEUVAW@CZSvIDoR#s`|X1gyqDtbc}P#m7m@cRw;(ex`+*qvaRpq~%{XAANOL zE?Pb<&J8qsIP`09$&8$h%V)dtNNgllwrt15-3{1o!4|q%q`b3ek(Mt~i$fPZ&81oAiXMUa3xbkuj1`e@1m-Qu-wc2)X?%v_mY-B{C|;_U;5G0 z@=Nz0Ex&YMY5Ar9d$j!jXYWm*<2tW1!CLSW8wpYbxNiVSQ4}dISO{>JK%hv1#3mF- zf|R9Fp-@;vpa54D2-0yJhn8Zy-AOFPNq0IOigNlSbJDWoOr}q#<+La1bY~oSP9{mu zSnf>EoK7OiouxB9aV9fy=FFMz-hX-jd-V#adH}7BviVR|@4f&1%f0uz+kapBeOxWS z_F=XBht=|-^P!GUsnzn=E>bOj(_{6a(4jBypg-R~9tvfsUHT9v&r?XAzR!QCHvf;i z9vj;9C);uN@9dyIbkpnRZu+K9|69I_?*5j!Tb|wwKgXfhchDdD;m^(8^4Wa)mp9QL zy1V+aJ><})ufbkF^anfW58b_=PSXcIsMG%wUqyFcFn7ymU)zeizrTb2&<{7w-Ok$w zHt{w85C5Sie$q7ITvHhuKs!GgZlJ0o|J*e4zg@)eE7NrDjqpY)Bl17G&dIuam4CMn z7yMRu7u8DsFFqHv_*KhaC#&VJlhyK1eR!+o*HE?m8h5q)nupc$e*o3;Px)5MuQAo~ zYbgX-h8SvqM0o#I%Rlk{u9kml`PK4kOtt(Pvh8Y2wfq{YmS00| z-Wm#3)=;(l8uGl>m}>ba>Ffr&EeB7$s-Razq1!5|j9)|fKsB^&sfMcM*U)b#>1+*O zLNT=}3LaMd2CiGOTK@0+D3TO?isKh4h`-^l(4`ubr&8T&PzCY7kDsff_f@5CzUrvH z>akFRDu~~RpQ@w3XijwZ9bqV)P>*GlD;0o^Rxq|z8uHe3& zE4Z)!_c$rma|QSHvV!|*UBP|#HM)@txUU~;ggDzj0r&M>z$VLb}qdu>$lTKRll7+ zs`~BpQPpp!kE(t7!G>ogUwy>bI+T{;IVaHN$HCMW{j5Z~s2-!1}AJ8dUvu z`RjjDzgE#~^OX0Z0iJTyNFQHU(;;i5|K>G#I5uyM{3_0Jjr5Lfs$lkgs3;xV`AdcP zYh2c`gTGXXwrB8VCx2NjUO$5`yZFmG@k90a(#T&L(CnT_6&xsBBfVoU{~8im_>ejt z8<>^B3wr$(%blps*wI8bUjr_?>JG-)sh7T**Z@0m#}DhHjIk&{3RlO zrx#~V^OtByd^d$}hg50r?aq*!F(sw$9v93QwqdPh&quhZDLKzhd|{_^QMDv*9z zo(R`bee_;=B3wu1(fg{tggZj0Zcf$F2dF8kj^6RKoF-Wvy~D1K-qBz2U(mgZI;xI7 zR6$SI#nJx--A={PJFZsCS*GIX*JQ85byORDguhgU>!>vPb^fwC9OBC8@6z2oXuC3c z$8+3NxQ;5LC#q?HsxbQhOV@vkNGbIQ(I>u9Vf2pmRdN=nFnUKlfBAGB6-IC18pWY- z9o0qOz+bTTR2F?Be?hOPD*7g_^SwG;M@7*$^OrT@I;x4@6uklZUl*>UlIRDb#0>kx zbyN}kY?Mg&DKs#Sw=+bE?nW>}K=^o+7W4UvIx2^LBTB0_U0HVubo+di=IfJHbx$_p ztshYuzN;2`M>;~xxVN@L))ziVb?1Rhj&+aAUX~^AP4wroy*XnY?;8DmkAx!zH+>+G>~&bh)ZYKKMnzu&ln_O6UEm zZ=X`tw=d}n+$F?cqMx~hIK8|kOi(KiU&2#l330xJPN0N1LBXc~c>#sEof6`|MooBb zq`O00Lj1TaA^sh@$QdrTPWQ-K;Ad1V@HIDFP4V@7;9B53Q9S%=ss(;Z)&f67_jqc7 zPn>%hKSo#m>z|Ufz`Z4+Q41VGoNIv}rCvl|{`F_M7WhT_J^J$3p5=-A~~As;X1NbpAgj8dNQCVo-d4wn5bbSKps&Xrx--)iv^2-+6YD zYklKU)zP{066L1;+qa=S)16RvN zQ>+~|g=#nBGx{3p0Y^pXPumuBsw#A{_EhbO+Rga2;&AxMEzvssAWqa~>U!#1n!=~I zjMay6POJ&>8C=>^e;h!uYNPc7mdn1kr~dR7x~XbysJ5w!9$0Noa|7~p%{qO$)^4l? zt*AFdTAN`m!t-6 z&55<10Cf4ZBe<*TWYaoDOlarm3Aq~7eN-zvfss24(PBo&({_4GN-;^Rx(h!;zf#X8 z_9~#ZV{+AYVyNw=HMwluLET~pu44u|t|o+elhzM!&p4;q=cGBw+(0K!RiMjfn<{IY zDthWqHnmYFc#2PNGILHdent%qi}Lv}GwoTXyQVOUfu_}T(UW=_w_Bt|C!R8WR|LeJ z|3bJaEa|9IuFp=n=CnZPw$n;AfxNnyoSHE2+fFt8W#tJ;Qr+?n{Pcg|r$_kOmL`b8 z*hx!Loo8lgYL*N38c!PQrxIl}{JUK&?X$Lw+a6a97-Y z;{0jb8Z8Yr8~gI0p&s-a0*D(IQK>gsaMAtUaVThN;?glpw$T(1b9t*yn} zIHY`IjbfZn8RG)99=nu`?s(2t|1 zuzET5HQQLb=tN%1zHTAQ~`T>ku#GES74WX&I~HLNo^v`HX(* zdW~%L4tO@0MtsEC1}}JR)M)2HLreN@cBAPQ7l>}Po~DqAs9~G?XAL*oZPKLcc9`p= zOqJZV(?@FT@Zjm$PpmeKE)ecfxGi}kyF`LgN^0m9bjRBUi ztwRI)aXi2c=qHTuBtSpu2J};A(s>RX0e;#B^fP>wT1&6`c-8@QiI!50Cg67g`coRv zJI%1L&~jMk44`)zVb>Iv(yrSL+c8I^D%d{HJm7-u3#!9SUf90q9 z5dzfmRYwW}Dm8?U5QJZML->t?*{~q|8NZVRhaQwPVE3#C!k@DtJYlF%LiqDc1PVko zgnRJO1>vKG5T4QyKITAp+TCkvg8Dq}Oc6o21WNUEE&C_Ut)NRYsws!wXmVdL7b%9J zA8$$spT?7&$F@cLw5{{Jw!Bz(&UBFnT!3|5av3bF>o!;y^ToRJ@{U5RyI^D8Med`Gbv+vE zE)}5rWgpG7S9Kf~ZK2B5=T>lNZE!fJLraIir6Di2(an_F$ToN!2%CfC7K#dP%Jl!VI{@DLYV-gNg_im_>y zw8V}=x;8#ANa_V23sWV?u7J7fK&$P%EpWOuXlUJF7EO|j?7d>U*$XjeaJ)E%2QMfciReN_c2GkZP%dO zVFVXJ@NqW;JD{ngfp+$uv>{m9q-q7d5PaH!U}=>Wu{OynW%u!u24#)4`ILcR#}q|} zBm|#xLvWWP&lCiAGp)NIIHo7g3&H2TM8|4^V{TrMOJqUtMFYV-z7Tv#-cbm_mu(1^ zPF)*<`!odigHo`>1g#h`d1{agCEdq7LG;UDA(lSvVCj&=(l}x1u*3Mo_E&5yy{fVF z8e!>(8%urRQj>!RG9}QG8RxM{4VHe)gQd^fSo)kHNojf}{IK+S_e#02H0j1A8tACT z(v*XxV}(snpW(i>u~fpQ2TP?rssP`NYSN)ShD~?-QcZtBV(Cph#D%5P?mkN_opHC| z_=l7gvSuB!ls0Ug8I#wBT`T#EZ52pG z_??Scwahi7mnb$`Un&-xXR{ErEE^}Rs?FR@?+YxJA{S|Hs^^wnra`okptpQOmLbJ4 z3<-)|QPD>WY*_6+Hhs`N(8ev>-^zyF&(r4$ygsgh^?*OH9xMXU(s}H3^^g>rt~eZ$ zfTSQbG;u`h5=&w+Pi-;iZPn=7#*l4?YmXV>MtIxq##?F3D$AN&5?a6>xA9h@auK{G zQx;Nz!nG2Yi{LHcGUKgd)f&7#Yw*?qW1b=kUOwf<+fGO3DZD*bh__vOw!C=T?dGil zlQ&j?x91JsUhu`+i^cG^$Hv=B8eK1I7GZoPzos2j=yepPzCwuYcOZ5^LhK+x?9&c@ zkT@Q4WEo6Z4Y9)nu~*y>d$nLPEOYgm-${ZikCAJ@2x*C|En-#KBE4ZlEZMROz4+wE z{2=yO_aj{p`*FA%K94$6MBZI#)OsM+L1&D>j4JJr8$HvpX<0T) zh@FrSJL!ekDR-YG#KNdW>IlPv{Nbh>R;Te*vYLX888Xe@7f|X2v|4+;wB5Iw`9Z-R z!Q;wUwLIPW8IG5j(OLgoa!6JiyBqBRxT3$CG{BYL(vt`_8>NV$ zgf1(b+9UxcEE7mbD-UYfo-~%N7hWHLg{$GUn2VUZ&}6!Fr~on%c$Io*>DY<+Gb~kt z9a{w9kI4ylA^L~Ntknqh(Fw3Bu9T*(7m6R6xGwzt@R+#7#f}x5aWpPAXkpIc0wXO* ztbV*009#U>!*9|#PHIAhojWWXg^YlFl?x!DjZ{LHlc~T}?iQW)sCQ9%?{KD zPvll#x7pU{sKqVzm}R~I{k+xg5M_LAbFA>~+9WBG6QvEn!vwr0(RLTZfMwS=@?v9v zl;SK+T&3!gMJ0!|TVls?=?#!snS0to7m$A%q2Gwk_G-1{QLTLVz^@rLo=4+zBD1^_ zDl}{CsRIO`MD6r|gBp9E;JK3eZ$T*FkTG};`zh&19D7fOVT;&%&3Is_MNOfaEi&h1 zf>YC3np0@FDmTpW9rLKLL%x|^kH`SN;Ifch;a4kP`}k2FC}pWTPGlxJ%JS4nwI&0IWPW`3ftEtz<^OC8*X8JJ)UjOwu^$>JWI^AV5 zFnK+oJo4;x7g11RT36zGX~nhiN`!wwjlC(V5)eGDW@*TB_O6p!++!Ay+oT1g5N++r zrhgNnVbeTa)-;A(VeWy&8+|;QrnM#uyN|8BN5m#1z|`!qZzCo3N{6&|WDz zO)`d_rn8Ehnoc!+HO%v;JY+C^)xGuPY>h!G449p6a9mn(E#8`(G9-W6^1;zCM_Qfd37us21dghJ}DUKJ!~f4<^G z(@S4?772J(}ijF1T^9G@-tFCelCpUc_KrZq@Phd#VbbV z$OxD{g8XjBd(FF4n${S@|Kqm%CdT;=O2(Elw10z zrY}TJG_}be7YGy_Rpd5(B|I?fd<sUD@+AGb^77d%Qd^hHW>`OJPYpJGT&3{uo_sdwo9Z zX_nA26#87)={#}D=fiHl2~og5aIV4ZwD1tV;IxL{B-VyP|1kX7yI~9!1!!o<>hYn_ zPdHaIQxM_(r2I`yixw7NEV$Ba6L>i+T|KW*cU<9=p9*XH=}TcImQ|t9PkRO;{XIV; zhoXEyG`N3+2VSV}F(@Rd=pQ3?!Yjs98w&kw_%QSZ?JW$2{t4eD)r+5Vb=mDx{HNg> zvkH$uvi^KnNjgJj_i#5)6hBEnfqM3;t6g_$^L?v7pTK0krurlAr(fQ?=#Nd?dRc3< z@>;lYfEmw1t(9?EF;VKLmmK`jN}xwWwxU4GOT@6J#?en#(q$zf-{Y;4>5WP#TY6iQ zyFWBtN@F%B2-76?uY6u3%gOTMKT`cMxr%aIU6YeUamWT6>=WQ|Xidkf?Hw`t74sem zrK3f(yJn*dm`z+QTA3oH8jrAc>9rZrOA5g;B?<8mVryq#9e%JC4xOBVpOKrPdd@iN z?f41D46v1IQfHY|HIkgtHr8n~QkFY3(lf?PIqPUOPr9|OryLosbc0St3s-uDOk~6a zc*8w14rEmHf^d)8QfH-C#EkWG-Z$K%5;6+YD=yml0ye)Qq;IEJI02vn4Wd`#zRR!J zrwEa{HWFG*bKx04EAngXeV^DCvZOJPNS%PslBF zX5TP2&=~?(BuVooQyEn!&8Ws5GNg-~bPUBn^dkzw(>}c^uWImuyU!}>W5gS`;D&69 z0a=RSi~?+2`Cex@+P&7$R^x@w+U2BIm?ya4bDak7MMCR6ypu1t5dsLtbRQriS9*u7w2_o6TC zs%>|LuzSgd-OJhr^M%wxBz>4r0YH)dO9HSDY(j<6wOG4Fs-ru@V%lJe57rX6T3Gwu z*{mAjO5E)31>N_B&8hAT3JsLFfxy_g z4=mflaI4~}qW*nCb`AG`uu30|ZVhI*ba)O;=Q4l1q_oDv; z-@oTxPz`ORLa;_$y$9YT=Q{@JE-7W$B7s(_@&d|t8;^uql{?)$Wt9~abqU-S} z8!zgJ$2WZ4_6?KcSh-z!i@-B}zF|*k85gcT>-MwKK%djT;e_KGe%{?{?Hf)yQ$)cJ z=|T2HhULBi)k!m|F-KpcXF3jKwgaR=GcJ9@6L^R#Y&_}ivouiPL3SIko|-alIQ8xy z&~B{v4o2+>Hcny#mbEHz(V;;JmQKv%I0IN3>;aLn^{v z))R`REgDmfR@T{m=PJmy$qU9y)-$z9jT+u&W=y8VNSdMaM0h5gl5LjE*8sfJ7d7QR zyh0OIqNyd~bTg)?sS70^Kvh!}1oTuv+b>7q#84mS9}MVOb!DgwZ!z?Hq7eNK=?E#o zDDJZ&q(_Xrp$O?w#l%=}T9Ib6B8rK%%xh71;b&(*Jax2y?Aqk=(Z;xArZu^~OnJJ+ zc3j6B<2ni>q{mH!^n^KyCld#tQk&bC>(ntl<+dkJJMu~Sa*^5S_2r)BF8bJ$PRTZ& zi2{4_DYsG_M2cvt)Y&x5fp zz`N!K529NnC#sx82k<QE6`QF+rb9B9daRAUTMV zh#2~uD&0(rgl?w{^f{SBc(R1PGsU3qLzhUTeW;Xm?@m1SEsRzOkPj_FSB&%hZxOoL z&u!~bZEg!7UwH3rJq|R$NBq2eQzLQI6o&qqQ%`VfsEZE)8S`@RPFO)D{BZYwa>IRD*k< zaN|eVxby<>dr+lJO2g8POQw`!j@6GEVron|Tg=RS(g#~U9CgZ!B-PrI4Ve$EOM5TM z2QuEs`mF^KQwAc~P3Sf^UvQh7H?_+2K7&jz>@CY5t1-_BDZ1>>lKrq=`}1LjPKg^k z4Q7>tn(u`_c5%oojMsgrlXHq8<%iG6bbDc!vN9h+<_8`!-BDI)U`}~)v>c0b`hAL{ z8u|(gBp9PKK&Gn~2#dW~(aGj{Z{JkmR*1Aq^kJqeT;d2K(>oRsgP;gqu>#pEYkInX zg%nr0U-3ijvGuVo&lWnZKlGInq?jaso~nzDT_%Ni`fwAcE5P}I-NflmdDSJq*i@y; z5O$uBr#`~_%p5gf8PtO-Lt!!kxneF{H>_FdKn-4iE}9?YZbC<7oorWER_s>y)gKHT zH8IHd!;TS&qozws<_GbF7j@z42q(R0!X4pkc4Y&#xU+%eE1yh^*vSUc1%@~qNG7-z z$p)eXSCtJUt9KU32BMcIayF2Y>uR!rPMT~W=Z%Rb8|bu4M`&^qVb6S&fK)rJFBL-M zWhY6tS0>5!QIf2D=dekV9Z(S)UeQ6FB>OZa$qu=bWKm8NY1oD++`B@C{Z3MntY`hj z?U7JOgsMVw(AvY{@ZZ<1p+EQ%l0WQPi;tn-LN;Fpe_zJGH}LOI@$bLlUj;7Ofqxh9 zFNuG5@b72v?>F)9JGdtj-W6GU{5q}-^WkHt?-}_UoQ(c|bg0C`E7su<*@;6GFG3HA z6F7vr>FW?3o~6S$9TIfN;~+jshnH|z_2W2H{v#Z!eu2LJ3Vr?W>C^AvQ2l%K>DzSp zk97D`94h~s4k2`7RTUi?=&%ik$~$y8K!+3b+a>xmMu&MEYUo4_J$Kbh_!RjP4&vu= zh@Qu9(O;ymU!|{a(5K&`!<#sS{|JZLzobK?A{1I(kHeaMIMg-KB_bTEj`VEDOyIu_ zVolX&M9o*eA{xIcR#lCN$Z1jCD{88~C-&a={IJ{mL)~japcw0oPE{U#C zq#}Gtbkm;^(LsOS7W?QAPVVj%wb#X?x5T~?vE^-1g`W=firrOtvGuQoz(tYh!Z>P@ za}%qhYu*sy>&>F}t#|OB2)`4Ff=Fn*L^=N!{r9CD5+7wz&LzwYQO^SY5(WJN{(c=) zM3l64btu%0e@s!`$8jdihmS5reH(MIn#gL+cX6ouJ`QV%z}8kFs=sbK9a?aBgy?O3 z7e3VwFTVb2~LP?yCB_h*Z5QK%wGAt^i z3nQZXH^jcG7sXawv^R339;ExbXu7wdYSL+YucvMC*kWCY>|HM+Xzi7%&w!zJq46gC z-GhHsRWI?wB2{-q^-E$uPHoAH1M^~AUL2nn+s8%iMAg@+?Oj#xifCTof|~oHQT1-y33m)%U9YNK{vSmCoLvNjQ$vkw-DG z`=TcDOudM_CZcbOJ@>`I$f1p*;w>R=iPdys+kLSo@>sptN>?{jT^Czl#H6(~h^?>C zUp(}_*n&rFo)^)}qUpXk9XXE%BD?FICSDUwvWc_xbY;n@ z730{3ayi!KR-02lVRP$~UjliB`S8)@R+j(7sB4H(>xfb7h&|U5d#)q)eB_sKSpTnR zu82MB9f&ypgks9bB_{34?}+LzV_CNnZNL1g*!-&4^$O8z%}byVFw@Io`&(kiTVnOs ztMETy$crFiy8fNWxeeg7ja6@n$~-W%WBCp>rMqV4sB`+@^*d+EfkeG|i zy1qqI$A^zDnK3A^ocBWpBDi%#aE}ndt^Z>j>WS(k6cE*IVESWFU_AJRqnh;guNSKT z{*iaZ{u`pQ>UE-?$}dSmtOPYcAgzwptka2XLM6lqliSWSKSlU(Z}Cr0UbF`{T5aCA^RmCyo27qBANh9v3xg0_B@k)$c|hv5dX=Pj|}JBoRBz9_cITUZL$ z(k)Nk7twLSXMUF&Q)j>>4G{d$(O$%S9N_ubg;C4f1wCwLGxD1>${2RNNE%B>PTu z=aKv3B(%(ms>32r^EV+_7r(eqQW)4OsUMHN5W`A;v{b@2jHiRneLk zZFfcYJ+XUSv{oIVKO3u#idAojx);U4Z-|<4vF(P~nit#dii7vW<#DlUoK98Fi^gZg z4mlO8Xe!o_RH>lFjgH=vYG_{UiZ)?+d#di!_>SHX)p;RKi#5IC!h-jg^98^36#PD&c8`kv_{#A{O zeXp>#4tCn{lBmO#Yx&B0Xis1uEXIyr^m3y(@@HblxM-XJv45Lb)sG@~+y{MeFQPQ- z)sY{9QiBezy1we|NG&A#zg7yvtHmVx`f??@HV#R(C$*kbdXn<2)<5}wK>~&O@X?jv zB)nOzUrma_8a5e8qpu^my|!kRQV-UV&c2$&{UeT|@VWC^T0d%}^#PZ(z7KkMk%(H$ z>aJ(RxxDDQE6(2&k9uXbTRLwg>HNeS;$U7paaSCC9KpPq z1@kj3m>*Mu`3Nf#5p<{WO;PFkVU24lfX6)hs9l z9pW!?a3d3Nm?=5M8uczSKFzinlMrKHPVvt z;UQ6nETSe0)lz|<$22{1iw;E8>tDgA`d_5OZ`0vF(BZ$*p|TQ(?R03S!$mrfHq*fB zO9Eekhd8hzL&^=2M0Mo%E-Ti6=A!hN$864MbXWqG6Tr9TSHuO-=J~w1a93QqCmsXg zks`DEMRK*QCcR}H&hLQOCB8T^E)M6#k-MVhp4f4^>b5xYP5$AF@(1zgcSSUse%oP* z9n2Cpm?icrmN?D2O3nSZMAdg#U-=AZoAi~RD%4lDL0@6J5)L9(RyN!h$I<47Z$q7F z6m_2!wO@Hl|0k-y!#Yd{db~FeSpK?*Mh>nQ+kr#WNCg_HCD7dn5TX;XBuM+;3e2m5 zwM=kBIvOq&xO6pLx{ral;OE-t%@NTU-86!h_cuVN%W3a5Ztss>?d`IAzMRHCi^lgw|K8R3a@zYpp~UQnz6>R1Yh?chaT)}) z_1mDk#ur8HYj3?Js^1bPK=AwWF#JF|W+{fJ4*iU=x$sbC0BQZT-{M}bw|n7T|t*r(8D9->K5ect|nJ^CAqpQ$< zbyxou9gM4cHMzQ1vp3PPLD}Cy7NvB09K>^_E<;j#9l0Z`S&cb^6YHPGAVGotYwSUYE{&d|rIvoNZ6zKg?l`b)>n*Tt^uV)u38vu(X% z>uphaLxk_2g|ZLN%j#Pq@)=P%2^$P18JwCEA_{(+gjcnCMASs@kopA(tA^?yy>*YA zt%nyPkF6KgeQg7NGlAL;5UG|IO|acg84PR|=~OrG1o-X!RI zI4||MYC4IFwngHk-g$rCK@VDmpQX!LH?@Txx(Yz<{<)E!z3Q8uUmGHQ=<%8Si+ z#qN9Lgp;2S-xJYa5{F0w&NJMTpW*Yc>c&NM9uwBb(~y3VTpD$VxD<3~KXs^Xi4G0Z zU<*353BJ9&*mPGk-4mN$Ri6*}bZGzQF%(yao_JBLBQh!I&H?Jqx+S`E)weraK+Jiu z<*wLsPi%pol0U<6D43rEpT|^icXsjo5N$;UHi}(LH0(8rLJe61DESK1F!&%vZ{!+z zzn|TN1-h{bKK64BkvGEiq74%tjr>G-gLr~I-4i?M4{nZB;nHO?V)b*^8ImFdN$W_M zkfiyV76=|mQxO%FIQ{$j^gpW#gYmD6rZ-rasMCL=PybO>7!H|@?}&AOEw;YF9($Hm zy+5p^iIF#7G_s1?zoXCpvsGa@abE$V9u~V#OMylG`{(+Czp4lW*$=-XYQHFs;-c0| z@+s6xJVF^UcD$fzXx4*T60WJI*cKlE$lFb)-~MsQ@ORwevft0AQy0-2e(T+bSo$_btdIJv4Lf2FVd!!SLq^}C|s4YB4Do_SbQT$U?D*A4!tdg5R3 zb-Vww*!PBL$kC-;aJQ*T(Y-oc{D!{xO8~G_XtrDSP4)hd^yzP+_tg+;n_p+}!|C<7 zJ91Y&>X&i)Ebcz{*OFufFWmus`hP%L-QyVhVKsg7biY3RWLO-=+2%`p^DvN_jPZYg zwtdw%4j7XWT}rCKp91JfebX@l3K;)Ae%k^i@oD_~EdG51|5$bFd=qEFeE5hN;kA^4 zAoViRver;oz={=nA_AmQ)srFJKsp$d3apr8QnPOJf?C`Sk&D_|g@FM5eFKz+2-yM% zty0vr3bx~JfGya#S3CwKzY-Tg9=mPM(Rzv;Q1~|r9b;?cN(0Z`8`*b)10 z89p-_{PDLzqC!Vp6{q^4#@S0lZZ*ZGCtKP&T-=s(G=_5xfc}639H$oHHy#e}o zM+4f2{}UH|PdtL>!`mL2Q;!$bukj%EU=Wq?|3Y1H_Zy1AYPkCEiN}wM{dw{DUGW4U z7ZCP4#>D?4^6^?jdtSCp^FtwJXMSK2J&GtqC87|1^RxZF*!GTT2Xa7qX@xe6{=MR> z#lyNQ!B;Mxda|YlJjI8HJmt?*#7^spo$8sLJe)N9<5I{L=cG!of!O~lvq0^AN&r}t z=y!7j0l7U*AoIxX1`s)d6}Q6!6d0dLg@u01g64$Bv4& zyf_BM6}tH^>yXcyzoT<)M^$L4(LT5HfAz4J9+zl(4ZdWGM2=H*$ZnwHo@lxxDn9LQ zzxAkS$&1#zqWzv|v`?4uh?b+GIWJo7id}XeW&fLxilcead{^wW&v_cJjtoe)j%v34 zITF5r%dh?5;qs~D#M*p#$lCs_%>i@=E{)5%mYH070e;qpzYDRFa8o8@xDf{Yw2Q(u zZ;GApO%p&a4mP_H83oD1A-V%$nQiYH#Ml}!$n#^2(nX#I7kG8mx8N!vZ2G#w?gPD0 z@Lqrf0(ib@b2kk4i!5*Idc_NoL-k@O!i`f5_cz4j_eDGBmpl(u9Dc$X`t!OtMSr|V zig5x-rKWJOR~&GV@G%OIQ&zx1?V$#;BTcG6TM*Ucj$dRVF@tWnjXVl}Lu3!6o{vI; z^h!)52U5R`$*{n8Yb32f{B!J3U*wrsJm;BMt*@w?N;*3>sjNN|&LJmr9w$TQob5^&*u{(#4uLMeM7D z2kV{@8xgO5S**P)HhzPgG_^QHz6Ps&4~`A+E4?E&;ND5N!4M^HfLi#wViWoD*MEz0 zL-xKx5o`{4ZzO|oJFcgA!;Z+EjZXBTBXVUkJt#Fn3fIL+di0mn#63+DHZESLudoe& zp8tB03KI?}wGt&>z)CSv*od}0GTH!$L7oG80Ih2STmDr>Ji{AG;`v@N@r=xH84@hV zn$h7!ZOOPauCrq#mih3}70aC0lBETq4hZSd2U$Sq^!Uk!_6Y(_bXA7WX@Daehp4er1p|e?XyZ6t*i~`CymJ8VwV2NZ_v{7;o;I3 zWc9K{;%tVZHsGz_(3G%PJVd?=#rctT@)_(sKxi;eVYF?KL*5({?cyUBR#ER5toyA{ zqS>Qok>?KFbB$bbh%!FIQAVVLC{i6AiMQZT9o?~)eQ+EbbmJxh6w=J@; z(dlkAg$_ykGxqd9`GJT?Egng6lSz$RkmeZX!$+4siz;m#`Ddk#ZD~JBoqkhO>aYe& z_BWS6rj@XVU|NEPKyiC}L9ZXf4xO{~&FwLU4f+^e$ch-dV?8ofxur>EdkoDjeI>48 z>zJQPR^(Q4NkO))zzMvGN|`#J>Lcpp!$a!y z2XLlNqSJZ~hxqApmw#WAs6ufmOP!Di9JyjY3B+Qd3}kc=981pwC4EG8Zv?fxyNCmq zXp!8(MU4UzOz~W~wHLdDT=Z>X3WgkiM#U6JQT2`0ajF$1zLsL${v?QuVs)Ave-Yn* z8~?tKe?*E$kam^Ezn{}dvz-e#6XwH1vMeA=@;%BdS=KAr+$HhZK&er@gU9khe&c`9 zvZg8elPxQh@3%w4A~cTpA*%;LS8NW8Uq5JT616{xRZOUk^itOf{Ft*!eb!40}ib@C_ zqJ5a)k0T?1Oz@O6!Px;6L2kKQRlv2|A&(Ks!?U(U9@h>JwzB3A|jiJ zF}GtJTj@5B!|caoej{=nXjI$Z7L|7kV;yJ>F}#xiowuQ_5CT|{PEl>z*hOt@dRuJc zt$KW!;miv1JCR|(Spmi3ey59`VtIw-q=T{UNJ|W4l8auFA#WmX<5;x-c*5qhz zER?v>AJ2Cr5~4Cbc~%y z^d(Z+bTXfg4b9A;8QI`?XnZ1_Pnqx2A#+_QH}#2hB2Q1ed?JyU$jtLY@$AfOb|yKU zn98TK$^2}#XYg|ORIpyfVsrV}E$%}ul%GjV&dz5;iNvks^n5z-P}`?6xpX!k>tDLp z@wP-P);;wDdlc3Oy_?EUC8sgD*~IizE>Fu7xC6(q1i5s{LyezE1b$TWaUzY`42W$$ zl}{w+Zzoz}Gnl-QSpS8d{#asQFxDTB_a-_AdlFqk*9V6at=+NsBBzJC+Cr(x>}+Nh z6G6l@oul4e#w>N%gq^rGm0s|t?%1*P%v}BsXeiM$keEqkZ>F=0JTczab^ctz`N5%q z;eoD!-o$WkJQ0r#U5yQeGTnDF$(gCt@YGCtb{<@S=2Np{>C~-!Xnrb_PmCvX`Sv#A zj|6|8PUDB;^t~^UOXm~Q>C8lalJCnUZ>1CI3^Q+8gKNv;E*e{zlX83}c{@SuOZUbT zvzbJ0AvqUH=2CeKCp0}hHgzkskjkZUbD7ZeY$`dO#=`P*q`2sAqdWT&$+59)dYnE% zN?@cIxEynt9cpeLpUR9SrZGj39{I%VIJl0a5G{59Y1Z7z?Tt@m(I6Tdx(rT6dwn$R zA^bKH|2Rb14O;}XX3`6ZOvImPG!*6OFn2*vXSh z?4CSnQ>VE~U1Z5$bLy-*XCCjIX*}C_Hq<$vpPbE-yp5-`x296*#9%U;oJnW$7t_;o zG!VHiNl@qIIP>sQGI<#yc{(-?VLS)==O-6pN*m37jKu!TP`o*~NFh*~na>j_&0qnUg@*>pA=>K*JFi4PCqk@H#b$@Kh8#!+Jk;zH;U^in7) zB=!O?&xyJD++<=jnYyXe>R|Zph{eQ03Q81<=u%f2%S##=>tX?|rH*WRZaSGNORau# z;e%+@N@toeI24d^v#c6Q5gmA0nvX&;981H}oV^p%g5K-cXqOh2g~&yfxS{T;A>dl* z*1{YdC3&c8Y;^|iUl8%YQ$kFpH2i+3_mI>1*_qK$HccF)2rK|79+R`q9L>{J7M&X1 zM(g0&^sRI@mo^Tb)5iNlCXmPbV|e>PgC@+R(fGntJ~i2$o=)e}tWsnWsa#?%n@*)c zE)08+2C)C)PxnGtmd&zlB)^D@NcNI4nGR(x4i66wPr`Mk?e_o+)RD?+MSm`ypHB3` z?{gKN3a{>Rn$1k}tC?G}5fdX-g4Y*`_>Jz(a-XgJf@Byi=OTWjT>7 z{sCE$_mF@pHJOHys2w?FN`DVe8hJ(ys|8MvB~r<`WNIqUCT>~lXqn*XvD>5QkPTU= zcgB);h$RML(FQ?xi*{${q{sI_NPjwLJ{@8m<$O|)# zL_t4zv$-Xa$lZb(OG;OkbR4pHyC_`243Wr_B%05V0g@hT08Zwd|H` zZaLnlZ)G7AL=3bUf5VRJDUwH%%o?O`dk(nP2Gl8M(e{wk^z$S!8IOu+Q|*5 z6me;k1T}9ge|aFcvNi|Yi(k41?&Id>xtEqh03vEnX|=(Kf^j7ZM!VBVm@J_V_U40E z$)7(n7s_Rm@Nkg7Gfj4*cCZ2g-~xk7Ab$(t3HF4QgOJkk43QCdC=@-Ko|>7;!_^Bx zle+_nHa(rlP0wZ~Wbfxjvo|4(^U%!~;F?XP=kik+AQMA@YTq)QhXg^y6MfX ztx&7sdBX6aTTvWFwg%t{AQ)Sv-NCXU!0jfw1M((mME*j?vY-uupXBhC<$;m7gQE-u z1ezHrTLa)&7Kecv(B3?4YFu_gsj@hZ93RgR#Eu=JunDT@=6A*>bF%%&-~q^h2;{ zTuaQ3zL1s%e4u60x=OKt5^nsSdp-x0p#S$8yBOeB`BSPc(G;|TT3@A#9g&s?5o0wvCGKilgbw(SSr3B#5l6wjk z2HO$k5~_A7XVMV$b{r&_fI2pgycWuBqJAtf`@yYYbQ;+|x7Zan=W>PNv4P0SZKOe% z6x9-25;1ZsjDT^Od!L?9Q__~q!O@940hrHroJeefbBQ^K92toViE)IgNH$n`H##W= zojsPYcnk#A-0H9#zDh+FMir;MaD1K=XT(`}#tQVz=H~RrDeZ-c3L57Nq;Qr?TYixM zX&8|8I~>xPbjl7i{+k2Fvs<*y_r;h7*eCp7wb4%Y-)YAmjV8n2P^+%eT)0NQBJ&5vT(WI_-kktC685uhzlirdA z8N>$$ku!tEE1dadkd&M7r8-A4EJFeY)Ot%L=>%HPxn7E?W8S*YaqtL)@xXuuvO%VD zjC4&;Aq`DBMT4)Am8bxTpftd_dCQHt#89B92V(=I7*jr*d$QUR+T|$oq*d1ARE(KM z!1{Il1c)Ka~f%A1Pe=2!ZN0h zNkLhVQ{z*}o-|&W08-b9KLwR*61LhB%QKTG6GErZDW@ar6OJYkWN<2JkkSdD@up=; zZCS2W%i|YR-WJBrXn^q!skc~sR_G#gB@WZ`mr|#gID)QZ5GNG;P?W^ZS>M5-v2co( z5T)^B3F!tqj#=yj>ruLQ+AyL!ULHz}PbVjGEp(+sCKCIcOPzya%v&kO(xdYeE*-X& zvas4IHJg-M_(&+^EYp3o5%kQnS{@9NDjbkN0!{lO8yAAfMvoxyPmcw8N#?vYu2VNm zf|)ZFG^szpxghSg6~x7X(!92;B5reOQK3Sw&?_hjM&@TA(+&C93GmBoGLH}* z&zMdhK!=T~<-2P}d#XmdE_M$2>3dz-J9FSA9bF31b{m;uQ9P5sNEW|;20!vL3Nrhb z*eOtM`@BDZRY(9odC8AJCto?hqAvLn>6z^)%ZN zMsrAvMrLt_oRkZ*+29*14Vuo(5HJ)36)8+kb74BqL3fygK8? zwztsuIMQh+L!;dq@k>z22AOl5+@kSp8nQdb+YN(Ho)2*;rU(eW+KD2g6+RT&p~BeY zcayHb;NC9ijR~cmt35qIbq4Kur@_NpEjN~!{A}I`#HzC|W-Uu$);n97(t>uMvn}N2 zCZiGr@<-?(8WzrXsGzi#_ToF+rUnO7Sk(M1ryU0Cf!gV7vUND8kx_q^Jr)xt;83n) zQ(overOt4xy|c+NZqrYusgMw&J+nDJH{k!l#m6yD(}4OHbo83uST$yi5n-d$G&xK6s|3`?ebpkl897c`5#b%BfJh4q zW|=gwvguLmXf%FzMwsQU5Q_(2g-In6N|FrVW{|m`OaTa9L%U^eRx48mco%NUmGZne z&xVk=M~P$0>^kWrWFlerF}1X)OTw{7NZe*gw{wDmqqA`4q6w=7%%_LldMJB1&}znF zGdesm{#DPy-EwQ=haxK)HJ|3tU-ZSCF~@)|g9<9rH|Pp?TPR)Ctw{ z_EU}lBH}@J2I`v=DTQ5;$A&oSOu)7@G)w6?bJN~`yDX)a`HVII!xt`lR|cQ8x^z5D zKY3GSWSj>YpedO(L8gM-&=o=ka~3iYJKVDq_?J#XvBU;$8H0LY>@h|W9TLEhtK+lE z@8vkJ;5wkm3dTG>>ZTTXftxJ0VNzjyJe@^l4n}#22r^0l-e5-sp@vJ=6b&P^kbBvc zH%7@bTK@zD&QMa#r(BU~q6#ErP2~+`1e`a@|C)lbPuuJ?+?GLNp0FYO*qn*IT$Ys3 zf|+C!9eElEpw5x;hmBs~dQXyGD`)&E>i}Ekq~Hk7 zCo5r-nOz4U0vc@~ME2QzMe&bgQ2t4OmJZ=^r_$Q6#EVLNp>n=vv2o0f!^T=WatN@X z$Pm1Xn02WXaJWt`0u>-a5R%eYB$hAb0nCur$JuhL=tOjB+Apzskn*h!Xq(~Qn8Vl{Ol_g5};fZ=k*DB46v1$I!< zrE4CU#=QELMp6cdTHaPHLP<0tNp?B408A>W)o0Ab3K|()11<0*dl@U3)?n9@alEm5 zM^z)aWdrxn63J47n?WY}?9FsWC;z||I+Yv4b_QT#&tNBtPC>d($oeg;%W@!WdQ9ax zy50YQg`8`18|XQ!S~OdoztZ0|+%wQ0zt%I{b&*u>fR?vhGWIQDQUl3o z;Jh?)bR|CqHwc#{lFe{mH(A}d64s?>uMN7g)cwf$OzToZfjVw%+NF$k%k|VBZ%>dF zFI`dR*a?NMdIK7U&PV}V*6ivX7)!7`9usW!VllaXGMCh6C~fX49Ux8QdU7O~BQ{)Y zPHtEzZfC#_QxzIvn5hT=B_e>^7C4ob@))?x2^I4r_O^ywTq=`&;4*DE6_O(kIdbmF z!jjxxdFr62rkm8_b?U>xgK)LyXs5GsT2SCdiKNnTQZk-$KT%y3=6Q-hb3ILRreOyi z?6B(yP|L9(9|P&fAD^F9c7FgE)SFcjygOQM>GOqL$BlffxkVxuFR~pKGET}Of#g=i znhJx`Its;w1Q4sB`YH2NaRx~&U}&}#)fVWB-E073m2H4E3DPCIQFL_2jq2cF9g<6`mY^Jh}JzcS`f&TM77eWibE3($(D*r~izCxceDyN!WnR5^jGpPui zrDMt>iLh5JKJwEPmLWED!hcZMPuD49c21@5b64~S`^e7hcw|`IJ^A-osiKSttd;3xj-m1(mT+9L6RCVCOy(e+Bdf#5-&A# z%KWBiXQpRBN0E5rE)^})dFFZxuzzDllQV9RKse2VpMlZLK6-0yiXsD4hd9(?sZ%h1 z>Dddw`F^RhPzu4=mR20c`(sLJ$>#20aiDWbZpq1w7_5lm+5f^v8~ zVvOd+l7B_+4r&O<2qQ=g8_cOV1F8?DLP(!WQ=M9;Ky3iIpyTDd$UuB0YE*c^wE?1N z-Ki(I3=8X&!O5cqT*=N;^4oE(y$3p@kSH7!CULfeHJrLNY9Kzq3>z6J`N-HRC=GNg z&#?`)-IZz!PGo22=O9MdZ!o=(ypv0$KR%ztW+bXG#=DV5$*7^|J6FW#{7K%FATt&y z4F$XSbMSm})Idt?0NqaA!p!*V@z~TUC#2{Vg=V*7%PyqYN<}SESGjTHtADNq-!u#ZCs8({mKA2>g7+h*;DiMxTI*OL71Z zK}B`QJ%(mmj}}kJpz`3$(Xv_*-jkAmilSrb$#9zE8n9HN7P_Ams6+9+Njq8>NFe)# ztH3_XsCdBnvvQw>D!2p>$0uep<%fHG1Bo+o`+6$mo6DmZQoAAoaHC}njgll_{^xz{ zs!~>H8p0Ectha=a+N;$@q7Wh)6u0K`hZ&+-+g-p)OG!QhDly2`$r3VCdae+6Aq9(B zMa#WIheDsSpUuRCcMqVRmn0^0;Te;{bBGEX>K)z0M;W9Muqqm0D*ck!CHk#wn<^v> zfCuw`2)rib=RAVb5(S78#$+!XKKwuN;l(h0n z&*QC65Eb<1m<8PGcqFxnTb3c=t_!pjVr$QAps7E`^{^G-r7aJempUFA;F0aJ3@zm+(fb5UIX!J^SQA#<2S65++iytboi1h^pjT4d zP%S=#62bV+C~Mkab?8=w2g@Q`kAs3l0^S8d@>u2xa0zLovcdDdoXW92Sy1fPK@>GH zJ4f6n(`OhSWQB0bx?<{6Y#m_Io7~5RmriPPj6nXnsgEQBaTqVx zQi^8qo^gpAOU%hV!dATomFHFxgOHOfX{rBG8d~dGt8OW$J-CJw>2J`Xgq{XY-dt@$Dz5#LwMKGos6uR zJ)b)?pCK>YAvSPwI0= z;!vgs%B!s@f3mSO-}a)SeN<~t8E_BMdo-i8nLzqb5f0MHqk##9hz^=OW?CjYlS$LX z^=DxcxNB8YG*=Z0TUHsE<2uBL`H=gIIgNyJlgHBIjr2}I-u{-zCnwzBXp{~Owj$me zyM0@M_^sKgG5InG&X8B{K$KBqR9*tMb3}=9w&b>GJh}_j!`VN>=`9#`hRVDx^i5^v z;o;MDJmoIl#I<;5iVB^EG6R`uq`ou7#QLxFB}}E`^8-VP?id9(6T{aBV~N48#FhS@ zk zqpg{r@9ACVmEns6Lp?WQRKdBY6Yt%_xTp!DlQ`#$x3oD=qWUulbVAM)9yf*kjU~5> zXJBC6q2^;FUA;Y+9eO_@+1V%p)XfzK%a|g}?*&fyqzUQEO@tQI8-+Z*y%z7{cev<+ zLnywUx(QFq#e9B_c3YIN%vhd8Z_nk}g$tq4p24eAcsmb;3aF4!rl-4qer6OTnW4sd zDfblCIK**pdK~6|*CY~u&(pi{tfe&Tg*~scxh~Ga9_`7=evaNb2SUxwvKxyMo@B9E zMWl)VXy$=EH2X9TGd5(+WAj0xhwA2Y5xCgx(9n3Q3olTB6DE_-fy&kRJJzmA4Ow%`T4wdQQLWz^% zOtaQQ8x}BbX4S=SzS4iWf8bgOlEakYHG?-zsb+_HKl9@44Gdqz8z%kckXHk@1#+R%&J`>dC-4; zfJro-Poh9qW^fWjq{w|l3M`ANwQP`N%p)sB*g%5vlIGO=U~W%>ENPN1CbMH)@YFR) zmiPt945f3R_h$2{#e8ZtpW4i)W9CzPXo00QUND4pDHudDcazq)EQ#Ga5RWZE`LsSm zs8@RaN^gh+?@;VQg64U+^IY#z_ktF#_4IcST#FOUA=kzw7Ourf3R+Tu-IpzDOTTLZ z6J8LbUd21lcMkOsKlV=X+a9SvF@)Gae=isyv~ZDM27IFc3W#xdy%n)z+4^uB+Yn1X zHP(G07Lwv9=dOmIA?eAId6a#yp5Yn~Pa?q=!4Io#97aM%Uc zLB1rFptC#C+21`h(9_LoL4hDu;#a;n$6tcbta{e7rCAe<;ZW|{?MW@rSx7)KEB59g zmZoeB$3}+La;uk$pc*U|(%qJMu9tp5nSGsIkme(US83F^HP(k+M6C4r!h{*SuiWLC zmT-sZp-7wj!tIS-gpx(*o9K@X%irmNBpkVPM1h>vJBO}^MrD{* zDtXr^8jN~|8g;tU{Ek>AyvaC9=%5ZJEsFZ+AzaC)C5Q=lnuj`pn0sw(uHMeUf>+Ly5EUEPTlAy2aN_=>rj|n(Cd;1RQ+hvgFU=QW9-6+rz zmBycQd`AuaPyN9Gwl+H-DX0FEN&R$gT z3;_~DQ#_4rV#p?-ALJXOLE|)3h#P6~k`jX{R;-1kI_ATR0d1-7&g)C8kK&YA-?>p$2hYYMtCHPdMS|HL!wUKkzhZ)#u zy?C(-SCa?E=WHoE4DlMf#da|5o4ErMOy9~IX-JWAb1{0~2RA`iCv8}9oC)kf80mXD zq@l!ErrkrZtY%7YgxJE@B)W**J1&8;SXa(p`+EF} z%1Gb^6{s$`k=|J6)iR#hbrJR)gbi56_>CNvk#brx;_cgD#4@~6EiL|P7db%|)O@m_ zhA`>B(9;k1+|a=AK-WMo#D(qDgY65YlBgA43%S$6NP&{4Ww2#rkTfXGyu@k?Fh|J& z6B@bF(?1L@P#Gzqk@&@dVI$+b)8UaH>Xn*WcsW-~PBK*0cLy6|ETTGx4J5GM=(R*y z${&yhfkK2|r0^uV@1RV@6ud=v*&azTUo8kH0O~Er^(6Oo_Jb$~ z2L|9f?2KQIU4>r{aU>uxb0}xjkph;HIrMN5IS=HQ-mrF^AVlp;qP_tpHJjnLXXO*; zlJMA4J-8O*?WE2EkEPPBvx-3hdb)hi7l3{@bRQCP@W0JY_hiP>%4wwsWl>IockK>H zhwo6llk}NxmK=KNjogOzNQA_mnhd>HRJ!)k8A*-+cVev~Eg;8f@)+kF`hY@B*AL;?`s2Ncjx^9};HLWyoGxLgnXzEDgmp!=mzn_!i`Ya24cefpM+OIy9*0P_G6=C5fGDae_-N8f=km z3ij!fiZ1axi480+Lp41eR9ff;wTQH>#kH)92HX}I0Z0`Rzb}5lvEqPz(xc+nb6`;s zE7zue7QE^e7+64x+AsuT%J5>~&bcWXDkq~SvnU;fE&uj2+1g}Fh&C(vpP_j&r_?Oc zQ+Xaq0fN~K{lpZ&Yk?!f8I|({LNm$svU%ycaK6^ zAhp(`_Ixhc0Q`Vv|x2i|;?9ykv=sLwr;onqeCWFv%D$U}dIO)hWv`ELlH4j-R)w{?v zOWOjXvG`-9NLcc*>N);>QnV?Fj%PxVk>pL{OJiiZg@rvgRv&PK3D>%Bu*grZPVq%# zN^vz?;Dx7&v%qN3*N-(6ds_OjFf7OpdasNc;1y_6DznKa12csTHCM%rR4iup=bLTy zy0#Ek!8gCIbkTh-ieFw=y){?bWj^Eav3VG-@Tm4o$MeVdV^8mNbBzAQVoPS5`%DVn zC4`yL)em%S>mo_GMelF+$-u?C$tWwAvyJ9p(v~*?)(bcEd(U|PnX~;zMGdw%g^okhpzyniPJnnp!Zc--LD&chUt#3GmHU8rHjm^$W7|Oaw?{`_65RU5qKoRXo-ckXVLNALQ0%^ z76594ec&#s4R2t2h%;>Ynnu_~Cxyy&TAHN5iCxV-)3;*ST{5hTl0#<7RZ(S+u(ZWC zXce8WSd4e?1Y<0b%S#lIy68p4*L}GXqkA^l2q?H zkLMjk>5wbLh%(7hAASVwT0%Jw-ZDKkPStC**p~$124*dekH%uHnfVz+^<2zdDlL0o z0!B0E^OiI$MZtcI%c*6NRw+Ug6fR3+U}vn?2Lpp9F+y-a{xt7N<$~{%S!P7YPIfa2 zTCCV$-wrUn-GT)k-nPg@bB~kG1X!s_k$3tC6HKFhz2i*sTkSr{-m63zP{{Dmv z5+xGTlR4jPfF4K{wic}PZr=$AwwMwN?cDK|ZTuF>-LR%*@JwmZK1laK^y}_U5547KP@v=TmrngRkLv-m6RaAxV{~m#zyd149s=HNQ0h{ zT$Z$hRw{sG;_8RsKA59E5<2)A!z;@Los*o3_Q=baO z1Y0C-{CDdF5(}~8%22`pQ0Wl0Qa$()T!3Q_62pQ~f{O2*ENd2cXOx-=gH_Absx;cn zXQq%%6HKa8$ytOVVV`IX*MFg~fU3KMMZq)$z)$Igisg$Vxqus;|1zZ+Y|BI)e>H+~Xw_ z-(Y&5c_on5x~FzzAT7Xo(Ghe2myDX3@^em3gXCFNg4@Ayp7mUUuH*={;RJLcx~dIY zQFCILZh>=BDN9hCAk{jJ{am8gw@uYO1x;9Uu!5!q6oG&g2a}0ZGsmHjvaiZ78+g-#5P6a->{w}GHilm#5dBlCsbgUKSzU24=2vsl4 zDA`cH=D=m|d8Y?$MOu~WEmZcgO)T~xu zX7Pnjt&~(O1u+hn4LsglJ$ndN3uzY=9xBL+BRkgDz@>b*?Cc$B<2oz63~Qkjhw4C~ zJGDeOFmmGuV!?7o3T+W32T4MvPpJ(Uy!SH@qLp3|G)3ZB3LQs#a^RlhOFrJK;EQ*H zs_u=W^oG*f0tgTP_tmX{Sr<^6`}&Do>lS>vp!TtAGe0@SaW9KwJ!qba72;9w=e8UJ zq@?JjD6;&c6@G*D4__;fZ)IHBD1dP*lu6^IaJ1u;@^e?-<_m_a&HQQ@iq=p~P+6%Z zHpBS9b^w&<^h7o}E$fCRGx?s;-ck5_O~Fn_+?DEF51@=%9YUzcgr>Nro?m<_W@?+v z%usa`3{KUB;6+_pjV0ae6Y1=1Q1vIk7#9ImUWrl%F5f7rJMImIsiNd78k~T35vOX; z`6TjDp!O{i1dN~1eARAP!FuP^3V9~<>zhcWAa@UH`MS9yxYU5O@?9v3gDQzpqVld~ zSpazO>XsNL>avCAdQhK3=ChM0hO0kuRRx>q%X0-gI0=p*L&wU=DBC-Hyr_3LQ1C*9 zFQxw`Sm4R~<{?Z}arjvg;&eF;20@+dEU{=HIBB-a7n*?cwJGCvS=oLGKN~Ta6+SmD zi#%KN=A&o_GQ?qi$M{_a-ZE_{la6vEl#>D8W;s&C(vyx>`A(UWCv6GJl~{|sxyApj zEwC6H^%?b=niXksr6d#N3F%Rg1xSrSS?OZPt)!I4d#T=YYSvIas~<>O=oCR~5rg-Wv%{PW zzu1t+ryacI6La&qNq+4U*wvd46};JY8LN|OAEv;s2(e!@+*V4sw4jUYg3qBOPHp*>-4CyAy<9eAfsPD2cYu@>O=&P=)MYHR zPGRJ^S}YHUVhto#iIfs~D9)T`8JbCFQ7ptY)1?xL`(^Olgnv*a5Z{**`z67{J};e_ z7^0f!-a_ZWDabh1I5D9_Lx3HSh#bt}4VxxduDL0AU*Nfb%iMa~IcWz)6$2z$yB9b3 zgKb5G+6*98Ogg)Z-hy{Y=_ZSsrrcEvll+vIU@EeHR~$B6dNx&a$qGBA_<=lM%g6`S zc+ov?U*e8~i|p;*^dMJc7?mTx(3>GRJl%!K^X4=9I?H&TNy=8!uOkT#w4{bkz| z*yfka&$DlWCAqK44$e$X8(i0Np;Xxm`$>B_v7?gfclGvb+woxW$x?QiOYjtoi0Xdi}tp#791PXe0Jc`3p^YSI~{j`A$9 zNGj&!1gOxd*RR^HxT_$x8XUCRb92+!XS%pUl_C{zsw%%~0H`hY4k`|t$@xP5Q%QyO z1F3K1aB9=M=gdLywzL{7s|2dF1*hRsC%5noRVnyM)C;O; zb0188?|z=(opx|t?HTTzLs1-5Dn!-Z#2|KH&yF?g4|pdusHMO*3qU|p>S0)=o1M5t zdW>Wiq(%nnk|n}cPJOjr9!FIJ!xpB{xsd7_bmx+)h}(`Ct$g>rt}Cieqj9TuvlY7dn^nzY_R zRNP0;3coR%bXg&nQIi;iIfHiw(B=?SWktayH;DyjQ73aBE8^YBC*z!b6mQAosFFAc ziWpfbxxsVzDZx)F8d3+e=xDhLbPK7tBqrTTA3X=04xx@?OGv)`~Rs7+|kXo+D@>BEq( z9t^PD_Iu{kI+XZeKbT^|HsX}tF5+A0U;ve+)vB+64wIgl%iodK&QcOBpi!y_2EGP68Hiv)y>m`aQ>ip(vO-EEIykcB!OI@^fwJ%HxU!|%kZ=B!8I#+7FH8olWA@Q8ZA*dqv^uTcb*< z(N%Voy!eIoc%#uoM&%+S zDnb;XcW4G!e;ozX_KGRF$__N_m!+OQU{2IY!Pbf{oBp&nnfxSr$(Ig20V+)Gk_9-K zgDq14^=L4q3JX|sP$E_9$PAEJ3H@@_IlbL1s7F(qAS9bm!Bw*~A}R7ktgfBc7A-wU zMU3+`oeksA19f=}$6X`K*2-*1hsNo+KB6^~-ew)hyRj>lM9CG@3ZgA{i_!sNsxUcoqxDxC^%iwitm zCmeyzX6zDhVyRA)F&JbceFo^+mzd8?&d%PXPZT}GJ1&DYr)_PU^WqXNrY4 zpJ;sGaZf)RWf@p84)pA0>#>P%FyNJYkd94s=rR(h3qBRrff zxXKtdXQ=+Xy#V9M=^R2)CP~PWp1~)~--Q58!zaQXNUE-A@VL2k0s&5wWd^}fbil+~`E5@{oLMWxJ67S(BJY(` z$!Icizak)a+|DUF5{}svf4yrzPFFT=@q_0Oc^x-9ZsEym<{KkL^tL;UhdsX8ln~Bs`IJP=H5x zn$b5;L6DZ|JghE?zy*|4UJF{ghHQlK=_Q6y{#?MsSMi`?_IaR2V-70-AcKaqr5w^; zEoJde=Zlw;9i_ma6@XN=W9ipcr+RF_Wl>d=Fdixy1v;=e%!j`N%^PJ1bAiTOdOD4& za%w}D?Jy{p+Jk9nWNka4BBuJX`OG}orJtJqFW0-cNOF1*slfhEt&i+~Tn@QZ)7yAb zu|3+)lUkxus@2Nn<^{@hKsSkcK!7C}Xqj9#_H+do&jhu#c zK&3sdbZIC+dPz<)Q?$GwMiS2_v+DgT#iS#CS9DCC~_c4%p?F}@?Xq`TUjmzZhsdAc!(r?22;L5ajfX8!;0?OUKDJ*qQ* zn;|kR51BOthQw~{!FD`YGt$iXu^4Cc=c8)Q>v5}Y-MV$F>R$3eN2@>2P{ab{LWm9%RME~;Ic2wVw%gzH?S2Gjp9JYX zzrb;|?lZ)UB_dwbJjYI9qbli6^EUa@@lgq7%k?;?8Ev^T3KsH`m z!d?(WAp5gSm3_X-CFn~|{$g_;Q%$%riuN4C);$S{nM6nE_5zk!d^%Q(yshn?FxSCaduAb#h2r~)p)9Lj5 zn+z+$WLH&gsNysQJQdR!Lk=3nD!f*)UfqcWa-y*1n}#2-UDAQ{1o#%FnM$+$zOuLkm*zS@5KIi?D>?{K3zD}fHl znAo?}3TQ@o?$M$r|E+NkYnhxUzB^B9buW$4E!*&Qi0}o8Pdaw4ka=}-cx<#df#{aU z@t5yTI^&`Hs@fwtj-wIhirO^a+fP`NgQtiRT7uV$xKwVHm#U4GNJ9y7EF)2KOy8YH z-Pp;e^)9-71~ir*tJyismtkDYzDt?D){-*oYiIu76ek8^C~x|lj{Pr()&mai_*5i#I3VlbBF>d*nC1r5Tb{N)ewWXG9ed_@#( zD8^ydG3h5}adl>hmmg1Erol8s)yzU#8&$%>8%@!XfzA%gct=K!2 zkbAso%)p$20?XUk=_8~}cKEq-x-dg&>q`5e9pM~aGaL;&FWDJuXI}eY8it<@bm2LsEo7J_)6B)rB?lmE?#7q4)X0p@@*H@-5*zSupyIkMR4ie@|X9#+W_MO-) zw8wtB;2-Z;9FGZ_;Po^S#-47)2k*%wT>@mf3BwoULk-p4?!s_?vYltGXoyV@-P1j= zmuNNJ&kA{B3y`_rRzo77ruUP~te;ovSp|({9Sy&3x-#p0co+HH&|aNK{78*mv5mp0 zvWV8baqATO!B2W5Z&Tp@Wo)ca6+PH$5BYT8t+@^Sp6tshM9l^kj~~k#o1BV1Z-b|1 zV1qgZ#A~L2<0=csgYk%)#zSfX~N&?G|abTYD4z?jzR zhIn%#B41m(hMJU9mF>!tls`o~dh!mz3`gCQy0zOy8@NqNGfNJ;j@u4U9=bJVs|GEX z&CQkdj6=K0x!FzFYDXq&-UD>cV~@w>g@sl`9t5D>!V1jG+t}Dt)NNrZ#?j8ZGNd^f zXW{iqbXov*FL4jHv9hxJoO$g9nW3_~uY|D$>xsXU%j6m_79(MMrrgE_PGU(rzIIqF zV>%DX<>FXrcyhcnIYHYI@K`>1TWq}uOp+^TsafuJ(|GrCzB{3)`=%2siMbJMTB!T{ z%#B>h(UITCdZ(=7xEapE!pYs!w>ipy3Y1*t2SneD7b^?JIwrsgx~I<<@MI#}dh@o! zM{ZsjoH-8iCWg$MfPEHnoUSL`-J;$3*7=;zVRtg@gj!recv=Nt=AVXp{pMl`ffZV{ z6%#clH~U(56L5&xtlU*ynOt5$cr6@t9l{1OEBT1UBiCY_-pw#*@GjJ*{;cy>O4hA1 zqBbvcMt^Ntjy!4R= z|9Wi+KGKX5vvq^IJ&_#kg8H_-q|0q|V!lHsd^J1c%*oaTqVu_&)KuL4L~}^Cz3H?T z&7obWtQkf~TG(M-izA=aGva)rV`6vph@8ttP;T^Fr<&(Mx;?M6Dc8!q)(aXR&Rn0k zpoK)~uy=M8{-h*jc9=RChnSPYM>A%}IyY zJm%iHZDP;v(|v>XyN+=nGIi@e)Ri5Vr;CaAVRSLXLN*I@raLcZAc=Dz*DRGK-Mc(P zmJG!3R7Hop$h>(*xE^W|~nbC2NUel0W zAJj0Oe>xR`?$);1Cgi+>RIU_~U58awZ+aN0z7~^$2qcel0QhJ=`WkS}CDYiq$-PZ2eC3Tc`8`@-sS&9~_7kGED>vqG` z*|~hFB-;=dde%+uiPFrmRIW9m#6Koc<&3n96?s=8k6qT04{(Gu@9tYaiSJr`nL^9Y&PY&b9<|RS(+ZaMlFo zEVY^|&5B$^ZdYSA>B9SDb+S=MgiXG(kK4>R$J%i!@>sjtBF)pyg3fJl9>et-E;Vzo zA-eUCEErXv**Qe0WXd<1PnSPjZ=$Z68a@>L1kt=W?kQJYUeA>0>(wNso?LZm;54^w4|#2ShKN0i!-(^v zZ9Fa{xw-WiZ2+s28zd{Gue}meuTULZ?9T@$f?ijR1t;d!S+f;2BnGfFo%Ss^Rzncw z#Y%aRGec-w%|J*+GaN0qxfyJ;r>M3Kw!92n$x=#ms+2yU9oO2;%FQ>&?RKTyIB7af zDRvq#qtgbmTT2^+;y6zgZ;PjkQ=@}pGlN4gsb<$&3q!2f6F3k1C-)wkR(35X9qHZ9bmF(YZ1rd=N^E7c)(6Lr}+w z$Qh$w0n^-|Cc(+m2Ghq!OWX#+uGEB-L9yWsMrCr40(ln=95lRTx+JECEDhd4iA_cF zlsz;!k*lAmiiRi2eML$dg2(cdHB~%5TAa;nVq%>bhjh6YR-?voZf)&s+xh*64B0cq z@e6B@N&h9(E6MsngRS15aNzlxSP(Y(8(lcsPWM0*-s0TDpLpfPoPtjY={aR#Vo{v0@9 zw9!P2<&j*ekv37BA=6FNFpG)Jn<wosZ$WLI$aVze)#&)>42#P~1K}PkRrdYG zQh(5e4D2`h&EUkul*OaA|ODd4Q6wH6B@Ol$UB1BEi&Q-%?{`->Jou?R{pkY9+UY zOgC3sm8$)Tec0)0iwa3VM%wF(sBfRmCI&N~tS$CcmY1V_tL@f4TvDvBE>!oOx#@=Z zhJ)9`NVR(AdidksH(y(6=Rn!Fg2l5U)@$?o7Auv`y!!i1IjI~|KlWAj?%mhlp9RZP z7fGFgsV^3)^Q()QnbXitHHB&WQE8e@U)n|=ZerfuEE|iNHnc|-9B#fVUgM0mxYjP-Co8e96n^oyE*iW4|-RD)T%WW#+oBqI@n&>d)87=jk!<}v|NS035nBm6N&he`r{!Pa4<9Bx8bSb=F(CcV&thnCrj1Fbi0o0c~r$zMiwMP zI6-lTH-cMqj%`!8GPLDH6^QxRRxHr@a8seUtlYH(z+J{C2MIFXGKl9f zm&F+BOiLZ_Fge{37>(p#9a0;WaCYEg z-hl(GT(2#XXqxAx4%HdInI=A=8*$Q=N+lv5r16{ZU{Xi|v()hh3p0!>o0Q>L1}4lA zci^eg02v6k3REdf4dNRTKYZ>ZPD>OH<|*v~QaUoR`}#s~Y39w}CWWataH;MpCgebA z+IhBhG@Z(hZKg8PV4KN|gv(B5tH$l8j2&#hG&YZooVYx=a^mXv%!#doJSVmYik!$P zk&`nGiLNYE$jXF&9I+U}&0tl^LZrbKFO!0{WK=iLj$|P|-84~<-!@GZWbRE<(G=Ig z*OVg7sP0rl?ftK#D0*si3I0aWt`A=N%a`qX@Us7SS@d!j{0GncQtz%W_x|Fg(XPiX z{a=^u`s!tGd2Y1p+s}J&_pV>t{fE1wT~F?Q$K|`;dHEk*9_{+CSA6%%U4MV&Z(J4a z`utVjyL#6TuYUJ6QSU`bAw5@C@C%=N2YU9rK_0K@8PTV`JxzUjZqJ)6>`{yNxIXRa z`Fnku?HT(8$>sW-a)D)f9wpRVn>_!s5vwLRDA)1ICQefk-0g1{e2 zwk!I(AN#ML2Eavl^T1Q&O+gW;4=;*d7!^KxF++AKoC?Xx=NiB-j(Vd9Unmt+^yudl ze$Ip6qVVWv()d$=Q@MMzT=VwT4FBoq$*R-`Kl$@!{H1aad-=Q_@Qb47Mc?%B9|b(C z{-0v}-BDp#@-N^weZGYM7e%|H!wNsF75cWq&%RdhON5LMH8A0CDEwN6M$u(RNAN;R z@IRpNYZbnsaD)FcgWneX{fa-S@Hr1Y2l!@mtt);(^D%UtQ@Br8w3bRAZ>PuJNuX4AEya8pl1SK+MS`*dw6+~6C!3ik@WPuH9We{>7F))n8U z>zu-Ux}y8C>6%lxsi&c9UEw}mb8nJ-48EajUEw}m8y@`AThLW_v*hp7by(p(U1#5t zP1lCPO+5`=g6-K4Ujtn94 zm6Hnh>5bl+P4Aq-P5lkM>k9Yjo%?0U$KV@!*A?#5yWzo~i{zWh|H1>3zfad;h5K}! zeOoqN8wxk|G;|gIt>F7~Z7AH}8@dX=BKSUCa~`}8Xq(ZsuJ}G(=M?VK6}>&1t~rI9 zdK$Xc74FkD_mJdc@C{w-3is*S@ZiNQ=qmiG~uEPrV={o!FY`QiSZt7|1D!fPVeY!RjZtx9Vh2Io>pRPF% zPQ!CEy4Drnr|X=;eY&FeWz#jMa8pl1*Sf-ey5`m;AA@h`T35JF*M-=}NNgMSKWoA#ID`*fXCxKCF^ z4TVpM|0e5~Ifa{g8oJgM?$b5*e#yt+8@kpN?$fp5!T)9px(XkV{0mx7GcO-jxKG#F z4`$P~p>R`ALs#KLg74F{p>Tt5=qh|z@O`@GJoxv3wrPJUzE9UVh5K|xzn4wdoWe~# z4PEOB_vxDZh~#7N4PEOB_vza3;2}G}rLZGh6kQgLO-cURUHp~R4p%V#3!+PEY5YSB ze}44CY8rkk;H1|*`gPIko}&d60gqsLy5+Vs{t3Vhj-v9{Y5@LF0RAC{_eOVCrQA z)0NieX;010|GEHt1n^5?=Q;IJ>90#PpHcw-y#e^gDW8jXN4=VlW)poXfZzXgs%LK$ zsXgjyP4K@dAJk{gtIrdF7fhzk_tSqWo8GG!-Wz@A8tJb)&|dTz3gF)fIJKuW_6d6Q zi2(jz1>pY>fM3>wdR}~Kw4vigvyXNY-28C9ZwbIB0`R*S-WwSU>|2HG=xhN0T>B->A?H7;ocs=|M!3s-&&Ko;{QVc|2aJFOm8ILdjao-T{Kers(Eu0 z;FP~Lo9m1F1NnR~0RL0~{y#K--*|q@zoPoQutT041)Su@H~vK0=Plqr`m_M2dfIIV z0Y@KYeEs2keKr99j^_WYk4gR`7|-;1-ZQfMeINiY2H?j7@YMkPp#c1Y0r-DncyH8v zo7Defpoc!+4&eVd0Dr+VMGimg$>FO2&*J}=2H>v-ycZJvJD%KI2;kozfPWwW|6~CE zMZk%FHa?!#L;f0YnqLkpUD8TXw88oGM*DR>8kA;>z8lED=ULh9usZ<1p5eXG?T<@| zZOmu%ITpab3vjCE2fX%Q0i5{UZbeBp(N_Zb{EOn-Z7Rio)w8qff0p6B(Vy*;dXj!m zpZ5ju&jsLL3c&vnaH_xErjzWWMW_Nau0MCXl&k7;^Z>&Z$@%(_;=i#V_`9^5KNrCN zRsept6d`8^9k@{E~-10XWfXH!_umHwE%}PXPW2&ByL(YCg}vV9Xki zdjs$z0r;JOQ$6j*tmgkv0RO`Q_0g){ii@aKYN+bTmP)k`(>2_ z6AX7LmFL$4;P(aKzZrmk9B|_2`#t`A_-C{E=TCvpe0x^vd5u=>vgc;w4=}tpI{in2 zzpV4-s{;6E6#vLe1phwm_iqI7{|RuakKOXu`rME8AHnUR0EIsWI9RUZ^Th!C?*i~k zep=e?ah*rBd!y$9o|XTh0K61{-xYwrH2{B40R9n%_eS?0k@i$`Ui5_k{`Ug#-sfl2 z^EGHSz{&&%Iiw+X1Kg|NfN%H|vh3!bkO7$M@xR^pL{uIUsPA7#d?N5|Bdl`qp6Qe{r9MR`#~U|XR;jbjsEyA1%EH}PWl{F_|NNl@J<0oCjxSN zH2{Aw0RLbB{^!E3)};H{jI2%bq-WaRC2i4DXHZ({a?VG{0K&dC<$}HGzEY3BcbKfd75~ z{&)cXw}AIvoE}?L)qiIE-sqA2@{aZc=<}jNcKZwk;Bx`^>jLm!3BW%RfPWzX|5gD0 zlow^!|3v}#p#Xe30Ivq%_Xgna4Z!~-0KXn`rI2Bt`R~A|dCDH6jO5dErSR=pkKdjH zc$U1qAppN406!go|0>|c>w8;9m~Fe;9y2>&4mmUmbwo5`fP#9CqnFs=f;DsJ5z$xQ10lh>N8d_f8wQ#2m*9&3LiioQG$U1$d}x$K};CQKh-GOkU|mKA`6rvj7JPAw4ak6 z9buHDzUHcF0VKe|F*Hop~0~jPIRV=aNtRv^8g*WV`6Z8bU4Db@iR3<_Yw+eBTe$%H+O^{fC=dNpOV4{uSuu z3|$vbUH7HFMwYliMB$MTvov+VIL38hNsVmT8CMu%78e+cr!h)7@ae!o!)JOQnM!5f zm~e?(E1m9i|1dH|H@IDR%3m9GMMAJR&JcD`M;Oi}P27SWFIP^HOTuZ~9Zh)&udifz zVy(kbYOy#^-dN+CjMLRo^x}Si33?zNo#~Hf2rH>Y$kj-k_Re_twz1Kn;dr3$Mns~* zrDJJQb?Isxv*z`!eu%H?7f(y3Cr-o%`VRID^k;Jsx|Mn(o*5rjE_Lo~OJwPI;uXdh zv4qKzkhT%%9gh=PjvPpmi$hCumm9R4Any$DH3-*&-0%H|OutjhkGB`m-H6IotKknz z5xJx7IOt%nG@hUN^9=~Yq1G1R;I$2Bo`_qRImGBTE$W>4PIxNxHW@8EL1m37CKGta zTJ^zYig(kvd&%vxAfMAP1$suzoUGA4RxO{dVp6PDEt3uO9qN!85EkV10ri3ZrsL)M zYRa*zb-zMolSs}Yh({9olliG~rc9LMO7-i~1^YsWM!gk00nvh58PSrJ+!f(&tJzvZ zgyC*Fd&%*or3TqJLSA-_`vNP|K~aY%nv}?qj0b!UVTTILwa#E7BFf;WRtxT87prhJ zSZ<}d#33zJh`79gn$%9WWcd`A z#Y{_ebo_$vP*^~U+*O7&$rvQJqB(xLee&`=vCxiO#~*%OsW+^V{Fgu`=JV) zbzve#k!XJSzp0$MD?VAS)h(MG%w%Yp;GK}@12<$>k_3cPN4alp{Q|@a8FxH0YaUnUbTG|lPO=lK-tz~Z-;jH8BZ@KhFMXMi;W6AL6KA)xG9?^ z8R-sH;u|7WQCkzyJxHpl=5gi}I$(|VBmJm!X5gF+piT~)L96dj(% zFy6sY{&L1KrlCH7?1F};!d*WF~D^UHzEaq7IH~KY2quE-tBRtV?|7h(rtwLtv zjJ)Azzgg+%K@u>I2XOAeoeWIjNNwAC($ehj(&uJJSlU-oE@r>bUkw> zhJ$v@kIF*r0D_xBwLGM%_wjjNNp(P4qg%uHBKqzUXR}W9GtRb8OMy*}(+iqcb@9OW)44cJ4Fvsw8X?ets zFcpEB%EpmeMmPx>%EdFJjnZs#w5qBo#Twg@XiE#Uu=HvwY{>H@#^ok0EY)+G!x0*G zU2bQdWF?TueYcO!oIx)g?BCqAs|0jl57Gkz2-;veK>TQOqz00Uv(rb|#OkqABCPrk z82bpv${kI~`1C>bb~UUMqwZ}lc-k#x9-{khDUs7`fNuu%_FLtRZ<*IIb=D7`?Nh;FPbiK_}vjE z9gCKj-9ARf;FO}-FQ2TduRLH?B-?8&g`9~1qpnn{XbfT#hqn8O$u~oX19_sxIg#c= zZRa+#CCpmV)D}lp7GC@r^I-Q&d5p1fgt>w%T)Q&dxj=Zs16wN9uG*?o5eX=~j zFmjB$DITyaoEpDY0Q=Lq8naa&>l}kJ{5i5u*1%15P9E*ejmHKx&MGcw6T3Qc+9YM& z0nQDUhe^TV;cHfbHLx&^@qt7ep)gi47>VWxo#aac2Pi0!!7(fehp07Q{9x|&Wuk~Q zX%l^Caxj|;)JkH(;{CT|1(oV0S|56LszA>m8G0olTZ~SQr*(S8n%($neWk{BLyjLX zUZ&_CK0Am^We!rG?xHMpNJrj0V?iNu-I0*$F|-S!`#uAl^-t8;e;+Qr@%CWnjjt%3(H* zpJ6=RPaPSa94}2y6enh;(`v*YDj6`N$Va!NH^fGK5aLvCzcTw*brO2_63 z-Y4r6=%jM9H18Oyv(xT=7-kMQm=!gZe1R_47E)zot=?50`EBBGy&VuqYhnMHcjwb~ zBs6ehzmDT7;*+ex6)%)EW5gY>3m@th!^$LYj6UI2ksKVhV|QCHQ+f((+S&~XaC8e4eA4=w{C zo|A4)O?E1o{i;FGHL4ZtA;(nY^r`Y)*e61e%@k9Kj*-g>VeQIn#1K9;YMIqu3~!;0 z>l8y2jGr}+%ECqlv^xnaT{L!0PS6P1r8FyoK2 zo~EXXuP6=T^Z`voewAjYQ;LLFC6<`HZ3ut%78R* zCOeT%b)4TUMpng3m3p<@@LJRnR@Ppof(jiN*lD4jaug9KkCea@9!qsdy&AUCZugLb z%pB--o@SHQ5!EaesmK?0Y=xvhGfi5yg3=6i)msQ;brTOTjJJjyXK-wV+cQQa?8R1z zG%Ib_K5b1#pxh5pvRD z*;=H$!{iNXsj|1v$nN@7=a%yx>tqFj5eVZMMj`w!VuuwoFCE1p(@^IqK647HJq(Pkw2HsYI8v2uMlWaB9udyZpPubX zl+Hh9%z+qhqP~)DsapnqPf1nH%8aFTJG~QXWSS^Wia9dd*Fp@GEQ2&=Tf`@!6GmXp zn2wQInRnoztD9IM#%H$tiV@37?X%v{W@Lxvz(X8t-l-Hw`%{)W?ZAS2{#KELdNL^L zYp*Rq(Z%;lOTJH;CrsAW7QAgYnk&^l1n%iuZZ%=RUs-cN6dh*a`r3kmV9mdt4#qP2 zsWQST_bse7P=tI#2=W^oxg(u7^&`eRtW(OAK%bWDh&EA!wJ_?#W8Y#^AE2^EeY{`X zM+anq-Q?|ozUnDG5_<|PXMdrXN(CxC9UZ~3U5dWUxyotTi1RSdD4aqkp}Mr+(1%kC zQ6FvT(Z+Khho1o^EfoQmpEX2aFwf=r`BwF``Nd(m6$@?Zg27?-cdM~j$BLwFjv1ft zH?9{(bTa*7&FJ}0kq7gQYj>%SoMKNvxPB4!;J-o62Kh>f6Vv$@ykvB;4`IM^KI}n8Ey*5$9zBPrC-52DEdgE{Khnl`uUy%Hvk15yi!G{4OnoN4*$MBLn zr2aol1{Ni^=}kV*M`Aa<^@BAh>3dZkaAN!^m)Di-DZiliiF(x$!?~xY6BN=v zBXS!+N$ z`sF`;8YlRRx45=VQ{DZ*r$#o*lGk>_?J*&3ozno< literal 0 HcmV?d00001 diff --git a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/XEngine_AuthorizeService.cpp b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/XEngine_AuthorizeService.cpp index ef866c7..db0ce74 100644 --- a/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/XEngine_AuthorizeService.cpp +++ b/XEngine_Source/XEngine_APPService/XEngine_AuthorizeService/XEngine_AuthorizeService.cpp @@ -50,7 +50,14 @@ void ServiceApp_Stop(int signo) Session_Authorize_Destroy(); Session_Token_Destroy(); AuthHelp_DynamicCode_Destory(); - Database_SQLite_Destroy(); + if (0 == st_AuthConfig.st_XSql.nDBType) + { + DBModule_SQLite_Destroy();//销毁DB数据库服务 + } + else + { + DBModule_MySQL_Destroy();// 销毁MYsql数据库服务 + } exit(0); } } @@ -139,13 +146,25 @@ int main(int argc, char** argv) } XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("启动服务中,初始化内存池成功")); - if (!Database_SQLite_Init(st_AuthConfig.st_XSql.tszSQLite)) + /*********** 初始化 MySql/DB数据库 ***********/ + if (0 == st_AuthConfig.st_XSql.nDBType) + { //SQLite数据库 + if (!DBModule_SQLite_Init(st_AuthConfig.st_XSql.st_SQLite.tszSQLite)) + { + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("启动服务中,初始化DB数据库服务失败,错误:%lX"), DBModule_GetLastError()); + goto XENGINE_EXITAPP; + } + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("启动服务中,初始化DB数据库服务成功,数据库:%s"), st_AuthConfig.st_XSql.st_SQLite.tszSQLite); + } + else { - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("启动服务中,初始化数据库服务失败,错误:%lX"), DBModule_GetLastError()); - goto XENGINE_EXITAPP; + if (!DBModule_MySQL_Init((DATABASE_MYSQL_CONNECTINFO *)&st_AuthConfig.st_XSql.st_MYSQL)) + { + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("启动服务中,初始化MySql数据库失败,错误:%lX"), DBModule_GetLastError()); + goto XENGINE_EXITAPP; + } + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("启动服务中,初始化MySql数据库服务成功,数据库:%s"), st_AuthConfig.st_XSql.st_MYSQL.tszDBName); } - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("启动服务中,初始化数据库服务成功,数据库:%s"), st_AuthConfig.st_XSql.tszSQLite); - if (!Session_Authorize_Init(XEngine_TaskEvent_Client)) { XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("启动服务中,初始化会话客户端服务失败,错误:%lX"), Session_GetLastError()); @@ -295,10 +314,8 @@ int main(int argc, char** argv) { XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _X("启动服务中,信息报告给API服务器没有启用")); } - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("启动服务中,功能开关选项,删除功能:%d,登录功能:%d,找回密码:%d,充值功能:%d,注册功能:%d,CDKey功能:%d,公告系统:%d,动态验证:%d,多端登录:%d,临时试用:%d"), st_FunSwitch.bSwitchDelete, st_FunSwitch.bSwitchLogin, st_FunSwitch.bSwitchPass, st_FunSwitch.bSwitchPay, st_FunSwitch.bSwitchRegister, st_FunSwitch.bSwitchCDKey, st_FunSwitch.bSwitchNotice, st_FunSwitch.bSwitchDCode, st_FunSwitch.bSwitchMulti, st_FunSwitch.bSwitchTry); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("所有服务成功启动,网络验证服务运行中,XEngien版本:%s%s,发行版本次数:%d,当前运行版本:%s。。。"), BaseLib_OperatorVer_XNumberStr(), BaseLib_OperatorVer_XTypeStr(), st_AuthConfig.st_XVer.pStl_ListVer->size(), st_AuthConfig.st_XVer.pStl_ListVer->front().c_str()); - while (true) { std::this_thread::sleep_for(std::chrono::seconds(1)); @@ -332,7 +349,14 @@ XENGINE_EXITAPP: Session_Authorize_Destroy(); Session_Token_Destroy(); AuthHelp_DynamicCode_Destory(); - Database_SQLite_Destroy(); + if (0 == st_AuthConfig.st_XSql.nDBType) + { + DBModule_SQLite_Destroy(); + } + else + { + DBModule_MySQL_Destroy(); + } } #ifdef _WINDOWS WSACleanup(); -- Gitee From 5d6aeb6bb2ad09b3fc629a837285bbd5dce31185 Mon Sep 17 00:00:00 2001 From: Tina0595 <2825103297@qq.com> Date: Sat, 6 Jul 2024 22:01:04 +0800 Subject: [PATCH 2/2] mysql --- XEngine_SQL/mysql.sql | 150 ++++++++++++++++++ .../ModuleConfigure_Json.cpp | 1 - .../DBModule_MySQL/DBModule_MySQL.cpp | 18 --- 3 files changed, 150 insertions(+), 19 deletions(-) create mode 100644 XEngine_SQL/mysql.sql diff --git a/XEngine_SQL/mysql.sql b/XEngine_SQL/mysql.sql new file mode 100644 index 0000000..a148690 --- /dev/null +++ b/XEngine_SQL/mysql.sql @@ -0,0 +1,150 @@ +/* + Navicat Premium Data Transfer + + Source Server : 本地mysql + Source Server Type : MySQL + Source Server Version : 50726 + Source Host : localhost:3306 + Source Schema : xengine_authorize + + Target Server Type : MySQL + Target Server Version : 50726 + File Encoding : 65001 + + Date: 04/07/2024 20:51:48 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for Authorize_Announcement +-- ---------------------------- +DROP TABLE IF EXISTS `Authorize_Announcement`; +CREATE TABLE `Authorize_Announcement` ( + `ID` int(11) NOT NULL AUTO_INCREMENT, + `tszContext` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL, + `tszCreateTime` date NULL DEFAULT NULL, + PRIMARY KEY (`ID`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 0 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of Authorize_Announcement +-- ---------------------------- + + +-- ---------------------------- +-- Table structure for Authorize_BannedAddr +-- ---------------------------- +DROP TABLE IF EXISTS `Authorize_BannedAddr`; +CREATE TABLE `Authorize_BannedAddr` ( + `ID` int(11) NOT NULL AUTO_INCREMENT, + `bEnable` tinyint(4) NOT NULL, + `tszIPAddr` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, + `tszLeftTime` date NULL DEFAULT NULL, + `tszCreateTime` date NOT NULL, + PRIMARY KEY (`ID`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 0 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of Authorize_BannedAddr +-- ---------------------------- + +-- ---------------------------- +-- Table structure for Authorize_BannedUser +-- ---------------------------- +DROP TABLE IF EXISTS `Authorize_BannedUser`; +CREATE TABLE `Authorize_BannedUser` ( + `ID` int(11) NOT NULL AUTO_INCREMENT, + `bEnable` tinyint(1) NOT NULL, + `tszUserName` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, + `tszLeftTime` date NULL DEFAULT NULL, + `tszCreateTime` date NOT NULL, + PRIMARY KEY (`ID`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 0 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of Authorize_BannedUser +-- ---------------------------- + + +-- ---------------------------- +-- Table structure for Authorize_Serial +-- ---------------------------- +DROP TABLE IF EXISTS `Authorize_Serial`; +CREATE TABLE `Authorize_Serial` ( + `ID` int(11) NOT NULL AUTO_INCREMENT, + `UserName` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL, + `SerialNumber` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL, + `MaxTime` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL, + `CardSerialType` int(11) NULL DEFAULT NULL, + `bIsUsed` tinyint(1) NULL DEFAULT NULL, + `CreateTime` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, + PRIMARY KEY (`ID`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 0 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of Authorize_Serial +-- ---------------------------- + +-- ---------------------------- +-- Table structure for Authorize_TempVer +-- ---------------------------- +DROP TABLE IF EXISTS `Authorize_TempVer`; +CREATE TABLE `Authorize_TempVer` ( + `ID` int(11) NOT NULL AUTO_INCREMENT, + `tszVSerial` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, + `nVMode` int(11) NOT NULL, + `nVTime` int(11) NOT NULL, + `nLTime` int(11) NOT NULL, + `CreateTime` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, + PRIMARY KEY (`ID`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 0 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of Authorize_TempVer +-- ---------------------------- + +-- ---------------------------- +-- Table structure for Authorize_User +-- ---------------------------- +DROP TABLE IF EXISTS `Authorize_User`; +CREATE TABLE `Authorize_User` ( + `ID` int(11) NOT NULL AUTO_INCREMENT, + `UserName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '用户名', + `Password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '密码', + `LeftTime` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '剩余时间', + `EmailAddr` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '电子邮件', + `HardCode` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '设备SN', + `CardSerialType` int(11) NOT NULL, + `PhoneNumber` bigint(20) NOT NULL COMMENT '电话号码', + `IDCard` bigint(20) NOT NULL COMMENT '身份证', + `nUserLevel` int(11) NOT NULL COMMENT '用户等级,数字越小越高', + `UPTime` datetime NULL DEFAULT NULL COMMENT '登录时间', + `CreateTime` datetime NOT NULL COMMENT '注册时间', + PRIMARY KEY (`ID`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 0 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of Authorize_User +-- ---------------------------- +INSERT INTO `Authorize_User` VALUES (1, 'admin', '123123aa', '0', '486179@qq.com', 'DAFD2A2DAD', 1, 13699430000, 511025198881118888, 0, '2022-09-21 15:06:45', '2022-09-21 15:06:45'); +-- ---------------------------- +-- Table structure for Sqlite_Sequence +-- ---------------------------- +DROP TABLE IF EXISTS `Sqlite_Sequence`; +CREATE TABLE `Sqlite_Sequence` ( + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL, + `seq` int(11) NULL DEFAULT NULL +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of Sqlite_Sequence +-- ---------------------------- +INSERT INTO `Sqlite_Sequence` VALUES ('Authorize_BannedUser', 6); +INSERT INTO `Sqlite_Sequence` VALUES ('Authorize_BannedAddr', 5); +INSERT INTO `Sqlite_Sequence` VALUES ('Authorize_TempVer', 1); +INSERT INTO `Sqlite_Sequence` VALUES ('Authorize_Serial', 10); +INSERT INTO `Sqlite_Sequence` VALUES ('Authorize_User', 5); + +SET FOREIGN_KEY_CHECKS = 1; diff --git a/XEngine_Source/AuthorizeModule_Configure/ModuleConfigure_Json/ModuleConfigure_Json.cpp b/XEngine_Source/AuthorizeModule_Configure/ModuleConfigure_Json/ModuleConfigure_Json.cpp index 33d79e2..dd051b0 100644 --- a/XEngine_Source/AuthorizeModule_Configure/ModuleConfigure_Json/ModuleConfigure_Json.cpp +++ b/XEngine_Source/AuthorizeModule_Configure/ModuleConfigure_Json/ModuleConfigure_Json.cpp @@ -147,7 +147,6 @@ bool CModuleConfigure_Json::ModuleConfigure_Json_File(LPCXSTR lpszConfigFile, XE pSt_ServerConfig->st_XCrypto.bEnable = st_JsonXCrypto["bEnable"].asBool(); pSt_ServerConfig->st_XCrypto.nPassword = st_JsonXCrypto["nPass"].asInt(); //数据库配置 - printf("%d\n", st_JsonRoot["XSql"].size()); if (st_JsonRoot["XSql"].empty() || (6 != st_JsonRoot["XSql"].size())) { Config_IsErrorOccur = true; diff --git a/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.cpp b/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.cpp index 46ce206..89094b4 100644 --- a/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.cpp +++ b/XEngine_Source/AuthorizeModule_Database/DBModule_MySQL/DBModule_MySQL.cpp @@ -188,7 +188,6 @@ bool CDBModule_MySQL::DBModule_MySQL_UserQuery(LPCXSTR lpszUserName, AUTHREG_USE nFliedValue++; if (NULL != pptszResult[nFliedValue]) { - //printf("索引:%d 用户名:%s\n", nFliedValue, pptszResult[nFliedValue]); _tcsxcpy(pSt_UserInfo->st_UserInfo.tszUserName, pptszResult[nFliedValue]); } @@ -196,7 +195,6 @@ bool CDBModule_MySQL::DBModule_MySQL_UserQuery(LPCXSTR lpszUserName, AUTHREG_USE nFliedValue++; if (NULL != pptszResult[nFliedValue]) { - //printf("索引:%d 密码:%s\n", nFliedValue, pptszResult[nFliedValue]); _tcsxcpy(pSt_UserInfo->st_UserInfo.tszUserPass, pptszResult[nFliedValue]); } @@ -204,7 +202,6 @@ bool CDBModule_MySQL::DBModule_MySQL_UserQuery(LPCXSTR lpszUserName, AUTHREG_USE nFliedValue++; if (NULL != pptszResult[nFliedValue]) { - //printf("索引:%d 过期时间:%s\n", nFliedValue, pptszResult[nFliedValue]); _tcsxcpy(pSt_UserInfo->tszLeftTime, pptszResult[nFliedValue]); } @@ -212,7 +209,6 @@ bool CDBModule_MySQL::DBModule_MySQL_UserQuery(LPCXSTR lpszUserName, AUTHREG_USE nFliedValue++; if (NULL != pptszResult[nFliedValue]) { - //printf("索引:%d 电子邮件:%s\n", nFliedValue, pptszResult[nFliedValue]); _tcsxcpy(pSt_UserInfo->st_UserInfo.tszEMailAddr, pptszResult[nFliedValue]); } @@ -220,7 +216,6 @@ bool CDBModule_MySQL::DBModule_MySQL_UserQuery(LPCXSTR lpszUserName, AUTHREG_USE nFliedValue++; if (NULL != pptszResult[nFliedValue]) { - //printf("索引:%d 硬件码:%s\n", nFliedValue, pptszResult[nFliedValue]); _tcsxcpy(pSt_UserInfo->tszHardCode, pptszResult[nFliedValue]); } @@ -228,7 +223,6 @@ bool CDBModule_MySQL::DBModule_MySQL_UserQuery(LPCXSTR lpszUserName, AUTHREG_USE nFliedValue++; if (NULL != pptszResult[nFliedValue]) { - //printf("索引:%d 充值卡类型:%s\n", nFliedValue, pptszResult[nFliedValue]); pSt_UserInfo->enSerialType = (ENUM_HELPCOMPONENTS_AUTHORIZE_SERIAL_TYPE)_ttxoi(pptszResult[nFliedValue]); } @@ -236,7 +230,6 @@ bool CDBModule_MySQL::DBModule_MySQL_UserQuery(LPCXSTR lpszUserName, AUTHREG_USE nFliedValue++; if (NULL != pptszResult[nFliedValue]) { - //printf("索引:%d QQ号:%s\n", nFliedValue, pptszResult[nFliedValue]); pSt_UserInfo->st_UserInfo.nPhoneNumber = _ttxoll(pptszResult[nFliedValue]); } @@ -244,7 +237,6 @@ bool CDBModule_MySQL::DBModule_MySQL_UserQuery(LPCXSTR lpszUserName, AUTHREG_USE nFliedValue++; if (NULL != pptszResult[nFliedValue]) { - //printf("索引:%d 身份证ID:%s\n", nFliedValue, pptszResult[nFliedValue]); pSt_UserInfo->st_UserInfo.nIDNumber = _ttxoll(pptszResult[nFliedValue]); } @@ -252,7 +244,6 @@ bool CDBModule_MySQL::DBModule_MySQL_UserQuery(LPCXSTR lpszUserName, AUTHREG_USE nFliedValue++; if (NULL != pptszResult[nFliedValue]) { - //printf("索引:%d 用户级别 -1表示封禁:%s\n", nFliedValue, pptszResult[nFliedValue]); pSt_UserInfo->st_UserInfo.nUserLevel = _ttxoi(pptszResult[nFliedValue]); } @@ -260,14 +251,12 @@ bool CDBModule_MySQL::DBModule_MySQL_UserQuery(LPCXSTR lpszUserName, AUTHREG_USE nFliedValue++; if (NULL != pptszResult[nFliedValue] && _tcsxlen(pptszResult[nFliedValue]) > 0) { - //printf("索引:%d 登录日期:%s\n", nFliedValue, pptszResult[nFliedValue]); _tcsxcpy(pSt_UserInfo->st_UserInfo.tszLoginTime, pptszResult[nFliedValue]); } //注册日期 nFliedValue++; if (NULL != pptszResult[nFliedValue]) { - //printf("索引:%d 注册日期:%s\n", nFliedValue, pptszResult[nFliedValue]); _tcsxcpy(pSt_UserInfo->st_UserInfo.tszCreateTime, pptszResult[nFliedValue]); } @@ -449,7 +438,6 @@ bool CDBModule_MySQL::DBModule_MySQL_UserSet(AUTHREG_USERTABLE* pSt_UserTable) _xstprintf(tszSQLStatement, _X("UPDATE `Authorize_User` SET Password = '%s',LeftTime = '%s',EmailAddr = '%s',HardCode = '%s',CardSerialType = '%d',PhoneNumber = '%lld',IDCard = '%lld',nUserLevel = '%d',UPTime = NOW(),CreateTime = '%s' WHERE UserName = '%s'"), pSt_UserTable->st_UserInfo.tszUserPass, pSt_UserTable->tszLeftTime, pSt_UserTable->st_UserInfo.tszEMailAddr, pSt_UserTable->tszHardCode, pSt_UserTable->enSerialType, pSt_UserTable->st_UserInfo.nPhoneNumber, pSt_UserTable->st_UserInfo.nIDNumber, pSt_UserTable->st_UserInfo.nUserLevel/*, pSt_UserTable->st_UserInfo.tszLoginTime*/, pSt_UserTable->st_UserInfo.tszCreateTime, pSt_UserTable->st_UserInfo.tszUserName); - //printf("22设置用户信息(SQL):%s\n", tszSQLStatement); //更新用户剩余时间 if (!DataBase_MySQL_Execute(xhData, tszSQLStatement)) { @@ -894,7 +882,6 @@ bool CDBModule_MySQL::DBModule_MySQL_TryInsert(AUTHREG_TEMPVER* pSt_AuthVer) //插入数据库 _xstprintf(tszSQLStatement, _X("INSERT INTO `Authorize_TempVer`(tszVSerial,nVMode,nVTime,nLTime,CreateTime) VALUES('%s',%d,%d,%d,NOW())"), pSt_AuthVer->tszVSerial, pSt_AuthVer->enVMode, pSt_AuthVer->nVTime, pSt_AuthVer->nVTime); - //printf("网络使用模式插入一条数据:SQL语句%s\n", tszSQLStatement); if (!DataBase_MySQL_Execute(xhData, tszSQLStatement)) { SQLPacket_IsErrorOccur = true; @@ -1593,7 +1580,6 @@ bool CDBModule_MySQL::DBModule_MySQL_BannedExist(AUTHREG_BANNED* pSt_Banned) DataBase_MySQL_FreeResult(xhData, xhTable); return false; } - //printf("测试2 行:%d 列:%d\n", nRow, nColumn); if (nRow <= 0) { @@ -1609,7 +1595,6 @@ bool CDBModule_MySQL::DBModule_MySQL_BannedExist(AUTHREG_BANNED* pSt_Banned) int nFliedValue = 0; if (NULL != ppszResult[nFliedValue]) { - //printf("索引:%d ID:%s\n", nFliedValue, ppszResult[nFliedValue]); pSt_Banned->nID = _ttxoll(ppszResult[nFliedValue]); } @@ -1617,7 +1602,6 @@ bool CDBModule_MySQL::DBModule_MySQL_BannedExist(AUTHREG_BANNED* pSt_Banned) nFliedValue++; if (NULL != ppszResult[nFliedValue]) { - //printf("索引:%d 是否启用:%s\n", nFliedValue, ppszResult[nFliedValue]); pSt_Banned->bEnable = _ttxoi(ppszResult[nFliedValue]); } @@ -1628,7 +1612,6 @@ bool CDBModule_MySQL::DBModule_MySQL_BannedExist(AUTHREG_BANNED* pSt_Banned) nFliedValue++; if (NULL != ppszResult[nFliedValue]) { - //printf("索引:%d 过期时间:%s\n", nFliedValue, ppszResult[nFliedValue]); _tcsxcpy(pSt_Banned->tszLeftTime, ppszResult[nFliedValue]); } @@ -1637,7 +1620,6 @@ bool CDBModule_MySQL::DBModule_MySQL_BannedExist(AUTHREG_BANNED* pSt_Banned) nFliedValue++; if (NULL != ppszResult[nFliedValue]) { - //printf("索引:%d 注册时间:%s\n", nFliedValue, ppszResult[nFliedValue]); _tcsxcpy(pSt_Banned->tszCreateTime, ppszResult[nFliedValue]); } -- Gitee