From 04b6c2b6480fadd256bfc8dcf6a8b3da36e50771 Mon Sep 17 00:00:00 2001 From: BlueWhaleTech Date: Mon, 23 Apr 2018 15:04:10 +0800 Subject: [PATCH] First version commit. It is TODO status. --- .gitignore | 8 + LICENSE | 0 README.md | 0 src/cqbot/CQBot.php | 161 ++++++++++ src/cqbot/Framework.php | 169 +++++++++++ src/cqbot/User.php | 81 +++++ src/cqbot/loader.php | 37 +++ src/cqbot/mods/Admin.php | 41 +++ src/cqbot/mods/ModBase.php | 44 +++ src/cqbot/utils/Buffer.php | 49 ++++ src/cqbot/utils/CQUtil.php | 488 +++++++++++++++++++++++++++++++ src/cqbot/utils/Console.php | 67 +++++ src/cqbot/utils/DataProvider.php | 48 +++ src/cqbot/utils/ErrorStatus.php | 50 ++++ src/extension/PHPMailer.phar | Bin 0 -> 217925 bytes start.php | 100 +++++++ 16 files changed, 1343 insertions(+) create mode 100755 .gitignore mode change 100644 => 100755 LICENSE mode change 100644 => 100755 README.md create mode 100755 src/cqbot/CQBot.php create mode 100755 src/cqbot/Framework.php create mode 100755 src/cqbot/User.php create mode 100755 src/cqbot/loader.php create mode 100755 src/cqbot/mods/Admin.php create mode 100755 src/cqbot/mods/ModBase.php create mode 100755 src/cqbot/utils/Buffer.php create mode 100755 src/cqbot/utils/CQUtil.php create mode 100755 src/cqbot/utils/Console.php create mode 100755 src/cqbot/utils/DataProvider.php create mode 100755 src/cqbot/utils/ErrorStatus.php create mode 100755 src/extension/PHPMailer.phar create mode 100755 start.php diff --git a/.gitignore b/.gitignore new file mode 100755 index 00000000..fe7871cc --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +# Created by .ignore support plugin (hsz.mobi) +### Example user template template +### Example user template + +# IntelliJ project files +.idea +out +gen diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/src/cqbot/CQBot.php b/src/cqbot/CQBot.php new file mode 100755 index 00000000..850cf2f2 --- /dev/null +++ b/src/cqbot/CQBot.php @@ -0,0 +1,161 @@ +starttime = microtime(true); + $this->framework = $framework; + } + + public function execute($it){ + $this->data = $it; + if ($it["post_type"] == "message") { + try { + $this->callTask($it); + } catch (\Exception $e) { + CQUtil::errorLog("请求执行任务时异常\n" . $e->getMessage()); + CQUtil::sendDebugMsg("引起异常的消息:\n" . $it["message"]); + } + $msg_arr = explode("&&", $this->replace($it["message"], $it)); + foreach ($msg_arr as $item) { + $msg = trim($item); + $msg = explode(" ", $msg); + $this->checkFunction($msg, $it); + } + } + } + + public function checkFunction($msgCut, $it){ + $cmdList = Buffer::get("commands"); + if (isset($cmdList[$msgCut[0]])) { + Console::debug("Call CQFunction:" . $msgCut[0]); + $temp = $cmdList[$msgCut[0]]; + /** @var ModBase $class */ + $class = new $temp($this, $it); + $class->execute($msgCut); + return true; + } + Console::debug("未找到指令:[" . $msgCut[0] . "]"); + return false; + } + + public function callTask($it){ + if ($this->data["post_type"] == "message") { + foreach(Buffer::get("mod_task") as $v){ + new $v($this, $this->data); + } + } + } + + public function reply($msg){ + $this->function_called = true; + switch ($this->data["message_type"]) { + case "group": + $this->sendGroupMsg($this->data["group_id"], $msg); + break; + case "private": + $this->sendPrivateMsg($this->data["user_id"], $msg); + break; + case "discuss": + $reply = json_encode(["action" => "send_discuss_msg", "params" => ["discuss_id" => $this->data["discuss_id"], "message" => $msg]]); + if (CQUtil::APIPush($reply)) { + $out_count = Buffer::$out_count->get(); + if (Buffer::$data["info_level"] == 2) { + Console::put("************API PUSHED***********"); + } + if (Buffer::$data["info_level"] >= 1) { + Console::put(Console::setColor(date("H:i:s "), "lightpurple") . Console::setColor("[$out_count]REPLY", "blue") . Console::setColor(" > ", "gray") . json_decode($reply, true)['params']["message"]); + } + Buffer::$out_count->add(1); + } + break; + case "wechat": + //TODO: add wechat account support in the future + break; + } + } + + public function sendGroupMsg($groupId, $msg){ + $this->function_called = true; + CQUtil::sendGroupMsg($groupId, $msg); + } + + public function sendPrivateMsg($userId, $msg){ + $this->function_called = true; + CQUtil::sendPrivateMsg($userId, $msg); + } + + public function isAdmin($user){ + if (in_array($user, Buffer::get("su"))) return true; + else return false; + } + + public function replace($msg, $dat){ + $msg = str_replace("{at}", '[CQ:at,qq=' . $dat["user_id"] . ']', $msg); + $msg = str_replace("{and}", '&', $msg); + while (strpos($msg, '{') !== false && strpos($msg, '}') !== false) { + if (strpos($msg, '{') > strpos($msg, '}')) return $msg; + $start = strpos($msg, '{'); + $end = strpos($msg, '}'); + $sub = explode("=", substr($msg, $start + 1, $end - $start - 1)); + switch ($sub[0]) { + case "at": + $qq = $sub[1]; + $msg = str_replace(substr($msg, $start, $end - $start + 1), '[CQ:at,qq=' . $qq . ']', $msg); + break; + case "image": + case "record": + $pictFile = $sub[1]; + $msg = str_replace(substr($msg, $start, $end - $start + 1), '[CQ:' . $sub[0] . ',file=' . $pictFile . ']', $msg); + break; + case "dice": + $file = $sub[1]; + $msg = str_replace(substr($msg, $start, $end - $start + 1), '[CQ:dice,type=' . $file . ']', $msg); + break; + case "shake": + $msg = str_replace(substr($msg, $start, $end - $start + 1), '[CQ:shake]', $msg); + break; + case "music": + $id = $sub[1]; + $msg = str_replace(substr($msg, $start, $end - $start + 1), '[CQ:music,type=163,id=' . $id . ']', $msg); + break; + case "internet": + array_shift($sub); + $id = implode("=", $sub); + if (substr($id, 0, 7) != "http://") $id = "http://" . $id; + $is = file_get_contents($id, false, NULL, 0, 1024); + if ($is == false) $is = "[请求时发生了错误] 如有疑问,请联系管理员"; + $msg = str_replace(substr($msg, $start, $end - $start + 1), $is, $msg); + break 2; + default: + break 2; + } + } + return $msg; + } +} \ No newline at end of file diff --git a/src/cqbot/Framework.php b/src/cqbot/Framework.php new file mode 100755 index 00000000..218a91f0 --- /dev/null +++ b/src/cqbot/Framework.php @@ -0,0 +1,169 @@ +host = $host; + return $this; + } + + public function setApiPort($port = 10000){ + $this->api_port = $port; + return $this; + } + + public function setEventPort($port = 20000){ + $this->event_port = $port; + return $this; + } + + public function setAdminGroup($group){ + self::$admin_group = $group; + return $this; + } + + public function setInfoLevel($level){ + $this->info_level = $level; + return $this; + } + + public function eventServerStart(){ + $this->event->start(); + } + + public static function getInstance(){ + return self::$obj; + } + + public function init(){ + self::$obj = $this; + Console::put("CQBot Framework starting..."); + $this->event = new \swoole_websocket_server($this->host, $this->event_port); + Buffer::$log_file = CONFIG_DIR . "log/swoole.log"; + Console::put("Current log file: " . Buffer::$log_file); + $worker_num = 1; + Console::put("Current worker count: " . $worker_num); + $dispatch_mode = 2; + Console::put("Current dispatch mode: " . $dispatch_mode); + $this->checkFiles(); + $this->event->set([ + "log_file" => Buffer::$log_file, + "worker_num" => 1, + "dispatch_mode" => 2 + ]); + $this->event->on('WorkerStart', [$this, 'onWorkerStart']); + $this->event->on('message', [$this, 'onEventMessage']); + $this->event->on('open', [$this, 'onConnect']); + $this->event->on('close', function ($serv, $fd){ + //put your connection close method here. + }); + Buffer::$in_count = new \swoole_atomic(1); + Buffer::$out_count = new \swoole_atomic(1); + Buffer::$api_id = new \swoole_atomic(1); + return $this; + } + + public function checkFiles(){ + @mkdir(WORKING_DIR."log/", 0777, true); + if(!is_file(CONFIG_DIR."log/last_error.log")) + file_put_contents(CONFIG_DIR."log/last_error.log", ""); + if(!is_file(CONFIG_DIR."log/error_flag")) + file_put_contents(CONFIG_DIR."log/error_flag", time()); + } + + /* Callback function down here */ + + /** + * This is async function in EventLoop + * When it reload, it will run this function again. + * @param \swoole_server $server + * @param $worker_id + */ + public function onWorkerStart(\swoole_server $server, $worker_id){ + $this->run_time = time(); + Console::info("Starting worker " . $worker_id); + Console::info("Loading source code..."); + require_once(WORKING_DIR . "src/cqbot/loader.php"); + CQUtil::loadAllFiles(); + Buffer::set("info_level", $this->info_level);//设置info等级 + foreach (get_included_files() as $file) + Console::debug("Loaded " . $file); + echo("\n"); + + //计时器(ms) + $server->tick(1000, [$this, "processTick"]); + + $this->api = new \swoole_http_client($this->host, $this->api_port); + $this->api->set(['websocket_mask' => true]); + $this->api->on('message', [$this, "onApiMessage"]); + $this->api->on("close", function ($cli){ + Console::info(Console::setColor("API connection closed", "red")); + }); + $this->api->upgrade('/api/', [$this, "onUpgrade"]); + + Console::debug("master_pid = " . $server->master_pid); + Console::debug("worker_id = " . $worker_id); + Console::put("\n====================\n"); + } + + public function onUpgrade($cli){ + Console::info("Upgraded API websocket"); + Buffer::$api = $this->api; + Buffer::$event = $this->event; + if ($data = file(CONFIG_DIR . "last_error.log")) { + $last_time = file_get_contents(CONFIG_DIR . "error_flag"); + if (time() - $last_time < 2) { + CQUtil::sendDebugMsg("检测到重复引起异常,停止服务器", 0); + file_put_contents(CONFIG_DIR."last_error.log", ""); + $this->event->shutdown(); + return; + } + CQUtil::sendDebugMsg("检测到异常", 0); + $msg = ""; + foreach ($data as $e) { + $msg = $msg . $e . "\n"; + } + CQUtil::sendDebugMsg($msg, 0); + CQUtil::sendDebugMsg("[CQBot] 成功开启!", 0); + file_put_contents(CONFIG_DIR . "error_flag", time()); + file_put_contents(CONFIG_DIR . "last_error.log", ""); + } + else { + CQUtil::sendDebugMsg("[CQBot] 成功开启!", 0); + } + } +} \ No newline at end of file diff --git a/src/cqbot/User.php b/src/cqbot/User.php new file mode 100755 index 00000000..3e8d0d31 --- /dev/null +++ b/src/cqbot/User.php @@ -0,0 +1,81 @@ +id = $qid; + $this->permission = DP::getJsonData("permissions.json")[$qid] ?? 0; + $this->is_friend = isset(Buffer::get("friend_list")[$qid]) ? true : false; + } + + /** + * 获取用户QQ号 + * @return mixed + */ + public function getId(){ return $this->id; } + + /** + * 获取用户添加词库的状态 + * @return array + */ + public function getWordStatus() : array{ return $this->word_status; } + + /** + * 获取用户权限值 + * @return int + */ + public function getPermission() : int{ return $this->permission; } + + /** + * @param array $word_status + * @return User + */ + public function setWordStatus(array $word_status): User{ + $this->word_status = $word_status; + return $this; + } + + /** + * @param int $permission + * @return User + */ + public function setPermission(int $permission): User{ + $this->permission = $permission; + return $this; + } + + /** + * 和用户是否是好友//TODO功能 + * @return bool + */ + public function isFriend(): bool{ + return $this->is_friend; + } + + public function getBuffer(){ + return $this->buffer; + } + + public function setBuffer($buffer){ + $this->buffer = $buffer; + return $this; + } +} \ No newline at end of file diff --git a/src/cqbot/loader.php b/src/cqbot/loader.php new file mode 100755 index 00000000..1fae19a3 --- /dev/null +++ b/src/cqbot/loader.php @@ -0,0 +1,37 @@ +main->isAdmin($this->getUserId())) return false; + switch ($it[0]) { + case "add-cmd": + if (count($it) < 3) { + $this->reply("用法:add-cmd 指令 模块名"); + return true; + } + if(!CQUtil::isModExists($it[2])){ + $this->reply("对不起,模块 ".$it[2]." 不存在!"); + return true; + } + } + } +} \ No newline at end of file diff --git a/src/cqbot/mods/ModBase.php b/src/cqbot/mods/ModBase.php new file mode 100755 index 00000000..8acd1d49 --- /dev/null +++ b/src/cqbot/mods/ModBase.php @@ -0,0 +1,44 @@ +main = $main; + $this->data = $data; + $this->cmds = $mod_cmd; + } + + public function getUser($data = null){ + return CQUtil::getUser($data === null ? $this->data["user_id"] : $data["user_id"]); + } + + public function getUserId($data = null){ return $data === null ? strval($this->data["user_id"]) : strval($data["user_id"]); } + + public abstract function execute($it); + + public function reply($msg){ $this->main->reply($msg); } + + public function sendPrivateMsg($user, $msg){ $this->main->sendPrivateMsg($user, $msg); } + + public function sendGroupMsg($user, $msg){ $this->main->sendGroupMsg($user, $msg); } + + public function getMessageType(){ return $this->data["message_type"]; } + + public function getCommands(){ return $this->cmds; } +} \ No newline at end of file diff --git a/src/cqbot/utils/Buffer.php b/src/cqbot/utils/Buffer.php new file mode 100755 index 00000000..20a2e4f0 --- /dev/null +++ b/src/cqbot/utils/Buffer.php @@ -0,0 +1,49 @@ +isConnected() === false) { + //链接被断开 + Buffer::$api->upgrade('/api/', function ($cli){ + self::sendDebugMsg("API重新链接成功"); + self::APIPushDelayMsg(); + }); + return 0; + } + return 1; + } + + /** + * 推送API,给API端口 + * @param $data + * @return bool + */ + static function APIPush($data){ + if ($data == null || $data == "") { + Console::error("EMPTY DATA PUSH"); + return false; + } + if (self::checkAPIConnection() === -1) { + //忽略掉framework链接API之前的消息 + self::errorlog("API推送失败,未发送的消息: \n" . $data, "API ERROR", 0); + return false; + } + if (self::checkAPIConnection() === 0) { + self::APIPushAfterConnected($data); + return true; + } + if (Buffer::$api->push($data) === false) { + $data = self::unicodeDecode($data); + self::errorlog("API推送失败,未发送的消息: \n" . $data, "API ERROR", 0); + self::sendErrorEmail("API推送失败", "未成功推送的消息:
$data
请检查酷q是否开启及网络链接情况
在此期间,机器人会中断所有消息处理
请及时处理"); + return false; + } + return true; + } + + static function APIPushDelayMsg(){ + $delay_push_list = Buffer::get("delay_push"); + $cur_time = time(); + foreach ($delay_push_list as $item) { + $data = $item["data"]; + $time = $item["time"]; + if ($cur_time - $time <= 10) { + self::APIPush($data); + } + } + Buffer::set("delay_push", []); + } + + /** + * 推迟推送API,用于酷Q重启后的重新连接API + * @param $data + */ + static function APIPushAfterConnected($data){ + $delay_push_list = Buffer::get("delay_push"); + $delay_push_list[] = ["data" => $data, "time" => time()]; + Buffer::set("delay_push", $delay_push_list); + } + + /** + * 解码unicode中文编码 + * @param $str + * @return null|string|string[] + */ + static function unicodeDecode($str){ + return preg_replace_callback('/\\\\u([0-9a-f]{4})/i', function ($matches){ + return mb_convert_encoding(pack("H*", $matches[1]), "UTF-8", "UCS-2BE"); + }, + $str); + } + + /** + * 模拟发送一个HTML-get请求 + * @param $url + * @return mixed + */ + static function getHTML($url){ + $ch = curl_init(); + $timeout = 5; + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_HEADER, 1); + curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0'); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); + $r = curl_exec($ch); + curl_close($ch); + return $r; + } + + /** + * 获取字符串的反转结果 + * @param $str + * @param string $encoding + * @return string + */ + static public function getRev($str, $encoding = 'utf-8'){ + $result = ''; + $len = mb_strlen($str); + for ($i = $len - 1; $i >= 0; $i--) { + $result .= mb_substr($str, $i, 1, $encoding); + } + return $result; + } + + /** + * 发送邮件功能,基于PHPMailer模块,需先安装phpmailer。默认此工程demo里已包含有phpmailer了。 + * 请根据实际自己的邮箱更新下面的用户名、密码、smtp服务器地址、端口等。 + * 此功能非基于本作者编写的代码,如有问题请在github上找PHPMailer项目进行反馈 + * @param $address + * @param $title + * @param $content + * @param string $name + * @param int $send_debug_message + * @return bool|string + */ + static function sendEmail($address, $title, $content, $name = "CQ开发团队", $send_debug_message = 1){ + $mail = new \PHPMailer(true); + try { + $mail->isSMTP(); + $mail->Host = 'here your smtp host'; + $mail->SMTPAuth = true; + $mail->Username = 'here your mailbox address'; + $mail->Password = 'here your password'; + $mail->SMTPSecure = 'ssl'; + $mail->Port = 465; + $mail->setFrom('here your mailbox address', $name); + if (is_array($address)) { + foreach ($address as $item) + $mail->addAddress($item); + } + else { + $mail->addAddress($address); + } + //Content + $mail->isHTML(true); + $mail->Subject = $title; + $mail->CharSet = "UTF-8"; + $mail->Body = $content; + $mail->send(); + if (is_array($address)) + $address = implode(",", $address); + Console::info("向 $address 发送的邮件完成"); + unset($mail); + return true; + } catch (\Exception $e) { + self::errorLog("发送邮件错误!错误信息:" . $info = $mail->ErrorInfo, "ERROR", $send_debug_message); + unset($mail); + return $info; + } + } + + /** + * 获取运行时间 + * @param $time + * @return array + */ + static function getRunTime($time){ + $time_len = time() - $time; + $run_time = []; + if (intval($time_len / 86400) > 0) { + $run_time[0] = intval($time_len / 86400); + $time_len = $time_len % 86400; + } + else { + $run_time[0] = 0; + } + if (intval($time_len / 3600) > 0) { + $run_time[1] = intval($time_len / 3600); + $time_len = $time_len % 3600; + } + else { + $run_time[1] = 0; + } + if (intval($time_len / 60) > 0) { + $run_time[2] = intval($time_len / 60); + $time_len = $time_len % 60; + } + else { + $run_time[2] = 0; + } + $run_time[3] = $time_len; + return $run_time; + } + + /** + * 获取格式化的运行时间 + * @param $time + * @return string + */ + static function getRunTimeFormat($time){ + $time_len = time() - $time; + $msg = ""; + if (intval($time_len / 86400) > 0) { + $msg .= intval($time_len / 86400) . "天"; + $time_len = $time_len % 86400; + } + if (intval($time_len / 3600) > 0) { + $msg .= intval($time_len / 3600) . "小时"; + $time_len = $time_len % 3600; + } + if (intval($time_len / 60) > 0) { + $msg .= intval($time_len / 60) . "分"; + $time_len = $time_len % 60; + } + $msg .= $time_len . "秒"; + return $msg; + } + + /** + * 检查是否为群组管理员或群主功能,此功能需要先获取群组列表,否则会产生一个warning + * @param $group + * @param $user_id + * @return bool + */ + static function isGroupAdmin($group, $user_id){ + $ls = Buffer::get("group_list")[$group]["member"]; + $is_admin = false; + foreach ($ls as $k => $v) { + if ($v["user_id"] == $user_id) { + if ($v["role"] == "admin" || $v["role"] == "owner") { + $is_admin = true; + break; + } + } + } + return $is_admin; + } + + /** + * 用于发送错误日志邮件的功能,请根据实际情况填写邮箱。 + * 此功能基于sendMail,请看上方sendMail函数的介绍 + * @param $title + * @param $content + * @param string $name + */ + static function sendErrorEmail($title, $content, $name = "机器人错误提示"){ + self::sendEmail(["here your receive email address"], $title, $content, $name, 0); + } + + /** + * 获取所有已经加载到内存的用户。 + * read_all为true时,会加载所有User.dat到内存中,false时仅会读取已经加载到内存的用户 + * @param bool $real_all + * @return array[User] + */ + static function getAllUsers($real_all = false): array{ + if ($real_all === true) { + $dir = scandir(DP::getUserFolder()); + unset($dir[0], $dir[1]); + foreach ($dir as $d => $v) { + $vs = explode(".", $v); + if (array_pop($vs) == "dat") { + $class = unserialize(file_get_contents(DP::getUserFolder() . $v)); + if (!Buffer::array_key_exists("user", $vs[0])) { + Buffer::appendKey("user", $vs[0], $class); + } + } + } + } + return Buffer::get("user"); + } + + /** + * 获取用户实例 + * @param $id + * @return User + */ + static function getUser($id){ + $d = Buffer::get("user"); + if (!isset($d[$id])) { + self::initUser($id); + $d = Buffer::get("user"); + } + /** @var User $class */ + $class = $d[$id]; + return $class; + } + + /** + * 初始化用户实例。如果没有此用户的实例数据,会创建 + * @param $id + */ + static function initUser($id){ + if (file_exists(DP::getUserFolder() . $id . ".dat")) $class = unserialize(file_get_contents(DP::getUserFolder() . $id . ".dat")); + else { + Console::info("无法找到用户 " . $id . " 的数据,正在创建..."); + $class = new User($id); + } + Buffer::appendKey("user", $id, $class); + } + + /** + * 发送群组消息,含控制台推出 + * @param $groupId + * @param $msg + * @return bool + */ + static function sendGroupMsg($groupId, $msg){ + $reply = ["action" => "send_group_msg", "params" => ["group_id" => $groupId, "message" => $msg]]; + $reply["echo"] = $reply; + $reply["echo"]["time"] = time(); + $reply = json_encode($reply); + if (self::APIPush($reply)) { + if (Buffer::$data["info_level"] == 1) { + $out_count = Buffer::$out_count->get(); + Console::put(Console::setColor(date("H:i:s "), "lightpurple") . Console::setColor("[{$out_count}]GROUP", "blue") . Console::setColor(" " . $groupId, "yellow") . Console::setColor(" > ", "gray") . $msg); + Buffer::$out_count->add(1); + } + return true; + } + return false; + } + + /** + * 发送私聊消息 + * @param $userId + * @param $msg + * @return bool + */ + static function sendPrivateMsg($userId, $msg){ + $reply = ["action" => "send_private_msg", "params" => ["user_id" => $userId, "message" => $msg]]; + $reply["echo"] = $reply; + $reply["echo"]["time"] = time(); + $reply = json_encode($reply); + if (self::APIPush($reply)) { + if (Buffer::$data["info_level"] == 1) { + $out_count = Buffer::$out_count->get(); + Console::put(Console::setColor(date("H:i:s "), "lightpurple") . Console::setColor("[{$out_count}]PRIVATE", "blue") . Console::setColor(" " . $userId, "yellow") . Console::setColor(" > ", "gray") . $msg); + Buffer::$out_count->add(1); + } + return true; + } + return false; + } + + + static function getFriendName($qq){ return Buffer::get("friend_list")[$qq]["nickname"] ?? "unknown"; } + + static function getGroupName($group){ return Buffer::get("group_list")[$group]["group_name"] ?? "unknown"; } + + /** + * 发送其他API,HTTP插件支持的其他API都可以发送。 + * echo是返回内容,可以在APIHandler.php里面解析 + * @param $data + * @param $echo + */ + static function sendAPI($data, $echo){ + if (!is_array($data)) { + $api = []; + $api["action"] = $data; + } + else { + $api = $data; + } + $api["echo"] = $echo; + self::APIPush(json_encode($api)); + } + + /** + * 删除一个和模块相关联的指令 + * @param $name + * @return bool + */ + static function removeCommand($name){ + $list = Buffer::get("commands"); + if (!isset($list[$name])) return false; + unset($list[$name]); + Buffer::set("commands", $list); + DP::setJsonData("commands.json", $list); + return true; + } + + /** + * 添加一个指令给非callTask方式激活的模块。 + * 注意:如果给callTask方式激活的模块添加指令,则在使用对应功能时会回复多次同样的内容 + * @param $name + * @param $class + * @return bool + */ + static function addCommand($name, $class){ + if (!is_file(WORKING_DIR.'src/cqbot/mods/' . $class . '.php')) { + return false; + } + $list = Buffer::get("commands"); + $list[$name] = $class; + DP::setJsonData("commands.json", $list); + Buffer::set("commands", $list); + return true; + } + + /** + * 获取模块列表的通用方法 + * @return array + */ + static function getMods(){ + $dir = WORKING_DIR."src/cqbot/mods/"; + $dirs = scandir($dir); + $ls = []; + unset($dirs[0], $dirs[1]); + foreach($dirs as $v){ + if($v != "ModBase.php" && (strstr($v,".php") !== false)){ + $name = substr($v, 0, -4); + $ls[]=$name; + } + } + return $ls; + } + + /** + * 判断模块是否存在 + * @param $mod_name + * @return bool + */ + static function isModExists($mod_name){ + $ls = self::getMods(); + return in_array($mod_name, $ls); + } +} \ No newline at end of file diff --git a/src/cqbot/utils/Console.php b/src/cqbot/utils/Console.php new file mode 100755 index 00000000..552f720c --- /dev/null +++ b/src/cqbot/utils/Console.php @@ -0,0 +1,67 @@ + "POST 请求的正文格式不正确", + 1404 => "API 不存在", + 100 => "参数缺失或参数无效", + 102 => "酷q操作权限不足", + 103 => "用户权限不足或文件系统异常", + 201 => "工作线程池未正确初始化", + -1 => "请求发送失败", + -2 => "未收到服务器回复,可能未发送成功", + -3 => "消息过长或为空", + -4 => "消息解析过程异常", + -5 => "日志功能未启用", + -6 => "日志优先级错误", + -7 => "数据入库失败", + -8 => "不支持对系统帐号操作", + -9 => "帐号不在该群内,消息无法发送", + -10 => "该用户不存在/不在群内", + -11 => "数据错误,无法请求发送", + -12 => "不支持对匿名成员解除禁言", + -13 => "无法解析要禁言的匿名成员数据", + -14 => "由于未知原因,操作失败", + -15 => "群未开启匿名发言功能,或匿名帐号被禁言", + -16 => "帐号不在群内或网络错误,无法退出/解散该群", + -17 => "帐号为群主,无法退出该群", + -18 => "帐号非群主,无法解散该群", + -19 => "临时消息已失效或未建立", + -20 => "参数错误", + -21 => "临时消息已失效或未建立", + -22 => "获取QQ信息失败", + -23 => "找不到与目标QQ的关系,消息无法发送", + -26 => "消息过长" + ]; + + static function getMessage($retcode){ + return self::$error[$retcode] ?? "未知错误"; + } +} \ No newline at end of file diff --git a/src/extension/PHPMailer.phar b/src/extension/PHPMailer.phar new file mode 100755 index 0000000000000000000000000000000000000000..3367ed4681dd026604854e2ce83d769264abcc7b GIT binary patch literal 217925 zcmeFa&2L;uvM+XR*oGls3>f|gPV;i6ijs;YQlCw=KG+o1;vG`rkW}}~P`agJ)gf7< z`ry<@OPcP!_Ji$>H_v`612$mT@B<95o&m$FXL#$iVeh>3HQrl!<*ni0FCrsPo^$dP zNwsF~%)H@DtE$e)jEszojEsnkjQrx!+3DGpD~s>aqvSzSYtN>m{;1te$IEzLyMN_M z?>MRVhOPE^-2PCnot?JFwd=`bI!@bz)=4^Ty&JdB&eHLuzO}N@*-=0ib>HFSf zI;q!owfGIZ`|b*VtgZEi({$WP&!$g%{q*T<*g?(vS0;ee8+Q7$ZrVC)PfxX_wPv%H zEGMnj)2;2zRtsNu*AJex_BVIe_tpedG;Il8;+Ohx*6&|W*h9Q>WfSR1 z8GcO~+#68!r4Dq-#fT}Wt>iD#oNh*4EyXY=6Mizlv71cJR!9$-km+B~Qw-+!N!8_E^ieX)N~TM|O&(LWj0 zr{h_QzAp}XgLHyn*1^028k|jP$%BW<>h&wNj(n?4)A!TnS-;&I*7z{~^z1BJ_}aDD z97$J6)ISn2nZXoF;Ec6J5*0vq`6?QeSu<=b929X0tAC5{HJ zkG(3P6kUC!U^82l`YfieG*Av|sT!glxroolyw-eS;4G z{5NN5_#8h^^s%FpVv;?^Yj(X>c{AA(Lw^|rqdTH~wvtH-z6wD~^&Ti%a;U{aHIgE8s2Cjqh zDLu(QKkK?72)n|E0Ci@}qn+nZJe|CY)R>%(I&a^#zfBv*kYlGTH_Z<&ehN_e3`lCv zQ90}le*(z+BgYGh0)O%;SVBMuhw#_+E10HNPE!it`oc!LbDB0bM#JfN)L%=6qeh2M zt|x=pWZD>~-?sa`ZhM+8ppwJ$fk!KK~R#Rk5=d{}!*YlEQaheX!2u=mLh}=+aE}l(+z+`rWrmEYyI3CG0E=2uw zSPyV>yFt}L%4H*c&YJEL#YZnB$>2kl`xoc2G| zGSb$zM><8;5-v(*aV&Jg8(l-t7V2UloN~!nY@_E`GyAf*MaYJFPqy|pH?XSxD!0HX z92p@1L6=;YL4J;CeX))4_`;q>Aj@z$_ORaGNN(M@l{_C!lc%HEu*+ViozqdW@C60W z!&k%P3)bM5B>Vk&`1ikns^~~Tv1eJdkX=f zsD_Y8z2WhQopa;qmeQlc8rG+DIDx3b`pH4Hu5q4V%o+zD&eF9cSjK`Ov@+Z2@ML zx%Q8tX>xr_pbjmnDu*)1?fxWP0?v!aXZ$%jgD^3{cs;3&k2p1sCu#b&jv`Qe)Bf?= z8XCak#cfoX4bR%0xAofB(28Y}*N=L`_V~lnF&RlK-J(vqI6!H8S)*p%9f2EwOS_9V z_f|e%RaRfzK3sW?sbivT!0FA`BEekoav_m2ShOf&t(gD^X-CmmevmA(AZjGvDZ!BwI|5}_z~lw z5*v`0YYPch+*!Yy9HshJ`vn=gK*EE=7AXhNB_({zk$Z8#t{mgJyg!8U`r6@#r$2M0 zzxuVzH!f~A{N6G-`5gfFv3Npf_V|y-qw!kuyMFH|@lqz~O|bG#6Re*{eJlXe>Y)ozdWIoI-4L6PQ!&@kBf2EQkP8uzoeFN5AW)2C0ng(eHX^ ztLLH{!l=Ob=y$7g5SH2O$6-1+0*kOWC9UeJ4+z^%Kn2V`3U&b^ zzgiP$T59eA5@jHm13CzVXi)xovT%Q4DftZY(@od#Euo1*QLI!A>e`BH?K8?zA~RaDOXE* zTM+eJ?p=Mac9olk7$=>sU{-DTlQ|?R5g7w5UA!Fj*vMVOHvDx!!_cs%yDk zn}!E&rf7F0omZ+r=}td|G{DLz3ca64g3F;vNFug`g#fETrox89=Q}O+v3i(@yAN!`5=ieOngK9gQ{P6s2bXk{9p^gYz1YXFezWx)YJDac&}C7izHN_{<4KP;0W+00X(8^T(b9^}t@L-rG9@aWF-48BjKmM-Zxi z6a`m1giJIDs6?z_ZKOiu*3D2qG0SU!0lS`vRsu}`m{b&6u~MSD1hrRg!Sq_}Lr(!J zi}WZ}K=1&#ghSC=1kaDDp$LEp0N@!qDGRt3;XLIWm0wuiq5SBCMOl2ic8wHA9@lF>ol(h*m%H*a zXw%2;uL|572w3%ED8lX4c{`a66isU!ECiQ)B47oZqOsSC z>l%wrF{0&HSggF3aMB+g)oWKF^Qj~p8#l?C>b5uVR31A$5oI1FkH-U1ukd3nc|05T zdqbLzAQp$YP@5Yjre!Lu3Ki)%rysdx)|%qd1o&m0!gb9$>sWO&x48jx7?~f`cDr3^}p)> zU;pIS{QRH){h$87|C1~G@1dZU+I-I)9~c1KRr+85jlYuO{5<;)|I7c+ivQavzQ1#@ z%QA!iUd!uSN*BH-=>S~>3#Z~4PujySH0Abi0zH4K8(qs*FZmi< zV016sUcN04<;7z-4zOtO?{qpnn_$1`q&GdC9WBG2Yx?GbZ^^-F8sPC&Z~AO@l$?!6 zzkx|Xm3p-%fknnN5-}N0`}YzP|rq*f|}Knw`<8e>9%KcR*^&P(7aLyFuFR zwSmF%>@CI^{eGN*`FT$UXXA_WWc`}+|7Z9`UBwZe+(-OQd$B>B0-ZDBk{axCp zm?9s;x6+4w4WDH?UQ*;cqq7fqb2?2{Z>+3h=G8A)BL`hxrl&Lc>iNrLTYe{BrNeZL z-t5kf04Ld2SPB?+rDL3fQ}`b+{wL%1fUbxxHde>IquCTbh2Aikf?ZDGwZfP7H0e!~ zcfEd}-V{*zc-BWBzuCfGtAkdZyo$98I1+f)2)N&oBR98Q*6SnV^?B8~k`qzbK!Bmg;QvQsXCAz5{Xar{as> zt|przvY;?xvP?g46!iHEk-ih`3t=-nsdv-k_N+f$x}K~+>v@LRb3M61KDH`&<|pCrcA%M>oC1f zR^f}VGn9oLctYSmL1SzM49VuPi#@@nY(;CFAj6Z21~&k2ACRCu_9mmoy?eJmZ>-cR zo8Q^m*-UKLV2YiEPl1AZF1SxYG=iOqN;F)D;e>=JMdy6a6F;yE_l|l~Xj}_--KYAY z`Go$XJGbzSE7-zsXAmykh8Pue(=B*lMzTZ(Z7vx%9U|-i8;(=(*{I*0=!kJyfLn}0 zT~{NgaQ=v)+@!|3rS4&v0#zLJbUcFEDD$G-?b0194%#2dM*Ds*7neT@)GMyb<^;Aq(2i6x^KW38|Ci4fbBUG?u zsev!Eo$QIi-Pna^D$y;c0teXHz`j4M}+EZP9#D{b~#NN zCfrlaQBlf*D#HZq*~eh;fd&Kla+g5wOTg!RuO@{c)u2GDKuTDQcmks#*$cWgHh(^d zOn^$=121qOv6^6ajNbKAxNEf2GKD?5o%UJ#sMp6L2cHVOx)}e#Y&wN)xjE~?5AQpe zY=ltRth6b#5#B;T$~)nmp)7t-r2{hh_RbfH>;36`3Ssnm8&LR6n4i%VMq*^Rz8GTG zO=f4bFjT>tP$|O<>Vv_+<$XrG!KU+CXWi70?!;$>iX_?VY^EW-%0% zU{3y9$Ozy;)Gv-UN@1|--atUQWt4>jCB^8OE+00ocX+Q z0NHg;`zmiIks+z>dme>ns&MjRh;xSF);loYvO%51zEPx1Mjd z5F7B-!80R>eJWw9^mLQ2pufN*rhs+uWV;)_9Vo%c&cV7zEqMX?3O_Ok?qu=A*Qp_l zp)u+ujpK!6q(+smm+#UMJTUg8VD&&>vpzZf9bMxlY;@=;8}jno@^%RE%w5)_yft|BVlV_XTFPuR4NK!L|uajD#w}N4K(*H@VVFY(JfQ&eJ zSXZvoKZ0o$>ZDoFo(65Vp0Dq0)?SNu)iABYD#nt8?KFnh)rK|v#-}~Hc?ai?a}b%D z(9J6RYBUqQjF$EX_~#OE%=HAmCOVcFbIQiu0K#(zhC{$$ulra#{%|4C{beAbrU;%8 zt+#ImqV?wTo#k7iX=MJY-U-yNG(#pMo+$+Mo=!2RCd<8adMqwBy40HE;|`(!wG-S8 zfo|39bKb(_ToI0vpmOCPa3oAE8Vs52Xja})b3B;{^!69pmX)8cTUm)BF_7xVWXS& zdxIX;87mmTGR_f6GdW8;z2gsn+(oc7mRX1)DzttqxWg-<7=%Rae?}B^QCGfNOAf7- zHCBD?>(}G-?yo<(ILIIdiy>fu7(d6ma^_fQG`Eb{6VC+=+UYPIH+sI zHm7~EV7cYn_wL@GO#1F!4uQ2>cW#GBJmV1fF^8W@Cx}QXkE(C?VseA*>LpQpF(lub zU=>z?zkp^jNn6ouwW_jUgc_dqW(wfUyGy(MeQ;LmjA_9=gN9d zDUJiSAyc$9RYT&*ar)>=^`cdl-+u2Vcn8YI)XCl+6 zum))?WOA^*AEM4ZH!2}8w4h}5jwxD{&%74Zn`Uc-Y&)RTo2>CS9Cd2!T!GL|zCX#A z5R=%Ou+5I4Y|=e^fIYW6Dm=z1PL{yP#V=5o1XKi|v~|)kj%e_Z3l%}Yko|B^(EPa0 zQQe5_Iy%a}&(YZeV$t4~apWcjWFc|jPN;7Z+8{Ab#f>Mr5_O?n_`9%$)}`W%^L5i+ zn#o&V^>LA30ZT&Fs!JGLD`B6?(dYM^@tYdW6r290&dLch#PN&I4kHPTk_QIC%JdGk z)U1S#P2ZGbZ>#`x?vYfUHhJU(s68sE)U0NWKS&N=M}?CN1I9y0RME&>-Pg!lJ+Gw+ z_M2n(F-_R`oYMrEN!BdihRFos?v1_moyN|S+t-ur7hi2Xhr+zQ&W~TdSbur&Y!xFN{c>C<7drOm%{ZXVAC>3Z)k6<7n8;=2&8D6xOiY$)GpHmMbEY zaSj0`mnf)?xv`*bgB4a6^XnG&|8Fj@R*Cx;Y0pbXR zO%RlsIVXU1@Tw0Po9)RNgJg=$)#S~MH`w%Zpp2q$!@XH~gKe(?LixLya}keM-z3m9 z+p?1ct*i9@=9^@FlB~i#ji3aZ*;vfzCYj|R-FlO3kKQ!|#RRHw+aVF59EBWvkM+1a zYDwn}Rr^%Fs3tF~D`~16EYC*p0*~Nt9(JMkh7|S~MG44rQ*V+NIu?Ngygh03;BCcu zM9A-PkGekf-i_@ok2B~=3&z)muF^hByVv2Cg$;WIiTPHD2vv=GH?Vv2#nJfTn=;g+ z@#q~`Ix>zD*42W0*0%yM8ta9Jw74-!$GsCQ{bH-Z@?Gu?dmhIx5zp?FwQPop(E>S| zywTo6XpCn=oehU;Ly>re`xdCvFUd-LWE zdhCBL(#_O(D4gP^7gjrWbO4~`jynA)uFj-?*>3HG(50FJpe4#!2 zZl6h2&#{P5Fk#0cl$GsdcYm*O6T>z@7_0cMFpwwkazKX|%}!3?0D=1TM)2~D;Vcg5 zY9a%|3!~TlIC2cJT{8HvI~m{HmUicNPBauZc>}Uq=k3#kxHD>ll3WK#>G(nt=vi;m z^h_14K<@BBSJFOa{D4@T&U(+L^cEuuKo9)iDV_AgQ5}N@KEf(A0-IAg%YYir@T56) z6GH^1L=+GFBxF<8q@B3I+V#u`^)u_R3KqlgF5>bc(X01IBTX?`Tt%$W`8;dc!I6MrPX^bF5-_*5c$K0;x{`9+|+? z{o<4m=fnXmscNlrAE#{)4$7N=`&J(V?2d3%AQ9CrGo``+tuqk@u&GcngYhsA zTY~HmyTMp+IRvpi8gMsb!n%X&6mWt#i%`bR(TPLPSUOyO*L&N;@`2bshM)0Q^XoQN z9)N6F3;+URxuY+KuCg&OKrVs}N3f>Hz4ro!xVQE;*PrZcY6RP^zSK_fkb!}*&vOk4 ztl?PEAEX_s^V_k9aQZ|Z{Ais@zVNBKudXpaIx$O1i=UY2KppR82 zx+Qw9kB$IZ1^`V}_{*i8tuAfEFm~&ui^iZ7%I^bEh;s?&8x5#5ZCc8C4$Bi{u7xA0 zV!;(0&Ow!C&e`c0(M7%`+OW_gj@5tsHiaL6^G>{MA7@MmLRm}apfrIWnX^V+(uw$$ ztoQbrJa!&FEG(G=v1YIB^8$vB;O3f|KdR6GzoiODib&8skDz#}UA9SscJVfK%*zd8 z`NOgY)uH_ss{{_Kc5s4KtTOrs-z+Ni75O*i>gRhXLjWzsqIw87FxQW8oH|)oW6CtI zig7#u+xsG7!>abK69Rr9EQK~9C_ilW2yow-WDCm^)L^s?)}=KFk2H&8+t7Qeb>87= z#9#U~kNt?UNHk@~{#;n1u3+SpI{*oEX8tJ3lRkzjr1vI57~NP5>dnuL6`< zougbO{;ICzxC2VFi-XeUM7Zgbpaox;VHp`-nT+J~Sb4G9eT5u0Bm)ONWsEcbuHrx6 z5d2o-wmjxP`itwIZM>o~7S4%i7qABUPwR)O6M^5ome^fO}Ut;gh zK-%X8B$NZ}XGx{R5Pvk7gdPPbYoy~Z8#_?#AO?!tS6c%v#a5 zTmdc}IhF{Vt~gR45s`r<3cPzm3I4O~(yS%jI0YTyYo@<>0t1ZU{ztQ3f7$?vJx+no z=>TLmy!?9&UI1O;#zrEvgU!9x*X!F`Pu34MTbmN^h!q6_1LqIn0nlSMMne14xGFz3 zYikaAx~?IybsnbRU%}I+1N41STIJ0(cj^kqS|uM5sEpx&tc#m$V4BdLC8yCea5HbN z-;d=CPeUQo&^cqG$|R|(4r$EM+7ubJs25-x084^57b>{#9IF5vP-zO}n`I`oPu48t z=mndF$o+)vQh;Bq;c2&Z9`WWGb;zrBV+dZYJ1u({><#&K?FYQys_&JOQJYl=p@?1R#ArT^^PY?w% zgPKE0?WSvPFKSC|Q^vr^YndYu*hzP$DdJ#);4CgSqeQ4Nk%KrU7xVb}u5pUdk&q)X z+Rjl~BhPj0poxi9BTg)0=?70OzO5(E|1hId9=doJeODh-{GKz4dwv9e!Ew0QFwUDw zzqj#pv(3}`(~psB!RTk77n%*O?m0xv31Dn^A^XPw+?%bpmufQuP(5t97I7{U8{!sE z>nVAuMmGe850tURHl0qY{F1un z8=B>Hmg=c%;ex?ZP+TOGnz8B?bU3e3=l5w51n6JkLCMiyn&fGdF0=Az10Ol|9?HcQ zKP1rX>0U*jM2BngBips=^EoaHgqDpRak!w{PzfttE|HzGOp($(qYgo!;rMPODZSqm z5(l9bAL-l3nx_AzMSzk&X#POE=0D!0QfL-{F3_qf*ihtM^J)kNG{7eD!p3@ngND5! z@>YGEx2J%bG{QC}7r@XVWZg-M7S1~N_TznZ1$0SCHeWq{fq!?3 zGJn*L4 z=bK@oLAQvxohz@rQRZ_9=zOl|d{j_ka|+TQzWV*G7tDQFyR&>_c{Of-ZAzjKF-PHM zM!G&-EM(gd2|Ey>gII@@VMjQn$H2@AM9LyWvDiO&vD@0g;qdjZHi1f9d{iL8t?#$k z|4l}3W%upVAhYq}`N7unm&9fzY9Ll(BVi0YG=Sw}gmh_$C6xF!w}XxydL$;vc5?D; zI+s8jds{d%zs?krt5KZ9CPs7#S_U(=5eOzx0lF(xF(gsmz(BflNM@&RlM)NB#;=A8 z(WWWe2krO00rIU#qb`vn6yVW2==*S<5V7)cnF_S32(h#N%kaz$kox@ddzBcmZJy`& zF?gvK>$=0kOv&>X2XIG7;&~B+S?Gly%)56mN09ad?-5nV0$B*}-Mb8QxO-2|sWa#u z`^}};3<|FK@Wpx`ze8J>}@~2521tDr}N?ys|Z>+gam@#y%VM9 z2IU2h1V;C>B&5Q*oC9gPuccN@^Fa$Pm!)K@)7Y09!eNk3$mgp=wjhmcK&BvO zi|-?`n*s%L`X$VU@B}GU3qw{(WrRITS##?J)M_>*DgoVvlx1{;2pSBFi!n}yNJP>% z*EuNVdKbhq%)@d6Lc$JR!O001Z~HiHF-EPSvAf5}tDbW?tmAYNPNfc+CPkcp3@DHd zYWUN^>6mwV&W+ER1qNH4jP9mM!x`zu;VM0cy@8a*J`DZ%tN=$w7pbCg0)hI71`C0w z5R%YN5LSDPJzc11@3XLEcicrnoVuf!jil291SSUZ=XX~Q0DFHKBIbp>aMv{;o*rMc7H_hte z#!=%2v&y6c67-6Ed|5tti1{RJ!2IMkBqizUwi=N(PgnDWsH(1 zNCwifz$w&u!pTKxifBhFsS~XHNG{C?8`uD29C5+{Lg+VocEl?)8lPj)Jn$%MtS9Iy zqBFNpNVEeZZn{bRaU^avCQpj4-<@rbka{S|4O}>C;Us{EAB=Y0L0q0+{xkU{M1hNQ54O=voL5i%)lxC3g zsWP_TE%T^~Q`_|jb%eY9{X`DUfP&W(+!#QMhcU1`D{|5T+P()M5vSt@~>> zpU6U}?0Y@=4G(mJD0zHX*wafHA{bADB{HV)yn{F(N8V`b8_0PKC3<#d6R4daagcZ? z@GZr8gfY+=;Y`%Yb;&&Iuy3J2=hTJfzw4 z`dX8$fd4p5OSbr1@7(9+^MlqeUcNZk+^;B5dwKA*anAyWg4$3z78t3m23GJwzE%@Y zc(On|w;fz~N+Q<^XpX!5SPQJAhE5Fsy_l zky2-P(-Wt-`M<}!K3Tdd~W6^9LjFDgvArHvh0`V&`0p+4tsRxnK zgakos27HqA)xh-bx&$!SodKebE`u#pF2iPbKn~9l@e(X0B$@k~r3!zqriBOiSw#(& zl&%Wd<1Lxy7C?>DTugZ@<@AN98L4W1A6j(v_3&K9YNKUJQqGA}Sg%a|ZbytHftrZ*fORVrGL^?M z0CIGL9dF%uFHgNmoe&mWo(qu4g-#7!ZSS;L+SNY%0dFjDp69IK|Lb z%=2+#s~5qEfG>^H;=Z%Q&d0+_#&Dq~Z#JD8hYz5=Iqg38LagX)7^xsg8Ukkwuo}Lh@f8~ z;$zmKs~_197>`et+S+aRxy~{{0}L9-`kqfCE>0L^iZw^k)e4CRNa#0AGt4;$6?z77 z;~c7$<-b{TI#W>P#dvclQ7h|1gTxpvK*_^1yE8fwP?NOZ*!WkB_8S|YlI(~j`zW%1 z`L7(^(c@1^ctnkT9OWfYrt!%{4(%vjYm~_o)eKEu{n5xA7a;U0$G}MWF#`cdxJx|? zx$WZNxE*dwa;Z-p00amA;OF zo*)Gw27mlfGe|l%!9|O%XErYO`3G3n%T7adJF+$}lBVTVLNWc$AqJ2qOjbKMb zTgIuhnVuj83hs-dBZr~~PIGug_Nn9B@p-!USUqSM`ac@Q;OTw0u3e1yW4{5%#`A{5 zB5IZF(PlGQpEek?MBX0Yj#A7BV>-gX-=cccEXpFgAf@(GL<;?Mvb2``6dsriKdt6X z4u*i$abLAe@Rmb1>UdGgM*u}AE10Q@h4Wt$|9}ly@sm1C!*K{oo2PhgS(46KOxfmZ ziF$;pGnPlnJ#U|bhga`doqwS;sL<8j&Ip3{;@rt>F$#=cwZ!S0MNvvQs&Wfk;7q4j zB}D@c2qN&-`w<3IWRHHjPa2@`pC7<)SGiJ7}9x*Q)c=4IHhIfc{nj z<7{8~8Moi~=E6Ob;{y^he1UFdg@2EIDpIDJl`~?1Keq;Qh0BzIQW(H2LdcD#Tl=}* z2jTJ{m4lz(zGw+o)DLAuAq4@%TUtzwX`6y>jQsoyV-wbCUj1k#$93}RU-ST7`HUX+ znLPeu)dM`k)Z+rS!q%6mn{D2y=5QF%!ZIl*7j0*=fdU}EZgFXsyDfNO9`eFmU~#p} z(K2nEm{hN^6-(ov|3WI`Ws8$p9GLq#_fA>3&Ksb=s6c-Z6^J93O`>X5A-{EN20`*BOy5Ta8g z^1^{&suhhu$%rc$A3+aiEzTu`D^uB(7;!$fU!jr_Q81$G`7U%+<}$#2D|)6EKWH)0 z;76$76h|BQRXiDp$wlU7Mg${$eq%DlrDse|HE1LC7d1epE-Rd=_6r)qy6A~ucxAGH ztIeGIOyqaRClU ziOZl}y>2oV5Y8YU`~~;Kfx6@L-EwCzTTZ((>?Wn-X8U9ecgIQ-$K{#etT`ATO`7l0 zqbB!#no443k-%jJLi7$A2xt6*dl%IF9etI1vgCL=H; zQIp{820c;{5@NiBTOY-e#V!jp^fVHWx5R2xL93GzDwR`@h1ae!pyN?(MzUTUO)I@j~Mvb8knh z8qLnr0U8gvdw4W@&nwCw*YK}lY~a)B+G)2vB0|O zIO_}JEKHyn3kXqEPjDV#46hH;IjsYNfur7KhebTpA;O2X z1z@{STYv{e@Fp`a#bUR@=JOIp@cl$XmuH$#enj-cj5+5yeGo||3p}qQ6kU;Do{K&- zFJ(C=_rR1%YssNk+FBviitkJx;b|NaFVIKy{t1T{qdE{w<)wp*q?8jPv=t1leO}VN zV$~`FAK(ojJ-pa+W)7x=u!A6fp29LubpBrUM&Ml3AYrfe)6MPYM3#ah`NrK_g2Od( zCro}T52HeNHt@%sC<^KGwpp+V>S*hxhCjY=K^Hpq>^?IMrRYM3l9vbWOInxLf22Qy zqy7mubsX`F0?(PofBrrv*HIBN*x+#F2sGfJfCwKHqSOdVa8X#~ge$Gcd?OjmY`aQj z#$4OoiIpfWWY}|LYp~sclFEyrD}7G`v}jeiqhG-#S;x=ykG3!K*tsSkFEXvGDyR%cy0*h4B#|&h2hK4E zd+n&X^<>_frYFzD&i4)v9!hXmWx@*~WH*uM`;mODeiEF!V|RHl7Ka&a@6LkvuQIbf z8SzabM^2Am=3DWE&;9i&#=TPG3?p;z4O2GAAWV>T8aTO&kE}jp3|up2+cfUBX}Gb_FlXt%2T?K zQa*^XDXuUzAU}Q_=AZ>=pKRU)zgJhU%1}DSju<~!SF^*#e!aMw{1AMP<)6>rjOCQ4 z0PP^JpYzGkALlciBIJj80q76(UJpG%Cz=)qNU|fk-p@I4u5({{DgT(TcTWx=fO4~s z@ifT4(0S`=|2R}Gebz#5Vd|8W9L`V}nG@1D6F`8Yfv`{Sp`x~F5A&*C(Lq%lUPB+6 zU%vfwPrJLbm;uhEm8%5O6rOCfY+8bR!J5P+FL&N8hg*5&bNrUyGp^^GM-Po#DoCM2XQnK$}rXcv!a>w^_H4Cs%Vc?HFi2X=xPz*stPRNg~? ztQTRK5?Nhu#eWd*ia(T>r<3I93^*c4epJfr)PR@>C26*7c82UyH~Si!hzsN z^J>1hyut>#bN|YX#qY)V5`QqnpF|-cZVpGB#hvZeX-89)lnnaT`%R3jpb#Wh$lEfL0+GPkpZAJX8Sgj;4|rK(lOP zKle@h@sV9?Q7X-S2k0U!wz7KjR`M7p3c-*y$qZxi_eBGFB=H8wfpTY9O;7=0UAk{ zS3bvm#CNcwFRxTWK&?ALtr~7=olKXh`aC}5yS4Vp+S+T2V$9PH+Z!Avr`17ZOa23- zgn+jOcL-o1#eG(9W#OZx2VwtNj7wtAG?AhnzR*@toO}R)6%c{%B=s;Ss*PdiClsY5d*m?+^cW;k7(kSz7vT z_4e)SKP+9S=pB@Nyab!oYoCsaCmDXIH*9z;uzp>K5Klkw8m-uf3|7|v2)vh*P9lm;vH+P@D{+|8C^BeAG{n5>( zrKPL&N2^P(@Z}o6ECCz*`)FQshoAj5AzypdY<&LU(cd=yuJQWX_Y2b1RnV;p8P=-8 z1!&BnA~0GYU=G}?W&T@#bW1Q_S$Zr3wX$^BZv5^>lEdIsjk^*cW-Jz4|MyXXhUjeO=?&y~IX!`dag~fDjoYukU&Y6**ZAl2*Wa(m$9Jpq`gyp5l8>Yy`@~WG z9JIOl!_v~L*LbqBw20LHPpUlhrX!W-ombGE^vI6V-@b%Wa1dDirrbid$+ccwkPB8< zCR{1?FKUB14CN!Pn@HM=V4wRPa`e1Ak;`Og@yUL61Gn8wn(iXx2A7uRU#AW386toH zTR)9DPbNQ*)gW>NIx)vUh|T3CE2q?YlUbGRid`x-3wXzkT<@FWT=cn?0ky4d`5ti)vO1?{pruRxxVnZ_2lvZHEa z$i>d!h_&|?2PAJ)7ctcO!8=4xfg)BNib5t@O+~Fkn z;eY}iVTQweV=?cS);iy1lELf{=MBih5xT?Hbku53Iz8qRi-s%=j+kW)`u`NyK514Y zA2JXf5FCeR>4}^a0?pM|Q!=%CD6zi3v9%>W8mGTA4j#HcQftkIAE+-~C&gfN$we5Z zW57Td@UrRlaEeWwfrFR7K+N-K$MUc9YaWKBO&sfwE ztcmzpW~IBII~fc&5u9sCTtMUx@QX7N$Q2o_tzv%i8TEwVnu5zQp_ggpgUHwm`x*uu zF0#jQkJC0xYCj?d4@agQ6Jj>Nf@teuAmd2T=`y=u=E2E}1_E}ya;x2Exg86KfXIS; zIX%tIbc4hqdslLL;8sHR~3DaDeC9|^n$ML-oqnBGp+H^$W!Vx8_7Bzk(n7Nm*=Mh zvp^L>L?FuvJ=72in~Z{#tRj$`xP2a0q*#vP0&BP=V~|oOSoV1FdIy(Rov0k-jK95n zD;qL`=ATAVlmD@`>b?8=P78REf?%>>t;jl)fw-P*JwMoPL42*_LYcj-b>usGd9Z)$ zPPmX8Y>r3BP)^!M$;vu5Z;K3dgWgacr9()V;ToZ1;IJgL;HO`~f>unkc7S}5a9?c$ zq7Zg{+wWm99KN(;)#(UC!feF*lt>w29}Xn?i0wxI34g)UviK1RlE)*&UlAA^vxH_Tm6rnm}kW z`%*DFyiG=<4maRfnyjs{fnB{HZf9~*zq5Mx_T9TTKVP}N@Gt+H|LE`k@qhL&|AT+@ z_y6tx@Gt(yfBOIY^MAAuV=U8j;OPqYYzw0v4z^BgFwsEe-7L-W~A00+tGV8wBM|jmYThCqG-wjiSK)BMN<76fmb9Bh5-B(_gTKLnAzZzZ&o zWSOeaO%O#iG&tNlZ{IQXH__x}&q$kw+t#G*etOdGd`PyDto=RTvs>B;Vg;RU9xhm5 zTAMGnbI4@nEdeXJ25BKrK8WGuHWVlxk+vGz7x+u#2NWUbj7X$C8sjX8qh=um8yUc- zY$B4&0MdHjQXn#dNwCL5(z8z$tdOB=1*s!e@kP0Gz3w^$V+q6^r@~Jzg+7?-E`04b z5W-h`_`tH%u%Yme*qsk#Z{$eJ&Q8W{XkAi;od!Zi26D>E-D|9HcNv7fwjA>SZnj?T!!VE7+`NO&`qKhY&~ zP|hpikhvLMke(uhpgZOv_@fAV)EqltC#mW2d-=<+ygKa;L+QzETK(8uW=84~cM?VS z?r=p;m^)Pf%4or=QwS&(l9u)Pm*302kyA|4~f7q@j@P`82ZB+fl%Bi7=9}PslAqgb~b#A=WXM|t=%;R zUkduD*vPwLU)enlP0nP_K`Tc*unzy|C*f5n1r3d_oc6`9_UEQp4mL1#k7?=@So9Lu ze`cD5^Vz4~dl3T?B_z>Q)34>EFOUlkO3yuqTj=A(QM%DXX}$ zfqFhKeTg;VYF#LeiPa$kSv||Z6PHd_BRX?cWIO6t^{O;E4P=EKV6O`tSptJOzK_Mh zyzaCzjSsMX4{%d<4>EJwZ1W~rI^w@IXS!=4AVN@P^F6lACz0GFtmSBixgVx$jkXo0 zYGloZs~2L%ctx@G)?G9KpB_yl?noi46;}jk zE*8huGe;y*!5{l>w(&X(Z3;;0e>uVOC2lx~%abTW=;YPeByenM;w0Kf3i1QyS9Vtj zP=HM^JmLk<%W6l>eRt8eJ8+YK8lkQ8p~%$~M=95OyWNmpSlP9dcLTXiUL9Hz1ZZ)_ z>W3Eop%N!|Umqi6Q$!=41iC5d?hxWFbLX1rEJXTeG8eH|u=DsV#wXcZQB%di3n>Nd zl-G+`zc3EW*+qXjJu^WXDa8-NW_|OrK0~*#a>Tmho+&ok$r85ZddqAqYa8w4#~1Se z3w5V`CZ0u3b}@8ut-PNHkOV`gOH*^^jjxJC2@52rX`yU!)x+5$pz>rIdDRxPG!X>GVg~;%a!Mda`!kZ^;>0X*f@OK5~N}?N!iP zxgsmq+zgKyBmr>MOq6K0(&cX@QBmcf#Vpw(8A}433lI~fiQVwz=UY2uh;%4-W#o|; zX`7R)EZ)+6go1=%Cn$#Vdm>UEnlNnA(YT^UJyHdEW4?vRXz6ZKq#~Q6&0byC?a9Ie zV|%u400k%4K$L)aB1ETzyE~`VeG4h?<&8jwMi{ZziEl)D*t3kODs(be_tN|^ADoHm ze2a z@fNuSbYcme3!nu%S!(r30PzPsHWC-kHushf<}>uQI$_hs%#nMsfX6 zE$B@K=J>H7qRZ}{IOefPptHhl1KIX~7W^(_wun;&!fE4l1Q{*Ja$4}42ZA~WLa=O%Z^lwPFxM>A~3=(hT;&Gme3^P7L&l|!JlI-$MptmpKDrVCIpYD z0>x&Q!-_WzT&ziy{L#%-5r7@d_mCxjM03>vPHbwC^xMHTawA^PYQ)lkN6reiTeL}7 zjelI9^ngoF#6zdZV8*QgtzYbCQ0*fJl5k6sDBjqQASzlgn7==H=0?KX=YJUa=lc~Z z(vBO$vmlT40L2kC$V^z&CMpwb z!~l$X0wihVF1lcIxtW^sPKSWVEbs|B@Z)ixi*`5>edj?sb6NUlpeQbYk`bS9{5k`_ z9NKKka@Dy31=%xMMp`(jvkwzB}50 zg32BB3OlLpLGo(D3JV5Va;2xQE8e@tI-U9NvF$UzfU~r#3Q>Gkz0<*#eVmNRW$@fT zhp)@eV}v6c-jEZ;jxv8#+!!!t++B02X?M<)`@K)Mpf?wuEf<(6o~7r`l8elcb7zMG zf;)f9+%<1jxOedx;a*nH29XcdEmq8e;tVKq|HU}}56KkZkBqEkAA^4#>ZMN+LJ_J@ zH*bnb8$P;qn-Lp~qOh%xGvv9%wx`(gv!UF;Da&f0XL-v#NQxOO!0qvgv=cnSnk>65 zy&+;Kemi3vCS!{jOL8{j3GEb-)VLu7doj{*7EtBea=nLMOSPHDizaK$<_Ru8o*ga2 zx!v??bnp!qGR)FR^YhhPIYO}42vI?l9F8OyVEZhFtp}0k?kl#Ipk&%stOaKWy1E;m zSmpq)Agk-i$MqwKCeS`}{>MP0fPVaRMwfmAR>kNz;|MZrp5AhGD|b{>fGfnT0)-4l z;4`0mJE)BT^tEw)?m~_CQvy^CH-s*{T5!K!E#UZR2C%d?M64$^>N%A^7I8x31eerE znkant&0@jNK$BH)VINA}xR3kU5H8{B-A{09La)^FVh2SXmWPWyCb-Lhv00FDooAh4 zsEq@@)*yeReNjGy4-1Ye>{4Ot2LW$906dk9w+yxehsw0TX_sNAKVxJB8l}hRnz1Zf z!k>&8TANHqXGwi|39T?lKGFzg2@a+sYF@9Pmm?uKo`Hr&Gwi2;=Z5J?zjxBZ_0rg% z8W+zTqowCQOD(kk*^hB2>~X?l*w}_g6rJgx!3F0|r^6d(XF%k5KZ6-%zerEs==u3# zOR`#acto$&?gLVN5m78Z`x(ts2H@2mw;G6nO89hsHpU7jA>D!%F~>6(6n@n7i$*!) zwy3xwWYbP?*kA>-x16b$A!5UH+C+#YoSe;c*u>O+i);c2VZ=MfTmgtbRb!n!BH_#d zUTLUP3m)^H(!(%)WYJ23pj6X{yKm)bDljC&t6Sz->?vLGjF=ipr9kr!7y@t6Hj@|O zBm|O{CbFSNl(>>-lidZ2p)9Ys4`AUUV$Kiv*)`f<0)tbWg6qRX6Q?gEgKlvm-Wz3R zV_poenW&wcvVn-)Q;UGbD#}@d4ZakS6G8qunJT%>EN6qNd)e(#*kVE(65$Qr9>rL| zNl_wQv$+ldf(xzPU0iP($8Q*hIXcq=lqy0f-jJJ*(xyLxd_s@09rl682Y8fEk1KWx zVIIvU?-`>w!x95QGr-D>EpUWOAk!bVb{SiNqdggoRmLF>WPlPKWUB~{{^FLIfgJqh zmj*LKHQbrsCdxMXph-d4l5d^U22iF?b-0AxnSm9$iP>p(&!~dwM7NSm zc?)R}X@z)(mD21E#HdKw^W00`6XKd9AMfID4(yW|1u2C}HbNTm<0Lyiyh~O?W{YFT zt~j`X2gP+8+M$EbdxDe&;MuURwCU`-nQ-d*^^e6s!zxm2HXw0@b$?#3eG{dY&*|}; z-nv(?ajjcH4?nWEK~KptFj-P8f5ygT*iE@U74Pj}+8qdXs+P^H%OzjT+6)|mIX-i&UtsNr*8jCO1IaBIb zwGaIv%iSjcs4qxDL4jgUgR8WIKyy*;B{&5?Sbj@-oMrY2^gGuhmU7*!+J=Vq5WL9C-=;vA;7d&|SFaDSR;_v_Ce@du&{`CL;@BZt* z|L6a>c>Z(|ke07t#mIyVcm?6h$OGYLCK=*|=-H9Gj?NXM#ERKD2(iUf4Jq## zgZ!C$Y9o;1IK(LWh)*?PrUR`L>hwa%z%j$_)WVaLTEDac$h0xl$#tKrbGVp9w`XOnkp;gO0e^aTd8X7sxDxQ?wi}HZ*qsEIp@R`|)nPSIsa-MgS z2L}+tUQ|NnjHXoK3GIuFUDo%-4*Z+kgDTxbL!T7#eIl;hhpuB4LuuNSy|W%BzU}Qp zqInfjZ*6QmtW-(#oXr$52&36qY0y0!sBu!l8SJHkR0GQc=TW1Yd3YmoHy`WqPmi8Z zI_uCCX&R=Ef3ds@o>PISVDi zqr^vZrj*WRf@vYYO{?AEUDp>CkHHj^=`SY>;5>!8*y;rlUY_r^;mti5x3R+^g|?oE z7L|b^SzP}p@qeDCXX|~qc1k_U5dlUCwD(Ys#JMR~3CS??b%bNWd7?YqIk2IAlg;8x zywGUu993Z(m~vT{jbTymu;v&vw$FVi1;DPaqi-+#(8%j7(g-3I+uW|A*pB5|hmvHV zmFEDJ5fRpSod-}!W1NZC1R^45e0(dd6Xsc>@<)dyoOfwqaup{}^b7;#BfRGjOSNKP zO*XnV|3paRM`?70aU3L`eLxwxP4zWbLKmqa&!iKzIbw#8VskZ5Eom=Yi!%X}Tagtd zv$$Bx{e^nZi{}Sh&tGolTc{k53mTPML*yjpek1agtJVdHz!esjrkE7Szz!SIYtuMG zO=z&TBYOdBC}QU0eaoB$;Bg=+lOrrNYZaPhAtCBb&mT9)H<=ve77`n|0hoQKs8h zV~M>(j2I4@IfhER!S!UpvY|_jFBCZ=S>|C*iyTn`k~SWq&j+}<1DT|3X>vcqSyHU= zB*k9$HpteuO5}TadTzBBvnkA0t0#5PI3CTb`E@!zvnt(D3*&W`E6&RWss8$#!R}`& z`7>TT7?6GurY@!hH380BzmJm%iA*{wT&{ck2JLG6p*-Y#)nj6%g3(99bL>8Y1$EM@ z%E-)Y%=O8n|NXQ-Sz3G5eAPrI;w)|FtL4V)tH`N~C&%lJr^qY1_WBw!!>&E5OVZe@ z$PXJkiKT~GGOQzlQu;*1vz`;>vZ=(UcC5vMs6z?u__4*-Bsj390eo5O0r?4xf4Z{_ z87jtR!m>EJ1p?=>VNt-39hwJI^R4{>pzqP)>gzSXbCrO)bjX3gG-i;pT3gQIYxj*&e`4g3p|z#8(JK5=Vf9s)19rv?tE$ zYf|03E#YIDOIZb-j~PDkSse5YO=0t}s2CCxhr4b*k$*SZ+@+P%%=`P>Vy7K!?=ygf z{3QuidHYj-RtY3eFF~|GBQ;~B-=0cA2TOuBz^%eg2Ck&L9T}#pza5?O1?1R#5xIPC zn$0J&VLeQ-WzSx}K-e{j;Zy$x3${X^^zjZnfcb|FXPgm!vAg*kRa)!YU%hDUKU-hD zeW$!}NG@>Hpxasb4IE%2?H@+T6K2_hbTK5s_}l=QCfMv?d=j#4**R^Ge~Y^tlo=YL zKy?Ub);X>qsHQ}+ur&71{mJxR1TO(j6eE_4Dg92RaES`+qU@I3G=i`&hM3o&A`dwu z&h>{GHiZ?T@KYoX=dNe6n?-8{X(S=WQADTHE`AmGVsYwoWZ(PghkT0(l}u* zv&Q}WBDr(>_RTv{dSw`}okHV<4rvS6rGgqKen+UF#Dj-NEyiv`aHOF-<`%E`6{-7#lmI2!8xlhQatJykTJ*!w;%9^ju z&4f(aZMKBL`g(k`V!TR0-x)!e#umD#b(nS^p ztV&KE2+OP7`pkDxOkmtph~y!-^#T|ChBQtsRF%&pTSq4yd_&Ikb)9_ zjr@4m%?A_&p^ zjS3ghcf6a7%LIo~LtEMfzqD&KgCgQy+-8z9KF0(l=2vFVb4tL_IZk!l8AizY_hA6a z2D9XF=o4a^)!X zkp=TZqb_6^2yrbeSGbbda;3_nUEoK@fKh_&gAsL*hbJ@SL=(@0`1WmsA|q7Uv)w}| zNqb1$LxQF9fDoDBX)I0=b4}0+khWlTY$C3)H#zkMop350K4%?CTAys~zew)f{JgP} ztTz1712CzBDTOpi*i*#1Ah`xwSvba>jq^aaBocd<;n?tOl==aa2>TKYeTKn=14B$Z zhD6HngG`twyNx%9hXuQz`c|^m9Ph@?@)TK)mlA6~>X;X<$M8&~LpnJ5L=mO4!nG7| zB_{coF5NRPp3_YN&G*brCQt+GCo(*TqzYy<0{f&u%UYHQgZyeyI~vPASnX`u!q>ur zS?l~x-*zUYSKYVzs@pET8tRsOZFp3AHA%JB6uo`@#^A%zgM+-qRYeQp=`u|LhNbUhMX_c}H*K*3~94M|FCx$@6W>A3* zkxuhs7SEB)T*n2&P0$iMQhg|f^<_A?`Nv~t67g5=fz+3UTj}Z)A8t)+KJN&E-(n|% zqNoM&(MDyec$}sKW%A>~R9_Oout}{w#nee*c$?{g#j37-n z+WpQ9q7#}OwB)17sLwlAW!c8zB2`56hFO5z_~r?heKHhJFy%#OZXIp4o^0*4TJW9W zb93Y1#on)4`EJifvGATp7sD1YOqeC`MhWe0Rr9MJ8G`NPDM74p!Z_$;(UkzOJ4go$ z*#OXNUlmniEaQ*XxSdW;&Omb*gwSl!XW5eO@kyDItdOHqXl(E$|EgV$&v7F`oZhu0h}D}dZgHKUyB_M z7=x9ZO;Gsi>8O!Hy)JQQvC+KC9ILn5i+b1^|4{KWK|s{v1BUy-X9lPAUP<(Mlj8kp0x4J*ps zQ4U443+;z_7RKa7+Bx>>hV05Cg)x^f3SbRX^Jr!bW#71CY4ulf^<}&HIt*KlO)u=cxhfnWOquMI={^an_kq3m&m4}jft zIe!;9ED*(fRAvv$*^k|`LRd%^UBa5-l?5edK?bDiNV6k*==bxyN5VUn7hJh`Vco?? z7P&5`oE;F}iJD7sI**y3%9-k55O+2(y{8iU6%bl`mhr+wqyxP4|k<(Vk~VKs)2f=Trfcau~Xq{E^D zlNh&9a#Mk+_z`f4xi?4%>_N0f32Z<626km{m~JSe;>iw3z;Cb(P3S9yU;jgWb! z4`4kwXopOBb9M^X3i5$_1bykpd3kQ>6=^`&ci7Ryt5^k?2=!c26Y-ky{5n#HNR|^< z4Q6<;Cf8un{kLZ=Tv3}Q-?+PxQDZ!V=X03+Lc5Eb_FQ*a&cN8`<=CBFIDid+%xN%+ z;XS0PDwyJnVd9QS#HWIlD$Byj=$I}hBvXb&^=HMC2S|Ace|VOdImh)79S}*uvMtoi zgUYJr=L?JS4^wgLIGIh48~2nWD1ER}LfA1}f-$$EqcJjM1U@vy6mKNIfg`0tnw;Uf zHN6|-=mV?)@355HtC7ka;4(fy9USIpq3wIPYaQb z5S)x~#L|W@^$H>_cE9US9%@^OmSp=Rli8B>O=!iIxU?nAnKIz;ERl!u`!$6s)Z7 zQa0!{VJ;rcj*IQcbKJ@_nGz1(7R*Av&v4PU7#YiNC0tmTE1OMc*#`mx3Lm;EICF(@ zMXsi}=|vEWl98m^pOhkg-f&C(1n z3e8KEFI1DW4`*pym^6_%rypK6$O#-w7b|`KX;yAtg(yD@r%sw3Wnj3e)PPaKc}min`3KhlCFpIE)_Da%S|&8MZf21 zt*gFJXAYxQ5H|97zBJ*CZ%N=MzEre#nWb4Ih>Fb$Xb}{J9h|(C(M8qxIEG`03cMGJ zY{*=a5^AqLY3b8kd6FAdDGq6UG4bhSq~U3N5`IRy7*$u6EGv3XpZSF25Q z%s!Z9-t zc>`>p-ttBZ_N>AyS=I*w^l6wFNy|33I_bsq*&We%D00hUA9*PmMS^!XgL&r`=Fjo~ zN;3odN0aHs>1-%gyHhnQu%jk#tx*Sa4Hp%$MOU2~u;PrtXO7UUEjX%h!*+lzd6yGh zdZ+1Y^H55Nvj!~xr({stolq1Jui+|%984>ou5qxIM>#p_k2-IS$q35*0b+L0%7BR@ z0K4coo>k{o#;SmarFV>bGiBDWH;xAk5{CA~bTvw1p6Q18J$#U?e7-twte(;j zphE?&hd-Z}xfX^lP90EtFGgc=u3*$WvHcuYB__TD>9Nkk#)I<&K@`>i1f|6)#4fbe8gZe@aqA61oQ*Nv??ICU*s}K;}sl zTiRk?0T;4tyVPvj{W*a1o9Ek)YTM04KSrT)y^aJi1MXMZgwbrIvA_a1byZuI-6Wig zk;+{QM{t6wDl$U(+3gla^htz>VXeRbh!Z=LdM-;S{a%hzisd%=qF#G~$SCgQi$~JE z-%-ywUnP$aFw1myzy!rOh*^t}hzD}5f}$Lmo7^+B8N^WxrcULxO)TTC z9A=D?a?y@NGnOU>VP-CKEeerCuer-bUgel_a1D!f24Gah0F=|3vt9la_ii=#LoQ*EQWiF>2)*ZPcpu+7}Mj_5ZKSm z^ZUv0Trm6Lp(g22QuASUsThAfM{xdY*~HI!4W8yUyM2O5w zW>BcQT2J1Qisfn<)j6aE`-?829Md6Hv(PWART2mDDG3^6q$IQ|T9!s`FNKQ58|E%Q zd{VU`T<-?afK|1Qk#tN4HAM9^Y@aaCFjN={>5KrEkq~9tgwt|gTgd36dhRn9@1iqE zlO^Pzxr+HboVlrr{z$$<=wPFFuyi^&^@bT_OX(KkhM8N1kw*~a1N3;5>^9J(zmrDt-h_UuxyV{LHZ6TX_8?|F@g##+& zI-KpdY(j_={$ly+4LlUBpmyA1ckO#gyW+!zWC|n z@lPiYv+gCoE%cj7w3+#Y9hOUZ*{Kfi1!pyK%f7O43& z&=U5iD%97Td;422p2NjkOX|j^^Dn(xs^uHb^)b#MgAc!?n1BIFr$lzKx^+8XF=9&c zEc!Yn$;l#f2@{Y3?oMkv#FHR`@yN-5(u~`{Wbcg!dyp?!G$WUH&PV1+Zvy8OvIOFO zq~|z=f6Qa;{GsYa7&cdIiNo?R=eo>c3dyqG#mb{XN=0N4pi)#eH>8}3L{U4nMv1<2 zyOSS#(oqLgVKL6oB8~aZ{W&hr$?04*#yRF8hocpY6bHvAW5Ai27Q)>nfcceSBNk|h?)5JTr@<%hj@8UK-}1m(^r{DjX=x= z=Gbc-fF2wnk5qG<@}N)merdqsKU-nEmfu z8gtwgb6pjgMQ*ejwq|S!mQNH*c-r_!jorZX>7Mhe>kx2x>PxtME|a zVnN(Rz*Me5dc#bv$@SazMqM7)p?^pcB zJm0`}t|#}19PG*?M1kY}vyFqz3>|ivD20?MVPS=8gcKT|m3SK^O^U~LQ$Nf+S&lqT z4TDFCDs6@9ticRM!ybW52XG@uzsD(*IX!ieO(2X6P7sxX=E}PgDbNXIIf<7a$iz1Lqk%V~vYz z3VZIj99=o@PDk+W3PU=@!K(?$mfRIeIf48R{S>}ZT?Q~Z9EjZ3iWs_bT$`Jx*g>_c zJv=yvsk;)_n-6PizNnS3&r9nk`&i=H6=%Ge|20rk9FfMM-M|{p#N5w>5=Tg%@eFF-nwmSU*G|-QO<;Y)@}~fRl5KG-*e;5YZmz=SZ|k)q z^~p&(WGe7<3n^ffssSxrAmGhao}s+CD*KKM(?Ie_$e!^24l=F5wBxNc2!SrHGU0CJ zB$85XQC_V9d!evNkohhg7A=s^|a0GoJbK4zeTT$1kK<@ zE+vDhbd_6qRFmzaYPvU@NYbX8eH}`{HuO%M{(zqa(307i6O?2roKwQg9pl7|a>i(076;w&3`eRvlH_){Q8q(H?troN zJfpBZ3E)aer?+MW-GiVU1{ypohqW-_?l!2{brB+XGR9%bAgiw^1(~wOzFMoY)S8b1 zvy7$KkiT^IOB9ZHV{iRDPI(bElTNQEN&&1LZVp4*KqgB6GI9#diAF}K+HBHjvvPO{34_F<{A)J1 zj`d)av;zmXTm_88bwC993Lxg>?4`TWKy!~$DmZ-{q8Or1Lbec+G3Mb(NR>h0L&AN* zNKlNf0pF5(DH)TX*Jkjz9#bx{8)`sMXU!0nfm2Bs>T|ilGo=B8N5{c7?lw-x2f$*d z{oX2E~8xH3@o_3KG5w}?5FVRSbn zTV`pq?!bkb@knE*H527i{GM5^-HR+yzz-0L4U7Wons=sC9aAdo!3IpVXr% zQip4vLo;Z{NFXaw5cq<1@k@VlujG%!78zkWo>e_Ax9SzGST<8^LWFI)FKS~bzZ`HA zFmpl0iC5Jr^=D$Os@I(V*YEWO3QnxS%eqcuX%hb>_)~Ro;UB=PD0Y zb16znlI3z#3qpo((LZ46qxrIBE{bbCh`u@QOg?0TRlO?tgxMlv5053Nh z^LTot%+u0O2FFlzk+K(Bp`4J5_3=xqVO7u3 znK`;njDzQ>1N~`5AbAewPpOIh`AkT^#MS`AEWfi}9b{l>dFICZxt6lWOuK^^H#|=>pOE zsm%?i@uJC6&_nIlfG_=k1DVCV7=>4LfWCugpH zj2ehrc;~sU=Np2>2Ir}P=Wy8N8v687`23j6TtueqdTNL!Omv(Y@AC*bHZCVjvYaMw z#9|N+&KoJK59sQ6qZ>LMjmwlM@L=1+gcWmVGT?waoNvr-f8)=%Gm)z_j}7dO?3yA_ zlIhgPvPWytFi0UeK_2sL^U=T;90J@Z58W^GSi)6}IUAh!<$PyD(b&%g15mYbjr1mR zO-AI7EM-0H4Tbxx>|IbhyN|3CzQ>a1Ub2_JfQHBTL+`B4@9=H?R)3{7{_vah?cUuRWzdVS9b+J?YJHKOgFGu|1-C~~z zGw2t8@(emL z!ovUvq2MFu%B%Lco!eErdqq-C2iGC#{R~7^+K&3zVtpn&1SOx-Yb_N8irBEx_-%VE z>1;S(5p9Wk3QzpeL42R^LXG8NI&IrUn<3c41t+O1a*9bsRSUw1ZfG3>4TlNyQ5*SR5p6^OI?6g2E8%rg ze9yo6^YVfuzSJUPa#XJ1YH0u~^p{8<3d_r7uGX#8e%NQ>NhS6<8W2ls=PIt{EuxsQ z1m0vnTwJnX=LLug< zrOMZ;V({QoRS{8cv(W3SSvl9$Tx7P-nG*~04`O}{Z_E{kBEMzW;FmQVIT7H_cokG$ z4z^35<6xE~ku^poU)f?q2^8>TFwh~y47Ui>>}3Esdw4E%-`8T0zo$Y5chg0Y#(@Th zaa<2e{tlykI1z(tK83-Cc0dlJt|dR6WXIykI(R!k%)4vs$O2?h8MnBwgdh=h-xusIioXBq|fU8#G4*Mhz& zx5aAJvPVI=d8B~Q65(i}jSPwO(vXIN9!Ar{dG3Zx=ikPN{;o=)CK*4s{rrfq2Gvx_G zvRu_rJhbNnmJ49&mgd#~QScXm>2^SaDH;cxx$`dqRZCYO>x7US49T7c8u{zDT8wsK zr^D$Lh+P%ZVeOLiRjse4Awo9l+R!*fn7sI+=sPloz%7D2d(?)53O8-LsCjq6mhy?j z=j+j10V~N7GmfXO5bu}6qDjYf+5v`Bv}#{o}c$w zS8_D@6#ez9Hnmm^qFL~M$ z2QYE7UxPvpu2rNzVoms0K`Yez%o9aPi1fg1-uQ$`WT0X8*wxoZJiN(#&hWOt*UncHX5vNpX*- zDMFS+rKJ3dKz0}?0CV;wbuIu);&HBOzMG}6NuC7XL3xaa)w0jzu~-imImvf{Tknxy zZryWC9ai1+6cbP=N~Jf@jv-8I?qrXXqA^v!j4VWd;4%YC9!<9n#v&XotgG{C< z#9e3SnuG*kmxR;z=(-bnkY7AM*n0kQGh75XZeCKjLBvrCUPRW`RE$yDHFjs)a5Sfm2j#7 z6h_^#p+lkZ5dJQwKbBn}u14C$&1fg}^UISttj_yRdL}pYMp>lNrBPx{w~QB)m*mR1 zGC_JI|GL7rq4(y}kn!RyQ?@hN=>SVNd~E?QTjzRu_gFYN5Jz7ZosIb#2Pv5+GE9xdz5+4Pgc$m zQw!Q-qh{H#(SGs#Ot@r7+gL@cnX=wT<6Saz$fY1OR_TQN|Ji%@t~ib)efa-9XTL)k zGt)>TXfBdvW9xztve-dF24s(aNP}8*gW7^_rW=f~Jnv_JpC>MvSyfpL$eP{RbGB!! zZmRMU85tQF8Mn0lz(>Rhxq2R&-tTu`BBMauYE;CZB<_7SNF=J4@5C4Q{f>(G7xZvF9cfdtI=6&|$mX`le_ z>pX4xQ74*@I|JC1MZp413oRc|Fhh#43s#_H(bNDLN=KV-aU$iJHC)NG%;{ZR_KS^Qstnf!ET1op`|OmG)PzzjReZfoGXYa$=>p8IC(yath4mLAxAj()B>=28z&pd<-u>4~k^aW5m&<9f4CGf9CT(`95&znKZV z$`mElN;8$z#Z|0>(}NipvHvvYf7~$|4*+q525c~HvKnW|(H^=>m1Ry9B4s364!X6E zdblzIW}&WG#XhT|DOh%PXn{I|ibbA4bxvV`o0W~MW>@hEFIY4Dp>~mPd8DCi6s;1P z)C~^Mk~$9Gs!#)VTD1&H-lczE!>po<$}2YOy9D4~mV$9Qbg=9Ct|l7^G3D7tMYECL z+^%LOq03zB+C~yxEBdb(1NLz1GBdPr)^~Axc{NSlz5PHIl;e< zx5Da-7Ho{RI@7Tw%=_~y_p?2hn3!>)$t=P4iGMXGKsSmbu4fv;X+P6t;>)S3eGaSs zv$Fv2(Z8?fwxCcuX<%RpNlaYbF2S)-s%rI2X=v(nh;vhK1pAD6;MEtphC!J9Cz4Lf)WBvKs-p1PV?{}Uy2%=sZ3am1n zvZ*R#;InFo5})ZvMVC++r@j$hUwOlN37#E}0o`DzwS5F-{(FSGaHPr7WHo*uLOtue zM?zzGZ1J=W|Fp5(JB{NoU1t=|`jE)ma6uPZwW&iiMls8T#<1YxE2{G_p}5g7eRA0$ zmU%Ri@)@XYq3aOz-)4N;&Nvxw#80N9=2mOF>?Q51aHgdC!;8lG$aUBpJ7~N+T1B;& zBcwTJpN_?Uh^Z`vN&5v$IfH81rU-&j z$|JWf4fs+<@0}DsF=wrKXmfu+J7|=Hku`JnZ`$}KLo!ZAu6G1}Nlx*-;u%FzG5GW-8Jv%k&H ze)Gkb(|`K&tJclGylUTj@b|qpAAkSn|5waj0VC`%zi9a;{e(rFKICt!KJ{wK$B)4! z6yW7Ee7HKkj}N#>OL_UQ?4pXq8(L zm^RK+gCT;DPVDN$7w=A<^+gT)h#TNGHl!X``g$zlVHG|Y-D8a-Km=G`|3(FD&7|+xYJ*JW#SNFSF|* zzC=CEG@?pi|eTg5vFez>gB@BP%&-S9QXo{%Q$ zMcVG+XmoZGoX<@@QI?CnM3QP_dBZ>Ct2=5qm=oUr<<|>eM+EcwiNn)(5LzgX@{*7A zdK~k7e^4we;ST7O+hNu}peic4Oj3~ui`gQ!oh%ZFRy*o82d_L{WJ(U?+b}L)>Ej}F zGj70&**&w1CgR?Ac8ZAQH~=z{lmzc{x1h8ovR%#*)gMU&1R;@a z2c`|dy9DStY%uH$i$@8ledsZ;8y)jBP6k86QZWSG zk$#GqsW-*F2j7Xcsdsw+!R`-_UgJ*<(z*ZO-kT|Rgyk^s5h$#L>9u*eiAgNFCg~O`+?g^APY?PSM{Qhyi}Bzt>74n@_ZX0l3AB1j zTNB;xPk`jvqp;%+YMX4cvNdTqbM8x)Do4eS&)X~@v1R|K;&!f}?co3!65H`idhqmK zg_)9d$TdP!HJ6#n=IPbYq%d*6fd#km&dlAsG2Q0n-e6e|l50GSNMP=mdZ6`z`3J9F zEj+l#h*<+Nr6EODot4bjNT=OipwxX#{viY}@^#<}xWooT^~0?8Q6`cA3YozVb!M>D zL)Os!>T(ys{D;s1R|Euj+mFX|>$hcG5!HOAuEwCRv)CMgkuY_%KNvLzF*?Pt&`~50 zqiC+D9SGXVY1!bmn{p~dmUIoi5U%6FZ9HY$meLm6;AOZz;S=EbZ=o$`W%%ax;Wp9? zi9H|YX^ZB3Q9oeUh*yDNTjFsKN5~w#;izP*v4(TNk*r41$<~&mtO*n>i|8NAJ#li8 zVFQzSLLN8h@AtqsyZtVY8T5|F<#c!nKO}6l5Jyk3$<$l$d2)D5+(Te(5H-p!7u8vA zW+-SgkdQYGP1R>59&jDnW}E~Qdd@TGb{mtAU^0o!<&^IFYIJj(-9;!MZ*BmMMy*;veDKf zz^@R{k`Vy3xrAs*)xP1oL8W#4mWczfGi8$e7&i62iI(?^P{TQ2qmU91t4pQ89bdR+ z6UrOCl0z>NT^FL&GI>$MaI0iy*&ID@I}36L|O#!_-_V*hNF?O1E<& z2G-H=7^0ugC6k5_mlWJX;n2@R?)JPm9$93qj+=R|nu?fVMk3JecL* z4u*eUPkGlU2~S5b?iB-An(I`Ab0L#pKn80N8e0z@JxHZ9FmLXmtq1oiPkAetyh)#v zwXkDsm=Ko(IJI3qzCzp1pt1Wj@$+dg8}KHa)lvTHj0Y#PHQZUEV#6_Rs8?rTYw5dt z#oasbCln82G8jV+6~7#|%?^md&hqH{?w#aRCb+zjJU}I1ccdkBzk*XGuTD$I3Kwwp zhe_M=H=0hy*d`ePO69c)QqbZf=q10pO^qPy^zh&Sc7@Dr4u|g_b@ty&?bs%9 z&>iMXJJu3M9l@o}#2QM5%trV@N)Z_HP=nKNRwiHx;zb|-DP;K3xCv=1NjsI}pERG& zo>%zGUz))BCp9+Msocb+Ac}OW7_TNvtA4(;PP1`Wz8ak+RL`R&NC#zDTj(kr% zl{&cGFf|jiJ)hz$VN!1>jOW=5R+1eLhn%DFT)%gEFgF|>wwcJYJv!J2YVUq&w~5c* zo?CPb_;+=00-ltVso~4xwpzt4H!w!wo>(C}sfd%;AvEf6V;)lZM^hAzAK0VWG-h3n z>*q9JNoI%R9xeuVu>AXad!5ani_~(tW23@i0TBUe)1%VT2v{lOt!-|A+Y7KI z;sJW-P{b_y;4dY&gs@_{O~nJ#?i8+o)}xXoE*FJsvVcFYK@5W;dO7vLw+3k5nRBs5 zr&s<>$C22LXfY~g)1BJuh}4q6&F5_wbiL5cTB~M<#S@@dmlUDUC3lV(7JURF5@St~w-^a+R+QPz z_L}_c=Hn8!^b+QRW|E8IUH|YMgiKtaO1t&obTq`xJNIrC4?yqTVlQe~eHl7p@eP(= zF_3MajZdJ+AD)eILPMfJ8pp;HtYd5}Og0vdo0VY4tD2SO@7{Se4~ytRVqy}drQyCp zfo!=-nc%Q|%ny`DutVc0m&pQDv35}AeoT@H;@(B8>r$cfiwBZ6=@4?e1bdA&Azx-%!uwAW9d>Dz+{6S z?k&zIs)*cT#x6axn3M@JN8C|b1y%Wyrb+j_aFPI6N))M#Cehk1ph0x6#m?g#HXO{- zXHyg2+;DDv6Wb&9alP}48W-Qmg(M|=fN~US`mNb+=d|NaZa3i{aemgsG2~{JZZaG1?@+rM!O6oD#`xdq$}cbVl@oY_!`W+?2JkDt zOYop4%Q*a8P8ZGRQkx6X+r(@xlF5Y=!U@yVzx-A8L!Fq@r7@q2WcsDL^EyBvA~YvHmu>RjNt4oQ@vA_rLhJ56z?Aj)7-lvt+52~e5D?u)@+g!Yt|7yOG%+o9r0+m0LWHNaP9F6&9)Nc`D-J0a?%q^SdDb z5FE_{D-6&Zb|#)ScCa_Zfv0DjrrQ5YH>{P2ata>Y6XUq&RKtP2)uw?exnv#!F1U^w zJ~2JCc#NWPUJJvGhBKF*0y6zyrGqB`yZ50Z_gl%mD|5e`9Jb(9!#u0VP)CqkvXQrc zIqBg|og%8b?QjIbn4U~J1KwhUNC)1OB7OLADL`G3h9nJ?p(y|X(_kfRgNAzqj8cpt znkcn)&Q6C=MD^kSM!zAX*7_AI^MAnxugB5yHgD(wA~GjZ?)^ytk*%n2PalTq`ScU2 z$p_lgXFZ(~;y8e0FO=EmiDYs*smqS4vZekv?wAt}sstsO7gBa(y3s$dUw+F3xk zqr+FSXGXROCv~o2oYd(i&jiup#h&$EDLV;)`i*wnynILfh?#F80(zm6G?)>n z!~0b2nNE%!yCbB@)MVs=37D?fjJ07ows=~81^Z)!{$GXa|3Q2vh!owiqT$Bp!fI^( zUxn1zgGTYhzd^(QQ-~Gz5N|{fAuG9|LNDfowDgB4HfgXCxkmrKK@qOm`zuGdE2w+n zs?q$KJA%~-9w5Cl9vHe^FuySjB8b~MgrqVk-uDMN*S#|HV|~Efg8m7kk;YOl7|(FFhv7NVnUfRc>r^&AcQS;7 zl#FV8gNhXVC2&-az--o#ZN+)l7~tbhh zHJ9AFikJO;wNLJUGG6xguYebHa~-^3{ag_*kFJjxRJjUfu!sdU`2J+vpzalr!=A2# z9hAQ+dT8vuxcz|m1;jM-b2WJ73P zm`%8Eo|Q6_XqdVP)OE2yU9H--83H5LPZ3mWrtlb(F_B9KgVcoSj3PxkoJ*$5Vk|8< z`AW033d7d$_^G7$od8Z+>{5VS4>%e@sp1j|=9_9ExjE7mLA_Cc(Rb&n5(PO>{gvai zeq4zvb`-B~J@Bj5%|x%Ql&liT?kGo+@$uTq^`Yf!HgjVrb%G&KvNvGaMrq^VHW?TF;03w5;>;KhY*?zY30%Xh~|2%Txl zcBnsL{pLO7{XyS`0aE0k_pE_Ef<%b+z+Gk@=3hZEtarb}HcTLA`I*+^Tg5NMv*PFC z>2iO0Tx?F3623QN;L-yafRUnNd`jh5;E{Ga$GB)64WYy3`#Jg5g<7{iXmPNJTtL2= zL8#+%bjj4^cq)N-YA|GG&+o~kUNs@wbU7=N@;2%mEjD4)>qV3HV$3))s?djUZ+mU) z$F(g@U{kwtprvp3p07Mx!{INKt}|>L@t|_&GO-qSOLg7Zge)q;;0Lr2%?JwMJaC?n z>WbS%@&vgdxNnH5ZUO+M8rh+PQuof-$4raKB(KtFxk}noM~Eez0It(uy9@=h?tp8;0>R! zOHMsaXcsfnNdqKyet^I)a8aD1zNrM>!adU7BG7*E&R22DYvgV;knv>DF6qaxfuJnL zF(M^k2VU8T^XhRgO6M*1z!5+gN8$kv0NS42*RnJU9Z*$SV*OiGtEy=Be(j9vZQLrJ ztZ(eBZSDQIva$YnWoK<~{Y7~8WMk!f{QcussWg{t!|nF^0gg?_L%op{8lLs9qy~72>J$37`Q3 zrDayzPY2{d&NlCj6Jzswg~_45TV!qV5V`jmn>;*h7B>ti3rALV+6QE z9;SdCyeuFvi$j8wjMu}rQDy~gyF}(|ghsR^ihhhR`a{?(&)&`io`92)UB?ns+Djohq{ai?jS1(3p9J0GxL7PA{TI&vJKJD6eV?$Pc=ff zMR)-RgM+3;Z7^jSJ&A4e(Yz!MHY`i9POH*M1s{sRT7QOZEz9p17ZNI#JzF@z)_I}& zrnJ#~rQbz4qc=Pks>RZty|{C#3QjxSZmQCnQRh6n5gTWMd`<(hf|ztbM^#7?#!PFOn=EVJDi%w-T+!p5&>yeX+-_-n zrK62Dkfjn`H;}j?#gu3z>Ny?FVV@8#>rWeykMmAC;GEjAOxbDaiE9&H2{=0-{Ua=g zVCHJ`6c>D~I&ogteJm3DO35cmEz#hx5&|H{xqWGq$BuY$e1YXa7ecaOh*J1V_&K>T zJ8`4lO-c24K7tMikwEmo>hWGY{vos@q9CoJ(vew6BWRC@sEyfu89PPN@Wo{IwsBThhv;+rlBZ`l8+$4rR0t_}hZLLB7e^IiY=uo#c_ z?@hIJ{O!)%$>4D6zJMpvsf9Sp!NDh49nY9gL4po|XsIn8fuw#1r_`vTR#8Ve5xb+} zJ`R6foH-H1KnG5!ZGMHoidpdHZpAUs9hY%)AXA9XN4*2&;~kt15j=)*&yX2mCn7F} zZxKs(q4Ayst;d`*Ca54)#j3(HmYA^Fvr*sa0D&1upYM?+Q8gde0bLy7dTP*~cNi1` zZ58f!$JNz{ABA2^u2&QN8uw(r7GG5%7>zH1dZVb41L8y4ELmV)=0k; z+hNCyOR75E6f1AX!=p2-Bw|(uB97Vy%TV)*!Z*o-nF2NGOmH$~0ag3sKKMHYWC>}U z?sR|cz&)|c;C~`^Bw-C4NF z)nw&GRI;KqahDZ<7SRRR0GOF%q4@Kki&ncO3HU8ph`mOpkcGOS%}K=Wxi%1|?0^f+ zKLZ^1Ax9q;hRk%vLs6veM~AjUcnNH6{*&L)-mc@p&8%Wo2J?fjNAH8&8-6xI=BotF z-T=TeCLufm+>^)L5_c$3zSqNdyDdz13X0**vJ`@ZeDEzX^40BITk}WXZ$3VHxAMcv zqZNKupWb=2vi8@Nm9>=(dBEpu__e;egYV7rd-tZw17lyDibxVOtuOyB-OXr!GY^*G zyZqqrcXa$aI6G2`JeW}cZala(GxwJpUy?X5c#;SM-}95?J=tMSOVVQxItwsccVHGD zK6wcoXVJ-q_?ae@kh&BWXy9qcv6$`MrILq-R?vT=TGpaAuhrS8bB>W-udf_UI7Cb- zc#2JFe|R|PQ}RRjJ$#C=$5Ic1#AlfUo!13Vf>=;wLQsK3Kc_S;&GG&DKL`v$y|Ifc`@D$*Op!UR7UpN#ZVTge7yWZTAql$H-&L6%Yf*Gizid5 z(|o0wu#w~;OLvvD<^*cbP&%g(d{^#Zh6u-C!6^Dsd?m?2U7QNNA}lfncn+6#Ap2v- z1sXAziC8msxi5tbzuh8l?KPAFK>4GocD za`!~Op&8}8t+_eqv6dM;-7o2$hWBWhimyh?yg3k|P>Rcz z7wR^`!x<=bQL><>^OIQ*Qkjdh&M%3UE3nJ71OLqdVE*euob2e=l;XV6$%2`eY8Yb* zQG!wmmKm5riDuc-`%5sN6&StT1h{Nh!4^^89O^XbjYU+XGmo5nbS@M9&V;&{?Mcl1 z3QdGPsks-o1Me}d=^o>Z#xo=dFtr=lh8Q=tyo{8HJmb-kB_@x!RlHc)dAk1m$>!eL z-*(oXZ?A7YzmZv=#6{ENNs?8v9g1*^gC}K_ii5Rd+P``90Deu%ukUnn9%2z`Q?l_Mx8^>sx0^~^b~J15v59A8$hGn)`7`-xwA>%dVU$LxvqlfzpmFJNSY5!`e{5E`jx4J30D8ckkea}Mpg*xOMUXL}IkKH|HX6s7dFDiQ8ym^DehT-id6%sGen%fx_3hI7CiD|_L-R*EfnZ2Ko z7k>sy4Q(|lq^{cJt$;1~KCp|xJXIey9dL!kFaUi$yLcK@TUx`ZL@PLLgnHt&x~HnJ zSoELCSb!!6*S{;SyGESSpZun(OtpDXu~FA&-Bs&1X$e=LK<7K;`ZViOPG1KD6a@?jz(S?Vvwy(EC*gBw;?7u2km#Xbk~-Q8tu_%EmlBxC9*`Vzya8TRc9GwpgrxMUbsFcLc?<6dPDKxWbd?dI99cj z@64_CcQZ5y{*L-bz2C>D7yNf0g->tn{{8;zoA>8#KKSlc8`n16Z;vU`t1}6S89DUI zJ*_?8+56$;=FZx7<%O}^Ror(0Khjvq$ux{B9CmwQGOiBcZpio>NMQ+$leQM$FV@~{q1zVL^mab~!`A|R0$ ze1AAT0u@31I7Z@qTv68Z)L?T+6^V6#OCfup?K%0b0rKJK^fR>0j2JNL^=i$Z3_q=T zK+fQE5jy~TbNeTshMG$IV>orvH|D%PfRoQMfV96_ALFC$C(S|HC?}YMs5K61_@u^3 zp{DY}DGbd!S!H_oG!)f(Xq@E_N1fyP(&7R*9?uFxnZt3oKbXUU9u3z9H1T!k78Yxu zVkN!3q#;=*bGpPYZEqiuCmGH)#C30{Oi14Y+?9=^)ji5^#mO~}uiHoOL$5x}iG3Ws z>s+_SZ||;I<77<7waR`l5h|ntzHW`-H7g9exi0XqI&UZ4gL>0^SS{G;XUf4%xM45r zon&SgD%qy;*DO9h&VYl5^*vY~*5)T$^thkFg{()ssNw^Qu8xp&@z!db;Dvu(38sl&I`D&2i#)2!0*hgnwx*30*=S^mQ{ z%m130V!(sPRnQM{F-{J4d0s7yv*=Q;FkP9uvv^x;9?x!HyT)}ZK$y91mE4;7FdN1( zi*&2-bE*wze4Zim53>*y_TQhwzA}3N{{OCC4bH6@`WT;{K|ZUKZNrrCadk#c4}Z(G zoGbd_T@DByt^UGQQf(Qht-yk`_A>xy8U4rf7Z!T9%^e73Y{!k zk6MPQ&}y9pik(#E&{=+Sp-$j%Qs%=f9@JSI9y;^5q?i-Zq++8W6(@@J-uLeyMje3f>NhK3<&N7Ruuc=#&mtf9~q%8dM=A)O(F z>76uP9oy*CW<-nOuWE^3_tO%;?&H$ZOc_3vnU!|(rTY6O+(;QHzTokiVcbD5kz!c} zJhok}vBa_Dek8@x9Tl83&j5|`Czi1}n^b0KD_YC^9p)H2uS-_Of!LQhSuI zM#|l!Vy)SZ%QV{VhuPzCz96IBN<+r}eAu7W$H}~>j_1^9*4zwnTnp)aK(M?`gVxA# z-4D%G*7CZP7KruIj)E4D>M*NT(uS2zKc?*tl~UE=Gu*9fib7g!)iE~c5rfJQc@dIq zo~hog)D!Llgm=mu+%?|z;VA-F13mDHgH~wFm4p@LdN3OontC+^oHCEL__rXbD6b%; z$2PCFC9vXsZs9M9{xNo8*inV0Kc1|fblY?74g{^9XeePxS%(uY+;l|$Dz3#a{B-E0 zrg>F>U8wjGwgg<5()2B_=9d{1YeVe9wkUbdwevg+G1j;HNBfIe|%wx$*v7iM5Kb9ZE#Kbd@SLe>E z*ZycY9z$H|oKoc}9fdY+7|@o}wHlwRU8(9l$~CGB^LKB5}@ z?88vy^Xb)z-`5q+vM^K7*#TEPo=DhSv4#jX2|*9;4L51C!UPXaovTf>E{S2mT6K;iiF-wTM01(~yNSQ$Xm6t4F>rrRMmq``C za!-#|w$~cF3JdG9zCyvtodp-HN_#r6IIWe}wV}n5llwymee>YLgkIKLC|K>xJTE5K zPu8B%1HP1nrUD$S#7u2LyB4CKg^?q&4i=UZM)38LaIT*b%LNq^lfP@qp|X?8EL?UF zBQ007!7JtMa18f%M0Ssh9?gHu2?}2*N-h$VJBu#hg$uXEz}8{2rXLKXvTpC~8SXjd z{cZqD#GD9`gC}0#pYrwtolXIvqm%VOdi3R6T627T=pQq3cE@v~c11eZ<88%!>o5b7*rwkhk0o zWCSH?E?HIebPs&Vk2M20HPGAsmQ)HYq$ugrmc}$x;+CkelzK6iB+{)dg*^S!U4tG$ z^xPAlJ#4%P+Q4n)Fj9jY`-5Nf&ex1YSCYS&bKlYK-(gNv;_=6gvqJLJkZrwvTq}IE zdccbf%RNm(90dF_b9drS6pf$LJb%>x4e_CLh&QiANWY$7D2&+s9mmDX=j(qfHlExn zo^|$%)h&^Je?pMh@O+FvH=b0Q0_CDH2x)L6iJefShGY|)Pfv%^$_z@Rj+J0Unn_A* z%gDkd7iZuy-ZP2VRnS9wj%F8RU5KR$qv@SAAvX#9#DD=wnGC0t1Za!}zC+)--9MG#5*an2Wj@)o!yF!HOU8nBYAqMI!DC% z7Kfo{KOnk3BsO0G#5xXm01m4_1a?4(T!LYtN$g@P=FJGXWWwSxy0(LQh8(SzNz9;1 z5jf^=tavy-!r{h4wkG;Sb6S377F5o)sJb zmiOP66c_YbasF;-xiSEDP-F=OG)cA z?mThAufPt%%(1h*A6_6&6j-S?k#K`)S=gMJ6c14PW5D1x62ioa$y@HQGt+$(nEw{x z8pt<=B{=xDKxW{6oyBrR-NQivmpY>zL{!$|H_5JNX68REE)?GZ%P6Wl_6&dW(fo&{ z708R|R-Pc34^LM4H>)kJHCDU31_#)xOD~s|jv4_=4pTBbzSm&ri8XO~Ho{t}msbn) z)y8bz*sdR>*op5PoB^v6-lr`1``(~8(o`%$I9w?mT-9=U4lb??x28 z*5JJ=yusi2cSQ=3qe!{?E9C|f>e~h!5K99zbuuIke1X#`P|=-fz4+_u_T9Z59KKui z`D0OI0rZqp^4CLIou*ph4#rGj9GC+|j3PS)`0W8qp>^z5CG;j&X32Cmr%n1{*Sdgq0^87HGl<8AADNv0{$}u_8#kpl&a!m+*l0Jb*0D_mXCC2m#If=-K z-$fXMA=L%&(GhaBA;1orF~ER15bYkC4kOd#eA;U%IUj2?n=!m(XGQI9=%)Bx2H%@U zs~AP_eXveb+R!#vZB6P@0w%E-<#s@vjEFvgvC@S+tCOXWOGB^^9hH#2%K(8;>;!AifB2N z#{69}5n+$yjMxUs{NBuyl;{>frP8MpPN;URt(C#uj*Oeh#yXaa;#b;NmqLA;p0Z28 z1Xf<#SC_m6|E}(<5{v%K(%vz!*$evjC+w?i2D>VouJ5PhIhH$J3e?!FO;9p1<*DQ( z@)I?Vu9pT;f zDU$6|w@GCgskJ_+ERn5ZX95@CGNqv6Vh0y6TVz-^lAt3t**q<)@?4y|vPMcd>3B~@ z@>H!BLh?-&;KoCnh9Z1h|7a>JkZH+6GBJ8V|NaC@TIoWKkV4JfT*1IEnLTa&qjiG* zr-`y4Ztox!2PmM0OhRybr@XHzu(tg~Q2ZJDFA{+Tc{imWHdPaz*_ukph`t3I>1m6r zRUsQ3TS0FV&{&A9J_l8Iog}D zXKx_Zkw%hFC!q}4dCIDE*`kD7Z}bL-FvVa~$m|Ah zzq$?7mQ_YLoxGoEJ-vx}<_3jp6mK<AFa%o>TI!JK|Zs#T|Gy z>~zb;ulE+dEjnzsLJRd>pIsFHXeg@tuM|0ID8iYP0^>}9WaW)7tz7zQM0yLcwLZEYv zE}Ovr?VfO&rq{oN-88==Uub@7OSlpGx9=kAxM(IJ=Iyi9Jm}4dc=+>q6%mq4n-9Kv6Kg$L9ST3%P7@k+&_nB6@Ld0sr%&{#`xhV(;@;{vD1Z&0cUS%7%ndl|rbv{gXzp@*%QWxzuT(m!Osn39M94s$CTlw4G#`^QMJ$QnCzw@;Ci`!unK^j&u z@Q7RgywMgPZH&gJK6`##A-<@2hC{!)LEu0M<tGa`SU_f5+NCQSV9q?E0 z;s!n@Lb_GIRbF$$p2Iv)tUrDZSqpkB2FqNCYv}&b88qIZ*&4zpxZwvYHtbA0LmdC0 zjDixq*{#JE^Xbs`;ZMW|?x6m+$H(ga)$y^v|HtsbOS%8;5%OsN8W_Qd{uoNO^z!k4 zf3z5&S0@&$@W;>tMgix({XS&u!6`yY-TyeSfqygZ0v@^L;9eb7{P!5! z9eF4(l?a%K3{ll{+<yNjAyXsrvmUtWexP5c;H~afdbwKphSJ*qK#dk$d)9d7r zQcK^)V`jCU!y-OY{?d)F!Rars_wI1jumaB_88%O|L;SP9&jXJ9Yl4v-c<{xJ@g;ra zHOsCBQ1O;&L5Bm$;m04U6DVZ@%$KX3e>jC{KEP}>K=z44F*@SO*UmxNZR~q;D>Q&b`Ou!vE4UHoWQRo$7pBM;?;*wi^!8licG z>-xl*D%_P*eBVEPdiItalFD_qsqGTO5ZUl~))^shCba0h9%WF>Y+nra;lI`12d8*D zI>Vih7zs0`_C^nJcP8H*=m80KNW zo(ot;j5! ztN}3f|NM{o8VbI7I3+Rr@F-a@PS_Q)zMP2Bm#j!kJZU|+^}*NxPd->V!ju2}kB=Av zKB=)5l#7_K16ZOC8{RBhVgPR zmJ3b)kF$ZRI3XhJ{r@-{-1E-Q&*%P+vt7d3uDGh!X$oeNh_NWC!a~HpdJK+eK__|@ zBh0hdunWYb!I{eqzN)aH;)Mb__hkCWK%|oOjLilPbs46*`fh|BWb2|c0LMyb{L`5& z`^)mv9c(92j1jN^lU(MBi_YIFcom+C5KJnxFr*4Yg+dTQ#gA)Syzzpn{;zPw`XX%t zS}1g8 zd~J0{7t_*}VZzDwO1R$G{ApwD$F&U%`1XXxl``Ob3Tg@K!@|*$Soxd4IhEg!*PK{p z-ps$bff!N?>DP9Uibm5x`GNw2ODh@y%)D7Z-Bl$a=eG@2Y}#htEY_aD_q{v7jYh)X*Vv3(Co|3WWlMvn)0NY@}R>x2Fw!mZ>ehI95@f6xz2;G!H}t;=BY zBe?d#r5*ac0nc*G?q=FPM*q}Na)#hI-2_SpP&Of z3FR&*X&O0VeZ(OVw^w>n5S%bO#f$B&*(G2Tw-cQ9i4foy7C(9d56=$a3Bh|X-w0eD zvT#%RhD{syTkO8w%h5qusfrG9kGyy>9xZK1zY_;nKI2W75!)gL^Kwb$?q%!;FT&~w z$b9HA7!bI7gSqoQ;siul!-yFE)&9}bRP=C7&k+v((4-^aZy?u&W!s_P&J^1R{STs+ zV9$G7Yb%eRt*J_4otewPb@;+t@NX58n$4bM6SPAnqV~VgQW?d~lZL=TY(oC!8u?%FnRzF0i_=&f8GGEhXVb zsy|_7K5-+*WvWQ;2!`?w3L~-wUkaeU5w9Wyp^2^X9g~uSrno2%5yf>1cY6f1V9{d< zL!9i-A|~J%>!QP3lmpZeZ^=wHL^cub5KLomdwu^_{5NxIx^oh(_X;4UkvY?V&cU8{ zpdcbE^^K1Yx$GE8@UNVO>kNmH0Fwsv0{6m$ugY|adLP~ce)16=hN|)l+}tP>!T=$O zok4K*%Fc?9JxrNsTo3vqoG`G5FnAUdK0HHw4x(W?xcLe>({NpNqE~}?9KD06*B{4L zo^2OvavIR}s0EyXuRp$J*Jv>+iYEgQqEVbo2xeHXVaEvektZaVS0El&c3(R}of`$S ziSYZq1P^=tE_s8Z3@PEPCb)MCc`7Yaa(fqdf4=^>^v`1RuRz>A-eZn%m82}sn&h3D zaW0l$#7PWJ!YE&uVyaxvI8VOX=KJN~Fo3mP>-1S4S6qyT2d8_2+Ik}bw)OuI*KQLG zI7XjgLzY7^X&nm}JMieD4A;tW2mZ`^+iTm^RyW^gAc3{5`~AqXd&l8V7y%P(DFUm! z5Q)?ggF|(jk?Q(m@Ut;VQSDd_!i0}ZpGY~O35p=G{JCj5aI z1I`60VgMP-VG#_=YBWyQ0E?I+o8eGlud-;^yV6W)fnXlO@+iF!l+pl_sTAHJ4_5hg zGxZohix|h!1UXUtAme|!wy_z8TdW@xoOa$-Uhs{}lJHLw7o4{}xGrMj>tT&FX(^0` zCX>%QNF#eAvRch1l$|PnX#d-8_{-&~kAULjK0C*Pa5}>hvMCZ5J25gn%-& zCDW%UG$jFI@i<=m*f~0bw9Up*wP+CwEoO*lv4TL#p7^oWk`*xXglx zV;ztW^2Hlz6w&K20t zut9Lq@)EwCt(R*An34w!GZ(;$ILJ{piNm&Rss}eT(`9e#?>Wb)!Rw%(ymDPe_t?21%;m@D0KVNAR#_92t`k71FROvXfS8__my+ z+`6dHX!$wWyTNz6{dhQNfjx;j=2r2`8CEIE#)wAUr{(3;dExi~-J&vhgjs-c(a>mll}!k8e?B93IoFdZzXB?D1^3c)HwQ zMuJXEDN_Rw5^x~oOn}d5eUNNQTye=q5d1yUYVXn%@LH1#paD)?^$JY~pz$hAFVK3q z^JMnx%pJo3Z;G0#Xvp;{{BB09P-z9RrVy<>WjjnJk;&6oM*|0m^wooS9AV6m0(B zx)c!U;M{pD<}{?JlRQBxIC|TH<$BwM2IvTR3G*dbN>DQKHA_`KuPk;pecXf%mXVmYCcrWg=moQ(=br0>{=&ksB20P${F#r!UmaHr`nWCTrpYw ziVIqsS1>V8xS?i(g$Q)lDKU5_DC_KEM0^<@5{H}irW__>k&Ke*fs}xWU-zPI3(~KbRJe02zJ7KKDLWA$fA)j{?h%MSQ*oeA< zGm2f*rOxP_B7Lve+k`<_5%ya$}AM+AO2FHI_-~Xc}{h zaIS0B5;ZyrQhh|?jy;#wWM*rY*<#3&WM|P?i)bQH{3wblIQAD9WA2Sj zedg8n4(uP#_S7Wo(~~JT?Z7Mc%3!54NJzlf5ZT$Q;4dwe4}xvCpU_xKw|`Ra0sG`e zWC~-;jt^(r_f(HavU`z8VId_)=0VX?O9^v6Kt2%gqvYfxXwox6b{+A3D_u)QGd_5= zl~ZYrOUnC4Wcbju0cNhZ8rZ4si!JkW*9Y9b3xmw@+sd8Oz{#&_+OeY2ky3xG0OC?ac3`mt=CT$f0v}`bITU(o3;M?Fh zUV)6w&i<{}OeO5#aKZ%lBP}QME9oRZ1R#?2AYy zm$+!ettLees3qB5MZI`R!Nmh>d2tn8SSV*e4;-GGagpM!8ptS?#37(rPtzanKzoO) zVj&Qnh^(sWcyK6}Rb6n4ZIC_@yo1@DfxF<|=Ju@u((KX=Bxo;MKdnDU3XYGlH0J~N zZ+yV^0#6HO7@cY1PwdZpY$HUv%0ugWlTI8{+1cS$WdU|#(gg|pA-6b<`fETJdi zjy7s&^}DO;fQyS=c2>4_PzTE^{k^z2U+0(2t2knUsXh^CEt>zg5ENvfuu5`pGq{F= zTwJ_zNf-D`ONQCuo+_U)Z!WTI{rqBQbMM(2Vmco00YDRCN@#Dlv6PBCb6?HfExOnd z;6j4sf>3MrM*9P?j8J$vm@UjLQm(k9{d6SAEZOPOLee|d?Vn;v2RTlUVEh3_t79RO zHTx*?H#hb3>%!imjU|&*w}Ot}oAHsflMr?WrIXuOh`2cI~Q4e;5BG9Vu zgg|jb)+fo+KG@;=niQ=kbV%_?KRm1mGfu`Xf>%ToF2c$q@2HwYEM*DJQf(ZiEdWbk z;H?HFLqJ@*<~`Qwemn4#S2SmXoJ3f1%q<<(EnI6M-s=i=4QwzNSsKB<3v(FMOW_3eEmRQV)r7qG zOaQHte>xu=Ty zNk(blz@{oDsFhZEZwd0mR1Ut@bZ_o(&RB?V?JkM1gnt^ga=s2+%*z_4>`2`rSsA_| zO(SR273PE;EyGfl0$E2AVnZ;H<3T_V=++`+_H~BI zDG}&k`eTRK&l8fo+%gn{`l)^pdA>5`Lg3NT>$uO+b{J-D{SoLgx?5X5t458IdQ+K) zW7;KT(1H#nhpXzWN>>ggwtRD*;A8*Ph>v45eXQ543#P0sh=+2Kr9hrsBmJ=i5{K9% z_{76K@c6`>h(t@zdln(xkQu;A)9qEx-rDjGIFRpZc0hzzNxZQUKDpG4V*xAubos(j&ir`kNhF~C4bl!*Lp2^IhDC(XO68BMUe`$@bzhcE%6hVEzgEB^%eP2 z%jv&4JFUORT>4M{&OEyE1hb96wB1aB*cdy5L-gm=M}fe26n(`IM4#E-9HXX(-miQA_4qpJ*pWG_mrYN!{+$o2+;?-23g;!H9K16II@mS=wQ*};A z+)Y4jg4USX_0p9dAOicab(2tM(q`}(airCjkNRoolFNDy6x%#cSE#B^)53)Vf|H}Q z2^zA&s3?r3y|i>Y&%Z7~7hfmC!V}w z)=Qon{#?AU13^y7$#Ugfol~#oC8MKD$kZ>|BL^(E>9V24r8{*<{M^6-_NmROznDOG zERsQFj*%&aD0lwXQ;6>ZpP53MrdlSIqynNWPh2?DKv?_l0w$7H6_`jXB#Y0vcABR= zY|j6(Sr6g_cY895^ucFFI(P)trexNTijZIihll#|nhx*4T8$vO2vy>J5URE|9v7WX zZx!HWC54=?KXmyBeu|Jm!%-?z7@sBv1x#yNTX{Y zqCuhQfUU_kX&wQ%les>~5shyy@aR?|&Hjt|Vzawlz@y1$Q!Ae!SzJ$+056ZzYSVd{ z9)1yO~6@#~)T!+=RV? ze+O-t*7V2jj}=_X1KhgmYUBK9HI44Pc<@gmu!5?LZrdg&6oEynhRtLxl_nMpg*d^z zVK6R;IUZ4rlK(bIya%9AjyHQDs+2*>NVnBig*}2y+Yap9vCK3Ie7SgcaS@_M92Dv! z(6U%uKr$>L3c1XJ;S8d&757QDT&kg0lSsfMMkMvh1=j4+AKvhTQ7}l8vn5(hcti+1 ze831rM1MkCz`jd;K-%8u(8p}+Y|MMbQlO{bUYz3GL0^=wZc74mK7f ztV_vMPxnz2(0e7A(Q8$fzA9H4US8$Se!0r~J?lqc{5w(;qKy=c_j}f=7vP^L5OHTT ztVqz(b9L-!KQO#={owjl>myKfY9CM^Lh~-5Dib=s(_EabbzM?t2ZsoQut|Fz$~Bk< zk^d2!ngpxWEVFfyOT2|}VJEY7=&aGYOG_*C1)V((y535HXKr33!n7UuB@7SXZdEmc zv#c$Cb<-h7Mf4DYBIpzZO`GRg4r7e7#mfBHw$$hp#4;_>LO+o|+CqsWMD0%5|8WDA>1u49@+d;g}cNq=e^1j0&nAjC>u)t5Q~W zLn09|E29f&x-bd`7>tX*cFkPFeK*1nc@`sn}JI-E{U6f`qM!Y+P7maH{v8yxkF-}ZX zb}75ShPS~01In)`Fs)1`K+tD|RDZp-hG`RW5L6oBkxK+LpPj@Zu$u#=9*5VBq*ZdO zzW339PUz~Z5th7>5BDxppN{-|c2R1%J8Q>vVXNw)1qhcF?yLFjfV2pEmcm580mZ7U z&wOC}I%A3%MkO+ng;ENNcoNV}_jr6LoQeCakfj)<+(dU1q&AQ-a&_>%<{FE!%i!jr z36QE3fzJl4Jcf{)cm~Oj?{HlyRr)xDNXQn;>XkX;xnhlx_WG9y0#-aU!nvh4`XRG} z@OCwoc_1-B1n3mst!`~RxgXp0zWNFJ45)(&RF+D8I&(HISkIV|l zf&hC)m6Tv6;5`IR;u~vzdLe|!B89{mcCD)DMudQ5NlB6jz)FG~lWblwNVnUDX!%M^ z9xyK>{u**EsH)tC7(65tm>UIxT|9=x`aGsaVq`6&ivz^Man*=XhD!i`W=@b=<)`%O zS8ik?l`Ckn1hL~lZ!1f$Q?%xAza*8Rh;QSHEE7E5mK%ovfbCy)qu}Z%?($gG$QBD` z!j6!LN@VLgbfDKbiD2H@@H4Onnu3@P3ARa0N34>$v6oS2l#D$&fM_Xcp9TTI?yI?~#{woMRF) zqpwnb@CuN7JU~oNq>5sMRN|id_wta&H0Q%0f+ zmWR9@INe;QVT!X(&`4EI6Fy^B4(X_TC!0J1w<+vGHmP2diOXFi$_}oNu!r)GU~n|D z0s`{)IP3d8%3O@A$_eYqxHt<^gO_DNPRa@GWgx3~Fi833AKcgro@n7zLNd;E#uQw! zJB>@c0;m)VEN=&=e{V9QXcA%!bE?cT#sy&ma(Z6|--UinqIq`_!acxogHk8*fq(-E z3k?TjOf=(SSgLBJ&;tSFIBAQJ?yA6FNgw&Tesbbi+ij|r$b%VDAUuU(HmQ$G?G|S0 zT#HKc!s$bP2tgRwr!wx;H80|q{){4SXc(9jB^<_TkNaK3ym0Au3PfS}{_OSfji41f z@X0DjSBS2T+~qycl9HY)B*j({iH&_2DN-Sfz#R)YPT&xM?FHs@T{yzH=gSkzin59b zOqTMrX;_8_NHlH;5gRb<|8VC7FQE`1qpvs3%0A58Xpm=|i8WcQ`iX03_jQGT2zCVE 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 $t) { + if (!isset($t['file'])) { + $t['file'] = 'unknown'; + } + if (!isset($t['line'])) { + $t['line'] = 0; + } + if (!isset($t['function'])) { + $t['function'] = 'unknown'; + } + $log .= "#$i {$t['file']}({$t['line']}): "; + if (isset($t['object']) and is_object($t['object'])) { + $log .= get_class($t['object']) . '->'; + } + $log .= "{$t['function']}()\n"; + } + + file_put_contents(CONFIG_DIR . "last_error.log", $log); + break; + default: + break; + } + } + } + + function CQMsg($msg, $type, $id){ + if ($type === "group") { + $reply = ["action" => "send_group_msg", "params" => ["group_id" => $id, "message" => $msg]]; + $reply["echo"] = $reply; + $reply["echo"]["time"] = time(); + $reply = json_encode($reply); + } + else if ($type === "private") { + $reply = ["action" => "send_private_msg", "params" => ["user_id" => $id, "message" => $msg]]; + $reply["echo"] = $reply; + $reply["echo"]["time"] = time(); + $reply = json_encode($reply); + } + else if ($type === "discuss") { + $reply = ["action" => "send_discuss_msg", "params" => ["discuss_id" => $id, "message" => $msg]]; + $reply["echo"] = $reply; + $reply["echo"]["time"] = time(); + $reply = json_encode($reply); + } + else { + $reply = false; + } + return $reply; + } + + //loading projects + require(WORKING_DIR . "src/cqbot/Framework.php"); + require(WORKING_DIR . "src/cqbot/utils/Buffer.php"); + require(WORKING_DIR . "src/cqbot/utils/ErrorStatus.php"); + require(WORKING_DIR . "src/cqbot/utils/Console.php"); + $cqbot = new Framework(); + $cqbot->setHost("127.0.0.1"); + $cqbot->setApiPort("10000"); + $cqbot->setEventPort("20000"); + $cqbot->setAdminGroup(""); + $cqbot->setInfoLevel(1); + $cqbot->init(); + $cqbot->eventServerStart(); +} \ No newline at end of file