From 9ce1e3d587c77e658a4161574603e349f160883f Mon Sep 17 00:00:00 2001 From: xclhove <2959169303@qq.com> Date: Fri, 6 Sep 2024 17:54:36 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增笔记分类模块,可以对笔记进行分类,便于管理。 新增笔记分享记录模块,可以分享私有笔记以及管理分享记录。 新增用户图片模块用于记录用户上传的图片,修改图片模块,确保相同的图片只存储一份以节省空间。 修改笔记模块,删除关键词属性,新增分类ID属性。 修改用户模块,允许用户指定主页显示一篇笔记,增加用户存储空间限制以防止恶意上传。 统一 redis 的 key 命名。 新增图片验证码功能,防止恶意请求。 集成 elasticsearch,用于提高搜索笔记的速度和命中率,并对搜索内容进行高亮显示。 明确请求所需参数并去除无效的属性,使用SpringBoot-validation对参数进行校验。 --- README-EN.md | 26 - README.md | 26 - docs/api-doc.md | 2577 +++++++++++++++++ docs/images/database.png | Bin 0 -> 269139 bytes pom.xml | 97 +- readme-en.md | 77 + readme.md | 74 +- ...XnoteApplication.java => Application.java} | 6 +- .../Interceptor/AdminJwtInterceptor.java | 60 - .../xnote/Interceptor/DeviceInterceptor.java | 28 - .../xnote/Interceptor/IPInterceptor.java | 82 - .../xnote/Interceptor/UserJwtInterceptor.java | 89 - .../validator/UserJwtValidator.java | 83 - .../xnote/config/GlobalExceptionHandler.java | 115 +- .../xnote/config/InterceptorConfig.java | 14 +- .../{MailConfig.java => JavaMailConfig.java} | 5 +- .../com/xclhove/xnote/config/MinioConfig.java | 19 +- .../xnote/config/MybatisPlusConfig.java | 8 + .../com/xclhove/xnote/config/RedisConfig.java | 46 - .../xclhove/xnote/config/RunnerConfig.java | 31 - .../xclhove/xnote/config/SwaggerConfig.java | 42 - .../com/xclhove/xnote/config/XnoteConfig.java | 117 + .../xclhove/xnote/constant/EsConstant.java | 14 + .../com/xclhove/xnote/constant/RedisKey.java | 76 +- .../xnote/constant/RequestHeaderKey.java | 2 +- .../xclhove/xnote/constant/TreadLocalKey.java | 2 +- .../xnote/controller/ImageController.java | 136 +- .../xnote/controller/NoteController.java | 167 +- .../xnote/controller/NoteTypeController.java | 70 + .../controller/RequestErrorController.java | 15 +- .../controller/ShareNoteRecordController.java | 79 + .../xnote/controller/SwaggerController.java | 41 - .../xnote/controller/UserController.java | 209 +- .../VerificationCodeController.java | 118 + .../xnote/entity/attribute/NoteKeyword.java | 18 - .../xnote/entity/dto/ImagePageDTO.java | 23 - .../xclhove/xnote/entity/dto/NotePageDTO.java | 35 - .../xclhove/xnote/entity/dto/ObjectList.java | 17 - .../com/xclhove/xnote/entity/dto/PageDTO.java | 31 - .../com/xclhove/xnote/entity/dto/UserDTO.java | 44 - .../com/xclhove/xnote/entity/table/Image.java | 40 - .../com/xclhove/xnote/entity/table/Note.java | 57 - .../com/xclhove/xnote/entity/table/User.java | 42 - .../com/xclhove/xnote/enums/ResultType.java | 39 + .../xnote/enums/result/ResultType.java | 39 - .../exception/AbstractServiceException.java | 28 + .../exception/AdminServiceException.java | 22 - .../xnote/exception/AdminTokenException.java | 22 - .../exception/DeviceFrequencyException.java | 20 + .../exception/ImageServiceException.java | 9 +- .../xnote/exception/IpFrequencyException.java | 5 +- .../xnote/exception/NotFoundException.java | 11 +- .../exception/NoteAccessCodeException.java | 22 - .../xnote/exception/NoteServiceException.java | 9 +- .../exception/NoteTypeServiceException.java | 21 + .../OperationFrequencyException.java | 22 - .../exception/ParameterValidateException.java | 9 +- .../xnote/exception/ServiceException.java | 23 - .../ShareNoteRecordServiceException.java | 21 + .../xnote/exception/SystemException.java | 21 + .../exception/UserImageServiceException.java | 21 + .../xnote/exception/UserServiceException.java | 9 +- .../xnote/exception/UserTokenException.java | 7 +- .../exception/VerificationCodeException.java | 9 +- .../xnote/interceptor/DeviceInterceptor.java | 80 + .../xnote/interceptor/IpInterceptor.java | 107 + .../ServiceInterceptor.java | 2 +- .../interceptor/UserTokenInterceptor.java | 97 + .../com/xclhove/xnote/mapper/AdminMapper.java | 12 - .../com/xclhove/xnote/mapper/ImageMapper.java | 14 +- .../com/xclhove/xnote/mapper/NoteMapper.java | 14 +- .../xclhove/xnote/mapper/NoteTypeMapper.java | 11 + .../xnote/mapper/ShareNoteRecordMapper.java | 32 + .../xclhove/xnote/mapper/UserImageMapper.java | 10 + .../com/xclhove/xnote/mapper/UserMapper.java | 5 +- .../MybatisPlusPrintSqlInterceptor.java | 197 ++ .../com/xclhove/xnote/pojo/dto/UserDTO.java | 40 + .../enums}/NoteIsPublic.java | 2 +- .../enums}/UserStatus.java | 10 +- .../com/xclhove/xnote/pojo/es/NoteDoc.java | 83 + .../xnote/pojo/form/note/NoteAddForm.java | 35 + .../xnote/pojo/form/note/NoteUpdateForm.java | 33 + .../pojo/form/note/NoteUpdateTypeForm.java | 27 + .../pojo/form/noteType/NoteTypeAddForm.java | 26 + .../form/noteType/NoteTypeUpdateForm.java | 31 + .../xnote/pojo/form/rule/NoteFormRule.java | 12 + .../pojo/form/rule/NoteTypeFormRule.java | 11 + .../xnote/pojo/form/rule/UserFormRule.java | 23 + .../ShareNoteRecordCreateForm.java | 30 + .../ShareNoteRecordUpdateForm.java | 22 + .../xnote/pojo/form/user/UserLoginForm.java | 29 + .../pojo/form/user/UserRegisterForm.java | 37 + .../pojo/form/user/UserUpdateEmailForm.java | 28 + .../xnote/pojo/form/user/UserUpdateForm.java | 27 + .../form/user/UserUpdatePasswordForm.java | 24 + .../com/xclhove/xnote/pojo/table/Image.java | 28 + .../com/xclhove/xnote/pojo/table/Note.java | 38 + .../xclhove/xnote/pojo/table/NoteType.java | 25 + .../xnote/pojo/table/ShareNoteRecord.java | 32 + .../table/Admin.java => pojo/table/User.java} | 32 +- .../xclhove/xnote/pojo/table/UserImage.java | 26 + .../com/xclhove/xnote/pojo/vo/PageVO.java | 26 + .../xclhove/xnote/pojo/vo/SearchNoteVO.java | 29 + .../xnote/pojo/vo/SearchUserImageVO.java | 26 + .../xnote/pojo/vo/ShareNoteRecordVO.java | 27 + .../xnote/repository/NoteRepository.java | 10 + .../xclhove/xnote/runner/AbstractRunner.java | 44 - .../xnote/runner/ElasticSearchRunner.java | 59 + .../com/xclhove/xnote/runner/EmailRunner.java | 45 + .../com/xclhove/xnote/runner/ImageRunner.java | 73 + .../com/xclhove/xnote/runner/MinioRunner.java | 26 +- .../com/xclhove/xnote/runner/NoteRunner.java | 147 +- .../com/xclhove/xnote/runner/RedisRunner.java | 44 +- .../xclhove/xnote/service/AdminService.java | 52 - .../xclhove/xnote/service/ImageService.java | 293 +- .../xclhove/xnote/service/NoteService.java | 346 ++- .../xnote/service/NoteTypeService.java | 173 ++ .../xnote/service/ShareNoteRecordService.java | 143 + .../xnote/service/UserImageService.java | 139 + .../xclhove/xnote/service/UserService.java | 277 +- .../service/VerificationCodeService.java | 108 + .../xnote/service/impl/AdminServiceImpl.java | 55 - .../xnote/service/impl/ImageServiceImpl.java | 250 -- .../xnote/service/impl/NoteServiceImpl.java | 164 -- .../xnote/service/impl/UserServiceImpl.java | 196 -- .../xclhove/xnote/tool/ElasticsearchTool.java | 20 + .../com/xclhove/xnote/tool/EmailTool.java | 26 +- .../com/xclhove/xnote/tool/MinioTool.java | 197 +- .../com/xclhove/xnote/tool/RedisTool.java | 163 +- .../xclhove/xnote/{util => tool}/Result.java | 22 +- .../xclhove/xnote/tool/ThreadLocalTool.java | 44 + .../com/xclhove/xnote/tool/TokenTool.java | 39 - .../com/xclhove/xnote/tool/UserTokenTool.java | 39 + .../com/xclhove/xnote/util/ByteSizeUtil.java | 35 + .../xclhove/xnote/util/ElasticsearchUtil.java | 77 + .../com/xclhove/xnote/util/EmailUtil.java | 9 +- .../java/com/xclhove/xnote/util/Md5Util.java | 36 + .../com/xclhove/xnote/util/PackageUtil.java | 16 + .../com/xclhove/xnote/util/RequestUtil.java | 44 +- .../xclhove/xnote/util/SubclassFinder.java | 8 +- .../xclhove/xnote/util/ThreadLocalUtil.java | 17 +- .../com/xclhove/xnote/util/TokenUtil.java | 60 - .../java/com/xclhove/xnote/util/UuidUtil.java | 27 + .../xnote/util/ValidateCodeImageUtil.java | 111 + .../xclhove/xnote/util/VariableNameUtil.java | 33 + .../xnote/util/VerificationCodeUtil.java | 38 +- src/main/resources/application-dev.yml | 50 + src/main/resources/application-flyway.yml | 5 + src/main/resources/application-logging.yml | 22 + .../resources/application-mybatis-plus.yml | 9 + src/main/resources/application-release.yml | 50 + src/main/resources/application-spring.yml | 5 + src/main/resources/application.yml | 106 +- .../db/migration/V2.0__update_tables.sql | 91 + src/main/resources/mapper/ImageMapper.xml | 13 + src/main/resources/mapper/NoteMapper.xml | 18 + src/main/resources/mapper/NoteTypeMapper.xml | 5 + .../mapper/ShareNoteRecordMapper.xml | 5 + src/main/resources/mapper/UserImageMapper.xml | 5 + src/main/resources/mapper/UserMapper.xml | 5 + src/main/resources/static/index.html | 6 +- 161 files changed, 7840 insertions(+), 2907 deletions(-) delete mode 100644 README-EN.md delete mode 100644 README.md create mode 100644 docs/api-doc.md create mode 100644 docs/images/database.png create mode 100644 readme-en.md rename src/main/java/com/xclhove/xnote/{XnoteApplication.java => Application.java} (59%) delete mode 100644 src/main/java/com/xclhove/xnote/Interceptor/AdminJwtInterceptor.java delete mode 100644 src/main/java/com/xclhove/xnote/Interceptor/DeviceInterceptor.java delete mode 100644 src/main/java/com/xclhove/xnote/Interceptor/IPInterceptor.java delete mode 100644 src/main/java/com/xclhove/xnote/Interceptor/UserJwtInterceptor.java delete mode 100644 src/main/java/com/xclhove/xnote/Interceptor/validator/UserJwtValidator.java rename src/main/java/com/xclhove/xnote/config/{MailConfig.java => JavaMailConfig.java} (91%) delete mode 100644 src/main/java/com/xclhove/xnote/config/RedisConfig.java delete mode 100644 src/main/java/com/xclhove/xnote/config/RunnerConfig.java delete mode 100644 src/main/java/com/xclhove/xnote/config/SwaggerConfig.java create mode 100644 src/main/java/com/xclhove/xnote/config/XnoteConfig.java create mode 100644 src/main/java/com/xclhove/xnote/constant/EsConstant.java create mode 100644 src/main/java/com/xclhove/xnote/controller/NoteTypeController.java create mode 100644 src/main/java/com/xclhove/xnote/controller/ShareNoteRecordController.java delete mode 100644 src/main/java/com/xclhove/xnote/controller/SwaggerController.java create mode 100644 src/main/java/com/xclhove/xnote/controller/VerificationCodeController.java delete mode 100644 src/main/java/com/xclhove/xnote/entity/attribute/NoteKeyword.java delete mode 100644 src/main/java/com/xclhove/xnote/entity/dto/ImagePageDTO.java delete mode 100644 src/main/java/com/xclhove/xnote/entity/dto/NotePageDTO.java delete mode 100644 src/main/java/com/xclhove/xnote/entity/dto/ObjectList.java delete mode 100644 src/main/java/com/xclhove/xnote/entity/dto/PageDTO.java delete mode 100644 src/main/java/com/xclhove/xnote/entity/dto/UserDTO.java delete mode 100644 src/main/java/com/xclhove/xnote/entity/table/Image.java delete mode 100644 src/main/java/com/xclhove/xnote/entity/table/Note.java delete mode 100644 src/main/java/com/xclhove/xnote/entity/table/User.java create mode 100644 src/main/java/com/xclhove/xnote/enums/ResultType.java delete mode 100644 src/main/java/com/xclhove/xnote/enums/result/ResultType.java create mode 100644 src/main/java/com/xclhove/xnote/exception/AbstractServiceException.java delete mode 100644 src/main/java/com/xclhove/xnote/exception/AdminServiceException.java delete mode 100644 src/main/java/com/xclhove/xnote/exception/AdminTokenException.java create mode 100644 src/main/java/com/xclhove/xnote/exception/DeviceFrequencyException.java delete mode 100644 src/main/java/com/xclhove/xnote/exception/NoteAccessCodeException.java create mode 100644 src/main/java/com/xclhove/xnote/exception/NoteTypeServiceException.java delete mode 100644 src/main/java/com/xclhove/xnote/exception/OperationFrequencyException.java delete mode 100644 src/main/java/com/xclhove/xnote/exception/ServiceException.java create mode 100644 src/main/java/com/xclhove/xnote/exception/ShareNoteRecordServiceException.java create mode 100644 src/main/java/com/xclhove/xnote/exception/SystemException.java create mode 100644 src/main/java/com/xclhove/xnote/exception/UserImageServiceException.java create mode 100644 src/main/java/com/xclhove/xnote/interceptor/DeviceInterceptor.java create mode 100644 src/main/java/com/xclhove/xnote/interceptor/IpInterceptor.java rename src/main/java/com/xclhove/xnote/{Interceptor => interceptor}/ServiceInterceptor.java (93%) create mode 100644 src/main/java/com/xclhove/xnote/interceptor/UserTokenInterceptor.java delete mode 100644 src/main/java/com/xclhove/xnote/mapper/AdminMapper.java create mode 100644 src/main/java/com/xclhove/xnote/mapper/NoteTypeMapper.java create mode 100644 src/main/java/com/xclhove/xnote/mapper/ShareNoteRecordMapper.java create mode 100644 src/main/java/com/xclhove/xnote/mapper/UserImageMapper.java create mode 100644 src/main/java/com/xclhove/xnote/mybatisplus/MybatisPlusPrintSqlInterceptor.java create mode 100644 src/main/java/com/xclhove/xnote/pojo/dto/UserDTO.java rename src/main/java/com/xclhove/xnote/{enums/entityattribute => pojo/enums}/NoteIsPublic.java (89%) rename src/main/java/com/xclhove/xnote/{enums/entityattribute => pojo/enums}/UserStatus.java (75%) create mode 100644 src/main/java/com/xclhove/xnote/pojo/es/NoteDoc.java create mode 100644 src/main/java/com/xclhove/xnote/pojo/form/note/NoteAddForm.java create mode 100644 src/main/java/com/xclhove/xnote/pojo/form/note/NoteUpdateForm.java create mode 100644 src/main/java/com/xclhove/xnote/pojo/form/note/NoteUpdateTypeForm.java create mode 100644 src/main/java/com/xclhove/xnote/pojo/form/noteType/NoteTypeAddForm.java create mode 100644 src/main/java/com/xclhove/xnote/pojo/form/noteType/NoteTypeUpdateForm.java create mode 100644 src/main/java/com/xclhove/xnote/pojo/form/rule/NoteFormRule.java create mode 100644 src/main/java/com/xclhove/xnote/pojo/form/rule/NoteTypeFormRule.java create mode 100644 src/main/java/com/xclhove/xnote/pojo/form/rule/UserFormRule.java create mode 100644 src/main/java/com/xclhove/xnote/pojo/form/shareNoteRecord/ShareNoteRecordCreateForm.java create mode 100644 src/main/java/com/xclhove/xnote/pojo/form/shareNoteRecord/ShareNoteRecordUpdateForm.java create mode 100644 src/main/java/com/xclhove/xnote/pojo/form/user/UserLoginForm.java create mode 100644 src/main/java/com/xclhove/xnote/pojo/form/user/UserRegisterForm.java create mode 100644 src/main/java/com/xclhove/xnote/pojo/form/user/UserUpdateEmailForm.java create mode 100644 src/main/java/com/xclhove/xnote/pojo/form/user/UserUpdateForm.java create mode 100644 src/main/java/com/xclhove/xnote/pojo/form/user/UserUpdatePasswordForm.java create mode 100644 src/main/java/com/xclhove/xnote/pojo/table/Image.java create mode 100644 src/main/java/com/xclhove/xnote/pojo/table/Note.java create mode 100644 src/main/java/com/xclhove/xnote/pojo/table/NoteType.java create mode 100644 src/main/java/com/xclhove/xnote/pojo/table/ShareNoteRecord.java rename src/main/java/com/xclhove/xnote/{entity/table/Admin.java => pojo/table/User.java} (50%) create mode 100644 src/main/java/com/xclhove/xnote/pojo/table/UserImage.java create mode 100644 src/main/java/com/xclhove/xnote/pojo/vo/PageVO.java create mode 100644 src/main/java/com/xclhove/xnote/pojo/vo/SearchNoteVO.java create mode 100644 src/main/java/com/xclhove/xnote/pojo/vo/SearchUserImageVO.java create mode 100644 src/main/java/com/xclhove/xnote/pojo/vo/ShareNoteRecordVO.java create mode 100644 src/main/java/com/xclhove/xnote/repository/NoteRepository.java delete mode 100644 src/main/java/com/xclhove/xnote/runner/AbstractRunner.java create mode 100644 src/main/java/com/xclhove/xnote/runner/ElasticSearchRunner.java create mode 100644 src/main/java/com/xclhove/xnote/runner/EmailRunner.java create mode 100644 src/main/java/com/xclhove/xnote/runner/ImageRunner.java delete mode 100644 src/main/java/com/xclhove/xnote/service/AdminService.java create mode 100644 src/main/java/com/xclhove/xnote/service/NoteTypeService.java create mode 100644 src/main/java/com/xclhove/xnote/service/ShareNoteRecordService.java create mode 100644 src/main/java/com/xclhove/xnote/service/UserImageService.java create mode 100644 src/main/java/com/xclhove/xnote/service/VerificationCodeService.java delete mode 100644 src/main/java/com/xclhove/xnote/service/impl/AdminServiceImpl.java delete mode 100644 src/main/java/com/xclhove/xnote/service/impl/ImageServiceImpl.java delete mode 100644 src/main/java/com/xclhove/xnote/service/impl/NoteServiceImpl.java delete mode 100644 src/main/java/com/xclhove/xnote/service/impl/UserServiceImpl.java create mode 100644 src/main/java/com/xclhove/xnote/tool/ElasticsearchTool.java rename src/main/java/com/xclhove/xnote/{util => tool}/Result.java (56%) create mode 100644 src/main/java/com/xclhove/xnote/tool/ThreadLocalTool.java delete mode 100644 src/main/java/com/xclhove/xnote/tool/TokenTool.java create mode 100644 src/main/java/com/xclhove/xnote/tool/UserTokenTool.java create mode 100644 src/main/java/com/xclhove/xnote/util/ByteSizeUtil.java create mode 100644 src/main/java/com/xclhove/xnote/util/ElasticsearchUtil.java create mode 100644 src/main/java/com/xclhove/xnote/util/Md5Util.java create mode 100644 src/main/java/com/xclhove/xnote/util/PackageUtil.java delete mode 100644 src/main/java/com/xclhove/xnote/util/TokenUtil.java create mode 100644 src/main/java/com/xclhove/xnote/util/UuidUtil.java create mode 100644 src/main/java/com/xclhove/xnote/util/ValidateCodeImageUtil.java create mode 100644 src/main/java/com/xclhove/xnote/util/VariableNameUtil.java create mode 100644 src/main/resources/application-dev.yml create mode 100644 src/main/resources/application-flyway.yml create mode 100644 src/main/resources/application-logging.yml create mode 100644 src/main/resources/application-mybatis-plus.yml create mode 100644 src/main/resources/application-release.yml create mode 100644 src/main/resources/application-spring.yml create mode 100644 src/main/resources/db/migration/V2.0__update_tables.sql create mode 100644 src/main/resources/mapper/ImageMapper.xml create mode 100644 src/main/resources/mapper/NoteMapper.xml create mode 100644 src/main/resources/mapper/NoteTypeMapper.xml create mode 100644 src/main/resources/mapper/ShareNoteRecordMapper.xml create mode 100644 src/main/resources/mapper/UserImageMapper.xml create mode 100644 src/main/resources/mapper/UserMapper.xml diff --git a/README-EN.md b/README-EN.md deleted file mode 100644 index 40e26e8..0000000 --- a/README-EN.md +++ /dev/null @@ -1,26 +0,0 @@ -# XNote - -[English](./README-EN.md) | [简体中文](./README.md) - -## Introduction - -Web notes based on markdown. - -## Technology Stack - -1. [Vue3](https://github.com/vuejs/) -2. [Nuxt3](https://nuxt.com/) -3. [TypeScript](https://www.typescriptlang.org/) -4. [Vditor](https://github.com/Vanessa219/vditor) -5. [Spring Boot](https://spring.io/guides/gs/spring-boot) -6. [MyBatis-Plus](https://baomidou.com) -7. [MySQL](https://www.mysql.com/) -8. [MinIO](https://min.io/) - -## Git Repositories - -- Frontend: [xnote-vue(github)](https://github.com/XCLHove/xnote-vue) | [xnote-vue(gitee)](https://gitee.com/xclhove/xnote-vue) - -- Frontend (Nuxt): [xnote-nuxt(github)](https://github.com/XCLHove/xnote-nuxt) | [xnote-nuxt(gitee)](https://gitee.com/xclhove/xnote-nuxt) - -- Backend: [xnote-springboot(github)](https://github.com/XCLHove/xnote-springboot) | [xnote-springboot(gitee)](https://gitee.com/xclhove/xnote-springboot) diff --git a/README.md b/README.md deleted file mode 100644 index 4a1d9fe..0000000 --- a/README.md +++ /dev/null @@ -1,26 +0,0 @@ -# XNote - -[简体中文](./README.md) | [English](./README-EN.md) - -## 简介 - -基于markdown的Web笔记。 - -## 技术栈 - -1. [Vue3](https://github.com/vuejs/) -2. [Nuxt3](https://nuxt.com/) -3. [TypeScript](https://www.typescriptlang.org/) -4. [Vditor](https://github.com/Vanessa219/vditor) -5. [Spring Boot](https://spring.io/guides/gs/spring-boot) -6. [MyBatis-Plus](https://baomidou.com) -7. [MySQL](https://www.mysql.com/) -8. [MinIO](https://min.io/) - -## git仓库 - -- 前端:[xnote-vue(github)](https://github.com/XCLHove/xnote-vue) | [xnote-vue(gitee)](https://gitee.com/xclhove/xnote-vue) - -- 前端(Nuxt):[xnote-nuxt(github)](https://github.com/XCLHove/xnote-nuxt) | [xnote-nuxt(gitee)](https://gitee.com/xclhove/xnote-nuxt) - -- 后端:[xnote-springboot(github)](https://github.com/XCLHove/xnote-springboot) | [xnote-springboot(gitee)](https://gitee.com/xclhove/xnote-springboot) diff --git a/docs/api-doc.md b/docs/api-doc.md new file mode 100644 index 0000000..bb34057 --- /dev/null +++ b/docs/api-doc.md @@ -0,0 +1,2577 @@ +# XNote + +[简体中文](../readme.md) | [English](../readme-en.md) | api-doc + +Base URLs: + +* 开发环境: http://localhost:8080 + +# Authentication + +# 笔记相关接口 + +## POST 增加笔记 + +POST /note + +> Body 请求参数 + +```json +{ + "title": "string", + "content": "string", + "isPublic": "NO", + "typeId": 1 +} +``` + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|Authorization|header|string| 是 ||none| +|body|body|[NoteAddForm](#schemanoteaddform)| 否 | NoteAddForm|none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": 0 +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +## DELETE 批量删除笔记 + +DELETE /note + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|noteIds|query|array[string]| 是 ||none| +|Authorization|header|string| 是 ||none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": null +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +## PUT 更新笔记 + +PUT /note + +> Body 请求参数 + +```json +{ + "id": 1, + "title": "string", + "content": "string", + "isPublic": "NO", + "typeId": 0 +} +``` + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|Authorization|header|string| 是 ||none| +|body|body|[NoteUpdateForm](#schemanoteupdateform)| 否 ||none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": null +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +## PUT 批量更新笔记类型 + +PUT /note/types + +> Body 请求参数 + +```json +{ + "noteIds": [ + 0 + ], + "typeId": 1 +} +``` + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|Authorization|header|string| 是 ||none| +|body|body|[NoteUpdateTypeForm](#schemanoteupdatetypeform)| 否 ||none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": null +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +## GET 查看笔记 + +GET /note/{noteId} + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|noteId|path|string| 是 ||none| +|shareCode|query|string| 否 ||none| +|Authorization|header|string| 是 ||none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": { + "id": 0, + "title": "", + "content": "", + "userId": 0, + "releaseTime": "", + "updateTime": "", + "isPublic": "", + "typeId": 0 + } +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +## GET 搜索笔记 + +GET /note/search + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|current|query|integer| 否 ||none| +|size|query|integer| 否 ||none| +|search|query|string| 否 ||none| +|heightLightPreTag|query|string| 否 ||none| +|heightLightPostTag|query|string| 否 ||none| +|Authorization|header|string| 是 ||none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": { + "current": 0, + "page": 0, + "size": 0, + "total": 0, + "records": [ + { + "id": 0, + "title": "", + "content": "", + "userId": 0, + "releaseTime": "", + "updateTime": "", + "isPublic": "", + "typeId": 0 + } + ] + } +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +## GET 搜索用户笔记 + +GET /note/search/{userId} + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|userId|path|string| 是 ||none| +|current|query|integer| 否 ||none| +|size|query|integer| 否 ||none| +|search|query|string| 否 ||none| +|typeId|query|integer| 否 ||none| +|Authorization|header|string| 是 ||none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": { + "current": 0, + "page": 0, + "size": 0, + "total": 0, + "records": [ + { + "id": 0, + "title": "", + "userId": 0, + "releaseTime": "", + "isPublic": "", + "updateTime": "", + "typeId": 0 + } + ] + } +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +# 用户相关接口 + +## POST 注册 + +POST /user/register + +> Body 请求参数 + +```json +{ + "name": "string", + "account": "string", + "password": "string", + "email": "string", + "verificationCode": "string" +} +``` + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|Authorization|header|string| 是 ||none| +|body|body|[UserRegisterForm](#schemauserregisterform)| 否 | UserRegisterForm|none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": null +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +## POST 登录 + +POST /user/login + +> Body 请求参数 + +```json +{ + "account": "string", + "password": "string" +} +``` + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|Authorization|header|string| 是 ||none| +|body|body|[UserLoginForm](#schemauserloginform)| 否 | UserLoginForm|none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": "" +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +## POST 注销 + +POST /user/logout + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|Authorization|header|string| 是 ||none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": "" +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +## GET 根据id获取用户信息 + +GET /user/{userId} + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|userId|path|string| 是 ||none| +|Authorization|header|string| 是 ||none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": { + "id": 0, + "name": "", + "account": "", + "email": "", + "status": "", + "homePageNoteId": 0, + "imageStorageSize": 0 + } +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +## GET 获取自己的用户信息 + +GET /user/me + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|Authorization|header|string| 是 ||none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": { + "id": 0, + "name": "", + "account": "", + "email": "", + "status": "", + "homePageNoteId": 0, + "imageStorageSize": 0 + } +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +## GET 刷新token + +GET /user/new-token + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|Authorization|header|string| 是 ||none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": "" +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +## PUT 更新用户信息 + +PUT /user + +> Body 请求参数 + +```json +{ + "name": "string", + "homePageNoteId": 1 +} +``` + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|Authorization|header|string| 是 ||none| +|body|body|[UserUpdateForm](#schemauserupdateform)| 否 | UserUpdateForm|none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": null +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +## PUT 更新密码 + +PUT /user/password + +> Body 请求参数 + +```json +{ + "password": "string" +} +``` + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|Authorization|header|string| 是 ||none| +|body|body|[UserUpdatePasswordForm](#schemauserupdatepasswordform)| 否 | UserUpdatePasswordForm|none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": null +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +## PUT 更新邮箱 + +PUT /user/email + +> Body 请求参数 + +```json +{ + "email": "string", + "verificationCode": "string" +} +``` + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|Authorization|header|string| 是 ||none| +|body|body|[UserUpdateEmailForm](#schemauserupdateemailform)| 否 | UserUpdateEmailForm|none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": null +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +# 图片相关接口 + +## POST 上传图片 + +POST /image + +> Body 请求参数 + +```yaml +uploadImageFile: string + +``` + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|Authorization|header|string| 是 ||none| +|body|body|object| 否 ||none| +|» uploadImageFile|body|string(binary)| 是 ||none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": "" +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +## DELETE 删除图片 + +DELETE /image + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|userImageIds|query|array[string]| 是 ||none| +|Authorization|header|string| 是 ||none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": null +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +## GET 预览图片 + +GET /image/name/{imageName} + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|imageName|path|string| 是 ||none| +|Authorization|header|string| 是 ||none| + +> 返回示例 + +> 200 Response + +```json +{} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +## GET 搜索自己的图片 + +GET /image/me + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|page|query|integer| 否 ||none| +|size|query|integer| 否 ||none| +|search|query|string| 否 ||none| +|Authorization|header|string| 是 ||none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": { + "current": 0, + "page": 0, + "size": 0, + "total": 0, + "records": [ + { + "id": 0, + "userId": 0, + "imageId": 0, + "alias": "", + "lastDownloadTime": "" + } + ] + } +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +# 笔记分类相关接口 + +## POST 添加笔记分类 + +POST /note-type + +> Body 请求参数 + +```json +{ + "name": "string" +} +``` + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|Authorization|header|string| 是 ||none| +|body|body|[NoteTypeAddForm](#schemanotetypeaddform)| 否 ||none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": null +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +## DELETE 删除笔记分类 + +DELETE /note-type + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|ids|query|array[string]| 是 ||none| +|Authorization|header|string| 是 ||none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": null +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +## PUT 修改笔记分类 + +PUT /note-type + +> Body 请求参数 + +```json +{ + "id": 1, + "name": "string" +} +``` + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|Authorization|header|string| 是 ||none| +|body|body|[NoteTypeUpdateForm](#schemanotetypeupdateform)| 否 ||none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": null +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +## GET 获取用户所有笔记分类 + +GET /note-type/user/{userId} + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|userId|path|string| 是 ||none| +|Authorization|header|string| 是 ||none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": [ + { + "id": 0, + "name": "", + "userId": 0 + } + ] +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +# 请求错误相关接口 + +## GET 请求路径不存在 + +GET /** + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|Authorization|header|string| 是 ||none| + +> 返回示例 + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +# 笔记分享记录相关接口 + +## POST 分享笔记 + +POST /share-note-record + +> Body 请求参数 + +```json +{ + "noteId": 1, + "expireTime": "new Timestamp(System.currentTimeMillis() + 1000 * 3600 * 24 * 7)" +} +``` + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|Authorization|header|string| 是 ||none| +|body|body|[ShareNoteRecordCreateForm](#schemasharenoterecordcreateform)| 否 ||none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": "" +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +## DELETE 批量删除分享的记录 + +DELETE /share-note-record + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|shareNoteRecordIds|query|array[string]| 是 ||none| +|Authorization|header|string| 是 ||none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": null +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +## PUT 修改笔记分享记录 + +PUT /share-note-record + +> Body 请求参数 + +```json +{ + "id": 0, + "expireTime": "new Timestamp(System.currentTimeMillis() + 1000 * 3600 * 24 * 7)" +} +``` + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|Authorization|header|string| 是 ||none| +|body|body|[ShareNoteRecordUpdateForm](#schemasharenoterecordupdateform)| 否 ||none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": null +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +## GET 获取分享的记录 + +GET /share-note-record/me + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|current|query|integer| 否 ||none| +|size|query|integer| 否 ||none| +|Authorization|header|string| 是 ||none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": { + "current": 0, + "page": 0, + "size": 0, + "total": 0, + "records": [ + { + "id": 0, + "code": "", + "noteId": 0, + "userId": 0, + "expireTime": "", + "title": "" + } + ] + } +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +# 验证码相关接口 + +## GET 发送验证码到邮箱 + +GET /verification-code/send/to-email + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|email|query|string| 是 ||none| +|imageCode|query|string| 是 ||none| +|Authorization|header|string| 是 ||none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": 0 +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +## GET 获取图片验证码的base64 + +GET /verification-code/image/base64 + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|Authorization|header|string| 是 ||none| + +> 返回示例 + +```json +{ + "status": 0, + "message": "", + "data": "" +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +## GET 获取图片验证码 + +GET /verification-code/image + +### 请求参数 + +|名称|位置|类型|必选|中文名|说明| +|---|---|---|---|---|---| +|Authorization|header|string| 是 ||none| + +> 返回示例 + +> 200 Response + +```json +{} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| + +### 返回数据结构 + +# 数据模型 + +
YZ$fo4;RfvpSh~yb3G4kXzRw8hHtc-0kgZ`9hX>)Vx2*l5Wn>;x{ zMurdFM9=v%bS5l!uNbK;IQ#cKI4lWs6*Oc>?R(*?7+x3M{?F _HDBV`0_4TLzN)FgVEq~oR8wr wpz+$1MGR#Hcj^2U_uml%wI>&9HoHAt*DxI*$LYsr zy~Al9?o3a|y|!@s!m2grlDGq7!&mz%oUGC))b6I=ScI8Ofbhhd^O(CH(zRdKVkMzP z9?esUE>39AAymL-U5+4+^zN94u}^klxUThZnfvlG Eu2nO^t2UF)y2$51t1)BGOj!|Lh=w wJa*K|Ez0bWXB~o@G#@osX-bTtdM#cNXG1cumV}j znu4FAjSlMJySd4@Y?*FN(Zf>X&CURvy(7BmVnydF3ghWtfm+cRS}<;K+r%G1l5W5b zFyO0u<|#_0kHDqK#Y_vpkT;;r5A74S+1$*dvWbCj9+Fl-&(XmVE*A22j*Qd34Ay1c zDPA2Ej&KG#l`Kefv)|a;tqHq0m7tlfI+rgE%-Ey##SG>q>{~}xk+T!U{)uK3`;J%? zm)uZ;<{H9#K ;sj3Eb^SC zttbOjLvI2R#$6OiQmTkSofI_>Ap(KaKvDM74iLaO2wid7+xVrZFIF|dG7ZLuKi*ps z2)GL@BZLsqDws4AxvW-Tte|Di(q# A*#Gv7PFsm8Q&nK-ZXC^dbC+=L1IokXA^Hz_QZIQn#z_a>~%H&}+(mqI0 zr`8H;$4Kx8Tt>!P**pk+Q6&*1u-&_l#Qe$T$Ijus$vgJM_+YC%oG5R@`rT~6Ii(hu z_7ty-u-^7EK)yBwi<95*t{0{AXhUi=eX_-_2Z$uypgHj#&`*CoF~gg*$A03CZ_$Oy z)FA8c7Lf+GwzUWLM(5n{Lu!~VIbAkz^snj>EWYqVv&w~r$kztku mvr+-2(v_xxdxO}kVa(wpMgPRaQko9gNfjppMbeE2y3!&RxSF2;9s|LSy4(*NPG z`LzDnUC?HuMEFF}F=Frz&UF)+6?Anw$7eU9kvvHN+ZKCau mgUrPSx zF=MB#rqd#}Z_bcrtW EjJ*|L}1^Y`5w#7Z>TEO`Fr-n5gn9o6e!!C6gk`B z)3hlVnb-|gkhkNOIN4E?tGK3rl}>1EB)jRNBgec*YMS`tw{8u8cztDR1W(bWmdx`W zP5r_4*41LQ#xG@#cSkBz=00_qGEoPp{#j{s75}5|qJgd6UR-a;a;$mMizf1LXguv) z3-De*6N@rcZ@Nw#&zPY{NSgI=GVzxzeFw~7oU!k5#-a4tN#Gg44S(nn?~wS+e~2I+{6hp0^RvpWb% 0-Wux6eibMy4s zUAUAk&26BZ1&4L-ootJuFL$rPctfep15MiJh{X)9#17gEr9e*t4WVsF+qy)EqgEva z(870o)qqz>1Prx(H6VeIjCwynp)>|aqK02(c@benn8bHSXmy{Z6C_NOJK-xfEkdNU z^A#Na>L-rA^3jGXfb2{7IP_i_ANPTXr-No1qKe>$+*-rE{e@4eM?RstRGU7L(1;WL z(y@DfKDqQ<-e5ufgtD*l?GqOfN>SzO{SjrnfYk>+)=My5E4jwo<`}rLdn-jj_CL!B ze5pvT2DkBdavMQ27jRB?6IaHD)RJRQJkdi{ibHb7aO}#hlaT_x4k8B=9r~lJ<8PAh zS9CV-64I?RI~0cotbmc@`9Ku5Nyqi}NBmI#I=G(rt_Udv-8?R| qsQTy3q$n@(}_glaZumnrwy~A<^#42uNsFx;;9cckQMOX^^GTU3`DE z9N!;>>r?9#?|XAE^XukLB oC8xz _ 6j|Kj!T1`{S z_wg^b;NS~n$mI(RnN*$LyLgU%iJsXi#`jq7Ow}GFMDY<7>JZmpxZQkW52`P>HkJ>X zr;brpCih34zMLu&)QzOpKezZ(1u{hoeKw>gOYdXca***o7ai)sH+HVDrX#t%%u ?zs~s+F2j61%QVl0@o 7FK!F&!%Ae z)(80lZPr(kBOMAkjoxtC<$3pv(Q3#Jp`I2UMBAAqHo88DgDl!Ywp);bN|_s9Q4vGb zRPZ5DXZ1rPZoCsFzFZ2o6`otBzu~h^ahUfnck?k_8yM)=nHJKu4Z?SO*Y*|~FBPlV z{fF6%Pb){#b}l;7-@YXLwmi!hfO)%%%k#b5Q#cJtixAoF&2U$UB1#&=$qpskn3tqq z!qAIrhY<=Zhc%nW++l50*gEWSv;%w;h0qZwGXVK ~&u(S%zcnL{xe9xS~5h(Q8~N|G(@dXsKlZKWQss8YY+KTdN5msEx> zI&t8ScquKd^(O |*IYF2e>DY<;7;ck8UJJl?T8Aq+HieKnEH$929=MTi+PQwJ!{rx z`RaZd`nbzs>_v-?D0b@A#7UPrRWuos2aI&47hjGd0jH7Up&psQ)o?X8dEo4XXqn%x z{o%FtWm#k6^S&zeE_0a^emU!H3nX|S cs}k-JVmFp |Oebve*NB}2KngYhvz)tJzi7j41LZq7SvW(=UQ0<~~-Yv#H z`I%1%69G`peC?yBnKoKK07-d|pB&-2I04PQdp=^=H|jpdqpO^D{28Ssc&E42Ieam` zw0u+h%|Y!Ew;K2x?p#)di*V3PuQBxQohHl*IXlC zSdis_Jlb0^Ee zeRwd_RD(?YG%NNf`gV~hv#WnD-@x?)e-@VoXS_gXAoq|ShVg~SjQR^P*w*yzuPbC= z57USj;NSOpq)Fj<+%$d@(YC^fw5^El(YWs3cS?5qw(Z%>)KM@+L$Gk_p2YrehY9~= zx^!0ChI6g2gK;;rLBvbVAqxj_V1L4(mPC>QLLVln()yugC9=IW(&t6ykV_cU)?&Q) zv4maiRBCY!(qK^jB=ajqqk7;~g>Y>k4FgibRiW7?mwOo$_mQFGtBk%B@JHU6N~F8i zed)@4FMb7S;;w?flI+`7JVAble*-{+TZ@b9YU%$+*ms7*xwUN*H3*`25xtj)5}oLs zsH68XdhbCHz4uOZ6EPT36Nx%X)L{ssM~xmO`0nhzpXc50@x1%_e)z#LW6izRwXSlW z=XK3AEx?g7JzNm|tXd<>l5L99c3wzg=F;HS^2IJI;<{A|-2*%5BR$UC6=Nq4M1n$j zeG=&{@{ND&nbpG2??K!T!u?&!)9y 7c&$Un4Hf5;J zfn=J*#9aHw&NWnG5hNf$tyrlA&~MJo{lX55g1U!zO!I~Bd@c+_1`3t`w2dLHQ-!WR zSJ $V#?n5qHjm-z&yS+#LF(m}4Ju#O7#HnT#>Y$T&eR$`| z@W2-gW5)Yzac!rw=OuNZWiy_in)b_gBFmKcEuadACvLv&qqpuiCarFJ#Gy2Ss@~5{ zk!-xz=a_1Ib6wgKlugqI2>}Y;{R#NK{d?T0tXFZ1k9??FHUl{ l!yiI?zj6@bvOmt1-3f3Um3 |ZU1gSVCgzITj!L`XX#wgdH<2x-O)W@XXQ30H&l2wFk5OzMg})i> z-969YnEL$rGvmG7jo{<6Sx42^KXMS6p04Y+25h;~T(hoU*=#55OhRHD^Tpx>q)Rbd z0v}I}DS_U?7CEo7K@8;XxizT 3DGA=kBwwQFY6%<-zwl z6vR#Uo_9E6uzV`wn5JT1e$(!bjy~iWKFO!YF-@L^3NnAkF+?$5Y(YNt(7 w9}B5615eiBhRx)yQQ2tA)P^QB3CfgN)AZT~#t z#(tKd-5rm;2d7G`?t;FEqjqu@UgUM6AeWV_XNDbep(VWg36gwM_ =Wo7k(sspYqQJ27-qcKX_NU98Vwg=9&ov- z7=CJqM*L^nMn7rug$H1BnEw3;!TkNMv%Y zT*OHgXs#!Gez8zGq-?l@07dNeFVy@N-lsCH4;+&RnksBq_P=Xx&AVFQywZ&_ g*vD;HhJhfuQ}+{6kXfyLRxKt?1ykmlU3S` zw7&=w1U!SDF-yg`K3vXZH`#KwP2M{rdeif0NRcP2P7h6oOgqn7p?{KSRj}C7F|X7y zuZ$wk(#W9lRk^HyW$VlVR7^snb$K86^4^5B$iui-BekGMn=}s#1RPC}abp$rw|iFn z#JIMZ9TWu5t21R+JR5V~DYfgn9j_F&%q#8=U%r_8R8lnb7Tkw#N<*@hG@RkgNG(V( zHEv9|`LXp-g_L%L1r;R+^U?1icQ0?k@hb;VFl{*bI$nYoTfj4{nvxD%;G2V;g}33) z?)M#xnr~x%4AtLhN)dyr3k2+hvT~g7lzKlR{EGU)`t 3H14F3)1Q6`k>&kE zZNMfr`T65ENKf>D0im5EU?G61%+Y_h2*k6H zhTUtz9YmN8BSeSc0m>qh%S#tfR~nn2*by4^VFK=AHKN>}Q&)(-F=hn8!1*)Fjj^?D z605Op|Dz~>^VN?+4c%)ts;pw7=&m7zI>}98k@ar8kU6Y}NNB4f`*R4f@1gp=JkO z-$_|gYM g#pl%li89At@z zqZ9Gkm|pSYWdGpFSk6D3w6;xl)R^N$EC=X{jj48m9&RXgZI(&=2~gV4qLxtsqe0G)dd;QSZX13ALXMU3i9`$v^@fEJ_$^| zN1$*dhRyDQEhoP{s2icNa20&Lf{d<{ic1+^P^s#6g?V8I|LpL)iAzyact0+B(@}?o z$@G|zlZNxdu3dDOk09?)^Y^H0QtrBGMXMBa4SK9bk{{Omui_eyb4f tpbi#4k*o-KyTZ6Zm74Q}DS0s%!Cy Y3l_!g`hLUhMO-ou&h%!>|gCi$j> zp59y+{f^<4Pi;oT5hRAj94mNepR6bc+Tmyxm%)aij8hqqK<9T%6}W?<>ou60^`!!D zc@@@&&-;F^4LPcu*DA1``aIRo-2u(j{pGJwY<>^qdM7pBb4u~?B^bjlyVw90db0T8 z_Ha$p&0h|!rN+1_Nrc1qv3?vaM*}}p?J;OVo5g3H=QttFE7<#HT19e?kJ2!GG286+ zVl{m<>DF1&kkkEGS9>DH;K!=oi4w15yT>|Y<7zb=4L4TuL%*H=?7~qK1mgC?RI &NoQv z&OKTXML78O4gV OyuuY%H$(!Pa*=9E`7%+RRw|fG^V3Jm}%|eXEc*Tz^TVx=DP; z&X9guix}4k8xk%eLB}cKaJX7tVTwUx(4nK!eqG 2RP3AT)96)cl-qc! zkagd-&M;?CaaJtLonmzJb2+7k3&Z`8!>;^gI4P6UukYTKQm>O^>Dn5nn2kZpOP5Sv z)LGsLCRKsHPj6q-ipCpDwi!NUUr?%$vfuUfa{j(wg8trs;0n{0D#Q`EE9m4y2m>f; zdUJo+Y*fyZK)pPj>V`xADz4HcHZoj~jCW5r30{f2@{S38^A;JwQ|Htl^RwkNUwtB5 zUT~fl{MoinG^+t}7>uk6Wv}Pu*^khxi{ZMVckIuuw?yV04>H%cmtfphy0=GM%LqsO zoQDr^N2ZDIwX5xN?>YXH_Z qdm{RJ)~d@E2r;$H zn>kUBl*$>uo%`?k#`Ib7Q{myMZ}(x%3?t!eYL8{wt!65MSvCYxkL6x1Q9{m-@vt)s zcn#@TKxg=!cX}?8HU|yD{^b?tOD26829#G$N#uvsaTBT3I;jeEQuzas52?wm%!1y; zEgr=^%82B_eY&2`r=PnDnw$D>muk#%`M24)wceFvRn0%tBp0KcZ5~sXgQ>{7#qrX1 z_!?B2Xz#qNGB+1JbA>CggMO0tGY7kG-mcl%H$XP0h%q9ess8tQbj-UvcXzu7rw|BX zg13bMtuMVz8`xXDVWNhLwGRgZPPDWRBAzDM<2(1RH?kJ`&y1#vDj>^ruWWY9b=l)^ zpGtO|R~Lq(7I)vQuk7n$2_OnzY*T!(jF2U4X6)+4-KHIAy0%K%I+DFL>1A1#Qu&qU zYxnNRBw-NtmMEUCcoIKhBVH2svwxhS2TxUJ^ev>>P|=DmXfCazX@;^?*f1CgZlR5b zXX^-26_>FpOSJRJXk{ts9lvAetxJKd`Y~BUMbK{j`OO`xvgJkXpD=VLX7{8@i@Ewl zv-Un_s9O9qxz6S&2JK8} R&OXYd-N~I+wu^i!){xlctLjGWl;g1Mbuosy=#DK)yB!Qmows85{zbf)l z@RToQ$-s#%v95npkXQ5>9iuM=C(#qmI9oEsjlQos`02$A_Dq@T`C+VR6YmEu2!hv+ z(QYW+SXaK@JcfbfF=o9sr9DTaE@27$D(>QbiyzSfQM7yI2jWt*v-~T!g7aSgjayS$ z7Y0(_#w%Y{t0aCb9G&-d^>w6XZ13?p0up#vxYa8DOI(uV(oKa>;iOCY5Nv?~IgAt$ zed=nHCJZPh@Mob7DveCIEvOTPx?Jcop0}%iRy2}cKt)q3>>pn-FZ;~q$J-m$Qx-R0 z dC^kJuF7CuCpFl0D%s);`Zh`JI>qJ=UuhKK5vR-1XAmhvyX$#y3pP z2rcF3k@_&+VN_Rz??y4K`XdG%R(|Xo!UxCv2REP`m4EUMKyGzofc?xw!uw(zi|VpE z73z>})LYPF^<-xY8_rJi;Y6Kv=3^n+Qcr+s#box|(g2y99Xb_V-a!hgLXFn^U9OMI zpJgc%?DG5US`BRtxiF2l`M1VD;@Q<{TlU|V7)FNB0V6fyFl8HsdR~9oZK0?>$d|u1 zGAchZ?B!X?oJ<*OOmg5$!v@kTi$TXHsc7X1j(%*J_c8AI#(TJ<88ImJJDdf|#yUK< zIe68bq-VAR%Blb7bKuNqj9dEIlZfzbx*TnSEFlbkYGy{eBr<1)A_FVzXl5vIGG^=k z%lk?8qkw$hZ8;FeypX$ddA@mNA64kfvYQQ=B^!lfYL#?$%VRYuqo7ox4*niBZ4p-T zx8kzYfw#B7=SWt}2W7Gnv@HJqSb0K}BmCuyE8E?~XmunCuzKtNZ*>ZL6^G8S!}6J* zOJ+QMg$W!D-# Cb4DBt91^y4l7B8WqV8efWGKh| zQzVs!$%fy 2)(eEH}o z7F0kA1nl-X*0UTsG>R0+$Gv+{Qs5!ASlIvC20^%f+KF*pzFX&ASfKu0OazbzC^Ig* z-mL%tgMN(aq7?9c6t&lXE4cpmE^tFL*E<1?@Ll!O-S<$v)$6d!se~*2F=CZ|+Jag- z;LSOh|6cv^=w3jP8?Xn!J|6v*kwivgBAp hwktvP7DFlYJ9e)U z&wi&Sz^B v8K)rCa_?`BlIC? z(#zqslA7$Bc-4PrI&X3%2LISUr0HK9JU;#iWGWK$(R}yL$ko`70VH2PCLDTkROQxv z9eFh_8U4s{>bPZeYuT;qB4qcnbt~J&i)x)+?^#FV8SwjgdJ9!W=?&edoWz1~3PH>W z8;AG>yQlc#S1JtM82x0YeV#SJh#rn)ph)399aC$BJ)Wk{E!kkcv-@{~O73W<`D?S{ z_82&*IpM#~b^I}ixu%v6(vc2%tRsNxb91ZkL&|?+8xTJ%3l}d14u7epu4XuKP7Vd& zn-s25 k*trPsnJ#Q~@ka^9>hZ@>a z!Y2nu5=2a+nCKqOX=szH9jGXC7=elgFk`=;kqYBN_972ozZ%)|uiE{eY7)4%FO|pt zRcxMZy!^xwQgH=W=^t=xCb&A?#)2FH2n^|bu8N(PYkK858s8OT)FlxSa|rB3wQ$@v ziuL`0lQW%`Qb}W?WZx`2O&-vFI31Vp^r%9K@+?)v5C>I`R-9Kkxk!^x2d~4EM&2hp zZa57DC}ybcRHz?@U6y^QP$Q05dzWROE H(F|e(vz^9j&JJWjFoT?88`k&K z!h)Oy%<~D1GxxDR$_um J*j }B+eM|`Nj49UgC{tEfCMTSC8}^L-ByLU%%#L*4(|gaPEFT z!uKX3dZ3l5P<391s#ds6awa_}4WBoFvg-x41I`n#niP;NmI_S{O}ilJBF^ zSy _#i&)O+LS4;z_}Xld>*{U(PpL!>Oun>-!tyD2 0`jH7PvR{9xB9q-?yQ)&Pd;r}A~~k1FKx!b z{8MUo+FYQhD-|BP=6NvQFrMJN0J2?<#~?x=NCB>2YJwNNhMFLy&+)A>^Vle?N`O#< zHA+SzMc>>q;k$9EzPIlZE{>e9?MY^z+O&KU%?C1M?F~1Z89hp8^tQTHWNcEQPCRIPdmBtZma*=}(wk;Gv!& zXu0YbqlnE*G!KP?z4pj}i$i>k_IX!P7??I#7v1rc$Gme^2Ol%>*Vh&gM$lG$Y%nAh zKW9@(rBj{9WQ}v?^%sr&@?57rdm+zmFl=%#dLNCMy^IlrW&hM=7@_dhT8l1?zfbU9 z2;J1n5f-AJiKUB}o%#DVyA*p&pn)J<=xo&i4vHB$_B?e%oK&rzIV*!gN2R_e ;ctxf1o@b2fM@;V`hJ zaz !r*XC7BbV!8j;p-sz_J#(k;%Bs7W?Zs}5!%IL*@$}`b;5`-O5fxnDObHY{ z&>KrInrBGVn?K0{>N^jNw#HNFn%>fYl9ujs UDE 1q1WeyD7Bj#urZfCi)et_^f1mwVR0(-Oq{kbCG| zl41R8uQr6ig$g&ByOyy{9juk_5b!~}gIY*qx5JjeY3uF2M(A5DOUfJRjnDPJ$jR5i z7%XUig04WY%0d4tQR0<> 4NFcd@UwDDqh@v)tSCA9G4e7p zBc%+9;vhm(s-I!OLuoPypUN=;&*yw!eZR70W1l9Y+yUSgo)v*)I zk&E++xHLnnp1aZtIg$j`TL4iUUZH$Dvv~#P?lp hj;cWZ&Uk)pZD_iy7j>=k05AWHu*A8pE0Pnoi3c>@Ym*cWJOL4CG;bG zZi}!Rxa@G|$J=gdJ3JF9mb)IGf~0R9oLHTcvOY+Qv20r&3zKPKX8iuku|j*1>mGvv zfw;sR?6mvz0bCmj<7}X_Bp|aW_`atc1&va03a%j9x5eF1(}9h@<^VZl-xffu4Bk|+ zr9+Ikp`=@MK$Vr$ffP-bqEL+~tFaJ_^=(m^O-0sc1q +JE1yt}Mv;hE$x(`}Mp|onQL( zBm^}JUmhH%Nnj4?M+h<}O9Zm0dd`2Hd+!^%|GCv!hI(Q4$q-Ajl-`f>3h6z|kf-cX z=804zBGuOqvC^+jDG@cxMIefI)TClz0lG~NFiVMJWp4wJ} z_l0Zs gsq$QpC#q}Evbl#?}&%oqioJX7co~8Px^NCFEFhv~uGjV%P=G-YW!n$=c z=XlGYFjh7tT`-KoV|-t?R<@V^{Ni&r$$3+Yipb0EvwlvAbk5!Ik^%<0{Q_N$p{$u? zR**Kq4mD-J64J@rE-NbUn_duoeWv0tg6{M3C;Z=;8>hk`!d1P2A9!j40G9quBm(>m zi_D*;V2|0b{w&trEFY4CPN%h)dYw6F4r^H7n@pKHc%zR%Bg|u?=kw_PTWuE?i4Vb# z=J0iykt4B{%|ds#XYs|5LhAk_g>~lVuu9ElM$i`? 5+D+Q|AVO4*P0yL6Ov6XY zS|-N|DHC3uMo *uTOTtr62S2C8F%dsyP1|zLe(O`iSz_KddMfO1j^|{K8AfClJSl z+Gc+w<9B|7Q$17LUO7u)!}$*DH~tKibU;OtUh;45c0 R5w>9DnVoJzTKn>f?a$yqF5Rt+P2n^Gv46Ge8m%>xC;w zU!=0iys&!FRajqduzckF5aguXE;fBLh}qQDou?0`Vx)Tz@=MElOuuvPgVtMag+h4n zYisNDNr;dD{|8#Pl$rhw0X{+Ux0b^5u}3saAhGy^g)*CLNA!12+O0I xb%{KzmLXK`?o2AD zWl+DLxg-HKQfQFq_YE%%vm;NI`b2HkLPvx1^ORUd;K1((SmhQt$NM^+&uicPT1lO< zC+NK I>0{ty&h=>V0i8KK0kZtZ!g>)uad8}>U6a% z&1=KrawhG?6>mFi>=tM)e^^ztSD?#?X7h$|V)#h5d$WQ2GnuyD7PKEV7iQ|QfN}?S z7;BE!PTYoW*a1%mdm|t`M)Hg!y@V0Vt&|B3n5V-@Z>!$r{Z^3p`a2x+JRdYV)!Ak$ zrIdCM5q?9c_Um)UB Ll^Hxwr1KWt*;XBz>G=x&K$6-{fog od9ug>!_7Dow{bEG6Rr>68(Q(X>7$4-ePf(ZyL}?C%J((k>xpc&_0YpSFIb#g z`g!J2BG-Tfrq%iswOTQ_B4H)Ye=)-;l8YxoHiR`3q8kWgWpO3?bvt=xYYb4*)`ps} zhlvXRF3$gVT%fhxU767gyEtOSu&VG^`eM9v@$F8(xGdU(caE$(Q?2gLB#fMds?FWD zyqxNHW%G9NcJT&c|6Tzo<4 dNc_}BG)L?mV!A8*^;8c>)#Zs zBtIP02Q}r{)KM}Uk4D#bG{y<^PPM&m4$l;T6LI_aZ63l5TrgsHu;BU#a=9#Y$a2*? zfbvwm1oNlLFvZ8uh4a{qw^qC{EN)n%Y6IKW->0Fjqv)rA&RA%2D~owtUJ;Wx$g_YZ zT1`YuO;@7I;+ n zfB{~t3>4oE7vJvo$kFG!;6FUVJpwiA#JN4Kh{mk0ok;VQjwnG>CC}ICpWzv-FcbG% zaV{7G% jo%6s!j)s{YK2TyR?w19=R4lH;Yl>98=A zLbpu}^HvlX4q-&jhr0h !;L*15bDXxtgGrq~VPiTC9ADVdt3nHA1 zqn=Rt00j4bif^hdq}@8eoO3|PMb5cdH=Ju2_^AM*8~it83x{UDNt8jo36%N318}fq z!zG>A#Vq0Au)(=`Y}gf*a(v7;^YIS*pwLyLCXt1;mh@j_5;Wz1$bQa#L6w;i^=N zLBm_A9@Sgz;N6=Rf?A&INlGqdQfix0@3M^iywO4L?GTv=^;u_!gLy`bmOz zzi$kfuMry5gq&=b;|?t0aE|N|0zhIeN1gD&V&~JmGp`^0XG~9P>EljbBou`Cu&v z!#q4%Hb;v(W2S}=m_Uh1r$pvMhBFJoiT8UhtVn4x@{WfZUh8jkoG{ZM;9HE*Z@XUr zNs|pknWlpyD#O>NZkafV$*b{&q*2Oa5OwD?NYoMb6L`fNyihvTEQQK2WGHY?9kvN& zkoV+C%s5EOqG1#jj&903r4)XNbF|JRaX>Ny>G`f+6~I(JvEhVU^E%&7+iqycW_S8` ztb6=ttn*I+_nj#;NoA9cYZhpM;zR^p=&SyQ?*2XEJ0Pzb?k-~hL~qE-4-RBHeJV%e zG-FI98UiH>&pf!095Ul}`NH2l4cQ(X#i9?rd+RQ!J7Uwc@={k7Q>_b0{n}PHH)DCt zqQAv-v)^b>Q*k`7JLE3CfNWVY1#^r#*)G1urWavU_ZA~VMb9CF^)Q5JPMeHbG56S` zYg{{R5@fv{XG5{Yh!1O>H)RHGC6vBthMIXoO_4hQg*60 +aul1 z3!NcRSsi&N%lt#@712+dy2$2=@mqtIq^tS{014q9((fnbSfg_~OL0kHt-*+}aZDez zX%t8}9zV!I?4rF4xi7_G=>A?=@ zNGRu(F4aP0O4cHwP-EG~W2hE)M`B3KX#uZ^3E57f?Bv20x*k-|?KtKbH#kIeyKilK zP`^0JTJ(uEpN`;^S4*XIeZnfJk%C)w_|^T$sr+2>o#9+SSE3k_3K0scX+6u*f<)2u z`+ljEZf;Ik_3~Qj=0a~^`R%7sM*jUl0erabv(Le&ncqZTQH!(UZ?)N;%5PZsqw`-# zc;p1sXF%|tHN%j;=#EgsLv-a`O0>SDXlBQaSY7m}!aP7bm290E<9mPi7()WBjLWEs zmu!=y=R=kjQ*J!V6c2LJB0?ZXyxVseC{}Q^+I2La<#IFYI2I32>P@2CLb2|3* XH5@K zoG+?)(!}*z>7!>3+C!~P#pU<3LP&uBM9?D=OetBIl!v*o#>kc>;4U~kRukc1cF& PJOQ GnOV$LRP{+8RGQG SyBw5iPU`n~{lUwKY7wAvg2!M}0?2EocvG z1F+<%(fZU%)08nDkl5nQrqI^e)XT{}ygz9Xr++kKaAD ik|#Jna!|sXr<#@Z z#_NPX+n*QRmLMY~d9A7EtqP`~?6}#{#$L=p{vDEF6c|rd}X3_M~^?#NXZq5Fg;4 z$O|g{3TNM @RA?j=Tsf_NX1*a(SJx4 zTjF3l`Zfmv^2fLgu&ukW5IuEt{4MAbw(T$OpSNP!c>-n2GWs<)o+VxVQanhMUVCp? zCdFaa`sg#wNe*SXGKQl1+!E23I4P>&`LY!PG@^gv$pW}-IAy$8vcGJ<<7ghVFpTe` zb#L2CurnwVp5Jp7w%0;@X|#(Ueo_)ji0-n!XBLyVaCYn)AvmY28q92Oz-0+zIcd4H zxLf^B%O^iMmwOxxfBrixLH&YuO^m8(!~|ukU+E zEwQ!7$1T@y10yapjYH(Q>=*0%zv=%IGx&FWKHo1%A>>z(^DaUD0*E(sd44|h%KxV6 zr)rW6SwczuN>q8V>4HBridt&fRWiVPrMEO9Sr=U#eyypHooo`^8LsIFgSi%)j&@Kq zYiihR47On iNEg(yrRJ1(Eo zIZENxhwD*AdDl;ge0!IFRg}i4D;wU}8AD88FC1;6$4D#ff}IGR`F2{V{iKCdPi1o6 zY9#TKThJDi1@Uo=GE$i-AiHer-~q5x8FJE#vFN<(;LmhPn=v*1xKs>ES^P$Z>9KTg zE ~S_45-gGgwt5rV9Ld6iZ_?w-fc_r?%Y1jAo*+<7~M! z>ZY8%MDVyKr{I`3z{!i2FIsyA)C=vt-s_s8db5 0A?jvlMP5mCJP%Z$U97B^Sc zHhg^z9nCNpeSxV5hZ-@tx#Y>&roOpq>}L9z9J|-D?3wEw0sYq{>1QpomnZx7KWAU9 z?wnPHoK<@`uVsAG3IwGI*-Eu7Eh|^u{6Q4t*E?FPuRBXr4MjNzS5O@x9h=A6SD#Re znhSv(Z9e<9DCU2T IPNCEBlgfbU!TNOA+mLmfvik zle# Ci&V7@g7Skh7J7)Vw{|u()_LJOS`b!i)bhuTkv2-s%-It*@i@%C zUQDzK_$X-=3>6QT#Efr4U>RSS_6h`8nz=!vn32NikP@u9HgE3D)^s?=g)TMI)!g&( zfy#no_;RX !yn2(>_72k3hIj;Uv >>LkF%nmYG6a5?w!(JP)eXO=}) zVCxFTC$ofnEnqH^bMlu28z?BAkDv2lbz-=9e`dHu6;)uLEaaUHI>zsNB=$s<-Q}%F z!V4A>b@|DNH)*Q5C0{4}#48DVR)&HribgZj+A_L!`PrMEL@g_Yv>CD~tmQfw4;mZ^ zS!JdTaDkeZvmlvTY^-K=FUW{$z=Eb@R;rxSWa*M#2F@BGDMd6ytBxP^ WALifU3Sm*32b18&gL zLY>Tv>{+-{P$gi6T;?|FIvLzWH5PtG5AO* J*csiyD1oBs2QgvaBiYl8YO@y%t|ZIpcL^@ zvN1Ke>=&K@(n-MIi_$Wdmsxa%_Ux>F#S%Xl*LdZze_LRm{Z1XLQu&j_tk2|D`y)i? zyNQ+`jFe)U`X;u3#1KXKxy*|;vpv>|*5^}7Mq@EH2*cx?$+fu4y|}3TRge(6KMA7= zscd0Pf<<9C&Adh27sWZV@kS<~+MCOqogYpgHeAe=pEiVXPLp88Qom=s7q_1%5{>H- z5R_KA7(in-pG|dd(T#9pe*?EotDS|QjhpmDGG=l;X`wrW%$A^J9dp>@%S(b-s((Dg zN#G3E4YSheC$A+tmp;jqn>W}#!vS;?{h4n&{jS!p0|K-dWS~Qu!i@zt2b1}4&6vOq zcLVeTNVA}4XGaD)?z<-~wMK~K#zQ38!B+kgA6+-Ta00hxSn6fhQE6*f8^26jHtz@N zs%E+nk}11v3iJATHfG!SdZP|vENe1FOl$o9Z{7pwj$Rz4LdAnBq9E!Gr-iP#J8rUL z)MWMUEeaWd`bB5I%L)n|v%w%!vktL|rAM5Uu#Qf$CJ%2aRP?QP?)4XD38>xEbf0Af zEUFxy7+dqqOmD53#RtyZ@gd>lL~o@f2e$Swy;aO@IF~*Y+2m@Qsr}KFBPgd;AQoQ) z60*rme#M9GK5Y-_;3SvfPng+?eWe!Hcfn+>`baJh_b1tyAKtc# P5RKsMz$IZ6TreVPXEh(j24mW%Rb%aXRb! zVmDsF`E6V+*`fcWt%gp_M8D0fI-mZ*M;*c#CHijLloA_WlywP~7bvSdq0+9P+{e!p zqS_0WhL#&mM7T11|Hh_?I*jOhJ=GgP9DA%|(3UmaS2D|E@YX9DWgeruTSujgq EmA2B;GUqRSNH}_UGb5+S#tI2I=DT=$R$gSK6o+N-1?@P29wJEJ 29sH%6JJB=V&KTz&5r2{$zi;&%>pBAPEJ@@{O;6!dDd ztO 2Y!GwgrWM0kS0ZmkINN+}m_1^wSSt4TZz8M Ub1NJ7KEc|9iPrwds z>FH}AGh|yQ^s{=$CwELl*gO-%s8gY(RoY#ksmQJ1{dy0skL9XNd7TOL;J9vOk%}FC zBi)dN&_PRM0Ll9Pa3fjMqAe__(-B &Joq!v(pUhjW($d5HBY$c|` zo^ir #l*GuT3D2EV`6pTVp(peZ>`JZU}@fxh}pxd1TSyH-SmZ6*qVfs$;Uc^8kf4t ziSeKh=6%8P)nqhsl3k`ioi)0Oj$M% 1mP`?+thuv8DaUnQJN&4}`OySr zyV40(8RTw1gBC#Q>6tf3oI0uVH)tvTXau5qq=d*bS>H_zeoxHjjLob)Smg;ucU%{5 zRH`)oC}wn~=Iw%)99!@R_NC3;d^N%{VJA)?=mpe=BN7}*cO9oSnw$k$<)dLInHV|2 z*vf%-P#cY$u&3`#RogueI_fb_0h_Y3{6^^ykN=~?#Fl $()W6ZS!(w)|1LY(KU< zCx=IeykIJ-)4Lrex69U4ZZbcV$emUlh*@wdOe}6XMJ_yrlzuLj^ko`JyP@}8BAy_F znX(Qq(S-76h-#dE<`}{rv$AOd<)gM~jm>T|Ceqa+Y2%IHJ;PmsS0xDu5f!WvfFD1> zN8({lD(h>}K)n6H$;Xo_j_6kS-1M0L6iyvdA%Grfjy^%je3w1T3U9=1wBa>?2C$qS z$tefA{yIpnr*_Gnc2yJTNv2DHBcG*$Z9D%W0Qm(zOQ%*9$+p4XTepu)5Wea8j?*5( zK)Ui*v(U;rpjl{fNrvuHzfRp1llfUJc9!*9)ZvjJ_Z7jV%uud%s2+}UUx3ms#vA?Y zGP5u>hxOhnM%(8QJ#mveOr!m-H3Q$)#?0R7rF;8$v5_@1k+8QtCUG4>WE2=L0uK{k z)LAw>ev>T_J#d)AmMD#0_3$Iohg5MUVW-v{rr`kqr2dih#(h;PDf8P13w+#*xQJyA zub*quIo6b1nuU3`yC2U*F43-@+sct~GyanVHXhJ|DQHfdy0y`^Y)ku!JLllZ$6yZX z%dMPjDFwQQoX98cI;)B9kdLd}b)`Ta|3Mg5pN!UF72YfmKV+f~J~<(dStg!D)oAfb zy;l(Do!UTFxMoxRg7H$I1wI|2^?K;sTc90kefqiTCat<}OQ4bsN8`C`tAKfRN$7=6 z1hq{)HhhQk8|Lw#K7yK U>fRDGa*k;f95{|?B KL#2 HZg^KC^&SO?EWVtXW}u)OMV5hh!u9R_96DQ`RiqsGjiTL*JdHw z!Dd@dVzG7x${A1$@nYBT{WPB!UqWX-CH_=^5qYnF -{$l*^uuOmvEg)lqWIP45{G0 z{m}`$D_{9}N5Dp4Ux=J+g_kg#$${3K*GkrFQO#mZhYsl#-S4K}4vZ*@1( BTdu-S>>>L|ZN@OVNIRFazYsHr(p}hYKCk4$`j0W894yg!Rr5x1 z<8|h0>9XhM{_>r62;8BP6D0qAZ##(lYxhj2$7b*K51QcJuJQq1@vk2%eF$thm8k)y zQAN_v`TA(lnbjb<)9?HDoq0%*NKC!|BI}3i@hTkA7mt{eMxq7xJp{=d905A0f2Bg_ zSbcr)`2O%=XYK_T;@cqr-H0AM*P9pNB*x{y7p2_{FMU1emB l|$2+)6pg0tDY&ra*X)A~IM}F<#(ckPn>l z3_J^_B;kLSH9!*d efg?Qi1tjw?VQ{C?7lFLnstyCB?hHff&)gBH8%e)nkl!B&?T zP}vyvOJC^**CuPATf;Dq0}5nF70)mCwKJB9*$u)80{4!e7l@TTwXaJs1tjr8A`)z} zMl2u?YsB|amU12 YaXW2-kXWTfyIU!BG3R35vnEuTg`2roI4yl(7-6El zHBzOt{gVMam1G_cR!eq-vM$t6tJq4W!Uw$c-jJs%bG54-@8a(}eZ(} IN<=u2UfLdE*2Q01F%R%6YX(`6MI0^YMq6MkmOQoz5@}~2 zWeL0SyE|O!`H5Vnnu!7Aco=^$=s*|jVn*e_y4!c_0m;kVyEB6wxsT33(}jgE<^RoX z9=H}%VAL)8-1N8mAGF~b%qVu?rI&sme}s(NaWvSxiEkAiFAG)n77`Zbp{c1@>bL>( z+SYkb|HWz!-*e2@q&F2g*Eh^$(Rm<4MZ3-1oz{2&C*pXdm8X&4M|;kya*1QS%bknR z5&ASiB9lw2Ok(<))4;!!C|;pJL(JKtBA AJsWtpu`Sj5RL>f D-Q9mQp-w>0% I$OkX{}q8_%$9DgY4kkQ zN3nTWpTviP&_=~WlqEZ|!#2-N=7|Hpn6rSfsZiB0ScqdX`rsbGTaGzF#YTlVhdGiD zlGyQ~O##M?^geiG qXVrKwHm54O ZOzLsSi8p#}19IV<@R59?L@8Lw$HfhA*Q~+;$g+ z1qq;_H(j}GHaan9G!qaJbAKT39uxhFi9ois4*ABoNd;KFq(sN`*YQZjGS$eAoKx9d zfw<3=no)Hf0sCCJYq;{iQ`wF@I$%uei@zP&Z%*?g)1x1b=OSH_t|}g{*?b(IQR77I z2|cMnWZw`9+IwF}th^AUMB-k`Ybn@6v$nQQkgq*bS|77Di6v66m+fGp?>^Yz$PGp= z7b}u-=lWq4xHin#QF89@@m1cDy<{L{vQ9$0y7Gie`Rle6)5|^5c1$2eJQKbJd*;|> z;tc9bkMV|H{s4(cj14Fz)g{*&83yWtgZ-=egQmIp7y#MW%*r#rm7UfF;0w?6Kw^hK z-2ev4;>UQRs03Z*?_>Gv1QN0!Vy-EGYPW pU^sQ#UZsU1*YYFzBoDaqwXt%z+#|`~G>SR@L?`qU1 zTkIp%ZB4wOgf76u_DiT%;rG}ri}{^>?W?o@5=t0ycDr-lw2~ur^KD`CWPkM9J|Jd? z4FzRQI)!T&`@J}R-)7gx;pbJBf%WpgZDV&A_qSg}YQx4>E)XC;`d=%_cPx+pA6;J^ z7G>AHtDvNkBGS^xNOvnJ-7&<_EezeQA}I|+mvjx?Dbn5GkkZ}V=fU?q-}%n M1LF?Ed|#WCTBTd6jTWIU(3Fy#DD6p!|qZRg0gT>zTB+*}7^niZ$6zuCoKzpLeC1 zU2*ts-=dZX&WQ)4K1?7nD9o||MMkQYXi_a0B+T(KA_mt=x{hiz*06|2%Np%e{0-r% z^E1yiDk7S3aBspRA+;ak5tV%WL*J1L56KhMX&IuKei3$n)|TnSNk!ylkgR=vS0Gcy zkyY!@;R7Z7GkT=Rh`Rf@p!pFP+-S$;ii3SeT-VZ3ET?PP0-XOD>gDyXIL%*%Np7Ot zp8Vfyb+oH*#3r}mu8HV~Shl|gO?*83KGecnBD`(meQJ3)JZ83VvlMr)TfpbDn5c35 zUGFa7ezoLo`Q}&ez|47z_t8y%UEir+r{2w~UcLv;qU>ZiwvYYx;O#YbTB_i!$xfQe z7PnRev(SNKZeNA_&Uh0lNzJ}6ujdM{R9T0zn$^bzxAWnY(||!9~Q?@%*nL=X`A@ zp!cI8C8~OwJr}j=!_O%TH)Lrm_-a07l;MW(&=sk!ExeGn3(G)@Dx-}ngX)CUX^ww3 zt}9g(=L!|=9eSpR%#0OudfXi_85cdDLP3l{5jNRzwluMdHqj_nMZ2bmkS2zg5jUG> z2Kq}l7@WW}6jo`sKpo#KyKwiqE9ZZCf7QPUBKDTM?FqB{J5S}KGm7@CA##d1#lpQ& z;O{FeVfjZd;vY(saYc_5=Yva>kMk+#9ZGHR1kM0X*m8f>6MIqhEwbWfOXL<9gLB@# zJoh;+Y*9&u$*y;t6-p>LTGDVOfDX3L$(M_@k_K#OZ9F!6L+^KO?!ewxX}6bpZ@K2J z7eBVTOj77Jd9Q0?BIb>{6z&!7kM$UetEiFTdB2BxllG;N&8@8#d@fY4mPRL%FhEx> zKKCs$1MS{9znMx28?VX ?-}yr4%J6B6I+n0% zwVh47G$b7{pBbI j_C#(VVgbybOXds#FOTB*TyY>YgTlu5-ExV>dZ#Ii0oCj zckU>K_jp l)B zmjkuEWBKMGO`;m(YlxoSf0Jkz5i2XeKkt(XYOFoguP41f83(5S7Mic$Dfuj~)ob`1 zog`-5O e6xMLicwoJwt_6^%@*4r6;Qi$5D$- z?z^Tnv@EJT+ (xJ4^jxCdB1}4web|+MiejZvX@YIwtH{RzP zdVv1FvuENqmC%XbQVpP9VqM-VL{%s~uVd4xXT#;nh#!6cM%!1hy3&J@%WZ5u&O@fk z>Sm8d@6&GOSzekmtD@EraS8$Vh9GjI_0bE<$WRuC3rfc{2Zv>7*|CN@_Wj_9vEyZT zM;FP3d=eZ!W2S!04D=$5{%NBhra2_S39)T-1T_wx$>`T_3s9N=9cVkV@cPO|Qu>wV z?V&dOW$B->=PymOp3s;lwFI7;XKzI8B_7fjXjFsk!HBLPR@a*moUYzMT6ps>EP01l zo^M(y%VuKXp4l7c7dzHz0=gaO&yTPMcfXtb^2);hNNNv(NYaljYV?{!t~&qunlGIh z5d;b8^-wiLqqEEK#RUc@+Eg3;hyv0>LwbH`QNLMX06h-yBWU4D;NSeLnJBiPoRYRD z|9t8Wglox$m;(olnH#T2>7Y;cBWAgCyNuUP#Jo8GDB!J;omPtV_YP5xlfeE`Lz!vg z8r~-7+`ghM=abNr#K@R={Y5BqVV`9c;+41?!K^99dEUkc(o|e7X9yH5-KJNuB009) z0|bY5x0tJY9z8PAAAyk^_q!$ccSCnK3;AAsA%7)9{^jag7nBq9>c+s=7obfSx0A Th%mw@KV+8Hel| zcaQh4ENiNVH@%h<#A_6DG~0dPO;P1l%i 9rJT9=U`lW4kY51>qo7-&YAMGS2edhI#$Q7g1f}zhvrF1 zRK+EwGSG`b&3tiB=V{V`^qoTS!MFi1u$sUtPdO`O^5XN)QL@Ej+?O5M@(R_lDyF0x z($~@q@2V1Av@#Q>^9BJ*3aJ@ie5PhFn_|d_d4&_xJcDx-d|5~q0a0|}vV6@0zv4x& z3ZD8FK05EJ=6M7R@~w*g9pnpHv(5j^B;sB7Jt000R|M~cS!j&ODJa{sSD0Z?75eFD zogL|_@BMncOr7IwPSid_(ic!91B;W$rD&59Gl8eG(Uf;sGwv+ 8V!E@8g1>|iHYZN;6UAZH7!uA~3es6?1I)uiCOd9b=V=iSndACnbj z9+2FYTIx=8Pgd`52iCzoYWB68?a$XH+9Jb%9c)04zPIGm)8qK?7E{mD?WjT~u4OtZ z >EiWw4QpDBopOZWN!DmDl;fBuphORoMAzv?@R{Hv?zt)Cf1h|22d9?JW3u zI9eiZQdm#OeQPDVYd7LI+$`5mcYPU49MgS&bc>L1au6=k-dly3t+hY bQyr&7@uEYC1{w(hM zQRurr+gvR#9N+w!)=|oW{$Ip_h^~wReuDwFN>)8enDe)x090dZuC6S2*@b8OJLM-P z`n(){2`K*8PAIJTPyz*mthZ%V9i?RFQY7ZcJZRLkp~m!x;J=Ijz>6F|jjq$sVo3iy z+ySMdkXbeC`6h>fPtFMGYgNow1%{Eoj~EN9X@9^fo9`Cao-_|FVOlM}1TxAYs)`_C zeZP3Bqm=aiu&fwEB$ue}4`ZIqU)w<}FLcPng0+GvUMW1@AFEP+`!ci4m^D!@Cc>4V zU?M%#>Uwg7=PTZ+sr`m-guYxh`ww$QDz0K4=>+|SwDKIg@Hu(UdB^7JU+NY;s@%!l z^xu`wLd2Pa8sRqy&%}g wq%A_iUPSPuzS-P=fYxF3Lc6pbbxkZ z1 x@2sdA_P vwr@aJ+r=*(o=;jt+}5!iAlRU@sy_cA^Odo12`PTS|@ zlJsXUpO+~^t%`Dtx0}gOnYrw)Lks)norT^LH`?g %)0ishO{0e!+j~f z?<_u08>;?DM{yH~=*4*!UMPFl5OdWCj5I9pe>YNxz)P^{-D^Y^$#7q+_j0>ZTE&tO z{WA|5(5Uw9-4to)Pr5t0LBC9NA6{~tpcQsytS{4s{9i0l7SE>%5MMeDd9$;Mt1bh{ zbmCaMDm0KyzQ!8JJA8vq#8;?MLIlnnK4*Vy@aRZ3r+F9%4d6Rqdeo+zf(3)0qUgc> zbxhwlp}Z%OH6UNbE&g#8QIYcHiI*VhCTVpVE-IEqEI;KZu}4+weo;e{GFP&tST@d& zz3NME_q9g|7D)`Td(x|t5Xc>|OG1-b5xcrWZPwpTJ8jXdD9P69TZkm3ZGv(l@lvo6 zCL)_EbzRo 6!Sa9{wboKFa%J`y~qCMy0NDoe!nv`GO5;b zv8rdq-Ew=?Gud+e9nb_lx3*rE#&2pt?@YCO6)rfRP&OsdAomMRoY fR5f-aaNSIyRy1rhBE7+284fW@pot37s~& zHAZt+-+mq6)vr%CLuly=zx*>DaZpx*_%nH0mz<-^45n+*M|N!yQdgYny%wYrH9cPs z26Ts0r`4=k*;?cCV_V~`-eGr8H%Ug}T6NXEj-+JoN+@mKl${+A|LsH%$ EUSTq^U7wH6YTI6yVdS^%+ zGCO7q8Y 2|oSZH`UwM@vKTOC$HhJL9+^(FBId`nepT70(>U*MWxQ9wHOE7em zG8#0PA~HmdbnAZ?SVQCvBsc>9Ozz#jwqQ>(-UQcuh0Z IN%uajIocj_iw+@^798 zV5R-3YMn3+B{{})giYz?Pgf9rtTuJPckP@1>C$xnhpm3)HMgV^57;rf{^^y0K;Pu( zR!7KJ5%sM5v&r4&s$fy-mX_urYLz@}9r f@?Oa $(n9(F00yrZ=q=%l&=M}cz1C-EkY#1Xn-u?cVm zhGIg@489{bj{W70xQ>v0Y1k-kR&dd9NC2{P9L3@gE4C$J^oVVCR`7tS{;slI^-%|d zy}_tb)dcxqhZr|Eg^7AOYycf%mFbcbIkBZ!?d;9&rv6y}(-uQg512-b1R`Bo{iNQQ z(nE}0+p+DUOX^Dbicya?QAtHmPVcZ_)n+5te&_{0*GRsj#PDwna_WWtB~F0|({zC@ zUn=9V$1+x~$b6kz#+Kt9L!O})1cR>~3 TEAy`DdLufb)%4AuVP zAabGkkZv9t2;c-e02&MUgA?DpRcKVU!zxC(6NkRZHo`&ufRQ-2Phx8C_JZ}+d*P1y z#G~mDS(ijxu6)P+7<;JK{E#7`F^cq0+dIclDe9k=2#$;5==`@j_N!ZRjdtt*-mOR9 zr2mUTm{ysfV?mTa)zj6}(2fMf)dX-+8#%uL(S*ASh1b=k-%L$hZ=vj&nzd0el(v0q zm_9sJO?^yMVW6aFwwBjrC9_dRFZ|W687tXH1$32(4jcy$-9-8ZOn*wW^Y*fpk37a@ z5B(~~kpH~>*p0qW=Y 9Tn%q&ZlFUQ9TtBJW2j_o z>d?1CG#)ZUGjQWq8m3mB8x^^HC7RJvFRFR2F+*akggUl72;2S+f@tb`?LH6gg%=eK zca_^LcsI7<0Hww6Iv~dcl!sB305WK-d<>|2a^R he4pVj4PUrA~HBUf-t>QW26o6ny)B;@s{G4S9MQg^hbwVfw#N^ArLQwq?~ zirRGfar;6L2*|`~y6r_I{DjUP)y={#LCUE&yYlK{w%L3)@;5ok*wZ12>NBSg-!v>0 z gycr-Q_cm(_@S7S8;QP#Liy 7|lj^+Rz3jLnNvKsE)o~@n zB8pyTgynXnFia8ZRF~ge>IJE-ot_EoFIBYxc(eZc1CswJo#F%85S^wLNIe3c^q7sx z0Qw7iXGyiieUk?`ZZ&J)Ighik=Sxyicl*u05{Kj(T$jeDNvd?`S2iQZdL>QGg{->9 zLVm60i`-$IV~&fNU9>gpZPV^(HaC0c`Hp+xK3neYp%A6SAz_IG0}4UyiLDTprW=f= zI3E(X{l2>IJFd0hlU2PI`~7W`dfW1gkw* 9wU7Os6HXl#key~y|sb%2z% znCvi0+O3NUuV?bL7ye6*%@~$fHvUsak+%3!GA}SP`}P$4$Ciocq}b{`@ kor~mEa`VcfS91lJ&T0eBL;;3`NvL=okeq^W`r1VDRJ08-_M-WbAZ$S@8-6l4& z;= kOwNkaT@&Z$i8sTn=%!ed@p`b1wIxR^r%3pXZR0-qV+#{)t@1ii`6SVT_b9#z0&r zuG2$Isx3N)wkZUr?{=Af8`Pu>@6L6Rm!H|LuH~}Hc &p;&18{cw9ZRGE&E^?Tuv9074=dbi3u*OhzKT@9PeZZPR>5U_pT^#KuDWXxo2yE zTbBkM I&`}?ZH)33ij#XaQ|vd+;C5U&PK zu0epQmHLP=M*?XSo zw(^)+rdX%R7V}?jCS1#aTnH)11?;xG{7`KAsUqKClL_0MPVdqeZXfgP4<-v*acUl# zTH#h^P{rK-3H{}I2=q|G(~1^!JS#nh?iP04EkA@5u?+?9iMWPX>zCD`%rLRq@<+mX zGx73Iywo68jFL0(#LH&l%pYTVagnpyP2NA-_3E|urf*j_m#^~!Rn*{kJEev4Xk}EF ztNi5wmJ8l6buP}>SD10b)W?A6H)#T2ax%ZY;n~gn=Zqgsrdu~0om#PL^abb`4aBl8 z ENk?Ojk8My+BA?$rL16M`d% ==MxST4)WZR_m&W=L@1MN*R1>FlmbV; zZ_bo~dEuLE#Sd2&?5t}G`ftbR)la8c+e=`)eQaoGF{I^`@Rk%T=YH$Sh5iUR3m-wO zpyaa0bbC?bGdygw5e@}b67oPSRo-94!M}}r{K0akX=$u>-ZhuiQSfGjU54vI43ht7 zeTp5g-1vK({XX`7Tm>#+s3uNBv^;BrJ_E)kRxxn){eJ4|+oKL4?HLA4pK3+Z-SxVx zjJQ_Er$1gL8I@DS$Y6T(H!}Vhqf!m*Z2&suz!PDs=jiY!jq!RX$=Rt$s|JEmU~5cJ z8|IHk<@pz_WzdjpXvuy|M)FWKC$L|W^C^ejcZ;Y4OGe*=i2*4*4uceBS~XUvxbgP8 zl3x+;yGcWc`UQUbby%#%JGaX)uIdCyCJaarY&J}pS)2EtWO6?p^-h~ge-DxvNs@W4 z>%vQR7JredYHcPe(UqJ`koN>Tiw=S>jJ$tGY0S`fu=cT<{r(Bw7}woe1tNANj&oJr z*_J2xDwW&;w$0izneuWL @#bj>9#=T>)6b7b z!PVqxmmw3G+8d(vTV62J 07Hl=l13Hhno?TKbNnt>f4Wf5c0}B^M%!RpSL%(NNSR?`JipN l-K6C%@t&>9Ru{HmfM>WipD|8;uo-VQRfpRm*jhx^dew|5uwz0Q8G)P;WrFz0l zCLjS-QA67tP`TQC85BMOgRVMtlXko_+5S`f>)^d)2r!%0b^G$o`5O;eAWN7aug8r% zQSbRUQbUoDt!*l|OXwew=Sa@(SL`&OFQz9|4=SS#leXupiHzR*P%wGz&^;18;(xmE z4eJRJghZP9ow8JgG?*fF);v7JW^AnoTyICGF57XFI6V~k;fHh9ut?}i*KP6&6BEvJ zbN7D6DT63D=k*x{LtGz1o4kZr_`i!L;$bMBYuL?4ORej*67`a~&O!|o5JW`i^l9NY zt>XqAo5dL qE-xD4WSM`tWERDM=RGH@eY13tw)?QVh>{U*Cqi zs)d?1m;4CTFk#WH(<=y+XYOX47fGwK{iYv{)v*1+P zRb=;=vj3F;ZW)imJ|MLrn_mg{f%p z$!HQ-YIzS`ggzHV3*+=;FbL969Y-srB}_=2Ft-yYQ7Z$&+J^i@RYY8wOiOE8fPTTC zi1^xfnoM4$pV09)`5JQ;#9yGj22~_)xk6mqH_jsAzV#Sw(gWTZeJM$jCMu?D?u*m7 zEcr1m)Km#)7ToWW=8gEp{C=VP#DplxDgs5*Qt=H4X{LgYzqK-1mQMLjzn^eG74p*4 z)M=Tg5&>+Sk&0P{HE$c1WwGEKca`^$dXbnlF5Z~-PA2z}hl~jHhJG}X0*L1WvTR-K zfRu2ZZo^Zmcyb;I8&+7~DgwcBP_PIndHp8{QN_zO|GAmz_5i{PkZh|*BmAezpMk4K z1%f-rtlU;77MA|GFZcENQ3a9v^7~;nYs%Y5=B&bv^D4gz{`Y3ALkn72HBGjg{JN0L zg#Be6{J!x!A^H+#k+t^N*i_;AlOA&HAtUbn(qnl=qkKO1gQH&)=T8_D-v#L7uMn zzc^&8*;7Dr2?-ULw9X&jI!Bv@@B27a>YF&yx7=f)hyik5HG2!qV~HJ@*GQzhpfL&T z XR^l%o)%ex5Cvotet1>F4tzEFhH+cvupUJ3K0a4O zNbgD}-X@wmincYH0=qwGfS;ur6 7k1FwfIa+9`4+gql_M)**Em+^~6R~zH6+9jRNhmQlW0p0`^zbuMtT* z275f&@$wx^{Htrs5q|uUQlVdPDv}AWpVLb9TJqRVZCZq)<#Y`os Ac`{@Y{F?_ g5EhtNkw#^TQR3y555WSVTK&uME+GWHZJYVlW;HwD1j|`)XvXY|0VC!F20_ z%i-@OSL{RI8?jnCy4Q)$U&%k@26~zHRmx_QN&Up3QRg1)8m^tOce>r2;-T|d%7q;| zsSsS*a0t7IPlYx!KK1^hnixPp{y(J?Ymz71B~YpYiF3`7 r<*;Veg*H}_)3m9lU}8IKpe+DWk+1&v(Gy^chl%HfL8&$~g`g{1 z3GrVmkCO-DxykjPgZoY{%bIeS$)BO3Cf2;7J;k5Dt-Vnm{rv8S_OR*T+1JVPs$C>a zfb{Zc82dG(=9%G2lYO0_h!6gM{UqiZi 7-QU =uzV!(AuMEKZ zVPHoOY1-wpdmd;#jt%<5@1H{|cj|N9Tvd;aqllBv)@hjkWf_1DaH0mY@evlL<)}B_ zCt}5)cHdWzKEykpSDp_6Zvw|R_FYPSnU*H&dBb;=EBRFWsH~xqq8|iKY5l8uCyf^j zBd~ds^RBj_cwBOSB)Wh8iR1v+wqGMLh8b1qMhDv0?K=b-6OkOv@u0PCYR}a&WY0 zI&Sx8dMp%3ytLfi&B8Npzt(Xswa;c!M#1gr{lEkpK9@+3a16&aqT%)P)~uohJZ@j* zOCZ$y)(*H2`+HtJN%_k{di47)P~UwvtgI}^zAjnX STeqv>{+2Il*XhE&8_l51wSg;e&Oqk*##%g?($=KtGSdoo6K4iXt zpObA_xVG_3ryoNb{37_iUVdU!&}xt^di(WZeU|S(++$YKzkk3pDOjJ$Rg3EcE1*sI zyY3kv9o){I05BmDj>IPP^3f5DYA8ucC0nd-7}@Q#3I}$pG*8JehM6O_D_;imq{CRN z%{ea+hEwHg251UVh}tjb8v)EQ-QjhPH)mf@SRk7Qc}3)fnYd=J <{MM(*>i&t zaEw7^_%~8M7IrdKwQFOUtp<>+N?njD9SO!$CKS1VsbbLvm5~!tq&BRF<4OfcIS)D^ zi|?L{Ejt5`_cNs#NiSHGjk~5^iP0toJecb`bi5@}->nK4<|X^H!S}6KjI4?G{vc_T zIGWgL_j _54uX z@ X8wrxARdVV?5?Wu9Mkj|xG4Dz)%AXPJ69Oc8JJg19P z8FuZi>{Xu9MSe6$%wnj?CdUtbA*eFp3Nf{^xYK>|uW$NiNz^N>53EAgsDN#~vai;y zuFg(~`+(L17Bytn))0GKuuYOpA70$=#piI;zpfseR#f&SW61Q4ka}_`KbE#h<(oNg zr_0vtl0omg4p^aHNf~8X_EGQpru+4@K4Vx_qqEQA-h}13wVueHmG!yp6Ko775(2)a zpD2|Xt#5VHQ8`?8JC$jL MrY(JR{K4dq82 z*H~?s*#h!iRMTr^Urs(dwMxa{r_&>}@}n&JN6^bz37odH;O`d@`8d1*KQToe5Q%p6 zQJbD@DRjQA@gmZ+uePNLFvv4A?1%DpiWO%mekfizdsDrXyJ)lXVaPMf_%TEEKfMAL zKx1ZIfrdh1Gr|7(Et+AsEu1GLSJd-4{^@Z=uW29>As!{H&E=K$UcGdMj#S{^XZ 8d *s; @2fB;aG-n^Qufy*c*3h7nUS1aif(gLrw!|GGrb|9sLF zCWW)$tQn24d!Mc0WR1(m&w*y1Bq8^A8-jnnDbV?7mNAJ<|MqO>OXUKiCEjA-&io#v zkiqlxdiz?C-LC+*YWXKsbl9J3OAo7^wxi@$?S9)v*_uD7AF(@64(H5d&wNWnf`Um* za42Kl DtxOmF+^?Jz&6AQCCgi9z?y z$~JE+DniMK2SZT-VE*$ufYAd9g+4D%>q#vca0vR{2q?lL{)%KyoFH-e D@}ZDU-;lZ=Vn5&Js_CHITs3H|!V z`vKZqk9^0#}xYG2l*9hDUplJ$Wrx8iI =c zii2mwWM--J*acRhW@zh-Pcl;jg-Jp`l`DquCKg*v^yK3R0^VCx1u<=|3R1)S&LbeV ziYZT)TPlJmP%PL);5~XY^Ri~9Q1#Qi_xhY((+P