From e2ec7bc3937d3a4d9c8fb8885df8144b9e478eae Mon Sep 17 00:00:00 2001
From: pfewmlupo <3097217416@qq.com>
Date: Tue, 8 Oct 2024 20:50:25 +0800
Subject: [PATCH 01/10] =?UTF-8?q?Add=20=E6=B3=A8=E9=87=8A=EF=BC=881?=
=?UTF-8?q?=EF=BC=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
注释(1) | 296 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 296 insertions(+)
create mode 100644 注释(1)
diff --git a/注释(1) b/注释(1)
new file mode 100644
index 0000000..1ea6a14
--- /dev/null
+++ b/注释(1)
@@ -0,0 +1,296 @@
+poetizepoetize-im-uisrcmain.js
+// 引入Vue 3的createApp方法,用于创建Vue应用实例
+import { createApp } from 'vue';
+
+// 引入应用的根组件
+import App from './App.vue';
+
+// 引入Vue Router实例,用于管理前端路由
+import router from './router';
+
+// 引入Vuex或Pinia实例,用于状态管理
+import store from './store';
+
+// 从naive-ui库中引入多个UI组件,并使用create方法创建一个Naive UI插件实例
+import {
+ create,
+ NAvatar,
+ NInput,
+ NIcon,
+ NTag,
+ NDivider,
+ NButton,
+ NDrawer,
+ NCard,
+ NTabs,
+ NTabPane,
+ NSwitch,
+ NModal,
+ NBadge,
+ NPopover,
+ NImage,
+ NPopconfirm
+} from 'naive-ui';
+
+poetizepoetize-im-uisrcApp.vue
+// 从element-plus库中引入特定组件,并引入其样式文件
+import {
+ ElUpload,
+ ElButton,
+ ElRadioGroup,
+ ElRadioButton
+} from 'element-plus';
+import 'element-plus/dist/index.css';
+
+// 引入自定义的HTTP请求工具、通用方法和常量
+import http from './utils/request';
+import common from './utils/common';
+import constant from './utils/constant';
+
+// 引入自定义字体和样式文件
+import 'vfonts/FiraCode.css';
+import './assets/css/index.css';
+import './assets/css/color.css';
+import './assets/css/animation.css';
+
+// 创建一个Naive UI插件实例,并注册所有需要的组件
+const naive = create({
+ components: [
+ NAvatar, NInput, NIcon, NTag, NDivider, NButton,
+ NDrawer, NCard, NTabs, NTabPane, NSwitch, NModal,
+ NBadge, NPopover, NImage, NPopconfirm
+ ]
+});
+
+// 创建Vue应用实例
+const app = createApp(App);
+
+// 使用Vue Router和状态管理实例
+app.use(router);
+app.use(store);
+
+// 使用Naive UI插件
+app.use(naive);
+
+// 单独注册Element Plus的组件,使它们可以在应用的全局范围内使用
+app.component(ElUpload.name, ElUpload);
+app.component(ElButton.name, ElButton);
+app.component(ElRadioGroup.name, ElRadioGroup);
+app.component(ElRadioButton.name, ElRadioButton);
+
+// 添加全局属性,用于HTTP请求、通用方法和常量
+app.config.globalProperties.$http = http;
+app.config.globalProperties.$common = common;
+app.config.globalProperties.$constant = constant;
+
+// 添加全局前置路由守卫
+router.beforeEach((to, from, next) => {
+ // 检查目标路由是否需要认证
+ if (to.meta.requiresAuth) {
+ // 如果是根路径,则检查URL查询参数
+ if (to.path === "/") {
+ // 如果存在defaultStoreType查询参数,则存储到localStorage
+ if (typeof to.query.defaultStoreType !== "undefined") {
+ localStorage.setItem("defaultStoreType", to.query.defaultStoreType);
+ }
+ // 如果存在userToken查询参数,则验证token
+ if (typeof to.query.userToken !== "undefined") {
+ let userToken = to.query.userToken;
+ const xhr = new XMLHttpRequest();
+ xhr.open('post', constant.baseURL + "/user/token", false); // 同步请求,不推荐在生产环境中使用
+ xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+ xhr.send("userToken=" + userToken);
+ let result = JSON.parse(xhr.responseText);
+ // 如果token验证通过,则加载用户信息并重定向到应用主页面
+ if (!common.isEmpty(result) && result.code === 200) {
+ store.commit("loadCurrentUser", result.data);
+ localStorage.setItem("userToken", result.data.accessToken);
+ window.location.href = constant.imURL;
+ next();
+ } else {
+ // 如果token验证失败,则重定向到登录页面
+ window.location.href = constant.webBaseURL;
+ }
+ } else if (Boolean(localStorage.getItem("userToken"))) {
+ // 如果已存储userToken,则允许路由变化
+ next();
+ } else {
+ // 如果没有userToken,则重定向到登录页面
+ window.location.href = constant.webBaseURL;
+ }
+ } else {
+ // 如果不是根路径,则检查是否已存储userToken
+ if (Boolean(localStorage.getItem("userToken"))) {
+ // 如果已存储userToken,则允许路由变化
+ next();
+ } else {
+ // 如果没有userToken,则重定向到登录页面
+ window.location.href = constant.webBaseURL;
+ }
+ }
+ } else {
+ // 如果目标路由不需要认证,则直接允许路由变化
+ next();
+ }
+});
+
+// 将Vue应用挂载到HTML中的#app元素上
+app.mount('#app');
+
+poetizepoetize-im-uisrcutilsajaxUpload.js
+
+
+
+
+
+ ';
+ } else {
+ // 如果没有找到匹配的表情符号,则原样返回
+ return word;
+ }
+ });
+ return content;
+ },
+
+ /**
+ * 将文本中的图片链接转换为图片标签
+ * @param {string} content - 包含图片链接的文本
+ * @returns {string} 图片链接被替换为图片标签后的文本
+ */
+ pictureReg(content) {
+ // 使用正则表达式匹配文本中的图片链接,并替换为对应的图片标签
+ content = content.replace(/
+$$
+[^\[^
+$$
+]+\]/g, (word) => {
+ // 查找图片链接中的逗号分隔符,以获取图片描述和链接
+ let index = word.indexOf(",");
+ if (index > -1) {
+ let arr = word.replace("[", "").replace("]", "").split(",");
+ // 返回图片标签,包含描述作为title属性
+ return '
';
+ } else {
+ // 如果没有找到逗号分隔符,则原样返回
+ return word;
+ }
+ });
+ return content;
+ },
+
+ /**
+ * 将日期字符串转换为时间戳
+ * @param {string} dateStr - 日期字符串,格式为YYYY-MM-DD或YYYY-MM-DD HH:mm:ss
+ * @returns {number} 转换后的时间戳(毫秒)
+ */
+ getDateTimeStamp(dateStr) {
+ // 将日期字符串中的短横线替换为斜杠,以适应Date.parse方法的格式要求
+ return Date.parse(dateStr.replace(/-/gi, "/"));
+ },
+
+ /**
+ * 计算两个日期之间的时间差,并返回友好的时间差字符串
+ * @param {string} dateStr - 要比较的日期字符串,格式为YYYY-MM-DD HH:mm:ss
+ * @returns {string} 友好的时间差字符串,如“3天前”、“2小时前”等
+ */
+ getDateDiff(dateStr) {
+ // 将日期字符串转换为时间戳(秒),并获取当前时间的时间戳(秒)
+ let publishTime = Date.parse(dateStr.replace(/-/gi, "/")) / 1000,
+ timeNow = Math.floor(new Date().getTime() / 1000),
+ d = timeNow - publishTime, // 计算时间差(秒)
+ // ...(省略了部分代码,包括日期格式化和时间差计算的详细逻辑)
+ // 根据时间差返回不同的友好时间差字符串
+ if (d_days > 0 && d_days < 3) {
+ return d_days + '天前';
+ } else if (d_days <= 0 && d_hours > 0) {
+ return d_hours + '小时前';
+ } else if (d_hours <= 0 && d_minutes > 0) {
+ return d_minutes + '分钟前';
+ } else if (d_seconds < 60) {
+ if (d_seconds <= 0) {
+ return '刚刚发表';
+ } else {
+ return d_seconds + '秒前';
+ }
+ } else if (d_days >= 3 && d_days < 30) {
+ return M + '-' + D + ' ' + H + ':' + m;
+ } else if (d_days >= 30) {
+ return Y + '-' + M + '-' + D + ' ' + H + ':' + m;
+ }
+ },
+
+ /**
+ * 保存资源信息到服务器
+ * @param {Vue组件实例} that - 调用此方法的Vue组件实例
+ * @param {string} type - 资源类型
+ * @param {string} path - 资源路径
+ * @param {number} size - 资源大小(字节)
+ * @param {string} mimeType - 资源MIME类型
+ * @param {string} originalName - 资源原始名称
+ * @param {string} storeType - 存储类型
+ */
--
2.34.1
From aa17f031eaab542755d9199270aa1ac1453251ca Mon Sep 17 00:00:00 2001
From: pfewmlupo <3097217416@qq.com>
Date: Sun, 17 Nov 2024 21:18:24 +0800
Subject: [PATCH 05/10] =?UTF-8?q?Add=20=E6=B3=A8=E9=87=8A=EF=BC=885?=
=?UTF-8?q?=EF=BC=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
注释(5) | 634 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 634 insertions(+)
create mode 100644 注释(5)
diff --git a/注释(5) b/注释(5)
new file mode 100644
index 0000000..892a781
--- /dev/null
+++ b/注释(5)
@@ -0,0 +1,634 @@
+poetizepoetize-im-uisrcstoreindex.js
+
+// 从'vuex'包中导入createStore函数,用于创建一个新的Vuex store实例
+import { createStore } from 'vuex';
+
+// 导出通过createStore函数创建的Vuex store实例
+export default createStore({
+ // state对象包含了应用的状态
+ // 这些状态可以在应用的任何组件中通过this.$store.state访问
+ state: {
+ // 从localStorage中获取当前用户信息,如果不存在则默认为空对象{}
+ // JSON.parse用于将JSON字符串转换为JavaScript对象
+ currentUser: JSON.parse(localStorage.getItem("currentUser") || '{}'),
+ // 从localStorage中获取系统配置信息,如果不存在则默认为空对象{}
+ sysConfig: JSON.parse(localStorage.getItem("sysConfig") || '{}')
+ },
+
+ // getters对象可以包含一些方法,这些方法基于state中的状态计算并返回一些值
+ // 在这个例子中,getters对象是空的,意味着没有定义任何getter
+ getters: {},
+
+ // mutations对象包含了直接修改状态的方法(同步函数)
+ // Vuex要求更改Vuex的store中的状态的唯一方法是提交mutation
+ mutations: {
+ // loadCurrentUser方法用于加载当前用户信息
+ // 它接受两个参数:state(当前Vuex store的状态对象)和user(要设置的用户信息对象)
+ // 这个方法会将用户信息保存到state中,并更新localStorage中的currentUser项
+ loadCurrentUser(state, user) {
+ state.currentUser = user;
+ localStorage.setItem("currentUser", JSON.stringify(user));
+ },
+ // loadSysConfig方法用于加载系统配置信息
+ // 它接受两个参数:state(当前Vuex store的状态对象)和sysConfig(要设置的系统配置信息对象)
+ // 这个方法会将系统配置信息保存到state中,并更新localStorage中的sysConfig项
+ loadSysConfig(state, sysConfig) {
+ state.sysConfig = sysConfig;
+ localStorage.setItem("sysConfig", JSON.stringify(sysConfig));
+ }
+ },
+
+ // actions对象包含了可以包含任意异步操作的函数
+ // 它们通过提交mutations而不是直接更改状态来更改Vuex store中的状态
+ // 在这个例子中,actions对象是空的,意味着没有定义任何action
+ actions: {},
+
+ // modules对象允许将store分割成模块(module),每个模块拥有自己的state、mutation、action、getter
+ // 在这个例子中,modules对象是空的,意味着没有定义任何模块
+ modules: {},
+
+ // plugins数组允许你注册Vuex插件,插件可以扩展Vuex的功能
+ // 在这个例子中,plugins数组是空的,意味着没有注册任何插件
+ plugins: []
+});
+
+
+poetizepoetize-im-uisrcrouterindex.js
+
+// 从'vue-router'包中导入createRouter和createWebHistory函数
+// createRouter用于创建一个新的router实例
+// createWebHistory用于创建一个基于HTML5历史记录API的history实例
+import { createRouter, createWebHistory } from 'vue-router';
+
+// 从相对路径"../utils/constant"中导入constant模块,该模块可能包含一些常量定义
+import constant from "../utils/constant";
+
+// 定义一个路由配置数组,每个对象代表一个路由规则
+const routes = [
+ {
+ // 路由的路径,当用户访问"/"时,此路由将被匹配
+ path: "/",
+
+ // 路由的meta字段,用于存储一些自定义信息,如权限要求等
+ // 在这个例子中,定义了一个requiresAuth: true,表示访问此路由需要用户认证
+ meta: { requiresAuth: true },
+
+ // 路由的组件,这里使用了一个懒加载的组件
+ // () => import('../components/index') 是一个异步组件加载的语法,表示当用户访问此路由时,才加载并渲染'index'组件
+ component: () => import('../components/index')
+ }
+ // 注意:这里只定义了一个路由规则,实际项目中可能会有更多
+];
+
+// 创建一个新的router实例,并传入配置对象
+const router = createRouter({
+ // 使用createWebHistory函数创建一个history实例,并传入constant.webHistory作为配置项
+ // constant.webHistory可能是一个配置项,用于定义history的行为,如基础路径等
+ // 但具体值取决于constant模块的实现,这里无法直接知道
+ history: createWebHistory(constant.webHistory),
+
+ // 传入之前定义的路由规则数组
+ routes,
+
+ // 定义一个scrollBehavior函数,用于控制路由跳转后的滚动行为
+ // 当用户从一个路由跳转到另一个路由时,这个函数会被调用
+ // to和from是路由对象,分别表示目标路由和来源路由
+ // savedPosition是一个对象,如果页面之前被滚动过,这里会包含滚动位置的信息
+ // 函数返回一个对象,指定滚动到页面的哪个位置
+ // 在这个例子中,总是滚动到页面顶部(left: 0, top: 0)
+ scrollBehavior(to, from, savedPosition) {
+ return { left: 0, top: 0 };
+ }
+});
+
+// 导出router实例,使其可以在Vue应用的创建过程中被使用
+export default router;
+
+
+poetizepoetize-im-uisrchooksbindEmail.js
+
+// 导入Vuex的useStore钩子,用于访问Vuex store
+import { useStore } from 'vuex';
+
+// 导入Naive UI的useDialog钩子,用于显示对话框
+import { useDialog } from 'naive-ui';
+
+// 导入Vue的nextTick函数,用于在下次DOM更新循环结束之后执行延迟回调
+import { nextTick } from 'vue';
+
+// 导入Element Plus的ElMessage组件,用于显示消息提示
+import { ElMessage } from "element-plus";
+
+// 导入Vue的reactive、getCurrentInstance、onMounted、onBeforeUnmount、watchEffect、toRefs函数
+import { reactive, getCurrentInstance, onMounted, onBeforeUnmount, watchEffect, toRefs } from 'vue';
+
+// 定义一个函数,该函数返回一个对象,该对象包含响应式数据和方法
+export default function () {
+ // 获取当前Vue实例的上下文,并从中提取全局属性
+ const globalProperties = getCurrentInstance().appContext.config.globalProperties;
+ const $common = globalProperties.$common; // 自定义的常用方法集合
+ const $http = globalProperties.$http; // 自定义的HTTP请求方法
+ const $constant = globalProperties.$constant; // 自定义的常量集合
+
+ // 使用Vuex的useStore钩子获取store实例
+ const store = useStore();
+
+ // 使用Naive UI的useDialog钩子获取对话框实例
+ const dialog = useDialog();
+
+ // 定义响应式数据对象,用于绑定邮箱相关的数据
+ let bindEmailData = reactive({
+ emailVisible: false, // 邮箱对话框的显示状态
+ email: '', // 邮箱地址
+ code: '', // 验证码
+ password: '', // 密码
+ codeString: "验证码" // 倒计时显示的字符串,初始为"验证码"
+ });
+
+ // 定义一个变量,用于存储验证码倒计时的setInterval返回值
+ let intervalCode = null;
+
+ // 在组件挂载时执行的方法
+ onMounted(() => {
+ showEmail(); // 调用showEmail方法检查是否需要显示邮箱绑定对话框
+ });
+
+ // 显示邮箱绑定对话框的逻辑(但当前代码未直接设置对话框可见性)
+ function showEmail() {
+ // 检查当前用户是否存在且未绑定邮箱,则可能需要显示对话框(但当前逻辑未实现)
+ if (!$common.isEmpty(store.state.currentUser) && $common.isEmpty(store.state.currentUser.email)) {
+ // 逻辑未实现,仅注释说明需要显示对话框
+ // bindEmailData.emailVisible = true;
+ }
+ }
+
+ // 获取验证码的逻辑
+ function getCode() {
+ // 检查验证码倒计时是否正在进行,如果正在进行则提示稍后再试
+ if (bindEmailData.codeString === "验证码") {
+ // 校验邮箱格式并发送验证码请求
+ // ...(省略了具体的校验和请求逻辑)
+
+ // 设置验证码倒计时
+ bindEmailData.codeString = "30";
+ intervalCode = setInterval(() => {
+ // 每秒更新一次倒计时,直到倒计时结束
+ // ...(省略了具体的倒计时逻辑)
+ }, 1000);
+ } else {
+ // 提示稍后再试
+ ElMessage({
+ message: "请稍后再试!",
+ type: 'error'
+ });
+ }
+ }
+
+ // 提交邮箱绑定对话框的逻辑
+ function submitDialog() {
+ // 校验邮箱、验证码和密码(省略了具体的校验逻辑)
+ // ...
+
+ // 发送绑定邮箱的请求
+ // ...(省略了具体的请求逻辑)
+ }
+
+ // 清除邮箱绑定对话框的数据和状态
+ function clearEmailDialog() {
+ // 重置对话框数据和状态
+ // ...(省略了具体的重置逻辑)
+ }
+
+ // 返回响应式数据和方法,以便在组件中使用
+ return {
+ bindEmailData,
+ getCode,
+ submitDialog
+ };
+}
+
+
+poetizepoetize-im-uisrchookschangeData.js
+
+// 导入所需的Vue Composition API函数、Vuex store、Naive UI对话框组件和Element Plus消息组件
+import { useStore } from 'vuex';
+import { useDialog } from 'naive-ui';
+import { nextTick } from 'vue'; // 导入nextTick但未在代码中使用
+import { ElMessage } from "element-plus";
+import {
+ reactive,
+ getCurrentInstance,
+ onMounted,
+ onBeforeUnmount,
+ watchEffect,
+ toRefs
+} from 'vue';
+
+// 定义一个函数,接收friendData和groupData作为参数
+export default function (friendData, groupData) {
+ // 获取Vue实例的全局属性
+ const globalProperties = getCurrentInstance().appContext.config.globalProperties;
+ const $common = globalProperties.$common; // 通用方法
+ const $http = globalProperties.$http; // HTTP请求方法
+ const $constant = globalProperties.$constant; // 常量配置
+ const store = useStore(); // 获取Vuex store实例
+ const dialog = useDialog(); // 获取Naive UI对话框实例
+
+ // 使用reactive创建一个响应式对象,用于存储修改信息
+ let changeDataData = reactive({
+ changeData: '', // 修改后的数据
+ changeType: null, // 修改类型
+ changeModal: false, // 修改信息模态框显示状态
+ avatarType: null, // 头像类型(用户或群组)
+ avatarPrefix: '', // 头像URL前缀
+ showAvatarDialog: false // 显示头像修改对话框
+ });
+
+ // 关闭模态框的函数,重置相关状态
+ function closeModal() {
+ changeDataData.avatarType = null;
+ changeDataData.avatarPrefix = '';
+ changeDataData.changeData = '';
+ changeDataData.changeType = null;
+ }
+
+ // 显示头像修改对话框的函数,根据类型设置前缀
+ function changeAvatar(type) {
+ // 判断是否有权限修改头像
+ if (type === 1 || (type === 2 && groupData.groups[groupData.currentGroupId].masterFlag)) {
+ closeModal(); // 关闭其他模态框
+ changeDataData.showAvatarDialog = true; // 显示头像修改对话框
+ changeDataData.avatarType = type; // 设置头像类型
+ if (type === 1) {
+ changeDataData.avatarPrefix = 'userAvatar'; // 用户头像前缀
+ } else if (type === 2) {
+ changeDataData.avatarPrefix = 'im/groupAvatar'; // 群组头像前缀
+ }
+ }
+ }
+
+ // 改变数据类型(修改备注、群名等)的函数
+ function changeDataType(type) {
+ closeModal(); // 关闭其他模态框
+ changeDataData.changeType = type; // 设置修改类型
+ changeDataData.changeModal = true; // 显示修改信息模态框
+ }
+
+ // 提交头像修改的函数
+ function submitAvatar(avatar) {
+ if ($common.isEmpty(avatar)) {
+ ElMessage({ message: "请上传头像!", type: 'warning' }); // 提示上传头像
+ return;
+ }
+ // 根据头像类型执行相应的修改操作
+ if (changeDataData.avatarType === 1) {
+ // 用户头像修改逻辑
+ } else if (changeDataData.avatarType === 2) {
+ // 群组头像修改逻辑
+ }
+ }
+
+ // 提交修改的函数(备注、群名、公告、简介)
+ function submitChange() {
+ // 根据修改类型执行相应的修改操作
+ if (changeDataData.changeType === 1) {
+ // 修改备注逻辑
+ } else if (changeDataData.changeType === 2) {
+ // 修改群名逻辑
+ } else if (changeDataData.changeType === 3) {
+ // 修改公告逻辑
+ } else if (changeDataData.changeType === 4) {
+ // 修改简介逻辑
+ }
+ }
+
+ // 返回对象,包含状态和方法供外部使用
+ return {
+ changeDataData,
+ changeAvatar,
+ changeDataType,
+ submitAvatar,
+ submitChange
+ };
+}
+
+
+poetizepoetize-im-uisrchooksfriend.js
+
+// 引入Vuex的useStore钩子,用于访问Vuex store
+import {useStore} from 'vuex';
+
+// 引入Naive UI的useDialog钩子,用于显示对话框
+import {useDialog} from 'naive-ui';
+
+// 引入Vue的nextTick函数,用于在下次DOM更新循环结束之后执行延迟回调
+import {nextTick} from 'vue';
+
+// 引入Element Plus的ElMessage组件,用于显示消息提示
+import {ElMessage} from "element-plus";
+
+// 引入Vue的reactive、getCurrentInstance、onMounted、onBeforeUnmount、watchEffect、toRefs函数
+import {reactive, getCurrentInstance, onMounted, onBeforeUnmount, watchEffect, toRefs} from 'vue';
+
+export default function () {
+ // 获取当前Vue实例的上下文,并从中获取全局属性
+ const globalProperties = getCurrentInstance().appContext.config.globalProperties;
+ const $common = globalProperties.$common; // 通用方法或属性
+ const $http = globalProperties.$http; // HTTP请求方法
+ const $constant = globalProperties.$constant; // 常量配置
+
+ // 使用Vuex的useStore钩子获取store实例
+ const store = useStore();
+
+ // 使用Naive UI的useDialog钩子获取对话框实例
+ const dialog = useDialog();
+
+ // 使用reactive创建一个响应式对象,用于存储好友数据
+ let friendData = reactive({
+ // 好友请求列表
+ friendRequests: [],
+ // 好友列表,使用friendId作为键
+ friends: {},
+ // 当前操作的好友ID
+ currentFriendId: null
+ });
+
+ // 异步函数,用于获取当前用户的好友列表
+ async function getImFriend() {
+ try {
+ const res = await $http.get($constant.baseURL + "/imChatUserFriend/getFriend", {friendStatus: 1});
+ if (!$common.isEmpty(res.data)) {
+ res.data.forEach(friend => {
+ friendData.friends[friend.friendId] = friend;
+ });
+ }
+ } catch (error) {
+ ElMessage({
+ message: error.message,
+ type: 'error'
+ });
+ }
+ }
+
+ // 删除好友的函数
+ function removeFriend(currentFriendId) {
+ dialog.error({
+ title: '警告',
+ content: `你确定删除${friendData.friends[currentFriendId].remark}?`,
+ positiveText: '确定',
+ onPositiveClick: async () => {
+ try {
+ const res = await $http.get($constant.baseURL + "/imChatUserFriend/changeFriend", {
+ friendId: currentFriendId,
+ friendStatus: -1
+ });
+ delete friendData.friends[currentFriendId];
+ friendData.currentFriendId = null;
+ ElMessage({
+ message: "删除成功!",
+ type: 'success'
+ });
+ } catch (error) {
+ ElMessage({
+ message: error.message,
+ type: 'error'
+ });
+ }
+ }
+ });
+ }
+
+ // 获取好友请求的函数
+ function getFriendRequests() {
+ $http.get($constant.baseURL + "/imChatUserFriend/getFriend", {friendStatus: 0})
+ .then((res) => {
+ if (!$common.isEmpty(res.data)) {
+ friendData.friendRequests = res.data;
+ ElMessage({
+ message: "您有好友申请待处理!",
+ showClose: true,
+ type: 'success',
+ duration: 0
+ });
+ }
+ })
+ .catch((error) => {
+ ElMessage({
+ message: error.message,
+ type: 'error'
+ });
+ });
+ }
+
+ // 修改好友请求状态的函数
+ function changeFriendStatus(friendId, status, index) {
+ $http.get($constant.baseURL + "/imChatUserFriend/changeFriend", {friendId: friendId, friendStatus: status})
+ .then((res) => {
+ friendData.friendRequests.splice(index, 1);
+ ElMessage({
+ message: "修改成功!",
+ type: 'success'
+ });
+ })
+ .catch((error) => {
+ ElMessage({
+ message: error.message,
+ type: 'error'
+ });
+ });
+ }
+
+ // 返回对象,包含响应式数据和函数,供外部使用
+ return {
+ friendData,
+ getImFriend,
+ removeFriend,
+ getFriendRequests,
+ changeFriendStatus
+ };
+}
+
+
+poetizepoetize-im-uisrchooksfriendCircle.js
+
+import {useStore} from 'vuex'; // 引入Vuex的useStore函数,用于访问Vuex store
+import {useDialog} from 'naive-ui'; // 引入Naive UI的useDialog函数,用于弹出对话框
+import {nextTick} from 'vue'; // 引入Vue的nextTick函数,用于在下次DOM更新循环结束之后执行延迟回调
+import {ElMessage} from "element-plus"; // 引入Element Plus的ElMessage组件,用于显示消息提示
+import {reactive, getCurrentInstance, onMounted, onBeforeUnmount, watchEffect, toRefs} from 'vue'; // 引入Vue的响应式API和其他生命周期钩子
+
+export default function () {
+ // 获取Vue实例的全局属性
+ const globalProperties = getCurrentInstance().appContext.config.globalProperties;
+ const $common = globalProperties.$common; // 获取全局的common工具集
+ const $http = globalProperties.$http; // 获取全局的http请求方法
+ const $constant = globalProperties.$constant; // 获取全局的常量配置
+ const store = useStore(); // 使用Vuex store
+ const dialog = useDialog(); // 使用Naive UI的对话框
+
+ // 定义响应式数据
+ let friendCircleData = reactive({
+ showFriendCircle: false, // 是否显示朋友圈
+ treeHoleList: [], // 朋友圈列表数据
+ weiYanDialogVisible: false, // 是否显示发表朋友圈对话框
+ isPublic: true, // 发表的朋友圈是否公开
+ weiYanAvatar: '', // 发表朋友圈的用户头像
+ weiYanUsername: '', // 发表朋友圈的用户名
+ pagination: { // 分页配置
+ current: 1,
+ size: 10,
+ total: 0,
+ userId: null
+ }
+ });
+
+ // 显示发表朋友圈对话框
+ function launch() {
+ friendCircleData.weiYanDialogVisible = true;
+ }
+
+ // 打开指定用户的朋友圈
+ function openFriendCircle(userId, avatar, username) {
+ friendCircleData.pagination.userId = userId; // 设置当前用户ID
+ friendCircleData.weiYanAvatar = avatar; // 设置用户头像
+ friendCircleData.weiYanUsername = username; // 设置用户名
+ getWeiYan(); // 获取朋友圈数据
+ }
+
+ // 删除朋友圈动态
+ function deleteTreeHole(id) {
+ dialog.error({ // 弹出确认删除对话框
+ title: '警告',
+ content: '确定删除?',
+ positiveText: '确定',
+ onPositiveClick: () => {
+ $http.get($constant.baseURL + "/weiYan/deleteWeiYan", {id: id}) // 发送删除请求
+ .then((res) => {
+ ElMessage({ // 提示删除成功
+ message: "删除成功!",
+ type: 'success'
+ });
+ resetPaginationAndList(); // 重置分页和列表数据
+ getWeiYan(); // 重新获取朋友圈数据
+ })
+ .catch((error) => {
+ ElMessage({ // 提示错误信息
+ message: error.message,
+ type: 'error'
+ });
+ });
+ }
+ });
+ }
+
+ // 获取朋友圈数据
+ function getWeiYan() {
+ $http.post($constant.baseURL + "/weiYan/listWeiYan", friendCircleData.pagination)
+ .then((res) => {
+ if (!$common.isEmpty(res.data)) { // 如果返回的数据不为空
+ processRecords(res.data.records); // 处理朋友圈记录
+ friendCircleData.treeHoleList = friendCircleData.treeHoleList.concat(res.data.records); // 合并到列表
+ friendCircleData.pagination.total = res.data.total; // 更新总记录数
+ friendCircleData.showFriendCircle = true; // 显示朋友圈
+ }
+ })
+ .catch((error) => {
+ ElMessage({ // 提示错误信息
+ message: error.message,
+ type: 'error'
+ });
+ });
+ }
+
+ // 提交发表朋友圈
+ function submitWeiYan(content) {
+ let weiYan = {
+ content: content,
+ isPublic: friendCircleData.isPublic
+ };
+
+ $http.post($constant.baseURL + "/weiYan/saveWeiYan", weiYan)
+ .then((res) => {
+ resetPaginationAndList(); // 重置分页和列表数据
+ friendCircleData.weiYanDialogVisible = false; // 关闭发表对话框
+ getWeiYan(); // 重新获取朋友圈数据
+ })
+ .catch((error) => {
+ ElMessage({ // 提示错误信息
+ message: error.message,
+ type: 'error'
+ });
+ });
+ }
+
+ // 重置分页和列表数据
+ function resetPaginationAndList() {
+ friendCircleData.pagination = {
+ current: 1,
+ size: 10,
+ total: 0,
+ userId: null
+ };
+ friendCircleData.treeHoleList = [];
+ }
+
+ // 清理朋友圈数据
+ function cleanFriendCircle() {
+ resetPaginationAndList(); // 重置分页和列表数据
+ friendCircleData.weiYanAvatar = ''; // 清空头像
+ friendCircleData.weiYanUsername = ''; // 清空用户名
+ friendCircleData.showFriendCircle = false; // 隐藏朋友圈
+ }
+
+ // 下一页朋友圈数据
+ function pageWeiYan() {
+ friendCircleData.pagination.current = friendCircleData.pagination.current + 1; // 更新当前页码
+ getWeiYan(); // 重新获取朋友圈数据
+ }
+
+ // 添加好友
+ function addFriend() {
+ dialog.success({ // 弹出确认添加好友对话框
+ title: '好友申请',
+ content: '确认提交好友申请,添加 ' + friendCircleData.weiYanUsername + ' 为好友?',
+ positiveText: '确定',
+ onPositiveClick: () => {
+ $http.get($constant.baseURL + "/imChatUserFriend/addFriend", {friendId: friendCircleData.pagination.userId})
+ .then((res) => {
+ ElMessage({ // 提示提交成功
+ message: "提交成功!",
+ type: 'success'
+ });
+ })
+ .catch((error) => {
+ ElMessage({ // 提示错误信息
+ message: error.message,
+ type: 'error'
+ });
+ });
+ }
+ });
+ }
+
+ // 处理朋友圈记录,包括替换换行符和表情符号等
+ function processRecords(records) {
+ records.forEach(c => {
+ c.content = c.content.replace(/\n{2,}/g, '
3i?QPbfk*63 z9Rco6BZ0HaYvi2faFbDUrtXS5tZ@lHJ;Hj8+FMWO>XtwL716QgTI}Ook(QHmLjSqQE|?A_e=T7)v>`3{EG41 zX=h-BRxukkk2fuy)1ni|2(mnlp=eR`IzZZ+7@m~d8IiWA!a15k=nDdRuc57v3~tLR zFL+Gr*@sg?hd9mnQ0N-ai1p8i=oZNQ=EQH~h?p<+=tWde=OhU_$m1M@Ej1T^Ym>Gc zgv;cQ%LX5 kcvClQvi101dCK^8>Qho!=#;E;!u(o@3W zLyIod^3%bdL-Yf>JD!2D3qGhQg-z?1Uy2z1)FYKKZ>{Z?#tiG$DRhcXFC}Q1XxkWo zHXp3SRr<6MGVl@0*0(T-rY2SfbI*0HWm~nz2D~LI3McRZ-=PHxbm-+@V8~+avLRnp z?N+sq6~^ro+qcxU)onGU^Kg(>9c{!_HtGDqXkjbb7p@wLVL7rxj4{hYKLyL0!l;b_ zrnd0eWlSw=^0tDbTz&F9&*i2WRDOaNq_gZ7Ao*FO?>ppD(;=4u;!x?oDVK8*BRC3( zRlK%nfu|&Gn_^OR54a?2bbMYI&3G>f5B3nk9EZf$RGdPPZZ0|c+6RUs9|aJz^N2W) zTlh&T<|@uWM1@B^Sc&?pr*upm1Zqme=H9j|xeNFoKuXvmX^ufR8&908T+mCRDjh!- zhOmd)#ZS6jW?1KuQq5~x`5&v#R^ooH6I;|%+HdM8i@X#r)|slcT%@vo1nbID`milC z>cccS&K0!|fCEr$yIIt>eqD6KqPkUg A}vV^rqYXJuUNZ_LeyJ4f0BV`+9wU`zimmw{$XbcDArJ`&UP$QGG-4fE~eSr{XJ2 zIfrfVo+d4W9%Y0fjgYAU2_0%1S&IPEdV*vkxUT7^n`UepbP!pdi%$4@!DrF7seQxy z{WHC|8oXa>{9XYIN8<{0%qVsC({{1DJ(}~&wGx?K&VJmH(b7(Q?c4kF1TS}aAQ1x4 z(gd3P-Z6cs@L4k4aP=znF4DM_+YodNP@6Hw05I;eCey%I4<$R@1QgX-K#7u7XXDSO ztIUAtRpiM)MnTeCdP5>j2s6f?qr~B&Zwu;It>-0Df~d;qL&2-nBVtfIb=?|s1y<`d zu{8i~7UI92gNQI{o5$r*&w+~?47p}hI|n&T OKEIjSlh09Wh&I!W&(2`Zw<= zC@ASfQq|8qFWX}JJ@~gq_piLMzEg9c6F#^ZopB>O_p>_s2|o;G&k%{{I>^lnuLOQY zZ@6l|!;PPK+mEB$=TV_M`;S jP_OGycpFj!8wj|= zyf`f4s%v)pqxr9+{-Kkeq?*=9Au9z5x>R8|lwPFQCTPxrrtWPr(1>SNQDKmU3}w@R zzhR%w%V9w@Ns1?_QFMqvbLxv6R#>UQk!05e9)m0$qd0hsI07nt02;x!PEI)LlK&QH z&AXFQnW N zjPNHJ1Pc(SQ1f(&MP^VEFJ!VCIuK9X|KNi$M2ai5OEo~nbBsY{qy|*d>s_5+ET{HV z(VGnDJuJ}vzJYQGbZU$u-;K&4Rc~CY#6uEMhVC|0MKHI_(W8coy;CcesQ}(_BgKrG zfN_FKc1M@3NFe*S%Q-rmVZ3p?l`sc8S|)N}Y7~bL;Q=>CSW8}S8PeGS?&mmQ;zV|j z;9mPCGBF`~0YuW&&6;$!M)JI&X#VhR19t%7(*|qd1j$|5*~A zE8LQ?mPR%GW0!qF5b+$2;Tn1L`7I9NXaMFn)IMj>XgG+fKDel{;hVrrxNr^6X(j?z zTTowbIRB2Q5tE^pPa(ML&QsR=H6Ed?eq6#FFxk0BnJr6L_{qEM%xS=iShEsa!$~;T zlMvFrR}K?Pj@-;sR|G}`w*5@-BTpq7=1%EN$3i^=C-9-P_rV7Y_hOVb663SyLEmC9 z2#=Y5tN=m)v}oq+y=U{>#jIQ5s5_Ja-t=^O#NH}q@bD$<$nzq@&BHm(Z&@E>)2Ll2 z85uLqD=&yA7zX=~vJ=i`0;Dd1*@nKhH1V03Ve^W$cFe%c9N43@?7t>25-t_01yrOg z8up>;-=EJHk};q?@aEgQ&_F^AYhuSs1%O;Qu*n#*3lNs3z~tbJEQNimh0A9!4;?sm z)qOFF=rz+V+K#xSpCF )Yr3R+2fF4 z5=?+{kjF3Q1`cK`>DBaFM(2Pd_a*`zx|hbTL>miEn7 L%xdX565dfz|x>qC2he~;X#pnG!j}u zcwm2!R>@D}5*B_x4$F?feo2(_MGWJBkdQhT)UyaY_dIP`f4?|?;{Drw!pQ45K+E4Z z1b;OnBmi;%BNr!UI~#QyYdQ;O6PthS67UO%0m$?4|4#ZpkE(b9xIlUYky=4dfJj<( zgx>g5Rhf)dN2PH9nRSf$STH-grBg_4+2gOYH>DfZn?GE^=8#zRW6%jA%k1W25Hb9S z9nIHNA}#v(rV+#HPciAg( a4m8v#nT#QUsdjnau@3R&vNoF4qCTSOGbx1Xoy zkslfP2F0H7Qh>li4dg%V&n~Upu9I~ tp0VJIp`a_u*0fUicfJr z*;zMlrM|zW=72bK6|R|yb@=-O+x0w_D?&`rQ&%~McQSlC1%6!vY%K#wQMFxlBd71F zsSli=0BR$0PGhK-lU=1U><{dSs_?IZhjYXff%1H%E_*P&jZ*Gf3x(YQqAB}rW;5-} zXY2>h2A}EY =!JxMd~g$C^$v+O=F2QLLefVb2c6R5ec5TzHF4JD z>+r0k?atr7DoAE-o} fyyQC#hPxns4D(FPf^~S3*8_9 z0Q9*3O(e2)u`x7p{QFPyFOf)HD)xXCVGDc|2L@2Xn4!9d8f$^)^wAj{2L?=_B&f JYtcLe4?K3jHE kfR$j0d@yH&`+)}H zvPc%3Fk?1^Ap`N4XTlkf(~Q!6t;SjSka6B7h=aKgm#_e4;-pc;GKW<9ngXCfi0|C~ zzucD~24lR4q-FXIv)Ua(`fFmc7Cg>=N}kmgPeT0G7IE3HSZSo$nC_yaL#n(z(5|3f zUZ}?*OB5?j9kT*sqa$4smr8*#BEg1TK>t`E=?l$UZn8FT**4kX*xW?XUjlT@(iw@( z2YPT7*tmq31eWo%%d=-S7z*MCxgo(Pn#yT+9PB9pvcvl0_v1u~g#1cHH*MV5f+9O> zt)|Q(q=X_{gS2wv296uM1RV6BgBYoHFB5IMF^EtfzVNkIiIzT!BGx2Qu)_=q|Dc(z z-P0Y** ^TFKDPrqVS; zF7c=F&sO_O%S!+fa;kG73?%cCc7_zoDy?Xr%R|6ob`-ZvebrZP-m-E@t=@O_hhId+ zHZtAB-de5p10cb8GbXT-KjuTUz+*{lacE{o0Hn%=8hZ!|?s9m|qs$s?#T*GIT_(6_ zv3x}oc>u`Qqa-TzQcVl~seqUuAp5WsNI#17&`G3*jOamzr_IRx8kC4&evoBb-}#$0 z#TsaEBTuc2gbgm?5zd51;M*b5_Vt;^rdLhb^pVKd`%y0R==o}sY^m|mF~Og2z`~`C z+*PEfx*KhYt-nU&(CS3W2X>ODVM+?|MbdKCI3-2Dszgs)E0g(S2T9Cm6~!G(8ijRk zS&7oZ6z6r#oJNnV#89IY=3C8)B-S_)#fM!UA& Z#l3Z@Q GFa2q3pSvofHs~)l!?kb)uS7SQ^JE)_ zAAgd;y~q75ybszb*Z#t$C5j@kT++)&f=?`>@SNid-R#|oq^0(d+eJ+N)hluKVFf|? z-#H`JT}swkOD>lOlV^g>ud?<5&bMBrK?h#I5FcogVR?R>><#(=d%K8d^jFz%HC)CG zGIS|$1~<<30|c2go${QM@1;Q}&Kveqk>V~SMP4ZKKC_u4ZQq-vT-CELG;XTK9|BX{ z>Luj{nCX#fNKDS90ch&J2OGO^jhg;oH0uTUJD-2W!T+fZMq{tq_rd}I!1@6I{G%TJ zOA>c-_OSjBJ$y4;#%{9}W8?<(9VeKh348=Mj^`Qdg4&v_JZ3nS?SR=VcJPiqb+EkX zPHGx7vLLL0d=^LqzJq*LX+vvHsAZ>Q%(X{EA~Iv|^%sjLxh?9J&_0I5j2!XLCm$h; z=i6gL2Qi$jc`8#5?&Eu0vnQa85N`eBdEU$W{oAlF-6(XTDDg1`&*|1e=gV3W-uLdp z#)yXl-U2s*KeJy}FnE`R!X&Pp?eShRDY4(688ZqM8Ml-;LAR+|CgfPnNkdFL8Ixii zLzIR?Pg_?L%cX_%a%evp66$;@cNQ5ljq<0dsFA>-1+Pg%XTer;{? pgz6dB@gqtXLw-nj&9@>ZZR;~$WweOkl z4_T!mxSPDB9;2(p *eYiN1GAmVn6b}3DaTE1!vch7nIi nz5TJv2<3`B^_Yxuz%@Uir7UWFA5UrAluugNrK$xgLv2Jrh`F?;} zUa?U{<0}^a|Ju6>x2U$SjUrOgjf9i}LwA=jbR#gr5CYOE9a7TW-Hjj}N=SEi*NCJb zAR;30jd3q9_x_&mAGq^8vz~MIp7&j6&a89Jj`i-zpUu3)%nFVWvzVs*h*4bZ_-YNk znPx9Mv n@iN8&s~J39R;c)y`rQ%@^pdC z(Gnqg6BmIP&T7^vBUX=*PudZYh5I{hzHGT}U{qdjlyB6D<*!|UM?(k&TWDdYp?9f+ z?+jD1 lYp2e*VDoegU2h~Fo`;RWt z`dOc8&|$%Q?FHQT_{v`Yfaq;sj|Fkhcw=Vp@l5Tc(Aubn%@)L~_Q5G}%j*kUhT?%S zmy;>&tW&!wpN(EE)bvMAjLwVa4iCF}?Cc#Y6YK4(dfl}r_-Z|-Nu!)~!k;&2h2bu` z&5XefgW}z)L K)boH>9-Frf$Xf0 z8usK|haic|V?E@yYKD!w=K1S&anz*@mkder(nAyCrU;`KJi1^e%+x5*1`4?2Ro+W` zx7sL7e8dZXj7JH^%s#S0F)!q1SzdZcHqtt;g%v5Do^PU&Ud|}q!sxum({!RX|5$Ou zA9pv=g{LQ$n#_eVi1ndtQi4I@+Ij3!1aB{;aCJy%yv8Q(1dgqEG>CWe^9o}WfwjcN z0SmE8V@6bHZ;V*8oWmBv^HlbM4M-iwZu<6+%gTE7NWV*#f>3eRo8YejJ3?}rtq$ar zw49x*qF;3};=rvAWxFUt8b%QY(HjHbwTjq>H5>rx``;ZiewdO)xNs$PUl5nyb~SHB z*(^nN5l|dkFb=~THt@q6cJdH(B 1i8vpYfQG-`k5N+$+J*31?HM zbkYL0d7w{AGD(gAqTCp%R)tQqfIe T{RH@41SgHE-tS{VzZ3f`l{y};9G5$c9 zIU^rLDB}f2!I@%bAz;vSC7?Dsba!x(4={^WIvzth%BKk3z>eo6iF>;nJ4H7TZj#o& zi)63ji-@kR;(Jh^dlv$ZCeE#=u0i)j;LkoTYz-H=k4HHI{KS%3PNf7ySXBV};Z`eC z+_qE;gw}+Q+W`FzcyijD339}OLzF2HewRZLen`JR)=lTdxzJk}>BB`Yo*9OMWs*~T zR7)C)09?_$6_s?#PUuXzE$4<@PWljzPrVpy}N9@!l6r+ zvkL8 1iVqj9KbW`24#}0Lf`1>Vo`PrJ;_uWfTE-nM+9h)Mvu&Vu CN3!b3$3$s~xFo4uS8W|>{ZO3(+^tmjs8e-A=fM+N^Q$6lu{cJSd|NIu* zTE#JQi-nH2)y) YA0y_GKLAnKdXP4IYHieWCaz-bJ?)Jjbo8*RUY3p!%r4j zO6c^n00=cS4HNaVDrq-N^b@F?BIUnKFB8<4+M^rBFb?X_EcP$MheI*Y4(7>uWhk+- zANAr9bq0R!nP7C;c<4ug<}Brvx?*OfnuSKN3s$`0>*@WVPpG5M50SUK(Bza)?|{(M z?x&+*EALlE`yqWfYxn{vQ3D+_*K8k^xWAua4Ea{t2rmG!#mjEkoG*XM^08BmKsjKm zE(Sa 0(c_dFr)xel430ZoW)&{+p0FOW!%hF|*`^8pizvyqOC3wxq)TuS$Y#k#Z=> zjLp3pl0ms+8U}Qy>yz5e65#`=I{2>=h7( tU+y*9equApWfUTaX*nXD>HXxvx%t`2)6C*6bp$)hRU7(bo{5Oes#y L<%S08j}Rx0tA> z$j5nvsMe?4pD%Od Gu }1O9g<-_r+KqhxO;!=Cq3RV51x9XV7@48nn)^RP=~fq2pE9@ zKV;4d@O2I(&0W=tKWr{oUu?t+dG%C1 0 2~a;KaZIxXxhMsN*5MfV9-B2xm2= zf!Nu7q*QN8V>X(%B@+)*3gznqU$jy&&~(UEsYFn=;j`%|;bc=|YafbRK4y6l5sGVZ zqRpN?TO-nt 07aIW)BpQJIDCCaCZC--0`r^?f9)wrS90AvY@Eruqu9cpj2!zzU;Me zmN$fpx0(?u!J2&=7I?Z7$CrXb^jQp(fg^^K !G;FwxK2wz7gAR0kWrKD2VNQdd{DzsLPIG+>uwz5}6TKrncW~Hw1W5usl&smoEk? z1jb?%2DtNkdY-Pg7aQ_Ye4%?-m)D1`?IazSpVk@MdTtav9Xc|txIcx%M|Tnaj7_=a zWREzC+`pav$8y-_;g8$2rA7Idk5v1*%mp7o)D~|;bU&3Jc`uwnqyL}R#@h%rNloZg z;|IMyu%H?xs4(f*R0*?zwcW2v1G)g{f5If_GvihCsDdvGuK&KgJK~rdt^GYo_<_RN zI9a(4lScDCBJ*6o8V3t&=JK$&^&R~mFTbw~7s!9)2k~l+04L}ryf>&2am!G%`f!`p zQJwrr43g+Ip8%vr$?hc^*Ks3T)0S~IZoa!^i9lGuPWRX)CcCBvt#jrxr_}Sta3yek zagAXu|28&vsAmN>%fUI4Y mrs%HXW;U|SK8icKFUi`Gu)D~cc~ zj 0DWy8);u%oOlGA-HHSs>4%p^?ueP_R@V@cpFkAv`Nt4CFH+C$54< zG8s^SW ~?{MV=puuF|UWCzKzY#8})zD2t94kSE@?C0#qi~NOgdryjL0{ zM)j%|SctdQlB1%^qc!xf!p5TC5$oKI3+>eds}I%uJEX&M_qfT^6qZI2jRxrlH$cgm zQMD@hpuDp~E62Ep6ez05mS}IrsQkb9XJoWaX$1(;-$PbTESH%lT;wzmt(^&CDX7Sj zw)A*JS<|dv`zEd s0l9k#`teEEfv682uEl)c{^=RBwg1Jj+XC=XDEn2u*p`D+fShWK -tN9`> z(qc}e^1dVYB;|!uoe3jZ J@ioSH zi9?y7`~2Uh=Iw=fUE84NkQN$hWY93XO7-}yCjL9&<3B0!Rlvc84p#(26FBa!oUbgk znpmeUDD`0#$kN&K%b>p_mXww==+`teU2guE53t{)4Z1v2ZfNq80JByVm}C~2DG`#Q z2`Sutd3J6FAKcm1%7i=GLP}J-xFPA*(J6y`u#59LTbzp}B-grhc94)kBbFt;Uy4_g z&LG{sa?j$?gswx=)am 8mgk9#iuopO5XHY2ph`tN_naP6!9+WeQlW>Av7NpN$a_v-}f zP?x`h=~oQF0%4cDzJlUH703Tr02>y5Qwe_shJzEJ`UC$Tx_DS7SSj-rS0~LMrW?X$ zSUjvI^a|fd`v-qrAqoqJ)z@9Y%K(4i*VJ~fXjt*m6*`jX2Ktwj2^I}247ozvvHn5B z%0yr(V6&F5C 0S?ke|xei$s#~U@P3Zr;lg1;B~l^!KllC*12&{} literal 0 HcmV?d00001 -- 2.34.1 From 35807223d499c75f8f187981d7e7740b3f0032db Mon Sep 17 00:00:00 2001 From: pfewmlupo <3097217416@qq.com> Date: Sun, 15 Dec 2024 17:35:59 +0800 Subject: [PATCH 08/10] =?UTF-8?q?Add=20=E6=B3=A8=E9=87=8A=EF=BC=887?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 注释(7) | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 注释(7) diff --git a/注释(7) b/注释(7) new file mode 100644 index 0000000..fba7c21 --- /dev/null +++ b/注释(7) @@ -0,0 +1,194 @@ +poetizepoetize-im-uisrccomponentscommontreeHole.vue + + + + + ++ +
- + +
+ ++ + +poetizepoetize-im-uisrccomponentscommonproButton.vue + + + ++ + + + + + + + ++ + +++{{treeHole.createTime}}++ + +++ ++ + + + + + + +poetizepoetize-im-uisrccomponentscommongroupInfo.vue + +{{info}}+ +{{info}}+ +{{info}}++ ++ \ No newline at end of file -- 2.34.1 From 53a74b9fe01a2a72c6490df0ca9d8efedfe3f5cf Mon Sep 17 00:00:00 2001 From: pfewmlupo <3097217416@qq.com> Date: Sun, 15 Dec 2024 21:29:56 +0800 Subject: [PATCH 09/10] =?UTF-8?q?Add=20=E6=B3=A8=E9=87=8A=EF=BC=888?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 注释(8) | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 注释(8) diff --git a/注释(8) b/注释(8) new file mode 100644 index 0000000..b573478 --- /dev/null +++ b/注释(8) @@ -0,0 +1,139 @@ + ++ + + {{groups[currentGroupId].groupName}} + ++ + ++ +++ ++ + ++ + +++ +++ + + 群名称 + + + + {{groups[currentGroupId].groupName}} + + + + + + +++ ++ + + + ++ + + {{groups[currentGroupId].groupName}} + ++ + ++ +++ ++ + ++ + +++ +++ + + 群名称 + + + + {{groups[currentGroupId].groupName}} + + + + + + +++ ++ + + + + \ No newline at end of file -- 2.34.1 From 0cbe29ef55618b191792feec6d5136b0d0622b34 Mon Sep 17 00:00:00 2001 From: pfewmlupo <3097217416@qq.com> Date: Mon, 16 Dec 2024 18:04:33 +0800 Subject: [PATCH 10/10] ADD file via upload --- 泛读报告.docx | Bin 0 -> 27547 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 泛读报告.docx diff --git a/泛读报告.docx b/泛读报告.docx new file mode 100644 index 0000000000000000000000000000000000000000..0e9e7ae36a4fcd6cd61b75bbae50dfbf6b1a3706 GIT binary patch literal 27547 zcmeFYW0R&q(IX3!N5R3)DS>GC_s=P+QN1KXH$T)zKVyvsgo|9 zyR8jjJ{SmPE)dAi`u{inFP1=K^0?dp1ET1E0;~Z>f!X0Z7)%z!79>MZVr93R{tn zc;3_f>vR^&V1;!cTegI(bg%1Mk&I|^99{{info}}+ +{{info}}+ +{{info}}+W)WwEEQmI+-$F)snB^u*)&b5BFjv7Js4zP%L4A0s zON5xwb$15)vnVF{v<#kGGv^tD!blnq8tiJCR47wuZKx71-ArfVQX8bCg&U8-rdR!N ztPH*kdF8kW7S47o*f})e#r^vgGYdn@OElG$w5(Kr=Gh=PY*P-AwR{ebI+GDWCUr0* zwP%Uhy}k-?ix-@33OjiutT&;M?6n12c?2)l@esmEPe5}Wu0%8jKDyW=?T)eu)0-@4 zpKe*T&gCE($|*v-?&*&NB8>C|2%Ib`xrySJh!&=IS8=&Bl@k^?AD4b<)qD{wZ(UDI z;mwEOxlhQ;x66{AH(Wz3TB+rJW&9rZSIfcEU&n~ifdK;g{ssk7`2QJix~lK5 zuOCG2{@5nWkMZg|n%X$g)BR`ue@6R%v8DbmSFcQzl?G)*480EgCYtEtUZ*CW+td>| zku~`Q7G`=6$V5miYyRG%jHFv=3d3jiI38mbUdrskTcjCbaaZrFrxdK4--4~K*lF|7 z*a(yonwmMmQ@7s%%Y3^t`Wz&Y1W0`%CjLWBr9Khu$1|Ga)s_lDxVV!&FCZHmSurI1 z6vEptr?q4FG85o6EUzjf1Wclp9wEM ZV;G`&X hvC_##ff#S1kWdk0b8!a?P;}NY0JhqNW7%3Wgjw6dB2r}6T;4*6NvL+un zZ6D|&TD~ifneVHD|HNtbfc~G%r5XP>q$f2H(2NTR5Ymr~-0U1p=uPa5U2J~>-hU$9 zg^#uqj(Ez^yV!-F!HHo$x2M)WFEz{IzophKZ0!YTDIFB~>`%bNL{OWAy}$xvcf(=| z%@$(|i_JExiL~kUHVzkTWN|j>#4fM^^wNuk`4A@v5a0l@r%l z_lIMDD83)Jw=yQ>vgI%$)4i{nKyL^+7?P)CkIk9d{?y>T+-F|dHGwJ*DN(ck`FG@W zx(uHsi-GX5e*S&$_i>&+!2Ejpy6RlbLKZoShLDq<>3i8*ret|_lP5fMs(iYta=T+= z)*erPB%cH?cWjPuD4#VdQ-Y8^hG7Oz1QhVSu0zD1O@}V(qekt Z%LLTSzeHiXKdiO1g#Emo2(m9c2_|QsIg!LX1YL)l@)= zT~)|NKa!su?3yxIkR0rmQYcDe36W*y2ExOiIu(&gaTl_xBKe`o;bFn1`tts zRHk&~PM%4Xjb;j>Mo*qR_Q@+0HK-heY<4TNOm-vO@S5(7KD{74*5hi>9nY=f_0 )wQ5xMWg}R09XN8CVRY+tsX&yC_L(+~CU1I#y=KT} zWx01$=1ElIcJ4plu=@5qH6bXfcwV@6VSw2Tqhjf6dtuffIPOM|1QIfvB+Bwv!BWUN z`!Qt#8q7`|x6C?&3xk?E#}n8>9N31d%7XUH)S`(AUe->!g_fd#Qti<(P%+`qq?sF? z`mER9I0HH@{kj}7`1~@S;O@4#K9ad8U3n8touEMYZdHZKg<91HGKQ9Ma}#Dx%)#6| z^Udq(;4ApdE#%{4!__kVGuhQdyX$X)NJ&(^RsU)wL*%>lM4fUOXP%3B2?7CU`Z$Kt zNJGA;&_Z!=qs%J_;WtL^AA+x%)0U5O$I3%`=6hu&Ydm+|o5uau^oBbpxedawW2KM< zBw#0Syi|)&hu$9QN*zf(vW!^U$-TWZ!#*hUE%!?xAQj;a7wpuFhlmC5X3}fIu=UW> zWhS@A9Y0)}?8(R_Jict?W)M6MQu;63c3(p+$~|X6J>CWPLIwI43&9l2_Gpe+eY3o$ zU+g(FXhSV>rjGe*&gB|Rk?AT`No%Q6H3Xl3?vE0BxbC#5TKD-kd<3`dL+;)lCu8Vo z^s_29xVEc%=gto)S}Nk$p7b?6PHC=#ic%a+mM?G_0LE4V!ghEJ{$ P~wcv$uSK{PGAmAtruN@>{_yfl+>v$m?$Y<;_; ^(7=8MRQ6bO>51(!CEzPs%GwxNYHF!lchw@#qV z4LR>RzxAFgi{GCr?N&0fr%uYeJHPI1E0rj}tIPNB^q^6TXq0_Gl@KcGb8%B>DP~EV zH;hObm8+m^URiUpsUu1aOdLx~C3Ci=kE(i{vxB{XVRoIzbrzukPw4;E-_q(-@~CTX z`_kJ7JodBi0qi&5Z|Yk-E4=SdkA_2A8b9v)xuJK8=-3GR&17~S_4!pu8sThCh(Hs< zrMVqmg}+S5&9kNCzq{NViTxYee49QFg^dhgc4*Re$w zSZe4rX+ji8KoOV=Oj~K~8kh?}jVF>>b1riuyra`wdHe7+SngcxNUn$jWkv0^vNkMu zy8~qfV+3Q_^#5ECq^reU&p{)FJQIT$LdX{&a6uq8=^)?dp;Ma!7lBLz5z5FyrXXAc z6&X<~*=I4ztl@j^esBDkMdLg^pYj%jNv}4o{n`!X$_NFD9XE(Y15|qFSsXf1Fj06x zWEs?}ep(K7xY5tBZS6g0o^OBMee8XWw|qSe*XcFh`2g?d<_U39TM5WH8(Gc~EK`u8 zfWZdE4@SEd0PnNsvD#wx1tZV1PV!|a`~$9|l#?lqq|TyGxoeQSaxRXa9t$}tcr`k; zs7?Aq{{SyPN7CeJeZTttbJfoGYtQ8xspW;B`{eU$kDMyV_+O#R9WQOqH;Hbqf9^)& z#?{rj9^(q%txluPqA&ussQnxbo%YN2V0*!vV~m`rnv`{;m4anoAHh7l2&d(em4>~k zuFdLKxAtr-hqS+zv~^$^7HsaYIbasi!qi{l%;QR=(({#M-|eB??n=#%2UNw~Ay_#{ z$agaa_U^J86PUvjtPQ#8l$g{U)dupwL~1zgh()EY5$6QFy2i(ZtX%!F)wEyQUj9m{ zzH7#=X?@jsUkaNBMZ;EW!$*(vG%KSv2f2V%i6~O~Z|Vo59knK15#8RSt9M>wl-JND zvEw%~@aDX$5`3zBec_GW^0n_(Z7b;LI;O$Lqc3a8<6tUki^Cgo1SC*LXDr=qr%fMv zMwE6Xtyxr^T*J;r?uWR-ieFr-YIj=hZ3vDEy&lcqy(3hNr?!-Mb_c0CNR3d<_|J;Z zhD9SyI--~d)}Qnw&_ym^ ^fV=Q*1fxG?oe?N(X zm}znW-_JmeK?8j8`g}-SiSVWUoxm_+K}Ui{iphN2*RTA HDa1-|`)S@mwx;d_>tr6?4}TM;njtas{kyOhI`Fq+I?@TXSum>U@L zI?zAiv)8g{ugc_ikCLaB@8^c|+zSs!{O9vt1ma8;42vS8T^Eub Ej)Kn3@0!b zZ{vNY>wWf{Z`1oWAzmbhF9##>rs8bCX>0j9e0zs}dRu+|OsK$mVTR &Tm zUTfGdzRR-axH2j-7PumriyMDe5=>!!F6D3aJ_QExf-H`_9cv@blss)mR&u0+I^=_8 zzXpuqfri*T%eD!K+X_JPBtA-7o=2O?u1SmavGDxUfbxixBi51McaA=d1ui5mqa}$U zMRE{aCSzF`atyN`_VG8Bf8hBZL;&RYHxy-(;H)5iotRDexEvrwT*N 8`lkm7~I3_L%b9y3$jIX=aU+RNnCuZaE!|#;ogV;#F{i0y_ zxcUO|t3Q(CHVxm_v?E73;_f!}aO2tG<1-0mNO+0Mem?GJ@+05qM*(w@?=`dSYQyQ4 zMi#ghx?;^PIQ9$JtbY(o01(2iueC@NXklQpzfD%O>iw}PD7l=wicV)Budztb=Lmrv zhZs-a>Jmq8oh2H_GMUvr#KtHD k#j`$ z{)8LbKu->HC!`q`s*rF|Z+ei+3^W13P6vmB!_LchB+rzb1QB(3ubli*Dg`rW-?u_? zl_1YuDKQ60kLOGaYsYt-a9*Fz%l>cSc#;d1L5@UjQF@TYhY||VCS?LC8fBtyZ;_^i z-?pYL4$>sJll^Dw8j-!^pRFTZ2C^l_YZZUwkWk%;6wd^%L(`cS1nGbj-{ys~hU&v$ zl8S(1t8^;{G}SgK7z|beMfr3Z<6jJpmmLPuod=9Lvq36Hd@B|WzH5^c;#f%;yY>Zl zqF|y; abLj)EA~f|0h;3Yu#SSHLt0O!N$!}L89D_B zv=lV3Xc+J$ukEizCmFtJBG(vhXgKN~tjvU>aN(36;u1)Cw0i)yP=_@iQ+WO-BE{yd zc6|=7EpsIDur#CqRCd``J<_JZ(1jJ8C6Tlvqn9dWj@FbzJ=EMRLrFW1mS)QdpEGNI z@JXsPo-ds$1=?KP #P5~m11)E_ksc Mb#yl(s$A z&PKkZV=af^Z1;Iys4P)@p3Pwz$EeFkctqj37g1aRt^k*sna5d6&u7V>BEQo$)VL{U zt4`(?f~|8GG0SRJR(%-^GF&tp(oi-bz)Kp2f1NR>FQsgLDT-(| JdQt!NiYZNQt6c=#qL7HU%7{e z@YB !QiS4 zY-HX2l;(4Ae-WzpxSs?VW^O;fctmG{LR2=+>)>&)+*&SuA5opUzYD~^G_ ^bEaPR@%WZas!I6WdB7D5zA2W`qa4qs=rdaz jg;gb3+^wV<;G^@@?e=a8 zshtoN2;oLW^>7G33W+hZ5tI@Td%y@VvqY+JYDRt>wYP{ zGbyOQReZgAwNGsxfiFly4ir)zrc3BT;dZExHQdFp6))?FxgGJoOvF4pt60yphB>_M zrq=IJ^Lcc4`sBTSd!1~u>l}~DwBA O{7fwsoeZP--ouC%RcXq&K@nIgW`ba=rDN@c`9V-eW1#! z-!@z(3X7KGLYx;73}1hE@5EfD t*4e1SV84#m6pt-rwNr6wUG*&`;{Q~cxJjTHdOjcMi7G`h$Ldx zXTY1k^wi&S96U4xJei6X g(D_O|UHn?w`2C z=L6tI6_Txi)qvYK@(+|MxfHYq{~i(2d1vz9zt^8vFiq;Jiitq$bZ!@dAqmkvi8Aky zm{NEVz`@{*5QjK;o_G;D;-FmNJHeP3cvQee!%eljYc>Ybi~BWVD)9K*InbwK4rwV7 zO#wsW2wi(S@UtwF_)>Re7uhHI_nte-Nc`&!9pN3$UTaevr`iZ_)+0#2x_mrL^=VvX z6%oR7U%~{>yg)a=O0qjj$p7&rV4_bbonq%|$v-Jv$F7!gwfJ=86`b}eGSTe!$jso| zy%>NwM87dn99C9HCq!*H%q~NviPB0tk%;&pSa8B>p$B@dI7r7^Tc$}%Gdn*xo}|Lt zlxuR&nZrX6UFI78NVLnW-fygMnsU;FaWEdpn(~-!V0?3ZGQdmg@%*sqn|k}5a*5iP z48s*ces%Agj(k9585f$uNmI^}DcW`t>`H_S=B;s#FnOKep82#=Nj6BsESG#HA}VYS zNVZ y+;`U6fOtHvJ6(~vpeFiy+Y_=5d4I;hRtZt?qE?=PGcW#EM zbQz5hQe1gn3@8eA&LLdLGXq^Rk65*EIrBd_j?%-C@Rh3s`Y=m2kWn=#xeWh!c}M%y z#07=TisFf8q_q=W)J hL4p}2ra+F{w4q3x^gaH`|xfLTacz0fVRB5rJ# zF%dCnuzA58bjryL$hqI}ySdF66b;34-K8tX(m{CuT@yxTnLl-4X~N(WlTF%NbB?cn z%nvCDMzj+6v(=sBLGlIR!lpH{U}I_y2oK4D=y0XBHT-Dz7#)b1f1V6Evyio=yh(x; z5oc6>&ZhT6+3u=w{KDM0Go^s1bSDh0X0`;Q;se!22B1N>RcA2SaMli&MV}nKA;lQ^ zO3ShgKgQhKfjt@H(BC$Y=VPI-pSjIJbH$h%vFL`Wk`GIdqo4x1lMVq&SFcd^3$sDW z=1j~K^Se$i1uehZ!=e?&9axu8 P?kH_}HhrF6j=6@iAp zHZlLDB}KU6!dWAt)H{c9t%(3!l!-=APn!!sU-41Oy^ w`EIQj z^I(nob&g|Mvkb7nW29 ZCtgk(8C62wzozdV=h-PWexehq7Ju6etH`89zOW)PfQ zpV!LOiyG=l?py~|R^{g1uiUW!ruVpI10ueT?#$0-`&Q}}GLZJ~^YFE*3-$EsRhxKO zXSMa{ceQE`otmEBWA( A<9tXMs!sT|EkuPBJiq^mF%(_mrJ$zD4^gG$|<3m zC^ -$* RW|Qe=W~rpw-2ha zu3x%*!3ye%>Gj)Uw(PZQK4u&6$PsklcG|1AyCFkA7lN?Pe88OG&FvZH1(U3@CO|6K zD=lO_E)=!D>vd1{a9B#lg>&_xGOa`I^Ho9yO+|mRnohsk+uP&({(W&Vb#c*@=%Ik@ zs_QCR;4t}G=Qbs!3*wk&dHdaCH#-HqNu5Dp*<~;pJ~dpqFWjSIC_;%VN8>STfYuBo znIY0)-l jApeZs5V(5^^}=FrDdq?QxkhA z*fo^pb$fMiV?}~1zzG6zOTBqRZiE4FJ}PT=P(ZigGKZhWb-g!vb{F~lIg$)<4&BI3 zZm#<}TyS^jv^Dgsa(3Mn2Y3~~9vDA7ccbRtP~UIc*hz`a7UVw96^oY+m%32Nn#?T* zW{o7Dy&C!F R#u}9>dUfh9{K++qHIXmfC?06y*<6)T8Rfe-1W% z`E#&iYJd<>yDTR`V{9Lt*n$cd3p>)4;!ayY8OnyzkwNMGhQIw%C-3vLI)R>wi#^wb zy>l|yu|r^zFpPEdXbnOm7AhgMhrXAwgbA72p14s1M$139X;n3ha{jLa-p<0|PYwrJ z*qhwCVFn6x^|eO~b7sQ8QGW|$pEs!I^PdB}Q-PDW79Z{ez_2%`nHp21uf(+5FSq3| zxEvBpsRFVQc<^EteXbW Qe z80(z7y%#m~&Jw}oYRD4C%(zWdiVW|Hz1*yDxvSnYjCmR*)t0S67~I(kpijvN2vA!n z;43b=P@pOgU!15w18S>B7!|QdBB 2%s);|Q!X#Nx?AT70(try@7k;P>@roew@rpHN!wRf8@07#tmR<&Tv47mz zKom9WGta{QaY)8IzXpN=qRWmIT_C7iQ vIWF zqC1TC7Pq_TE=@q7)J}|ydnbXoARxIS4o?inpngY_UKoqOB-jdLXa=DJ%oOGw9=flJ zWrMlFcL7Bq0i3X2!ahzKUpF0hF{yzx;77HYO%9>95M_8m7!+n@wx gz z4}4EDqZSXx`(KjzIp|SbT=y9k@Gt@bxWyToT7UKR&S$3wBdeb#O*x>XYDnhdXO6Y1 zzFriyym^>DzUN>}c}(YcO!GZm`H`>Wx?LtBqS{@y2O=8aoF(;kE9JT>BQ7_FLqS}2 zVpOU?m?h$rrjk(vGbB34ArS?WlME_w)w9d(9w{74g#9@=!n780-?w}`Y6^wg(D|Ox z)=Hom4M5Y;qM{$|V%=mA-V=g^Gv4u1!>xo# ;EgcU`gQIQIzYp1 zHaauiw2GB0mQsB6=>=g9yO%1)bLG}M)U>zLQb;^6(Tv0V_|asHibM?G|5P_EO y&QVs1HcK~L-D3$0o+Tu4M)ruX`z#U> !xCxP(gy%WP!S aQYT8zv>JVnhPfua9NF|!%WYzJS;qwZ{jR8X=FD?)# zqv&Kv)QLl)Ck4aA?GHFc^Y101gTZ1y!|u&1PJnzKg>)M*b^k1PyL4#ygn`$9J>06^ z;3B{jZCgEfrC3ZQC{+{|!K*H?r{kD_yJ#PNl6<&};UbXJ@0bq`YOCYU>fZ7x+FxB0 zx9yEJ|JLR4IBEjL7Io~)EoL;^x)Wde4os(?D1;IHuKCdE`kU`wV57yS=&cP|{Vff| z)blz2YSTTl@nZ8PLUq W}H0{$B;em=CN7>4*xI%bLqfH9l_sOzU?2o*h53 z)bFnJf0Ha NUj+ zGn&8eHZN9}S@1Nc@F!j;YlmrMA- EcC(Ld|4N3LOgAcZU z%V^wp2V)jLuwRcqm*xg9dyM7(Rihhey@4v)I&PCH8?zO+q0UzA5oNtt5|x~)-bK^W zxp?!@Q=yW^Yo#($K!}F8j>3xsTnCb#WsmHNZHSYR(W6t4FX+k@6e=Fn_#E%5FUM_e z@m%D5=OspYmUi8jwYJ-@5~Nc@DM?Bep&Jx5qeVCiX_P`x&!iJ?t%{c5 Yi%qst&ej@Cj$?9(IRYV**dVJl0WUd5lfOL zzJLtNdffUYhlrQMocnOqIj70`Q8}EoIi0%n6<=U9JTRWtL`}CxCtMJep{=R2F-aoS zm~~V?a3YVt%wE2IwNEc4@QnN%?*pZcDow(e&}V6I=Hg+pSbi@e!<&ndNUha{u8k=* z-q|&$EpmnmIFnwF@@t+;^A?END-zF4X$y)fvCIhe_V_s`txALyol!!)TXeM^VAG+r zxDi|;IlPQHP%zvJ6yiLz*e*_7C|L`flLOxhwG5eAW`0g$6s1o_Ft&|M*9b~gs#NKM zvTz{*>1{VeZNNT(6+5^~wMv8>GJx2UPn!hw6g{hF*2DQwTtTfsGP@NtY-48yFTsV+ z1{;VG)9`)pgqj+8G6go0+kV(~d`5U4AckwU-o9NL%-!hFu)(XYsayK>^5^+x?!-fj z!R 3xKNPt!Qk=7BLozzP*cF)>! z*&Q?k7V4^htQ;0(iQzA7(xf-K{a_nX6B1WcWEqA~vC%id ZuY|$h6f;S8Z{44GPvq;N}Q;Tw~BLO>HuSaI^7}e z*|U55GJrT@Al-TK@3KPGMBs$@!|?UW$lLfd^Z0(VbBex!Xhf58~i%H`^We5wu&4AT}^?eS)$I`76P1-7= zfbfTcYS3yKYJsq)oQ+-?^L|U`Oau?gd#BH2>z+(~jZ4U1atyb<3n34aV)QaJIJ2`H zn#nYT+eQywb*Z7Dr88bWo9wM&j>qK=iVbkxqURGCXlhyfW2x-?#RVytDZ5Zy2H$Bq zILGL8(hd&qwFqPwkL?ZlY=S^ qsj2@QmWnr`@0wZjObP{8DvAsmCh8g!d43Gv=^ ztn&+0xqpZR-oY%`6|_<1N=TQWN9eDLY59PZvSX=7p$P~k8rh-|T%WNyWV4ywx Cjo^a{0T&8Dj%?EPuo4nR z#-5`=MF!Opq7_c3fDBk6^j%phoQcQJ>CnP)d__{3u`s6~7mBEM$PN*L3ti#|L0k&x z5HFk*VMst4caz34R(WoikJ%fgdcMxR;4;I+;laJ*GW+Bnjc6c(WJbtw=gat9kMS^o zY*$$~Ch~EYI|{)L@(q42%nU=4wv=+NBnrYYuIdK2#D~pXU67~ENejb#OI__P0>@Ux z&{VkxN*Ko)AVGeOZ6zX|kx%75Ju)0*QdL^c$8H|h_JLzlO(;M~N(*c4tOf#w;WVD@ z(M^L8(XncK!mk8aq_o-Wq+v!=LtGYlVAkOVFEG$XMPGQR57^5W#pp=2kan0BY~@urAUPpya(})8hRlY3W{o)s zTF`Dw>_&U@pS$@BV#J0!ML2?@7?4ZPlca7ybBl}&>m8qw9ud{QIkHS`B*^aZe;oA@ zZY 7H8co{ z(K(2dkmHq%lD#_ctRJaHM9ILah$LHucdVDlvUXYB%)fTo-%z)`uI>QHy|}b{)YnT1 zukb8kX)C*A_kq)kL_=+JIK6p%i1j7LO`UsSlqd!@*uMU~`2>7gHhqua+^;$_BU^bk zzqodh7cMG1Hj^bg*;ncLxMzweLv>t*pA@^7Etzs 0olO1tUYb?rYDwj0b3c3}I`L1fUs`|JXp3e`R6)Z8^da4i2@^jkZzgD0qpEBY5 ze7+qGrzX=+jVU}v5!e7ejGaEa&IahaqT(vzy4SRP)!MqWz8+?e*7}du*tfbKCm$>F zhA$)-wf{p@$!6XX16(rtWebB4=yOoXQlGKDtRvK4en0<&eItB$yY3?Kd_mbfaup z&zV;5jy|ULtSnP0&7OC8ZLMphj*)KlAlo!2Ky-O`A@$bRwHXO?DS5Q+{;moaQ>FKA zXu64Q@iivQCS@n)^*a0grP6)h-Qv0GWuLcXxNPFPWMD33ac@22w`ZMcjk8!Y{cE{v zJnB&T8&g5wQyt(@@k}GnMvWr{QS#V{A*#-Lmku@=|JnZH>~z@?ahW(Cwe@J%BCoEg zSLXfH-|?NkVd(R2diV*`cP+TbbKS>$`+n4Lez^X<$Pr1#fhYKZl@&`!(CKP ?JIB%nU85yGtUe)a_#(f_**4{oBcsXx+3_}=|jRs3l~o&MmOK(D&fd*-C@X?>(0 z6^=XQ(n#C%EdIu_DDUjAyw|qR*`{WK_~f?EX8U(pf2jiu7F|hRGUN_dmSL%V{*h z`I8I`zKv|aDz_mFr2XsIzon3($tIe`5_w+_U+eSD )648Rx-hXX z$
Ny_E_+!i^f4398xKq31GkJ38-Iw`F>1ZSEpqt3Cnh-Z*2>wYU{KKe8 zz5XberV>%K>B4YUi4m^cs?zbHeJg2yh&>s*D^aHz4=mX%-+0lJ!434?YPYX?yVJey z6P|UMoR(Uedw5yO{v{||UIU0K6MyZf8C?G7Rx@7L`YrNMa?&*!Q^U5LGPp75^*~#! z9_98#MmU$|^XlII`zYbCsHPKvw7j!v{E)k4s3Up%c2P`V^-KbKhYVBy_4AjV?V|RZ zJgYJgAye6*R1v`@>cZ893i`;pMaa{o0Q>@{nwHt619#-<>D=rvVrUenhs@a{bN`wE z-b?kF@*Nl?+;Y;##u$IG_k2#y{k{9UT4_9|M>%N&J<#{`{;Lude}@luCf}^{vkDh0 z$z(dZ#SV%Q7tQyA%XXc+WB0+gW<%QiYvrJ#Yz9<*-(mX4!! WDSJjJLj6ZP+>L5t zWt*mF?ZqJTnrdLW?&00NgTHjAi>@0P&$;6^=v+Fa8~`ILj|DE?AnaCM#@KxL#Upe* z9u_@Zr{gJ{k%})kEFQ8+?4M~Ky6QwCf)QFH1U4G2HpfKw3yTTQ)jLRZ#is;=G+(%j z1Y|EX>u>EeRDyn=m5$s~gaO)D!Yd&mZ^7HAYfaigsNkFru2qEpBfOT93+SqUS_c07 zG!-EKtoSc@nc3Mn1MHklo&H0FZcJHs%w+gsjdRbt8ML~Ay-W;F6*|m~>6Ta$2q4uP z2Evm-8Ta_8rzr hM818?4J+f%F z#j>S|bD(7bHkcQ$HlNN@*LgNz3|kpgxO;cFCdgJ>>lm3tB>to^RoZC?CCwPw0m2O= zE}o(CC^4vo0*<|gvQ+{Vsto%fCgL K1WZow5p9l6q)zGryK zU-nt`aI>ecXN8dQl!;!fP2$N^#+F=j_NOE2T`oRa5fE8PB&s}Gu)`&1vWd5%fz1<5 zGkRM9hO4R7l`7q1UiMkhbV)Zp1N1&hzZ_eHaY%sTQ!`?vC2~0{-oNdnCWU#iW45PQ zW=Xbuz3NRZFat~rdFi2{60JHWP*?^Sm-I|g9crtLJS3Gh`uxj#)0Ku!_z#>Y(6VSi zuhJ{3hy-P5z %=sXH8wyrvA82Pjo=$Q3tLhCgpY#MFRjf`n^CUJW9Z{}0RI(;^9 zWj)6_oUotVgmg5Sv#wbGF(?LfPjN1!)MS8_LnK-)i4B(*72ve2cD<>YUGZq8`VgQ^ zU?qp2(Et`-j7(z_?AT}0@-axSm$btPbJ<|d03J2;VE76)lG4=AXi@2+`Bh2d%__#v zUJb!|dY#g+)>z<`RaE?b5XQ bIS6gdb`GfA5A9VjumcJ>$ *bzXoiIn@#OUkgt84vjvxIYtAdf(&zSA{c#mg >PV+=vUOocwV06&QfQ@WFivSP5dZh^$o+8q>f)Dm)7hS?17= z)#fDxb5P|-Cf^G!u*=-CG`{^|BspoXf{j*s^_#?DD_Vr6fN1N+^cr}WDGWR-z=N2- z*!qZPte|ZEMw17JM+6_;7v_aGX;b1azcr|BXW-{No{Luq-W#s>yS9Ym%T~)4RD=#* zRd%Bl8YE>>TS?5~?oqbNF|WEpuqA^>S%PwUqxyr6XFf}vBG5MZH8o#y!r|G6zq(v$ z_%?qS=U>B(7K=7w3(LHCO%Ef3Q?#zTD_PJ5o+H@s!4aMSs|CY%(qfCLFe9FpuRGQU zm@e8+Y1U;`!c_9tLUgkqfyAR0Aog|E4e(XI{gS32mmJy6z$L1Pf|IKQ{0H0|5UIbf z2I=;GKj+YtUrV9Z7ntT0@VZ?#H4<= VU*=;Dy|k) zf|=YZV+Ki!8aTd_5X7xx?uxpw^w*!a)vYLep;7i|FW>9g6`?*mTI|c2{QpPC{h;!1 z-tHF=5Em8@5ZeE6+|CxJwx;y|H8cKK6N{#H6b?J8FZ~05xQCt1^&2w%ZK$q(B3p;# zC_w4Xorh$aaw$5R^m^Ei%!3wHYCbUxTuT2 P-M#4kfln$j#92uO3HC<*kIz|63&xG4w;iBaNQ+JP#A zKv8>#_W=aD-V_=8$b|aoLG;Ezk$ TyE2b(nDT<<)N#^CVaA8-MMW`= zZF*7xCcys)RRJ|{;G}~muXa5>A76&Gy!Ts0XY%AB07xqSneIAcquSZpd;%llwWI=) z+$sS$)Vh6PZ*}nS!1(e4w4_N2N?U!($(T|dL+jPY33DrU*6>iA;n ZiY2$B zFF5~yraCRNRc_}_e&9fcrDhpUb#+afM}QKxA+6lbliN*8XEqx6t-GGK;O(;0njrSv zP7U4uXU|LGP;^TAB_2jgo5l+GE&n?sAE<50Yv*z}2s;5NvQ>L1-Red5^@i0cB2Y1U zuiZ(lrsb8iei)T8E!{RBa`mbv)GLN9WuQMg@ub3zO#PscXw`5@51fKtq;iG$;LQvg zpB~DTDH#vp62V!~CNwW5U{=Pc@ypY`o}U*`Ty4(}2U|51&(}E{??c8eSoJH-o{s~m z-#l-ypPvUE>ImIW`ynyk_s7#Y-?zyGl(sujcKF|q54TZa`kf!Q0TA5-d3FN`l99jK zBjaY_QpzJdz JE1~wdar27cfj2eeZbN>;r&sUxxwo2QA$AWoWYAbn8&A7J4Pr zhlu;I(uMCUh{kcNwnAC0SAXJ}`@oSm$t^I#*-66+uPclDPnaZC^~m`Gskh~9p6v2; z#eA-~Uq(gCb%7U-f9T24sRpz}k4&LSYoomJ5pf57!C`W}Au8#yjHabHhD6?M%P)g@ zUZPOp{Fm>}iR}_}V>4kJpu;vMVQ}kEg(URmiDYa~#*8Y`s536)U8HFp!p^#f!1c+e z-J-RBuI8VgWQ(%De&u@&Z?upxI6dzN!vo c!|4b0p`W@QdiA59s(8A8BWqJIbVAC}ZHdWr zKHT&YpyZ85iF^*8waY8UcvLAU!z_4J^-C( jFyQb^% z-&55-=aR17bUkG!UHM`> 5L_2(u|Lp#8nfh)d}!cu6+bVF_A@6YjxJF$D>u9+Y^@u$U&tPm1&?JW-{} zg&U5Ard5><+cVZYNvFa4iP#+9HSyNKU$`y5sI!0Z#_f?$RDzek-B+eAUUvnW~LqZUI;^Mda@z&W)sF=SmOE;;074^ZBs{ z 1r}q3 zru@aC=3$rs)(vmVYA%u`A8gucEgyl2tK{P5hwEQUJq2pM;=1Z1D$v4c+p5=)m#YW^ zPGk(l>)$^q#{d3u`z6N4i}uq>|NP^g|7Y^yWa{i}2{8Zf%v!_HDU$=`%a{3?famL@ zT};UTcA=}!VC`XVtLwNi`ymt7u@W4S *`FA{9guj_t7u)Fh*Bg zzm?hWReOpGOL0bO4{}iwHmM4kA+rJIrOyZKJI-_LWD%2&MAdR#2U<;Fw(#=RyY|!7 ze*~tW_UnH(KG(^w{^jSih)*#$cVIB_Tk(wWR4GU&)D;JSQb%nG=w+jm%ZJBW_XIX| z{BBmsjm>g(2DCjh{rqh2onHAI=OD)$!DN~CaQ|Y${~jHXj}`rj!*UXfzt$58*xZ8u zELfaw&CoeqPn~@ ;`1<5i)rY}t`>+80wZZ;p4 zDJ9WP*NY1|04y?>+a&iL20F`s8Nb=$cnQG^bln+H?liLM3&f9lvC{BpUm3C;Oev_r zoG!>W6`E&!V7&sg&@AGOXw~#b>7x7tuYmBKE(!FFw-l5(v)4K2D~ z?r9!JQo7W }*RRkUPjx@>$?c?d}8RPo#OH#v%)-B0ri(ce+*t zznf~Yt8K(v_82sIlR$G(qM3n7309Ppq~Zfud!y9o2eYkk>*S%8v~>z5N+x^FP~&Xi z)RCDzyXo@|Z;I0|)t(~{Nh0C8{idZjTh#Yca9p*3>93??d4rg#e@IN${K(JV2rin* z{2uOu_X=zCJPIr|=)6|F{IqCy`$e3#S~JwfH1?W(M-aary;|4`rg_x0odmeh>9D$t zoiaAreibSdZhQZ3rKu)8yo|sS dRzP*#}K4nNX&i)lYV^BQ@XRMS;a z=Q@IuAD9~=;| XiIUd2GZ`3mzl zsS2QRq3pFx*1EN$Ex&uNg@KPIkN4dO^keo{^*rRyjn=`lN@0T53+CHDrd|50sdeKy zMznt@nk+o_Vi|Qi87isaFN~%s^v|B^sVYYn>rL}qDA*@-OkqeDa`nQME(!UtL%8dg z{x^Y~qxWC)woyLCRdi5h9)w*bl{Z~y74xv?z47(Er@e}uW&PB!^NQ!g)H`91&sUJ& z{PfSu+k9Jol6=X_>gh0!Ux!ur^sh%f4Vo=?tDZA0M 25WIRIN)AyC F(XB8VRGf;fo-hkcp#b))>3?fTmtq$$Cf|NT^%l`m3-(j!1Mh zQlk4A&tm+WkTSIN9m1yi*ML}L8f4@P`AUg{36gV52z*JO3O5h}L$7G?Jd_aE=Idb> z#141BBMu?V&nJhS$;)%vtid|5(LopTzl+=`+v)F1km j4wUc&~vWSw#<6J9}M(nkwP-1x) z!Gp+l9O2%$>sDy7@lnV|oCLTYb)b)TR6<5>a-AziO>tcdvdU4m-2| SKuYJ^~vUfa|FPHD!d4cy`-o 8vzlGTUu8gPItgR!fvYvmgvYWBdILQQ`vx5HXNNu+s_6T>yuwk@f za0xp3U}osb&M{_B&z*Vv#Pm!`(iNR$qDOx($JCShs?{7Kr{5p)hORZ^TY8A2h-x%_ z=SJ}nG0KtG)$w&=+MKD|m|6?r#9B RB%~hZ=+mCj z!xW0q84%hPs@;j)t`4aCZp0*R@96SB2uz4zMx7eSwT4P?3+4s=|JwTsud250ZBXeh zkrp^~Nr!X^A}!tBjig8%N|5dpknZl1?mC3jp;Nk>-|=4GtMcCO`wQMP#yVry^Q^u1 zn0xQF=6dFu_q+6^B!1d#L44SsBwk3q!ouz#7bT3NS71uKUj59-dCgR9a|iiS{`WVu zmgF#J0@AhLfcU2VaZg#lv(h)RhkQkUba4vfw5(S+(7P9qPEh^5JT^sy70V6PR81o0 zTg8IJ (KGg~L*p3?- 7T8U|;P z`7rUhyga3h&mkj!UvYBxL4CdhENa%lDhksrwU0x$51Jnq@R*}$G#pk<{D{@QNIQ+Q zHP&Cnhza#J(ZGM4fjkfUb>XQM?KAZ6?2^pi5E7t05pyOKNyUO UjdYB&nz05ld}w$M7Y{#HyRRmkn&SMY0D^XqJGRo$8WiggDhuk%FOT}z|S-zL`4 z$Qba}>x1ya;}f|Mi|rK%AwBw7V^{~cX>G*TSb0txmDbd(v&qRbIi_}uZ?8U7IDMMz zW5Qahgm|kuzGj5^9^3Fx3>Y39wto?Jz|{QaaBK(F0u!h(cU)@wsaDVHM0Gw^#4R>v zWxPP2d-a*>HwUyE`2mFIba13Mty`rb>;iguZ%i& ;c*r&_a$)XM>4`~cLbD7h2KFenHn!w)J@=pg-t(Oqu7*83Q9n~%gXPB5{CnzMv zngS%KRzY zAmR*4n#N1PH!J+gAMK*_`1 p#ZdEr$`YUD&39CT38{uJF4p&Z)OYBGXa{G) z$xf1o0hK6AlO(fNPcAu9A_)(rPan56Pcd6j_Ghah6vw1U)-tzCY`KfcvDPH6PA<(c zeFHJkI;no>oDprA<-CteZ| FU94o6v9v^-dH^j$o7y@ie<3n$R1nKbY7#Uiu)y)Dm0FmoqIi!x6K5JU>! zg{|>E%TX0sHb56#vN+TIyd+fMgZ<95yF_Hn1Vg8jzuh9!y58H8?r9;{b;{fq4A~2v zzIt4rg|E*!#<}H$zE|`6?ce>Y7tg*-qQ@2DzApF#1@*&={g;p0!O_+7ZwK{G%COC< z1Wxz9#0{GA=fxLEdyY9#pEw#`v#=U=0FqJ+orWiz-qll97nIFM^(IH4Lq0Ze=*y*$ zsY~Y2;TBu;oTu-7^6l#yk~i$HV=PQ4I`k+%&hD?|Up1d=mdpt7-&|N>!r7R{vZfNF zh?5}0K}(Aemz}Je9&BGte*p@G;{rk?1{B@cYI80ZSHha_o6sPdrcRGH$AVB}H+GoB zC{M-8-Zxf61t2Ac-#l*4%)781s_?~L9^NsgBAwnfzocI6jl{O>(pR3_-$4xkd3PCV zQNQOmA@yi$R}uyZPwyMDJrzw|N2(s6o6*9ZAsWsw>JmxZ$N))d9$~hPu^Y2Nr}_Hf z4PQ212s(<_NTmB-n&y6xT1L@DgZl>KWhSw({0uI!jGSH?HP|+JE3usnxH9?dF?x|) z;Jn=g>ZM2`K_M?~1`Mi-StYrZq|j4 8->&eHF}9Q;G?A{ z-jDk4J5~EgwpFf_t>U!8TLMEp02y@4OISQq1+_hEpQnwo@5ep!NQPb1SHI31L MT z(uauZD_ys@Lv3?}2C<_N;%E?a#i|NB(5L&XtCB$vmT~bU8XOw1buVYb%X}3{!o?rr zuXb^NIkg @>j-J(s137rnE z0&s#=*+O{Hbi_^~p(atKl{ S4V7O6S98pphTvx!pzi$k56YBEzplQC~vYSjjV zy3qIb>Qw;RF`(JIvR6TO#MKC1CiMMHenPC1KscSA-lAyGE8@Aza?f^-!aKdw7j&*x zsp4*?Mg#2{0%jLGA0%1jGw07J`Bv-(_DxsAT$BtOPuN*konrtg!gprnn&HWLeR=+y zAC^lP@!^Mh%bf!l4cZh0>iImP(VxQItz(%?Z7}&*G)If&5Iz%V#nQ&+J?t8{@DjL4 z9{RAE >!r~FmD;s9NVKRHIjg?@u<{R1Dp~@k9bmi zoG4(4Kwir_5r%3qLcF4hJ(1321g`M}G++~ef&E~QN}!gzH=b0`rTJN+|1H)63|eC$ zzDGIj_)KQv1+9f=?Ol{Ve(}ApP#%rU(=ksz$7=uY3)A>RDkic9ksAY7O8KnAD$aDN z`*&wdFzjL7yh$bco{v?bn?iJ9PB?sdwJFT@D!PL<%G!fA8d`|8#1DDtr)a=oEKgmr zM83YKN!M*QlzX9rPaUrUeWjCU(0Zj){Nt}ev5i+68abXx;Mncz`~)Q&`gqL*alL;S zdm!#J4P-Nc0K(>bM#`^uGR&}Jal?2Lo>YmIX}ysqfQED5_xK=!Wxcw}OfBR0j5ZsK zX0CbFaG9EAp?oscQprpa0y(TU(oyuEcaKW>UoXcy$kJIQVTG1InJRs!E g_L;0 zl+R> K@F1FMj&n24UbZ5w%8LIm=_v@)|m6JYlaoJ_Qt5 z6q%oXupYEk+rV5~q|Y;L-I(AoPJhm$-ew?EqhY-cV(-5VjXj8mBVzc9LI!Go+D`>& zuyXXh<+xW<0Y2TBwK>kHvRl!cB{Z{|UiG=Q(te8+v&e +g^B)-()K_AztAmm$Rm z^=+Ua9Ia^DV;r&(Z$yku!FS0w8iOg1a1{Pt^@A|x*BOKf`kmE63Zpk7&5yDv_+!V9 zs($dId;g$;p?%?u_*O#bA3AmL=q7RQ2r+Ih z4j;R$VKEu{Q9!Cw{Q dlB-$qJYBR9yZe;iQ-N zz8){r2N}|pm3aKUN0r!KrWd$539I1kK8a3MM%Gq+iC9!hv_{E}%vw0U=WR} ~$tP+YYK4(qlv@f#-ddqu5l`7%qV+Wjf@+?7 zYIxBz=RDFrH3%*WUuLgVLFCcTy)p`qKQ)Y_uhFxM)=8q|8&-~od&S^mLXP;I&q|>{ zDLQeS+7HEH4lwYdBPAR~MAM!FnJAy4eWpyE1wM2Fb3A{HP=z5OV;Vtgq5`YF&y*_d zq*DK&ZARYIZ gQE-DM=~+ST7i_HP2Hr*Q_#(!&hNomkcS0P0ajxEkE~+ z)3O( n zbpg0JB+*PQao<3$lZ7|vdgCwdy-?gNcxt~ nvZ@_@PV-}LLMzP^&Sr1s z-GH$ap3bzhO4f?*cudTS?NvrzQzG?9{*K4%jPG*sFvvcXTVvAHWFJjOo=PVL7VwX7 zXYHYJ (d_t4LMlsK0#yXq3!-6aK?LLn_4EN_VwQ+(5 z1%g*}clT!A`RN5ntIobulNgh6!j8mx2^R&@6EG-~@(ZhjjAVw~!L+TmwbzdKy@!&$ zc99!tl*8$yVeiXyO ~z|Xd$vh;Zz+P3!$0A`?;gs+k&f;XI#n`3 z8&JZW5?=@0#ENO^otHUmdpR+nc~b~go =9Qd*{kKe@ya*3 JF z6$YH&R$qyQo*f$-wXJQjk_!k3(3s)DCqk`ZbE>3EY%q#D{J_3dv&WLK$A?^s%6*_G zRPQR~)}I98BuLbbXFNAJ5?jVex2&zZO1st{=stlOUpJVDww8h~q2f (HxDc z%jPyOxO@sfTZXE^N %G>lf_o62W;>{vWuqh7K$bIRM@Tg}jKQ&Vg# zA=CAyRz!68D#3HzSX*XtvVFm5&zM_@1j >{hXPRg4%;tNPN3T63)pt#}m`jVd$hv1{Qr$>yGl&dqJV=bgPhdXFsU zebs40x--CyLH$7CN|F1v#IJr=vn3Dy-Dr*4h^y)eH|l5hDRw|{Z01y{v*H=htWX`H zBRYmbJ?P_-$Zhjw`$F^G?J$t({wS&B{wBwGBHsoQ;hn9mSSqVzuH-rUXu!G7cHZP{ z%5`8#IQ7}_{mqH !OCZ 3zw1*i?`vwSA~ z#5OKO?$=W$qxJ@bL6uVeZ0knDMEp_bEdW6{>~=GW|9$2fqK;*DFA-jrN8y> t&o4e)aie0IVs#EZ!=S4cf zl-QKU9Zj~k9jQ0bd4WI)WSZ3^V9IQtF!y(Nn{&*GToVvk+^`!PLp6a3KLwk|Yd0JI z9B+)QWQQ!WP;^^4Q9nW6V6L{-uhjBB5*T*A-ax5j1Pb!d=e835*b#WaT*9qi{V)#( zmvwO<0X7J|zHJz<;JE-fPiUe?1IeEd20cc84HL%Y(+VA>*@+VbR6^%sVMOqkE)0EP z3;#7CnqI~c*y sX|5eMno(Hk3?^htkS1zhUHGOnmc>PbL z$e({e a0*JMgk-gXSxV*eHoNBQrEAE@WM`rZm`^EDGU959 z`G}7;a3Dc7^X|G~hx(Aus $vLDx^z>L&ylz0`1Zw+uNWw33AZmOUV zdRkVP=hZ1p8;UZQFV =#KVZ*%5jID &e@d8j$1Y4=Kg7~<=$j|-cvzC9*_v2V_+WcH9@rKZ0)nkYng1m2rN z&v|EpI$;L{&lExkh$wgj?f{C)M;dBfdVFl_B>@CkjlB41T&wTUiOMFmp4dUm+=GE) z{ R-uE1AuWq;f2Zf)e|=4$I;q%nKPS;PTx zL($*AKRMq+C)TIPthqo=KRB@14KXBA&55O-@w1(AV~wSJA~4EeV@)6>d2(c< >Z!5e%` tJAPJhA1#)CWvtq+O zaec1V>o;J$X;gJ!6JbIhlf0hgi w=1P>H$A z-zqJQ(iU~A<6Rz-xmE#dA@%GSvaM*(6I@-IoY-a9&4SdxP>CV8%$co57+ZhRfJd3^ zT*$)j&(uf!>bOQ|Tax`st9*hdqrNquiJx@k=lhtCtIyw&e$e3OuTeSmvn<#58uP9A zhL|LhxahD&TXB8y#JFLl*^V6~Xq5-zxwo!TTmUrr)zh+bTAPn>6Tr1s%1t)ubQ2PC zIm?7-)x&8aEjquuqTr2FpY*wt2+?TQX7eN^stRqE4*lw60e!Cd+zxj^(v@glpztYm zhy>eN?|7KC@)B2QHZ$q|pfT{0wUmqTfQ0$ejcqxi`9Qm|B`Ds4WCZ6qO_t(NY|K?UN3s zEI+1CVwn?Tqlh)Je*VV2YntOOuClTmgv%e)M9z;2Q!Nu5cvCey-U &Rt&KP~v+i)SM5XBn0&)C3}C7XC)OJBTXxzelpGtuuESA?At!F;_@(mEYd3 z?;IR$to~=Qe_QL1|I7$!sdmA?^AzlORFJ%jvXoRv4D)f3D_y76t1x@qYu#g=FLtwU zJ*v*@GP-hrI?T(8RiYgLe%aIOs7~Q^@yta5VcyX^&MRjZR=kz9T3LGDf&$An8n$rk zd%=a?*q3BWs*nxzK7g*xZmnofU=yMFN`q=$<^)JiLq+Cg=4>@q`G`JoW_h4K;d5q! z0ywS@E3H&EuBD!09O}tCZ>so0L*u%14!%sGR$E{mD3>-;KQj)G vQq>Qhkg(jmRxbQAfEa4QY3^N{ s&*JmzuKvCBFFAeWr2ZuMGn2^g1Wk~Z?{9fU9s(ccRQLtmf&G^Z3lHIc zM!Nk1LqWwb|AhZP;@%!IJq&94#dX5^Zy`<(@ejjBe&NSBe&T-*B6$dZD9!%`FXH|Q ze<;*{NbyiR`invq5)Sb90QhhH>WA=$vYB7-DDj{0KSVSS@efDbf8pa_|EKzY#@`=; zA36elf%(;cf*-gA9x^=aOZ{Tt)B4HqN6+dZ{?C@|FEr$V(Sd^cuXgQ2_@6C{-{Hmj szrlaDGajP