From 50ca6f49b75e529512084756307d6fd84b9b37ba Mon Sep 17 00:00:00 2001 From: chenyu Date: Fri, 10 Mar 2023 15:45:02 +0800 Subject: [PATCH 1/2] v9.4.0 --- .../project.pbxproj | 753 +++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../contents.xcworkspacedata | 10 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../IMUIKitOCExample/AppKey.h | 10 +- .../AccentColor.colorset}/Contents.json | 5 + .../AppIcon.appiconset/1024x1024.png | Bin 0 -> 151982 bytes .../AppIcon.appiconset/120x120-1.png | Bin 0 -> 5696 bytes .../AppIcon.appiconset/120x120.png | Bin 0 -> 5696 bytes .../AppIcon.appiconset/152x152.png | Bin 0 -> 7781 bytes .../AppIcon.appiconset/167x167.png | Bin 0 -> 8846 bytes .../AppIcon.appiconset/180x180.png | Bin 0 -> 9826 bytes .../AppIcon.appiconset/20x20.png | Bin 0 -> 700 bytes .../AppIcon.appiconset/29x29.png | Bin 0 -> 1046 bytes .../AppIcon.appiconset/40x40-1.png | Bin 0 -> 1495 bytes .../AppIcon.appiconset/40x40-2.png | Bin 0 -> 1495 bytes .../AppIcon.appiconset/40x40.png | Bin 0 -> 1495 bytes .../AppIcon.appiconset/58x58-1.png | Bin 0 -> 2360 bytes .../AppIcon.appiconset/58x58.png | Bin 0 -> 2360 bytes .../AppIcon.appiconset/60x60.png | Bin 0 -> 2433 bytes .../AppIcon.appiconset/76x76.png | Bin 0 -> 3238 bytes .../AppIcon.appiconset/80x80-1.png | Bin 0 -> 3423 bytes .../AppIcon.appiconset/80x80.png | Bin 0 -> 3423 bytes .../AppIcon.appiconset/87x87.png | Bin 0 -> 3848 bytes .../AppIcon.appiconset/Contents.json | 116 ++ .../Assets.xcassets}/Contents.json | 0 .../chat.imageset}/Contents.json | 4 +- .../Assets.xcassets/chat.imageset/chat@2x.png | Bin 0 -> 1209 bytes .../Assets.xcassets/chat.imageset/chat@3x.png | Bin 0 -> 1709 bytes .../chatSelect.imageset/Contents.json | 22 + .../chatSelect.imageset/chatSelect@2x.png | Bin 0 -> 1217 bytes .../chatSelect.imageset/chatSelect@3x.png | Bin 0 -> 1723 bytes .../contact.imageset}/Contents.json | 4 +- .../contact.imageset/contact@2x.png | Bin 0 -> 751 bytes .../contact.imageset/contact@3x.png | Bin 0 -> 985 bytes .../contactSelect.imageset/Contents.json | 22 + .../contactSelect@2x.png | Bin 0 -> 861 bytes .../contactSelect@3x.png | Bin 0 -> 1200 bytes .../qchat_tabbar_icon.imageset/Contents.json | 22 + .../qchat_tabbar_icon@2x.png | Bin 0 -> 1149 bytes .../qchat_tabbar_icon@3x.png | Bin 0 -> 1591 bytes .../Base.lproj/LaunchScreen.storyboard | 25 + .../Base.lproj/Main.storyboard | 24 + .../IMUIKitOCExample/Info.plist | 25 + .../IMUIKitOCExample/Main/AppDelegate.h | 11 + .../IMUIKitOCExample/Main/AppDelegate.m | 132 ++ .../Main/ConversationController+Test.h | 14 + .../Main/ConversationController+Test.m | 20 + .../Main/CustomRouterViewController.h | 13 + .../Main/CustomRouterViewController.m | 40 + .../Main/IMUIKitOCExample-Bridging-Header.h | 3 + .../Main/NENavigationController.h | 14 + .../Main/NENavigationController.m | 40 + .../Main/NETabbarController.h | 15 + .../Main/NETabbarController.m | 62 + .../IMUIKitOCExample/Main/ViewController.h | 8 +- .../IMUIKitOCExample/Main/ViewController.m | 19 + .../Main/en-IN.lproj/Localizable.strings | 7 + .../Main/en.lproj/Localizable.strings | 11 + .../Main/zh-Hans.lproj/Localizable.strings | 13 + .../en-IN.lproj/LaunchScreen.strings | 1 + .../IMUIKitOCExample/en-IN.lproj/Main.strings | 1 + .../IMUIKitOCExample/IMUIKitOCExample/main.m | 16 + .../zh-Hans.lproj/LaunchScreen.strings | 1 + .../zh-Hans.lproj/Main.strings | 1 + .../IMUIKitOCExampleTests.m | 36 + .../IMUIKitOCExampleUITests.m | 48 + .../IMUIKitOCExampleUITestsLaunchTests.m | 36 + IMUIKitOC/IMUIKitOCExample/Podfile | 56 + NEChatUIKit/NEChatUIKit.podspec | 5 +- .../audio_record.imageset}/Contents.json | 0 .../Commom/audio_record.imageset/Frame@2x.png | Bin 0 -> 1029 bytes .../Commom/audio_record.imageset/Frame@3x.png | Bin 0 -> 1394 bytes .../video_record.imageset}/Contents.json | 0 .../video_record.imageset/Vector@2x.png | Bin 0 -> 571 bytes .../video_record.imageset/Vector@3x.png | Bin 0 -> 845 bytes .../Assets/en.lproj/Localizable.strings | 38 +- .../Assets/zh-Hans.lproj/Localizable.strings | 23 +- .../Chat/Controller/ChatViewController.swift | 511 ++++--- .../Controller/GroupChatViewController.swift | 28 +- .../Controller/P2PChatViewController.swift | 10 + .../Controller/SelectUserViewController.swift | 16 +- .../Emoji/InputEmoticonContainerView.swift | 2 +- .../Chat/Emoji/InputEmoticonTabView.swift | 2 +- .../Chat/Emoji/NIMInputEmoticonButton.swift | 2 +- .../Chat/Emoji/NIMInputEmoticonManager.swift | 2 +- .../Helper/NotificationMessageUtils.swift | 157 ++- .../Chat/Helper/ReplyMessageUtil.swift | 2 + .../Chat/Model/MessageCallRecordModel.swift | 76 ++ .../Chat/Model/MessageContentModel.swift | 8 +- .../Classes/Chat/Model/MessageModel.swift | 1 + .../Classes/Chat/Model/MessageTextModel.swift | 5 +- .../Classes/Chat/Model/MessageTipsModel.swift | 9 + .../Classes/Chat/Model/NEMoreItemModel.swift | 18 +- .../Chat/View/Cell/ChatAudioLeftCell.swift | 3 +- .../Chat/View/Cell/ChatAudioRightCell.swift | 3 + .../Chat/View/Cell/ChatBaseLeftCell.swift | 15 +- .../Chat/View/Cell/ChatBaseRightCell.swift | 26 +- .../View/Cell/ChatCallRecordLeftCell.swift | 41 + .../View/Cell/ChatCallRecordRightCell.swift | 43 + .../Chat/View/Cell/ChatLocationLeftCell.swift | 1 + .../View/Cell/ChatLocationRightCell.swift | 1 + .../Chat/View/Cell/ChatRevokeRightCell.swift | 14 +- .../Chat/View/Cell/ChatTeamMemberCell.swift | 2 +- .../Chat/View/Cell/ChatTextLeftCell.swift | 6 - .../Chat/View/Cell/ChatTextRightCell.swift | 1 - .../Chat/View/Cell/ChatVideoRightCell.swift | 2 +- .../Chat/View/ChatView/ChatInputView.swift | 32 +- .../Chat/View/ChatView/ChatRecordView.swift | 4 +- .../Chat/View/ChatView/NEInputMoreCell.swift | 10 +- .../Chat/ViewModel/ChatViewModel.swift | 397 +++--- .../Chat/ViewModel/TeamChatViewModel.swift | 3 +- .../Chat/ViewModel/TeamMemberSelectVM.swift | 2 +- .../Classes/ChatConfig/ChatUIConfig.swift | 2 +- .../Classes/ChatRouter/ChatRouter.swift | 16 +- .../Classes/Common/ChatConstant.swift | 1 + .../Classes/Common/NEChatUIKitClient.swift | 38 +- NEContactUIKit/NEContactUIKit.podspec | 6 +- .../Assets/en.lproj/Localizable.strings | 10 +- .../Assets/zh-Hans.lproj/Localizable.strings | 8 +- .../Classes/Base/ContactBaseViewCell.swift | 1 + .../Extension/ContactImageExtension.swift | 2 +- .../Team/Views/TeamTableViewCell.swift | 4 +- .../Classes/UserInfo/UserInfoHeaderView.swift | 19 +- .../ContactRemakNameViewController.swift | 56 +- .../ContactUserViewController.swift | 114 +- .../ValidationMessageViewController.swift | 14 +- .../Validation/Views/BaseValidationCell.swift | 27 +- .../ViewModel/ContactUserViewModel.swift | 5 + .../Classes/ViewModel/ContactViewModel.swift | 83 +- .../Views/ContactBaseViewController.swift | 12 + .../Classes/Views/ContactTableViewCell.swift | 8 +- .../ContactsSelectedViewController.swift | 10 + .../Views/ContactsViewController.swift | 6 +- .../Views/FindFriendViewController.swift | 32 +- .../NEConversationUIKit.podspec | 6 +- .../Assets/en.lproj/Localizable.strings | 13 +- .../Assets/zh-Hans.lproj/Localizable.strings | 19 +- .../Controller/ConversationController.swift | 9 + .../ConversationListViewController.swift | 66 +- .../ConversationSearchController.swift | 2 + .../View/ConversationListCell.swift | 15 +- .../ViewModel/ConversationViewModel.swift | 160 ++- NEMapKit/NEMapKit.podspec | 4 +- NEMapKit/NEMapKit/Classes/NEMapService.m | 1 + .../Chat/add.imageset/Frame@2x-4.png | Bin 1405 -> 0 bytes .../Chat/add.imageset/Frame@3x-4.png | Bin 2033 -> 0 bytes .../Chat/emoji.imageset/Frame@2x-1.png | Bin 1488 -> 0 bytes .../Chat/emoji.imageset/Frame@3x-1.png | Bin 2110 -> 0 bytes .../Chat/file.imageset/Frame@2x-3.png | Bin 956 -> 0 bytes .../Chat/file.imageset/Frame@3x-3.png | Bin 1357 -> 0 bytes .../Chat/mic.imageset/Frame@2x.png | Bin 1267 -> 0 bytes .../Chat/mic.imageset/Frame@3x.png | Bin 1801 -> 0 bytes .../Chat/photo.imageset/Frame@2x-2.png | Bin 1099 -> 0 bytes .../Chat/photo.imageset/Frame@3x-2.png | Bin 1623 -> 0 bytes .../sendMessage_failed.png | Bin 2373 -> 0 bytes .../Commom/arrowDown.imageset/Contents.json | 22 - .../arrowDown.imageset/Frame 214@2x.png | Bin 338 -> 0 bytes .../arrowDown.imageset/Frame 214@3x.png | Bin 433 -> 0 bytes .../Commom/arrowRight.imageset/Contents.json | 22 - .../arrowRight.imageset/Vector 87@2x.png | Bin 307 -> 0 bytes .../arrowRight.imageset/Vector 87@3x.png | Bin 341 -> 0 bytes .../Commom/arrowUp.imageset/Contents.json | 22 - .../Commom/arrowUp.imageset/Frame 214@2x.png | Bin 312 -> 0 bytes .../Commom/arrowUp.imageset/Frame 214@3x.png | Bin 408 -> 0 bytes .../Commom/backArrow.imageset/back@2x.png | Bin 370 -> 0 bytes .../Commom/backArrow.imageset/back@3x.png | Bin 467 -> 0 bytes .../Commom/delete.imageset/Frame@2x.png | Bin 822 -> 0 bytes .../Commom/delete.imageset/Frame@3x.png | Bin 1217 -> 0 bytes .../memberPlaceholder.imageset/Contents.json | 22 - .../Frame 1016@2x.png | Bin 10032 -> 0 bytes .../Frame 1016@3x.png | Bin 16070 -> 0 bytes .../rolePlaceholder.imageset/Contents.json | 22 - .../Frame 1018@2x.png | Bin 13666 -> 0 bytes .../Frame 1018@3x.png | Bin 21856 -> 0 bytes .../Commom/search.imageset/Frame@2x.png | Bin 814 -> 0 bytes .../Commom/search.imageset/Frame@3x.png | Bin 1132 -> 0 bytes .../Commom/select.imageset/Contents.json | 22 - .../Commom/select.imageset/select@2x.png | Bin 940 -> 0 bytes .../Commom/select.imageset/select@3x.png | Bin 1312 -> 0 bytes .../Commom/sign_add.imageset/Contents.json | 22 - .../\346\267\273\345\212\240@2x.png" | Bin 1411 -> 0 bytes .../\346\267\273\345\212\240@3x.png" | Bin 1937 -> 0 bytes .../Commom/unselect.imageset/Contents.json | 22 - .../Commom/unselect.imageset/unselect@2x.png | Bin 956 -> 0 bytes .../Commom/unselect.imageset/unslect@3x.png | Bin 1369 -> 0 bytes .../NEKitQChatUI.xcassets/Home/Contents.json | 6 - .../Home/addOther_icon.imageset/Contents.json | 22 - .../addOther_icon@2x.png | Bin 2510 -> 0 bytes .../addOther_icon@3x.png | Bin 3495 -> 0 bytes .../addService_icon.imageset/Contents.json | 22 - .../addService_icon@2x.png | Bin 1235 -> 0 bytes .../addService_icon@3x.png | Bin 1910 -> 0 bytes .../cell_arrow_icon.imageset/Contents.json | 22 - .../cell_arrow_icon@2x.png | Bin 304 -> 0 bytes .../cell_arrow_icon@3x.png | Bin 355 -> 0 bytes .../Contents.json | 22 - .../chat_message_receive@2x.png | Bin 983 -> 0 bytes .../chat_message_receive@3x.png | Bin 1539 -> 0 bytes .../chat_message_send.imageset/Contents.json | 22 - .../chat_message_send@2x.png | Bin 968 -> 0 bytes .../chat_message_send@3x.png | Bin 1548 -> 0 bytes .../home_addChannel.imageset/Contents.json | 22 - .../home_addChannel@2x.png | Bin 352 -> 0 bytes .../home_addChannel@3x.png | Bin 438 -> 0 bytes .../home_setupServer.imageset/Contents.json | 22 - .../home_setupServer@2x.png | Bin 247 -> 0 bytes .../home_setupServer@3x.png | Bin 312 -> 0 bytes .../Home/mine_create.imageset/Contents.json | 22 - .../mine_create.imageset/mine_create@2x.png | Bin 1675 -> 0 bytes .../mine_create.imageset/mine_create@3x.png | Bin 2362 -> 0 bytes .../Contents.json | 22 - .../otherService_search_icon@2x.png | Bin 740 -> 0 bytes .../otherService_search_icon@3x.png | Bin 1050 -> 0 bytes .../uploadPic_bg_icon.imageset/Contents.json | 22 - .../uploadPic_bg_icon@2x.png | Bin 4759 -> 0 bytes .../uploadPic_bg_icon@3x.png | Bin 7113 -> 0 bytes .../Home/upload_camera.imageset/Contents.json | 22 - .../upload_camera@2x.png | Bin 719 -> 0 bytes .../upload_camera@3x.png | Bin 889 -> 0 bytes .../Server/Contents.json | 6 - .../Server/camera.imageset/Vector@2x.png | Bin 611 -> 0 bytes .../Server/camera.imageset/Vector@3x.png | Bin 774 -> 0 bytes .../count_header.imageset/Contents.json | 22 - .../count_header.imageset/Vector@2x.png | Bin 416 -> 0 bytes .../count_header.imageset/Vector@3x.png | Bin 568 -> 0 bytes .../Server/dot_image.imageset/Contents.json | 22 - .../Server/dot_image.imageset/Vector@2x.png | Bin 730 -> 0 bytes .../Server/dot_image.imageset/Vector@3x.png | Bin 1179 -> 0 bytes .../dot_image_disable.imageset/Contents.json | 22 - .../dot_image_disable.imageset/Vector@2x.png | Bin 730 -> 0 bytes .../dot_image_disable.imageset/Vector@3x.png | Bin 1179 -> 0 bytes .../id_group_header.imageset/Contents.json | 22 - .../id_group_header.imageset/Group 389@2x.png | Bin 1441 -> 0 bytes .../id_group_header.imageset/Group 389@3x.png | Bin 2078 -> 0 bytes .../id_group_sort.imageset/Contents.json | 22 - .../id_group_sort.imageset/Vector@2x.png | Bin 396 -> 0 bytes .../id_group_sort.imageset/Vector@3x.png | Bin 497 -> 0 bytes .../Contents.json | 22 - .../invitemember_success@2x.png | Bin 943 -> 0 bytes .../invitemember_success@3x.png | Bin 943 -> 0 bytes .../Server/lock.imageset/Contents.json | 22 - .../Server/lock.imageset/Vector@2x.png | Bin 672 -> 0 bytes .../Server/lock.imageset/Vector@3x.png | Bin 921 -> 0 bytes .../member_header.imageset/Contents.json | 22 - .../member_header.imageset/Group 390@2x.png | Bin 2175 -> 0 bytes .../member_header.imageset/Group 390@3x.png | Bin 3101 -> 0 bytes .../Contents.json | 22 - .../channel_noMore@2x.png | Bin 13633 -> 0 bytes .../channel_noMore@3x.png | Bin 21590 -> 0 bytes .../servers_noMore.imageset/Contents.json | 22 - .../servers_noMore@2x.png | Bin 16641 -> 0 bytes .../servers_noMore@3x.png | Bin 26499 -> 0 bytes .../channel/Contents.json | 6 - .../channel/Selection.imageset/Contents.json | 22 - .../channel/Selection.imageset/Vector@2x.png | Bin 337 -> 0 bytes .../channel/Selection.imageset/Vector@3x.png | Bin 495 -> 0 bytes .../channel/Setting.imageset/Contents.json | 22 - .../channel/Setting.imageset/Vector@2x.png | Bin 1007 -> 0 bytes .../channel/Setting.imageset/Vector@3x.png | Bin 1483 -> 0 bytes .../channel/allow.imageset/Contents.json | 22 - .../channel/allow.imageset/Frame@2x-1.png | Bin 329 -> 0 bytes .../channel/allow.imageset/Frame@3x-1.png | Bin 463 -> 0 bytes .../allowSeleted.imageset/Contents.json | 22 - .../allowSeleted.imageset/Frame@2x.png | Bin 232 -> 0 bytes .../allowSeleted.imageset/Frame@3x.png | Bin 299 -> 0 bytes .../channel/bgImage.imageset/Contents.json | 22 - .../channel/bgImage.imageset/image 86@2x.png | Bin 152038 -> 0 bytes .../channel/bgImage.imageset/image 86@3x.png | Bin 303404 -> 0 bytes .../channel_member.imageset/Contents.json | 22 - .../channel_member.imageset/Frame@2x.png | Bin 979 -> 0 bytes .../channel_member.imageset/Frame@3x.png | Bin 1330 -> 0 bytes .../channel_noMoreData.imageset/Contents.json | 22 - .../channel_noMoreData@2x.png | Bin 11101 -> 0 bytes .../channel_noMoreData@3x.png | Bin 17907 -> 0 bytes .../channel/deny.imageset/Contents.json | 22 - .../channel/deny.imageset/Frame@2x.png | Bin 360 -> 0 bytes .../channel/deny.imageset/Frame@3x.png | Bin 518 -> 0 bytes .../denySelected.imageset/Contents.json | 22 - .../denySelected.imageset/Frame@2x.png | Bin 243 -> 0 bytes .../denySelected.imageset/Frame@3x.png | Bin 327 -> 0 bytes .../channel/extend.imageset/Contents.json | 22 - .../channel/extend.imageset/Frame@2x-2.png | Bin 266 -> 0 bytes .../channel/extend.imageset/Frame@3x-2.png | Bin 394 -> 0 bytes .../extendSelected.imageset/Contents.json | 22 - .../extendSelected.imageset/Frame@2x-2.png | Bin 181 -> 0 bytes .../extendSelected.imageset/Frame@3x-2.png | Bin 222 -> 0 bytes .../channel/server.imageset/Contents.json | 22 - .../channel/server.imageset/Frame 245@2x.png | Bin 300 -> 0 bytes .../channel/server.imageset/Frame 245@3x.png | Bin 430 -> 0 bytes .../server_menu.imageset/Contents.json | 22 - .../server_menu.imageset/Group 329@2x.png | Bin 213 -> 0 bytes .../server_menu.imageset/Group 329@3x.png | Bin 266 -> 0 bytes .../Assets/en.lproj/Localizable.strings | 165 --- .../Assets/zh-Hans.lproj/Localizable.strings | 168 --- .../Classes/Base/BaseView/QChatBaseCell.swift | 17 - .../Base/BaseView/QChatCenterTextCell.swift | 40 - .../Base/BaseView/QChatImageTextCell.swift | 89 -- .../Base/BaseView/QChatSectionView.swift | 33 - .../Base/BaseView/QChatStateCell.swift | 65 - .../Base/BaseView/QChatTextArrowCell.swift | 17 - .../Classes/Base/BaseView/QChatTextCell.swift | 68 - .../Base/BaseView/QChatUnfoldCell.swift | 65 - .../QChatBaseViewController.swift | 25 - .../QChatNavigationController.swift | 22 - .../QChatTableViewController.swift | 67 - .../Classes/Channel/Model/QChatRoles.swift | 28 - .../Channel/Model/RoleStatusInfoExt.swift | 16 - .../Channel/View/ChannelHeaderView.swift | 66 - .../Classes/Channel/View/CornerButton.swift | 123 -- .../View/QChatImageTextOnlineCell.swift | 41 - .../Channel/View/QChatMemberInfoView.swift | 319 ----- .../View/QChatPermissionSettingCell.swift | 148 --- .../Channel/View/QChatTextEditCell.swift | 86 -- .../Channel/View/QChatTextSelectionCell.swift | 43 - .../ViewController/QChatAddMemberVC.swift | 233 ---- .../ViewController/QChatAddRoleGroupVC.swift | 234 ---- .../QChatChannelAuthoritySettingVC.swift | 377 ------ .../QChatChannelMembersVC.swift | 186 --- .../QChatChannelSettingVC.swift | 276 ---- .../ViewController/QChatChannelTypeVC.swift | 74 -- .../QChatChannelViewController.swift | 219 --- .../QChatGroupPermissionSettingVC.swift | 155 --- .../QChatMemberPermissionSettingVC.swift | 189 --- .../ViewController/QChatSearchVC.swift | 84 -- .../QChatWhiteBlackListVC.swift | 254 ---- .../QChatAuthoritySettingViewModel.swift | 202 --- .../ViewModel/QChatChannelViewModel.swift | 50 - .../QChatUpdateChannelViewModel.swift | 40 - .../Chat/Controller/QChatViewController.swift | 445 ------- .../Chat/Helper/QChatMessageHelper.swift | 35 - .../Chat/Model/QChatMessageFrame.swift | 119 -- .../View/Cell/QChatBaseTableViewCell.swift | 166 --- .../View/Cell/QChatImageTableViewCell.swift | 49 - .../View/Cell/QChatTextTableViewCell.swift | 92 -- .../View/Cell/QChatTimeTableViewCell.swift | 39 - .../View/QChatActivityIndicatorView.swift | 81 -- .../Classes/Chat/View/QChatInputView.swift | 80 -- .../Chat/ViewModel/QChatViewModel.swift | 310 ----- .../Classes/Common/QChatAuthManager.swift | 51 - .../Classes/Common/QChatConstantValue.swift | 31 - .../Classes/Common/QChatConstants.swift | 104 -- .../Classes/Extension/AlertVCExtention.swift | 17 - .../Classes/Extension/ColorExtension.swift | 32 - .../Classes/Extension/NEErrorExtension.swift | 15 - .../Extension/QChatImageExtension.swift | 25 - .../Extension/QChatStringExtension.swift | 43 - .../CreateServerViewController.swift | 86 -- .../JoinOtherServiceController.swift | 234 ---- .../Controller/MemberListViewController.swift | 154 --- .../MineCreateServerController.swift | 239 ---- .../Controller/QChatHomeViewController.swift | 378 ------ .../QChatHomePage/Model/AllChannelData.swift | 57 - .../Model/ServerMemberModel.swift | 15 - .../QChatHomePage/View/EmptyDataView.swift | 69 - .../QChatHomePage/View/InviteMemberView.swift | 60 - .../View/NECreateServerCell.swift | 108 -- .../View/NEGroupIdentityMemberCell.swift | 282 ---- .../View/NEHomeChannelCell.swift | 92 -- .../View/NEHomeChannelView.swift | 319 ----- .../QChatHomePage/View/NEHomeServerCell.swift | 120 -- .../QChatHomePage/View/NEMemberListCell.swift | 87 -- .../View/NESearchServerCell.swift | 236 ---- .../ViewModel/CreateServerViewModel.swift | 254 ---- .../ViewModel/MemberListViewModel.swift | 63 - .../Classes/Server/Model/IdGroupModel.swift | 30 - .../Server/Model/PermissionCellModel.swift | 15 - .../Server/Model/PermissionModel.swift | 108 -- .../Classes/Server/Model/SettingModel.swift | 13 - .../Classes/Server/Model/UserInfo.swift | 50 - .../Server/View/QChatDestructiveCell.swift | 46 - .../Classes/Server/View/QChatHeaderCell.swift | 69 - .../Server/View/QChatIdGroupCell.swift | 138 -- .../Server/View/QChatIdGroupMemberCell.swift | 98 -- .../Server/View/QChatIdGroupSelectCell.swift | 67 - .../View/QChatIdGroupSortButtonCell.swift | 78 -- .../Server/View/QChatIdGroupTopCell.swift | 30 - .../Server/View/QChatMemberManagerCell.swift | 26 - .../Server/View/QChatPlainTextArrowCell.swift | 27 - .../Server/View/QChatSelectedCell.swift | 92 -- .../Classes/Server/View/QChatSortCell.swift | 39 - .../Classes/Server/View/QChatSwitchCell.swift | 88 -- .../Server/View/QChatUserUnCheckCell.swift | 57 - .../QChatCreateGroupViewController.swift | 273 ---- .../QChatEditMemberViewController.swift | 398 ------ .../QChatIdGroupSortController.swift | 210 --- .../QChatIdGroupViewController.swift | 246 ---- .../QChatMemberManagerController.swift | 223 ---- .../QChatMemberSelectController.swift | 288 ---- .../QChatPermissionViewController.swift | 308 ----- .../QChatServerSettingViewController.swift | 494 ------- .../ViewModel/CreateGroupViewModel.swift | 103 -- .../ViewModel/EditMemberViewModel.swift | 231 ---- .../ViewModel/IdGroupSortViewModel.swift | 144 -- .../Server/ViewModel/IdGroupViewModel.swift | 99 -- .../ViewModel/MemberManagerViewModel.swift | 120 -- .../ViewModel/MemberSelectViewModel.swift | 144 -- .../ViewModel/PermissionViewModel.swift | 72 - .../Server/ViewModel/SettingViewModel.swift | 24 - .../NERtcCallUIKit.podspec | 41 +- .../NERtcCallUIKit}/Assets/.gitkeep | 0 .../NERtcCallUIKit.xcassets}/Contents.json | 0 .../avator.imageset}/Contents.json | 4 +- .../avator.imageset/avatar@2x.png | Bin 0 -> 2295 bytes .../avator.imageset/avatar@3x.png | Bin 0 -> 3542 bytes .../call_accept.imageset}/Contents.json | 4 +- .../\346\216\245\345\220\254@2x.png" | Bin 0 -> 3478 bytes .../\346\216\245\345\220\254@3x.png" | Bin 0 -> 5270 bytes .../call_camera_off.imageset/Contents.json | 22 + .../yx-tv-video-off-white@2x.png | Bin 0 -> 611 bytes .../yx-tv-video-off-white@3x.png | Bin 0 -> 851 bytes .../call_camera_on.imageset}/Contents.json | 4 +- .../call_camera_on.imageset/shooting@2x.png | Bin 0 -> 423 bytes .../call_camera_on.imageset/shooting@3x.png | Bin 0 -> 609 bytes .../call_cancel.imageset/Contents.json | 22 + .../\346\213\222\347\273\235@2x.png" | Bin 0 -> 5331 bytes .../\346\213\222\347\273\235@3x.png" | Bin 0 -> 8454 bytes .../call_speaker_off.imageset/Contents.json | 22 + ...46\211\254\345\243\260\345\231\250@2x.png" | Bin 0 -> 800 bytes ...46\211\254\345\243\260\345\231\250@3x.png" | Bin 0 -> 1132 bytes .../call_speaker_on.imageset}/Contents.json | 4 +- .../call_speaker_on.imageset/Group 361@2x.png | Bin 0 -> 701 bytes .../call_speaker_on.imageset/Group 361@3x.png | Bin 0 -> 1122 bytes .../call_switch_audio.imageset/Contents.json | 22 + ...6\215\242\350\257\255\351\237\2632@2x.png" | Bin 0 -> 812 bytes ...6\215\242\350\257\255\351\237\2632@3x.png" | Bin 0 -> 1213 bytes .../call_switch_camera.imageset/Contents.json | 22 + .../\347\277\273\350\275\254@2x.png" | Bin 0 -> 2719 bytes .../\347\277\273\350\275\254@3x.png" | Bin 0 -> 4183 bytes .../call_switch_video.imageset/Contents.json | 22 + ...6\215\242\350\247\206\351\242\2212@2x.png" | Bin 0 -> 684 bytes ...215\242\350\247\206\351\242\2212@3x-1.png" | Bin 0 -> 972 bytes .../call_voice_off.imageset/Contents.json | 22 + ...0\257\235\347\255\222-\345\205\263@2x.png" | Bin 0 -> 808 bytes ...0\257\235\347\255\222-\345\205\263@3x.png" | Bin 0 -> 1212 bytes .../call_voice_on.imageset}/Contents.json | 4 +- .../\347\274\226\347\273\204 8@2x.png" | Bin 0 -> 620 bytes .../\347\274\226\347\273\204 8@3x.png" | Bin 0 -> 935 bytes .../hangup.imageset}/Contents.json | 2 +- .../hangup.imageset/hangup@2x.png | Bin 0 -> 4553 bytes .../micro_phone.imageset/Contents.json | 22 + .../micro_phone.imageset/micro_phone@2x.png | Bin 0 -> 2691 bytes .../micro_phone.imageset/micro_phone@3x.png | Bin 0 -> 4365 bytes .../micro_phone_mute.imageset/Contents.json | 22 + .../micro_phone_mute@2x.png | Bin 0 -> 3289 bytes .../micro_phone_mute@3x.png | Bin 0 -> 5236 bytes .../speaker_off.imageset/Contents.json | 22 + .../speaker_off.imageset/speaker_off@2x.png | Bin 0 -> 3139 bytes .../speaker_off.imageset/speaker_off@3x.png | Bin 0 -> 4624 bytes .../speaker_on.imageset/Contents.json | 22 + .../speaker_on.imageset/speaker_on@2x.png | Bin 0 -> 2946 bytes .../speaker_on.imageset/speaker_on@3x.png | Bin 0 -> 4423 bytes .../switch_audio.imageset/Contents.json | 22 + .../switch_audio.imageset/switch_audio@2x.png | Bin 0 -> 3378 bytes .../switch_audio.imageset/switch_audio@3x.png | Bin 0 -> 5455 bytes .../switch_video.imageset/Contents.json | 22 + .../switch_video.imageset/switch_video@2x.png | Bin 0 -> 3059 bytes .../switch_video.imageset/switch_video@3x.png | Bin 0 -> 4983 bytes .../Assets/en.lproj/Localizable.strings | 37 + .../Assets/zh-Hans.lproj/Localizable.strings | 36 + .../NERtcCallUIKit}/Classes/.gitkeep | 0 .../Controller/NEAudioCallingController.h | 13 + .../Controller/NEAudioCallingController.m | 54 + .../Controller/NEAudioInCallController.h | 13 + .../Controller/NEAudioInCallController.m | 24 + .../Controller/NECallUIStateController.h | 83 ++ .../Controller/NECallUIStateController.m | 410 ++++++ .../Classes/Controller/NECallViewController.h | 36 + .../Classes/Controller/NECallViewController.m | 1183 +++++++++++++++++ .../Controller/NECalledViewController.h | 13 + .../Controller/NECalledViewController.m | 64 + .../Controller/NEVideoCallingController.h | 13 + .../Controller/NEVideoCallingController.m | 84 ++ .../Controller/NEVideoInCallController.h | 13 + .../Controller/NEVideoInCallController.m | 56 + .../Classes/Manager/NetManager.h | 17 + .../Classes/Manager/NetManager.m | 59 + .../Classes/Manager/SettingManager.h | 71 + .../Classes/Manager/SettingManager.m | 157 +++ .../Classes/Model/NECallParam.h | 32 + .../Classes/Model/NECallParam.m | 7 +- .../Classes/NERtcCallUIConfig.h | 46 + .../Classes/NERtcCallUIConfig.m | 20 + .../NERtcCallUIKit/Classes/NERtcCallUIKit.h | 57 + .../NERtcCallUIKit/Classes/NERtcCallUIKit.m | 230 ++++ .../Classes/View/NECustomButton.h | 15 + .../Classes/View/NECustomButton.m | 70 + .../Classes/View/NEExpandButton.h | 13 + .../Classes/View/NEExpandButton.m | 18 + .../Classes/View/NEVideoOperationView.h | 24 + .../Classes/View/NEVideoOperationView.m | 146 ++ .../NERtcCallUIKit/Classes/View/NEVideoView.h | 18 + .../NERtcCallUIKit/Classes/View/NEVideoView.m | 80 ++ NETeamUIKit/NETeamUIKit.podspec | 6 +- .../Assets/en.lproj/Localizable.strings | 3 +- .../Assets/zh-Hans.lproj/Localizable.strings | 3 +- .../Setting/Model/SettingCellModel.swift | 1 + .../Setting/TeamIntroduceViewController.swift | 33 +- .../Setting/TeamNameViewController.swift | 43 +- .../Setting/TeamSettingViewController.swift | 116 +- .../View/TeamSettingSubtitleCell.swift | 16 +- .../Setting/ViewModel/TeamInfoViewModel.swift | 3 +- .../ViewModel/TeamSettingViewModel.swift | 101 +- .../NETeamUIKit/Classes/TeamRouter.swift | 30 +- Podfile | 46 +- app.xcodeproj/project.pbxproj | 240 ++-- app/Main/AppDelegate.swift | 78 +- app/Main/NENavigationController.swift | 7 + app/Main/NETabBarController.swift | 21 +- app/{ => Main}/ViewController.swift | 0 .../InputPersonInfoController.swift | 42 +- .../IntroduceBrandViewController.swift | 10 +- app/Mine/Controller/MeViewController.swift | 7 +- .../MineSettingViewController.swift | 15 +- .../Controller/NENodeViewController.swift | 123 ++ .../Controller/PersonInfoViewController.swift | 26 +- app/Mine/View/BirthdayDatePickerView.swift | 5 + .../Mine/View/NEUserHeaderView.swift | 34 +- app/Mine/View/NodeSelectCell.swift | 67 + app/Mine/ViewModel/MineSettingViewModel.swift | 12 +- app/Mine/ViewModel/NodeViewModel.swift | 35 + app/Mine/ViewModel/PersonInfoViewModel.swift | 3 +- app/app-Bridging-Header.h | 2 + 524 files changed, 7571 insertions(+), 15352 deletions(-) create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample.xcodeproj/project.pbxproj create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample.xcworkspace/contents.xcworkspacedata create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatCornerCell.swift => IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/AppKey.h (58%) rename {NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets => IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AccentColor.colorset}/Contents.json (51%) create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/1024x1024.png create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/120x120-1.png create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/120x120.png create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/152x152.png create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/167x167.png create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/180x180.png create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/20x20.png create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/29x29.png create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/40x40-1.png create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/40x40-2.png create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/40x40.png create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/58x58-1.png create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/58x58.png create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/60x60.png create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/76x76.png create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/80x80-1.png create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/80x80.png create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/87x87.png create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/Contents.json rename {NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat => IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets}/Contents.json (100%) rename {NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/backArrow.imageset => IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/chat.imageset}/Contents.json (79%) create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/chat.imageset/chat@2x.png create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/chat.imageset/chat@3x.png create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/chatSelect.imageset/Contents.json create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/chatSelect.imageset/chatSelect@2x.png create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/chatSelect.imageset/chatSelect@3x.png rename {NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/emoji.imageset => IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/contact.imageset}/Contents.json (78%) create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/contact.imageset/contact@2x.png create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/contact.imageset/contact@3x.png create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/contactSelect.imageset/Contents.json create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/contactSelect.imageset/contactSelect@2x.png create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/contactSelect.imageset/contactSelect@3x.png create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/qchat_tabbar_icon.imageset/Contents.json create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/qchat_tabbar_icon.imageset/qchat_tabbar_icon@2x.png create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/qchat_tabbar_icon.imageset/qchat_tabbar_icon@3x.png create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Base.lproj/LaunchScreen.storyboard create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Base.lproj/Main.storyboard create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Info.plist create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/AppDelegate.h create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/AppDelegate.m create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/ConversationController+Test.h create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/ConversationController+Test.m create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/CustomRouterViewController.h create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/CustomRouterViewController.m create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/IMUIKitOCExample-Bridging-Header.h create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/NENavigationController.h create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/NENavigationController.m create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/NETabbarController.h create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/NETabbarController.m rename NEQChatUIKit/NEQChatUIKit/Classes/QChatRouter/QChatRouter.swift => IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/ViewController.h (66%) create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/ViewController.m create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/en-IN.lproj/Localizable.strings create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/en.lproj/Localizable.strings create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/zh-Hans.lproj/Localizable.strings create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/en-IN.lproj/LaunchScreen.strings create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/en-IN.lproj/Main.strings create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/main.m create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/zh-Hans.lproj/LaunchScreen.strings create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/zh-Hans.lproj/Main.strings create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExampleTests/IMUIKitOCExampleTests.m create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExampleUITests/IMUIKitOCExampleUITests.m create mode 100644 IMUIKitOC/IMUIKitOCExample/IMUIKitOCExampleUITests/IMUIKitOCExampleUITestsLaunchTests.m create mode 100644 IMUIKitOC/IMUIKitOCExample/Podfile rename {NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/mic.imageset => NEChatUIKit/NEChatUIKit/Assets/NEChatUIKit.xcassets/Commom/audio_record.imageset}/Contents.json (100%) create mode 100644 NEChatUIKit/NEChatUIKit/Assets/NEChatUIKit.xcassets/Commom/audio_record.imageset/Frame@2x.png create mode 100644 NEChatUIKit/NEChatUIKit/Assets/NEChatUIKit.xcassets/Commom/audio_record.imageset/Frame@3x.png rename {NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/camera.imageset => NEChatUIKit/NEChatUIKit/Assets/NEChatUIKit.xcassets/Commom/video_record.imageset}/Contents.json (100%) create mode 100644 NEChatUIKit/NEChatUIKit/Assets/NEChatUIKit.xcassets/Commom/video_record.imageset/Vector@2x.png create mode 100644 NEChatUIKit/NEChatUIKit/Assets/NEChatUIKit.xcassets/Commom/video_record.imageset/Vector@3x.png create mode 100644 NEChatUIKit/NEChatUIKit/Classes/Chat/Model/MessageCallRecordModel.swift create mode 100644 NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatCallRecordLeftCell.swift create mode 100644 NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatCallRecordRightCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/add.imageset/Frame@2x-4.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/add.imageset/Frame@3x-4.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/emoji.imageset/Frame@2x-1.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/emoji.imageset/Frame@3x-1.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/file.imageset/Frame@2x-3.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/file.imageset/Frame@3x-3.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/mic.imageset/Frame@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/mic.imageset/Frame@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/photo.imageset/Frame@2x-2.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/photo.imageset/Frame@3x-2.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/sendMessage_failed.imageset/sendMessage_failed.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/arrowDown.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/arrowDown.imageset/Frame 214@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/arrowDown.imageset/Frame 214@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/arrowRight.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/arrowRight.imageset/Vector 87@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/arrowRight.imageset/Vector 87@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/arrowUp.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/arrowUp.imageset/Frame 214@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/arrowUp.imageset/Frame 214@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/backArrow.imageset/back@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/backArrow.imageset/back@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/delete.imageset/Frame@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/delete.imageset/Frame@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/memberPlaceholder.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/memberPlaceholder.imageset/Frame 1016@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/memberPlaceholder.imageset/Frame 1016@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/rolePlaceholder.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/rolePlaceholder.imageset/Frame 1018@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/rolePlaceholder.imageset/Frame 1018@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/search.imageset/Frame@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/search.imageset/Frame@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/select.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/select.imageset/select@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/select.imageset/select@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/sign_add.imageset/Contents.json delete mode 100644 "NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/sign_add.imageset/\346\267\273\345\212\240@2x.png" delete mode 100644 "NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/sign_add.imageset/\346\267\273\345\212\240@3x.png" delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/unselect.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/unselect.imageset/unselect@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/unselect.imageset/unslect@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/addOther_icon.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/addOther_icon.imageset/addOther_icon@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/addOther_icon.imageset/addOther_icon@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/addService_icon.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/addService_icon.imageset/addService_icon@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/addService_icon.imageset/addService_icon@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/cell_arrow_icon.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/cell_arrow_icon.imageset/cell_arrow_icon@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/cell_arrow_icon.imageset/cell_arrow_icon@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/chat_message_receive.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/chat_message_receive.imageset/chat_message_receive@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/chat_message_receive.imageset/chat_message_receive@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/chat_message_send.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/chat_message_send.imageset/chat_message_send@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/chat_message_send.imageset/chat_message_send@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/home_addChannel.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/home_addChannel.imageset/home_addChannel@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/home_addChannel.imageset/home_addChannel@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/home_setupServer.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/home_setupServer.imageset/home_setupServer@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/home_setupServer.imageset/home_setupServer@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/mine_create.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/mine_create.imageset/mine_create@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/mine_create.imageset/mine_create@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/otherService_search_icon.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/otherService_search_icon.imageset/otherService_search_icon@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/otherService_search_icon.imageset/otherService_search_icon@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/uploadPic_bg_icon.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/uploadPic_bg_icon.imageset/uploadPic_bg_icon@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/uploadPic_bg_icon.imageset/uploadPic_bg_icon@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/upload_camera.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/upload_camera.imageset/upload_camera@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/upload_camera.imageset/upload_camera@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/camera.imageset/Vector@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/camera.imageset/Vector@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/count_header.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/count_header.imageset/Vector@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/count_header.imageset/Vector@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/dot_image.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/dot_image.imageset/Vector@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/dot_image.imageset/Vector@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/dot_image_disable.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/dot_image_disable.imageset/Vector@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/dot_image_disable.imageset/Vector@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/id_group_header.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/id_group_header.imageset/Group 389@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/id_group_header.imageset/Group 389@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/id_group_sort.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/id_group_sort.imageset/Vector@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/id_group_sort.imageset/Vector@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/invitemember_success.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/invitemember_success.imageset/invitemember_success@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/invitemember_success.imageset/invitemember_success@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/lock.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/lock.imageset/Vector@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/lock.imageset/Vector@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/member_header.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/member_header.imageset/Group 390@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/member_header.imageset/Group 390@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/searchServer_noMoreData.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/searchServer_noMoreData.imageset/channel_noMore@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/searchServer_noMoreData.imageset/channel_noMore@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/servers_noMore.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/servers_noMore.imageset/servers_noMore@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/servers_noMore.imageset/servers_noMore@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/Selection.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/Selection.imageset/Vector@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/Selection.imageset/Vector@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/Setting.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/Setting.imageset/Vector@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/Setting.imageset/Vector@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/allow.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/allow.imageset/Frame@2x-1.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/allow.imageset/Frame@3x-1.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/allowSeleted.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/allowSeleted.imageset/Frame@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/allowSeleted.imageset/Frame@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/bgImage.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/bgImage.imageset/image 86@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/bgImage.imageset/image 86@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/channel_member.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/channel_member.imageset/Frame@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/channel_member.imageset/Frame@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/channel_noMoreData.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/channel_noMoreData.imageset/channel_noMoreData@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/channel_noMoreData.imageset/channel_noMoreData@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/deny.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/deny.imageset/Frame@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/deny.imageset/Frame@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/denySelected.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/denySelected.imageset/Frame@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/denySelected.imageset/Frame@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/extend.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/extend.imageset/Frame@2x-2.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/extend.imageset/Frame@3x-2.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/extendSelected.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/extendSelected.imageset/Frame@2x-2.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/extendSelected.imageset/Frame@3x-2.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/server.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/server.imageset/Frame 245@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/server.imageset/Frame 245@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/server_menu.imageset/Contents.json delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/server_menu.imageset/Group 329@2x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/server_menu.imageset/Group 329@3x.png delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/en.lproj/Localizable.strings delete mode 100644 NEQChatUIKit/NEQChatUIKit/Assets/zh-Hans.lproj/Localizable.strings delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatBaseCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatCenterTextCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatImageTextCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatSectionView.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatStateCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatTextArrowCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatTextCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatUnfoldCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseViewController/QChatBaseViewController.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseViewController/QChatNavigationController.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseViewController/QChatTableViewController.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Channel/Model/QChatRoles.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Channel/Model/RoleStatusInfoExt.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/ChannelHeaderView.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/CornerButton.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/QChatImageTextOnlineCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/QChatMemberInfoView.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/QChatPermissionSettingCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/QChatTextEditCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/QChatTextSelectionCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatAddMemberVC.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatAddRoleGroupVC.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatChannelAuthoritySettingVC.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatChannelMembersVC.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatChannelSettingVC.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatChannelTypeVC.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatChannelViewController.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatGroupPermissionSettingVC.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatMemberPermissionSettingVC.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatSearchVC.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatWhiteBlackListVC.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewModel/QChatAuthoritySettingViewModel.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewModel/QChatChannelViewModel.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewModel/QChatUpdateChannelViewModel.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Chat/Controller/QChatViewController.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Chat/Helper/QChatMessageHelper.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Chat/Model/QChatMessageFrame.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Chat/View/Cell/QChatBaseTableViewCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Chat/View/Cell/QChatImageTableViewCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Chat/View/Cell/QChatTextTableViewCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Chat/View/Cell/QChatTimeTableViewCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Chat/View/QChatActivityIndicatorView.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Chat/View/QChatInputView.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Chat/ViewModel/QChatViewModel.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Common/QChatAuthManager.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Common/QChatConstantValue.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Common/QChatConstants.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Extension/AlertVCExtention.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Extension/ColorExtension.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Extension/NEErrorExtension.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Extension/QChatImageExtension.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Extension/QChatStringExtension.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Controller/CreateServerViewController.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Controller/JoinOtherServiceController.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Controller/MemberListViewController.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Controller/MineCreateServerController.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Controller/QChatHomeViewController.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Model/AllChannelData.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Model/ServerMemberModel.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/EmptyDataView.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/InviteMemberView.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NECreateServerCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NEGroupIdentityMemberCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NEHomeChannelCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NEHomeChannelView.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NEHomeServerCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NEMemberListCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NESearchServerCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/ViewModel/CreateServerViewModel.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/ViewModel/MemberListViewModel.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/Model/IdGroupModel.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/Model/PermissionCellModel.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/Model/PermissionModel.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/Model/SettingModel.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/Model/UserInfo.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatDestructiveCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatHeaderCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatIdGroupCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatIdGroupMemberCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatIdGroupSelectCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatIdGroupSortButtonCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatIdGroupTopCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatMemberManagerCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatPlainTextArrowCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatSelectedCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatSortCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatSwitchCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatUserUnCheckCell.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatCreateGroupViewController.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatEditMemberViewController.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatIdGroupSortController.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatIdGroupViewController.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatMemberManagerController.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatMemberSelectController.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatPermissionViewController.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatServerSettingViewController.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/CreateGroupViewModel.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/EditMemberViewModel.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/IdGroupSortViewModel.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/IdGroupViewModel.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/MemberManagerViewModel.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/MemberSelectViewModel.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/PermissionViewModel.swift delete mode 100644 NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/SettingViewModel.swift rename NEQChatUIKit/NEQChatUIKit.podspec => NERtcCallUIKit/NERtcCallUIKit.podspec (54%) rename {NEQChatUIKit/NEQChatUIKit => NERtcCallUIKit/NERtcCallUIKit}/Assets/.gitkeep (100%) rename {NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom => NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets}/Contents.json (100%) rename {NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/delete.imageset => NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/avator.imageset}/Contents.json (79%) create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/avator.imageset/avatar@2x.png create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/avator.imageset/avatar@3x.png rename {NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/search.imageset => NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_accept.imageset}/Contents.json (79%) create mode 100644 "NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_accept.imageset/\346\216\245\345\220\254@2x.png" create mode 100644 "NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_accept.imageset/\346\216\245\345\220\254@3x.png" create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_camera_off.imageset/Contents.json create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_camera_off.imageset/yx-tv-video-off-white@2x.png create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_camera_off.imageset/yx-tv-video-off-white@3x.png rename {NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/add.imageset => NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_camera_on.imageset}/Contents.json (78%) create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_camera_on.imageset/shooting@2x.png create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_camera_on.imageset/shooting@3x.png create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_cancel.imageset/Contents.json create mode 100644 "NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_cancel.imageset/\346\213\222\347\273\235@2x.png" create mode 100644 "NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_cancel.imageset/\346\213\222\347\273\235@3x.png" create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_speaker_off.imageset/Contents.json create mode 100644 "NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_speaker_off.imageset/\345\205\263\351\227\255\346\211\254\345\243\260\345\231\250@2x.png" create mode 100644 "NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_speaker_off.imageset/\345\205\263\351\227\255\346\211\254\345\243\260\345\231\250@3x.png" rename {NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/photo.imageset => NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_speaker_on.imageset}/Contents.json (77%) create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_speaker_on.imageset/Group 361@2x.png create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_speaker_on.imageset/Group 361@3x.png create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_switch_audio.imageset/Contents.json create mode 100644 "NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_switch_audio.imageset/\345\210\207\346\215\242\350\257\255\351\237\2632@2x.png" create mode 100644 "NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_switch_audio.imageset/\345\210\207\346\215\242\350\257\255\351\237\2632@3x.png" create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_switch_camera.imageset/Contents.json create mode 100644 "NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_switch_camera.imageset/\347\277\273\350\275\254@2x.png" create mode 100644 "NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_switch_camera.imageset/\347\277\273\350\275\254@3x.png" create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_switch_video.imageset/Contents.json create mode 100644 "NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_switch_video.imageset/\345\210\207\346\215\242\350\247\206\351\242\2212@2x.png" create mode 100644 "NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_switch_video.imageset/\345\210\207\346\215\242\350\247\206\351\242\2212@3x-1.png" create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_voice_off.imageset/Contents.json create mode 100644 "NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_voice_off.imageset/\350\257\235\347\255\222-\345\205\263@2x.png" create mode 100644 "NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_voice_off.imageset/\350\257\235\347\255\222-\345\205\263@3x.png" rename {NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/file.imageset => NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_voice_on.imageset}/Contents.json (78%) create mode 100644 "NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_voice_on.imageset/\347\274\226\347\273\204 8@2x.png" create mode 100644 "NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_voice_on.imageset/\347\274\226\347\273\204 8@3x.png" rename {NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/sendMessage_failed.imageset => NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/hangup.imageset}/Contents.json (85%) create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/hangup.imageset/hangup@2x.png create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/micro_phone.imageset/Contents.json create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/micro_phone.imageset/micro_phone@2x.png create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/micro_phone.imageset/micro_phone@3x.png create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/micro_phone_mute.imageset/Contents.json create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/micro_phone_mute.imageset/micro_phone_mute@2x.png create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/micro_phone_mute.imageset/micro_phone_mute@3x.png create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/speaker_off.imageset/Contents.json create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/speaker_off.imageset/speaker_off@2x.png create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/speaker_off.imageset/speaker_off@3x.png create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/speaker_on.imageset/Contents.json create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/speaker_on.imageset/speaker_on@2x.png create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/speaker_on.imageset/speaker_on@3x.png create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/switch_audio.imageset/Contents.json create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/switch_audio.imageset/switch_audio@2x.png create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/switch_audio.imageset/switch_audio@3x.png create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/switch_video.imageset/Contents.json create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/switch_video.imageset/switch_video@2x.png create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/switch_video.imageset/switch_video@3x.png create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/en.lproj/Localizable.strings create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Assets/zh-Hans.lproj/Localizable.strings rename {NEQChatUIKit/NEQChatUIKit => NERtcCallUIKit/NERtcCallUIKit}/Classes/.gitkeep (100%) create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEAudioCallingController.h create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEAudioCallingController.m create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEAudioInCallController.h create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEAudioInCallController.m create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NECallUIStateController.h create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NECallUIStateController.m create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NECallViewController.h create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NECallViewController.m create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NECalledViewController.h create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NECalledViewController.m create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEVideoCallingController.h create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEVideoCallingController.m create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEVideoInCallController.h create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEVideoInCallController.m create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/Manager/NetManager.h create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/Manager/NetManager.m create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/Manager/SettingManager.h create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/Manager/SettingManager.m create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/Model/NECallParam.h rename NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatBaseCollectionViewCell.swift => NERtcCallUIKit/NERtcCallUIKit/Classes/Model/NECallParam.m (68%) create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/NERtcCallUIConfig.h create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/NERtcCallUIConfig.m create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/NERtcCallUIKit.h create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/NERtcCallUIKit.m create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/View/NECustomButton.h create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/View/NECustomButton.m create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/View/NEExpandButton.h create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/View/NEExpandButton.m create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/View/NEVideoOperationView.h create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/View/NEVideoOperationView.m create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/View/NEVideoView.h create mode 100644 NERtcCallUIKit/NERtcCallUIKit/Classes/View/NEVideoView.m rename app/{ => Main}/ViewController.swift (100%) create mode 100644 app/Mine/Controller/NENodeViewController.swift rename NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatHeaderView.swift => app/Mine/View/NEUserHeaderView.swift (50%) create mode 100644 app/Mine/View/NodeSelectCell.swift create mode 100644 app/Mine/ViewModel/NodeViewModel.swift create mode 100644 app/app-Bridging-Header.h diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample.xcodeproj/project.pbxproj b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample.xcodeproj/project.pbxproj new file mode 100644 index 00000000..28c16230 --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample.xcodeproj/project.pbxproj @@ -0,0 +1,753 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 55; + objects = { + +/* Begin PBXBuildFile section */ + 39A2F20E28D9B2C400DDCAF2 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 39A2F20D28D9B2C400DDCAF2 /* AppDelegate.m */; }; + 39A2F21428D9B2C400DDCAF2 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 39A2F21328D9B2C400DDCAF2 /* ViewController.m */; }; + 39A2F21728D9B2C400DDCAF2 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 39A2F21528D9B2C400DDCAF2 /* Main.storyboard */; }; + 39A2F21928D9B2C500DDCAF2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 39A2F21828D9B2C500DDCAF2 /* Assets.xcassets */; }; + 39A2F21C28D9B2C500DDCAF2 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 39A2F21A28D9B2C500DDCAF2 /* LaunchScreen.storyboard */; }; + 39A2F21F28D9B2C500DDCAF2 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 39A2F21E28D9B2C500DDCAF2 /* main.m */; }; + 39A2F22928D9B2C600DDCAF2 /* IMUIKitOCExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 39A2F22828D9B2C600DDCAF2 /* IMUIKitOCExampleTests.m */; }; + 39A2F23328D9B2C600DDCAF2 /* IMUIKitOCExampleUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 39A2F23228D9B2C600DDCAF2 /* IMUIKitOCExampleUITests.m */; }; + 39A2F23528D9B2C600DDCAF2 /* IMUIKitOCExampleUITestsLaunchTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 39A2F23428D9B2C600DDCAF2 /* IMUIKitOCExampleUITestsLaunchTests.m */; }; + 39A2F24728DABC1700DDCAF2 /* NETabbarController.m in Sources */ = {isa = PBXBuildFile; fileRef = 39A2F24628DABC1700DDCAF2 /* NETabbarController.m */; }; + 39A2F24B28DABC6700DDCAF2 /* NENavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 39A2F24A28DABC6700DDCAF2 /* NENavigationController.m */; }; + 39EBBACA1D04C27BC1E3AEC9 /* Pods_IMUIKitOCExample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9F8E39DDEB8C36F0E96A1333 /* Pods_IMUIKitOCExample.framework */; }; + 39ED7B1E290FA9C700CAE608 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 39ED7B20290FA9C700CAE608 /* Localizable.strings */; }; + DD774A7729485F6600347A9E /* CustomRouterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DD774A7629485F6600347A9E /* CustomRouterViewController.m */; }; + DDC1AC8929651B6C008C085A /* ConversationController+Test.m in Sources */ = {isa = PBXBuildFile; fileRef = DDC1AC8829651B6C008C085A /* ConversationController+Test.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 39A2F22528D9B2C600DDCAF2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 39A2F20128D9B2C400DDCAF2 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 39A2F20828D9B2C400DDCAF2; + remoteInfo = IMUIKitOCExample; + }; + 39A2F22F28D9B2C600DDCAF2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 39A2F20128D9B2C400DDCAF2 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 39A2F20828D9B2C400DDCAF2; + remoteInfo = IMUIKitOCExample; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 147F8282453DD1C889BE79CA /* Pods-IMUIKitOCExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-IMUIKitOCExample.release.xcconfig"; path = "Target Support Files/Pods-IMUIKitOCExample/Pods-IMUIKitOCExample.release.xcconfig"; sourceTree = ""; }; + 39A2F20928D9B2C400DDCAF2 /* IMUIKitOCExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = IMUIKitOCExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 39A2F20C28D9B2C400DDCAF2 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 39A2F20D28D9B2C400DDCAF2 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 39A2F21228D9B2C400DDCAF2 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; + 39A2F21328D9B2C400DDCAF2 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + 39A2F21628D9B2C400DDCAF2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 39A2F21828D9B2C500DDCAF2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 39A2F21B28D9B2C500DDCAF2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 39A2F21D28D9B2C500DDCAF2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 39A2F21E28D9B2C500DDCAF2 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 39A2F22428D9B2C600DDCAF2 /* IMUIKitOCExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = IMUIKitOCExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 39A2F22828D9B2C600DDCAF2 /* IMUIKitOCExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IMUIKitOCExampleTests.m; sourceTree = ""; }; + 39A2F22E28D9B2C600DDCAF2 /* IMUIKitOCExampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = IMUIKitOCExampleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 39A2F23228D9B2C600DDCAF2 /* IMUIKitOCExampleUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IMUIKitOCExampleUITests.m; sourceTree = ""; }; + 39A2F23428D9B2C600DDCAF2 /* IMUIKitOCExampleUITestsLaunchTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IMUIKitOCExampleUITestsLaunchTests.m; sourceTree = ""; }; + 39A2F24428DAAC1500DDCAF2 /* AppKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppKey.h; sourceTree = ""; }; + 39A2F24528DABC1700DDCAF2 /* NETabbarController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NETabbarController.h; sourceTree = ""; }; + 39A2F24628DABC1700DDCAF2 /* NETabbarController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NETabbarController.m; sourceTree = ""; }; + 39A2F24928DABC6700DDCAF2 /* NENavigationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NENavigationController.h; sourceTree = ""; }; + 39A2F24A28DABC6700DDCAF2 /* NENavigationController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NENavigationController.m; sourceTree = ""; }; + 39ED7B1F290FA9C700CAE608 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + 39ED7B24290FAA6E00CAE608 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Main.strings"; sourceTree = ""; }; + 39ED7B25290FAA6E00CAE608 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/LaunchScreen.strings"; sourceTree = ""; }; + 39ED7B26290FAA6E00CAE608 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; + 9F8E39DDEB8C36F0E96A1333 /* Pods_IMUIKitOCExample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_IMUIKitOCExample.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + DD774A7529485F6600347A9E /* CustomRouterViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CustomRouterViewController.h; sourceTree = ""; }; + DD774A7629485F6600347A9E /* CustomRouterViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CustomRouterViewController.m; sourceTree = ""; }; + DDC1AC8729651B6C008C085A /* ConversationController+Test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ConversationController+Test.h"; sourceTree = ""; }; + DDC1AC8829651B6C008C085A /* ConversationController+Test.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ConversationController+Test.m"; sourceTree = ""; }; + DDF443AC294851D90077184F /* IMUIKitOCExample-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "IMUIKitOCExample-Bridging-Header.h"; sourceTree = ""; }; + F984299B79B347145EA4AF84 /* Pods-IMUIKitOCExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-IMUIKitOCExample.debug.xcconfig"; path = "Target Support Files/Pods-IMUIKitOCExample/Pods-IMUIKitOCExample.debug.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 39A2F20628D9B2C400DDCAF2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 39EBBACA1D04C27BC1E3AEC9 /* Pods_IMUIKitOCExample.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 39A2F22128D9B2C600DDCAF2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 39A2F22B28D9B2C600DDCAF2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 0BEF3C37E3BB9E3AE318BAB8 /* Pods */ = { + isa = PBXGroup; + children = ( + F984299B79B347145EA4AF84 /* Pods-IMUIKitOCExample.debug.xcconfig */, + 147F8282453DD1C889BE79CA /* Pods-IMUIKitOCExample.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + 39A2F20028D9B2C400DDCAF2 = { + isa = PBXGroup; + children = ( + 39A2F20B28D9B2C400DDCAF2 /* IMUIKitOCExample */, + 39A2F22728D9B2C600DDCAF2 /* IMUIKitOCExampleTests */, + 39A2F23128D9B2C600DDCAF2 /* IMUIKitOCExampleUITests */, + 39A2F20A28D9B2C400DDCAF2 /* Products */, + 0BEF3C37E3BB9E3AE318BAB8 /* Pods */, + 6B7A97EA6BE0B274CD63D9AC /* Frameworks */, + ); + sourceTree = ""; + }; + 39A2F20A28D9B2C400DDCAF2 /* Products */ = { + isa = PBXGroup; + children = ( + 39A2F20928D9B2C400DDCAF2 /* IMUIKitOCExample.app */, + 39A2F22428D9B2C600DDCAF2 /* IMUIKitOCExampleTests.xctest */, + 39A2F22E28D9B2C600DDCAF2 /* IMUIKitOCExampleUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 39A2F20B28D9B2C400DDCAF2 /* IMUIKitOCExample */ = { + isa = PBXGroup; + children = ( + 39A2F24828DABC2B00DDCAF2 /* Main */, + 39A2F24428DAAC1500DDCAF2 /* AppKey.h */, + 39A2F21528D9B2C400DDCAF2 /* Main.storyboard */, + 39A2F21828D9B2C500DDCAF2 /* Assets.xcassets */, + 39A2F21A28D9B2C500DDCAF2 /* LaunchScreen.storyboard */, + 39A2F21D28D9B2C500DDCAF2 /* Info.plist */, + 39A2F21E28D9B2C500DDCAF2 /* main.m */, + ); + path = IMUIKitOCExample; + sourceTree = ""; + }; + 39A2F22728D9B2C600DDCAF2 /* IMUIKitOCExampleTests */ = { + isa = PBXGroup; + children = ( + 39A2F22828D9B2C600DDCAF2 /* IMUIKitOCExampleTests.m */, + ); + path = IMUIKitOCExampleTests; + sourceTree = ""; + }; + 39A2F23128D9B2C600DDCAF2 /* IMUIKitOCExampleUITests */ = { + isa = PBXGroup; + children = ( + 39A2F23228D9B2C600DDCAF2 /* IMUIKitOCExampleUITests.m */, + 39A2F23428D9B2C600DDCAF2 /* IMUIKitOCExampleUITestsLaunchTests.m */, + ); + path = IMUIKitOCExampleUITests; + sourceTree = ""; + }; + 39A2F24828DABC2B00DDCAF2 /* Main */ = { + isa = PBXGroup; + children = ( + 39A2F20C28D9B2C400DDCAF2 /* AppDelegate.h */, + 39A2F20D28D9B2C400DDCAF2 /* AppDelegate.m */, + 39A2F24528DABC1700DDCAF2 /* NETabbarController.h */, + 39A2F24628DABC1700DDCAF2 /* NETabbarController.m */, + 39A2F24928DABC6700DDCAF2 /* NENavigationController.h */, + 39A2F24A28DABC6700DDCAF2 /* NENavigationController.m */, + 39A2F21228D9B2C400DDCAF2 /* ViewController.h */, + 39A2F21328D9B2C400DDCAF2 /* ViewController.m */, + DD774A7529485F6600347A9E /* CustomRouterViewController.h */, + DD774A7629485F6600347A9E /* CustomRouterViewController.m */, + DDC1AC8729651B6C008C085A /* ConversationController+Test.h */, + DDC1AC8829651B6C008C085A /* ConversationController+Test.m */, + 39ED7B20290FA9C700CAE608 /* Localizable.strings */, + DDF443AC294851D90077184F /* IMUIKitOCExample-Bridging-Header.h */, + ); + path = Main; + sourceTree = ""; + }; + 6B7A97EA6BE0B274CD63D9AC /* Frameworks */ = { + isa = PBXGroup; + children = ( + 9F8E39DDEB8C36F0E96A1333 /* Pods_IMUIKitOCExample.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 39A2F20828D9B2C400DDCAF2 /* IMUIKitOCExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 39A2F23828D9B2C600DDCAF2 /* Build configuration list for PBXNativeTarget "IMUIKitOCExample" */; + buildPhases = ( + CDCC4CE4D4082A1DA0D5A888 /* [CP] Check Pods Manifest.lock */, + 39A2F20528D9B2C400DDCAF2 /* Sources */, + 39A2F20628D9B2C400DDCAF2 /* Frameworks */, + 39A2F20728D9B2C400DDCAF2 /* Resources */, + DB787379DE2DF44860C11CF1 /* [CP] Embed Pods Frameworks */, + 8F14E37FD20AEF03EA4142FE /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = IMUIKitOCExample; + productName = IMUIKitOCExample; + productReference = 39A2F20928D9B2C400DDCAF2 /* IMUIKitOCExample.app */; + productType = "com.apple.product-type.application"; + }; + 39A2F22328D9B2C600DDCAF2 /* IMUIKitOCExampleTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 39A2F23B28D9B2C600DDCAF2 /* Build configuration list for PBXNativeTarget "IMUIKitOCExampleTests" */; + buildPhases = ( + 39A2F22028D9B2C600DDCAF2 /* Sources */, + 39A2F22128D9B2C600DDCAF2 /* Frameworks */, + 39A2F22228D9B2C600DDCAF2 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 39A2F22628D9B2C600DDCAF2 /* PBXTargetDependency */, + ); + name = IMUIKitOCExampleTests; + productName = IMUIKitOCExampleTests; + productReference = 39A2F22428D9B2C600DDCAF2 /* IMUIKitOCExampleTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 39A2F22D28D9B2C600DDCAF2 /* IMUIKitOCExampleUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 39A2F23E28D9B2C600DDCAF2 /* Build configuration list for PBXNativeTarget "IMUIKitOCExampleUITests" */; + buildPhases = ( + 39A2F22A28D9B2C600DDCAF2 /* Sources */, + 39A2F22B28D9B2C600DDCAF2 /* Frameworks */, + 39A2F22C28D9B2C600DDCAF2 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 39A2F23028D9B2C600DDCAF2 /* PBXTargetDependency */, + ); + name = IMUIKitOCExampleUITests; + productName = IMUIKitOCExampleUITests; + productReference = 39A2F22E28D9B2C600DDCAF2 /* IMUIKitOCExampleUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 39A2F20128D9B2C400DDCAF2 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastUpgradeCheck = 1330; + TargetAttributes = { + 39A2F20828D9B2C400DDCAF2 = { + CreatedOnToolsVersion = 13.3.1; + LastSwiftMigration = 1410; + }; + 39A2F22328D9B2C600DDCAF2 = { + CreatedOnToolsVersion = 13.3.1; + TestTargetID = 39A2F20828D9B2C400DDCAF2; + }; + 39A2F22D28D9B2C600DDCAF2 = { + CreatedOnToolsVersion = 13.3.1; + TestTargetID = 39A2F20828D9B2C400DDCAF2; + }; + }; + }; + buildConfigurationList = 39A2F20428D9B2C400DDCAF2 /* Build configuration list for PBXProject "IMUIKitOCExample" */; + compatibilityVersion = "Xcode 13.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + "zh-Hans", + ); + mainGroup = 39A2F20028D9B2C400DDCAF2; + productRefGroup = 39A2F20A28D9B2C400DDCAF2 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 39A2F20828D9B2C400DDCAF2 /* IMUIKitOCExample */, + 39A2F22328D9B2C600DDCAF2 /* IMUIKitOCExampleTests */, + 39A2F22D28D9B2C600DDCAF2 /* IMUIKitOCExampleUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 39A2F20728D9B2C400DDCAF2 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 39A2F21C28D9B2C500DDCAF2 /* LaunchScreen.storyboard in Resources */, + 39ED7B1E290FA9C700CAE608 /* Localizable.strings in Resources */, + 39A2F21928D9B2C500DDCAF2 /* Assets.xcassets in Resources */, + 39A2F21728D9B2C400DDCAF2 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 39A2F22228D9B2C600DDCAF2 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 39A2F22C28D9B2C600DDCAF2 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 8F14E37FD20AEF03EA4142FE /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-IMUIKitOCExample/Pods-IMUIKitOCExample-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-IMUIKitOCExample/Pods-IMUIKitOCExample-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-IMUIKitOCExample/Pods-IMUIKitOCExample-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + CDCC4CE4D4082A1DA0D5A888 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-IMUIKitOCExample-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + DB787379DE2DF44860C11CF1 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-IMUIKitOCExample/Pods-IMUIKitOCExample-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-IMUIKitOCExample/Pods-IMUIKitOCExample-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-IMUIKitOCExample/Pods-IMUIKitOCExample-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 39A2F20528D9B2C400DDCAF2 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 39A2F21428D9B2C400DDCAF2 /* ViewController.m in Sources */, + 39A2F20E28D9B2C400DDCAF2 /* AppDelegate.m in Sources */, + DDC1AC8929651B6C008C085A /* ConversationController+Test.m in Sources */, + 39A2F24B28DABC6700DDCAF2 /* NENavigationController.m in Sources */, + 39A2F24728DABC1700DDCAF2 /* NETabbarController.m in Sources */, + 39A2F21F28D9B2C500DDCAF2 /* main.m in Sources */, + DD774A7729485F6600347A9E /* CustomRouterViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 39A2F22028D9B2C600DDCAF2 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 39A2F22928D9B2C600DDCAF2 /* IMUIKitOCExampleTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 39A2F22A28D9B2C600DDCAF2 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 39A2F23528D9B2C600DDCAF2 /* IMUIKitOCExampleUITestsLaunchTests.m in Sources */, + 39A2F23328D9B2C600DDCAF2 /* IMUIKitOCExampleUITests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 39A2F22628D9B2C600DDCAF2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 39A2F20828D9B2C400DDCAF2 /* IMUIKitOCExample */; + targetProxy = 39A2F22528D9B2C600DDCAF2 /* PBXContainerItemProxy */; + }; + 39A2F23028D9B2C600DDCAF2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 39A2F20828D9B2C400DDCAF2 /* IMUIKitOCExample */; + targetProxy = 39A2F22F28D9B2C600DDCAF2 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 39A2F21528D9B2C400DDCAF2 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 39A2F21628D9B2C400DDCAF2 /* Base */, + 39ED7B24290FAA6E00CAE608 /* zh-Hans */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 39A2F21A28D9B2C500DDCAF2 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 39A2F21B28D9B2C500DDCAF2 /* Base */, + 39ED7B25290FAA6E00CAE608 /* zh-Hans */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; + 39ED7B20290FA9C700CAE608 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 39ED7B1F290FA9C700CAE608 /* en */, + 39ED7B26290FAA6E00CAE608 /* zh-Hans */, + ); + name = Localizable.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 39A2F23628D9B2C600DDCAF2 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 39A2F23728D9B2C600DDCAF2 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 39A2F23928D9B2C600DDCAF2 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F984299B79B347145EA4AF84 /* Pods-IMUIKitOCExample.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + BUILD_LIBRARY_FOR_DISTRIBUTION = NO; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = 569GNZ5392; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = IMUIKitOCExample/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = "云信IM OC"; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 9.2.9; + PRODUCT_BUNDLE_IDENTIFIER = com.netease.yunxin.app.im; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_BRIDGING_HEADER = "IMUIKitOCExample/Main/IMUIKitOCExample-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Debug; + }; + 39A2F23A28D9B2C600DDCAF2 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 147F8282453DD1C889BE79CA /* Pods-IMUIKitOCExample.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + BUILD_LIBRARY_FOR_DISTRIBUTION = NO; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = 569GNZ5392; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = IMUIKitOCExample/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = "云信IM OC"; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 9.2.9; + PRODUCT_BUNDLE_IDENTIFIER = com.netease.yunxin.app.im; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_BRIDGING_HEADER = "IMUIKitOCExample/Main/IMUIKitOCExample-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Release; + }; + 39A2F23C28D9B2C600DDCAF2 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.4; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.yunbite.cn.IMUIKitOCExampleTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/IMUIKitOCExample.app/IMUIKitOCExample"; + }; + name = Debug; + }; + 39A2F23D28D9B2C600DDCAF2 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.4; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.yunbite.cn.IMUIKitOCExampleTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/IMUIKitOCExample.app/IMUIKitOCExample"; + }; + name = Release; + }; + 39A2F23F28D9B2C600DDCAF2 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.yunbite.cn.IMUIKitOCExampleUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = IMUIKitOCExample; + }; + name = Debug; + }; + 39A2F24028D9B2C600DDCAF2 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.yunbite.cn.IMUIKitOCExampleUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = IMUIKitOCExample; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 39A2F20428D9B2C400DDCAF2 /* Build configuration list for PBXProject "IMUIKitOCExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 39A2F23628D9B2C600DDCAF2 /* Debug */, + 39A2F23728D9B2C600DDCAF2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 39A2F23828D9B2C600DDCAF2 /* Build configuration list for PBXNativeTarget "IMUIKitOCExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 39A2F23928D9B2C600DDCAF2 /* Debug */, + 39A2F23A28D9B2C600DDCAF2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 39A2F23B28D9B2C600DDCAF2 /* Build configuration list for PBXNativeTarget "IMUIKitOCExampleTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 39A2F23C28D9B2C600DDCAF2 /* Debug */, + 39A2F23D28D9B2C600DDCAF2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 39A2F23E28D9B2C600DDCAF2 /* Build configuration list for PBXNativeTarget "IMUIKitOCExampleUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 39A2F23F28D9B2C600DDCAF2 /* Debug */, + 39A2F24028D9B2C600DDCAF2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 39A2F20128D9B2C400DDCAF2 /* Project object */; +} diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..919434a6 --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample.xcworkspace/contents.xcworkspacedata b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..8be4f694 --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatCornerCell.swift b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/AppKey.h similarity index 58% rename from NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatCornerCell.swift rename to IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/AppKey.h index a83319a7..5e105323 100644 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatCornerCell.swift +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/AppKey.h @@ -3,8 +3,10 @@ // Use of this source code is governed by a MIT license that can be // found in the LICENSE file. -// this cell has rounding corner style -import UIKit -import NECommonUIKit +#ifndef AppKey_h +#define AppKey_h -class QChatCornerCell: CornerCell {} +/// IM key +static NSString *const AppKey = @""; + +#endif /* AppKey_h */ diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Contents.json b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 51% rename from NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Contents.json rename to IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AccentColor.colorset/Contents.json index 73c00596..eb878970 100644 --- a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Contents.json +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AccentColor.colorset/Contents.json @@ -1,4 +1,9 @@ { + "colors" : [ + { + "idiom" : "universal" + } + ], "info" : { "author" : "xcode", "version" : 1 diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/1024x1024.png b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/1024x1024.png new file mode 100644 index 0000000000000000000000000000000000000000..dbc0b4f68a5f286339789d885fa930c187a9aded GIT binary patch literal 151982 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 rA*jfm_+53(bX{hi!Y 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 QhyVZp07*qoM6N<$g05xpw*UYD literal 0 HcmV?d00001 diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/180x180.png b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/180x180.png new file mode 100644 index 0000000000000000000000000000000000000000..ac60d3d9aa982e764c6728f7ae79fda33e68d975 GIT binary patch literal 9826 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 QPyhe`07*qoM6N<$g4W36ZvX%Q literal 0 HcmV?d00001 diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/40x40-1.png b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/40x40-1.png new file mode 100644 index 0000000000000000000000000000000000000000..b3cff5b70597209f0ccf01f6bb3638e6f1f9a8f3 GIT binary patch literal 1495 zcmV;|1t|K7P)D)L}Vw4hIFThj*(t#1`G6zK9X$8+wzv%|7L!4;O19PV)E&Yj=<&$;K$ zj>04(qGWCg*mtpKv8Q2vEx_KwUZs?(oN*+><*|2A?5sl=rh_Y_#bbpomvWWk<|`~N zdx%3`?*evU{&Q`v*2%uj$8gVL@xh6uu^0IGPazhsX~3+>y|1+c8#yDl`hkj0#L_aA zESZTt$1ee|w({yxlAC4~)#U;?>k$+4P3}0$fanLDJ_fXHV>e=EOD1=0j5AQKiGr!i z5i^TW@L)Eu$!F9P-@X>un}L{FL=L*vc-geMcVSl6Hx4Al&2WCqv`I@aH=`)6D@gQc zJ5l0y#*cJIj(Oz*(W=jh5bSeIizL$?JG9bnEa?EGd(BgSF<@VA_wSIn3%s`(#lF zbdSAW=b^HS65em6o8A8AfcabplYAba4!7KBDM77dXGrHVg@qSZMJ4e3KQXKmBu_y* zSIZxqCS6eiioKW>p5XA2R!`ut(yBUOl+(Ewlu#4r8|l(QLz0W49BBnZi-!G;FDZJ! z;(LvXAq5jeJp-rW`FI7Z(q~k39kx|*wy)Q=BjFEQ&vi5~93^1V3eLrBGpSm|K&wq? zT?IwWR4(92U`P(7s22+PIGLPd6>~Ru%8^YKIWB9M`o7nCoY?`2?R(JdwQ8-WoCz~& zf1P)Ry>}~5y`Zn+g#GUhXgIMsz5Jvm@=L(& z3N?JO8dqlXXLSy2^`7(4PKAeCNcX#YaNz?gbY3EH^eKgcOrY{>-p_l8`xG)$%z07n z*Y5Gq_-Wr}X0p;t4w`r&B>NOzxI-aljS4$o)yUo;i;HtFUE$^Y+0A?8V z<_&S$1=?Cb09#@K=x-ZA`A0)2ej;AO3Dm$4p}b_ZE;Rzrb)ZE;d=; zTb63L-FYie@?<>TIX#RmDdy*)SUykAwlPG(}i|5113TFxSp~Goo98EGh5D)ql)6rJN$&x&z64Cp>|9vZ>%E z+NzZXMO1X0@uKF6^_5|O7BbI5rs01yxoOc`ebd5u_eZBF*L3XGdbdwaJy5GDA2#LN xVKSnGo4mh9LQxAZh%?KU#nsloy(a7z^S=)Pes6-frLzD4002ovPDHLkV1l+g(Eb1b literal 0 HcmV?d00001 diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/40x40-2.png b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/40x40-2.png new file mode 100644 index 0000000000000000000000000000000000000000..b3cff5b70597209f0ccf01f6bb3638e6f1f9a8f3 GIT binary patch literal 1495 zcmV;|1t|K7P)D)L}Vw4hIFThj*(t#1`G6zK9X$8+wzv%|7L!4;O19PV)E&Yj=<&$;K$ zj>04(qGWCg*mtpKv8Q2vEx_KwUZs?(oN*+><*|2A?5sl=rh_Y_#bbpomvWWk<|`~N zdx%3`?*evU{&Q`v*2%uj$8gVL@xh6uu^0IGPazhsX~3+>y|1+c8#yDl`hkj0#L_aA zESZTt$1ee|w({yxlAC4~)#U;?>k$+4P3}0$fanLDJ_fXHV>e=EOD1=0j5AQKiGr!i z5i^TW@L)Eu$!F9P-@X>un}L{FL=L*vc-geMcVSl6Hx4Al&2WCqv`I@aH=`)6D@gQc zJ5l0y#*cJIj(Oz*(W=jh5bSeIizL$?JG9bnEa?EGd(BgSF<@VA_wSIn3%s`(#lF zbdSAW=b^HS65em6o8A8AfcabplYAba4!7KBDM77dXGrHVg@qSZMJ4e3KQXKmBu_y* zSIZxqCS6eiioKW>p5XA2R!`ut(yBUOl+(Ewlu#4r8|l(QLz0W49BBnZi-!G;FDZJ! z;(LvXAq5jeJp-rW`FI7Z(q~k39kx|*wy)Q=BjFEQ&vi5~93^1V3eLrBGpSm|K&wq? zT?IwWR4(92U`P(7s22+PIGLPd6>~Ru%8^YKIWB9M`o7nCoY?`2?R(JdwQ8-WoCz~& zf1P)Ry>}~5y`Zn+g#GUhXgIMsz5Jvm@=L(& z3N?JO8dqlXXLSy2^`7(4PKAeCNcX#YaNz?gbY3EH^eKgcOrY{>-p_l8`xG)$%z07n z*Y5Gq_-Wr}X0p;t4w`r&B>NOzxI-aljS4$o)yUo;i;HtFUE$^Y+0A?8V z<_&S$1=?Cb09#@K=x-ZA`A0)2ej;AO3Dm$4p}b_ZE;Rzrb)ZE;d=; zTb63L-FYie@?<>TIX#RmDdy*)SUykAwlPG(}i|5113TFxSp~Goo98EGh5D)ql)6rJN$&x&z64Cp>|9vZ>%E z+NzZXMO1X0@uKF6^_5|O7BbI5rs01yxoOc`ebd5u_eZBF*L3XGdbdwaJy5GDA2#LN xVKSnGo4mh9LQxAZh%?KU#nsloy(a7z^S=)Pes6-frLzD4002ovPDHLkV1l+g(Eb1b literal 0 HcmV?d00001 diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/40x40.png b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/40x40.png new file mode 100644 index 0000000000000000000000000000000000000000..b3cff5b70597209f0ccf01f6bb3638e6f1f9a8f3 GIT binary patch literal 1495 zcmV;|1t|K7P)D)L}Vw4hIFThj*(t#1`G6zK9X$8+wzv%|7L!4;O19PV)E&Yj=<&$;K$ zj>04(qGWCg*mtpKv8Q2vEx_KwUZs?(oN*+><*|2A?5sl=rh_Y_#bbpomvWWk<|`~N zdx%3`?*evU{&Q`v*2%uj$8gVL@xh6uu^0IGPazhsX~3+>y|1+c8#yDl`hkj0#L_aA zESZTt$1ee|w({yxlAC4~)#U;?>k$+4P3}0$fanLDJ_fXHV>e=EOD1=0j5AQKiGr!i z5i^TW@L)Eu$!F9P-@X>un}L{FL=L*vc-geMcVSl6Hx4Al&2WCqv`I@aH=`)6D@gQc zJ5l0y#*cJIj(Oz*(W=jh5bSeIizL$?JG9bnEa?EGd(BgSF<@VA_wSIn3%s`(#lF zbdSAW=b^HS65em6o8A8AfcabplYAba4!7KBDM77dXGrHVg@qSZMJ4e3KQXKmBu_y* zSIZxqCS6eiioKW>p5XA2R!`ut(yBUOl+(Ewlu#4r8|l(QLz0W49BBnZi-!G;FDZJ! z;(LvXAq5jeJp-rW`FI7Z(q~k39kx|*wy)Q=BjFEQ&vi5~93^1V3eLrBGpSm|K&wq? zT?IwWR4(92U`P(7s22+PIGLPd6>~Ru%8^YKIWB9M`o7nCoY?`2?R(JdwQ8-WoCz~& zf1P)Ry>}~5y`Zn+g#GUhXgIMsz5Jvm@=L(& z3N?JO8dqlXXLSy2^`7(4PKAeCNcX#YaNz?gbY3EH^eKgcOrY{>-p_l8`xG)$%z07n z*Y5Gq_-Wr}X0p;t4w`r&B>NOzxI-aljS4$o)yUo;i;HtFUE$^Y+0A?8V z<_&S$1=?Cb09#@K=x-ZA`A0)2ej;AO3Dm$4p}b_ZE;Rzrb)ZE;d=; zTb63L-FYie@?<>TIX#RmDdy*)SUykAwlPG(}i|5113TFxSp~Goo98EGh5D)ql)6rJN$&x&z64Cp>|9vZ>%E z+NzZXMO1X0@uKF6^_5|O7BbI5rs01yxoOc`ebd5u_eZBF*L3XGdbdwaJy5GDA2#LN xVKSnGo4mh9LQxAZh%?KU#nsloy(a7z^S=)Pes6-frLzD4002ovPDHLkV1l+g(Eb1b literal 0 HcmV?d00001 diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/58x58-1.png b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/58x58-1.png new file mode 100644 index 0000000000000000000000000000000000000000..ff5a7ba2f9d0c61f5d1e95236f4f45766b79b50d GIT binary patch literal 2360 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 Be#rm; literal 0 HcmV?d00001 diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/80x80.png b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/80x80.png new file mode 100644 index 0000000000000000000000000000000000000000..ec7963dddf0570d4a8dd0c40cf908aba525168a5 GIT binary patch literal 3423 zcmV-l4WROgP)~f|_dXY4@BWg*nK?7} z%$eW(pXbaD0%bxUmJoJ6EGQ?-=JkEk?bcq2ol zlgbJrGgIv3K?$rg;*zkONL(@42?Yrx^3qhjj5A+Ft3`&&yh75LNFb5N_KnG_N2yCf z7MjGJ(E~98N60IPL=r;;8nxYl5%LOwNo;e~IZEJOjM%(l$Uu|GWFlo-iM$6fLS89I zLq{bFN&=1Q?!^d71xw#FmO?9m4`Kx6fPI9LLMwqIwy%6-Ndj9^Cbvyv1m&WcxnmW+ z10$#ucQnvHGfO%1a1MBKAMpG^;LTp3sS&tk0&xE&z|^x)ub3%Hv48vefSXJmi>>^Y<*tk~RjwjXtgq6E%p)@mvYfow5F z0-00KMO~t(4O~DT7RJsgRql`2KU3N#qApRCz@{<4vae{8ya;KQ$f(hqNmA8Ty^{&F|fO{hzh6bD+cLwWXfT{lzqF^95{Tfd09Mp*=&3LMVsw6TeF zqiGZ>0;if;>ZA3np-(eQQsGm9ZAXDs@9WxP>S*A;3xWA1W;m-TDP6ap9>4&Z91kj1 zopBEEz~?D%A0j7rT1X%hx9Yv*@QCq4y7@;g9=wm)uaV>(F}b=S&lV>0(Juf?E-?fm2>05>J}J<%2=`HI?~9;<77=$g>CU>znV=6xpF5(Xp9g z6db4jW0tm!E_#jwS8mgUaZy>Ohp-fyZGN~fUXPlhXdIY?1(TtP9pokgJ5A69*;(c^eo0rqqRFX#9!fu&%R74=#xAyZ8lR6QRMq5@=?AVoX^AG(}>J-tybIpK5oHT{!B)dNi&gVY&ei|M_ zh&(TRjQ7{RMN)VYHA6)NG9I|x3@jpriE2&f{NSbVjLp`!I3O30A30hpO`iin-_lCD zDbG98X3w&D=-1~*ukVu?8Oz~5GeuV;R7_y|1!e}?8K88fCZbB5y=-_p`2Dk8^iPAt zz$=nGS%fG1zM(##CsCwNlL)&H>Osm#C==agDeR(^y`KFfb&ck@6v*!cMzv`hY9-f~ zCNJp2wyz`Ay@=yaR`pTlI1wxC-EcS~gV08|Np&r0LYwE_rI_$SRE?@Lkqs2Ye*a~} z35)Doa_3x3hW~Aeo{yd5L}ugdLKEN;=sC{G3+x%!`S-P&3)Uen6vT@r=el%T_L@Qw zC(SXvl*r4n?<^8%9)qe-l?pR%rGUAaZ#>D7 zv+c75K9SysNVJ2#Q^^HRO4Y2o95W6C=gVH_I)*4M$-;PbmP+A2;I*$+?@X#Dkg;Tz zep4aj1s$*G5|dzRtc#?H0PmnodRR=sP=*WJKlz@cst##>7~&jLDcfk{C@irm zq!E4_k{+ZN9^*q>Q59-JAY;jw5KHZ1fo)?TeOi5aU-;YdxYTPckt`&p+Ul585~lhZ z&_xk@Jh&!8p^S(;Tx}b-{+CJy6{BVZHjx*++l>n&s;Kf@*Krsrl&&pg2l=rKq|Euf z?~n#$h)9_-&c~`T5vbC`2x-0}@!JEne(vqcZDGv_WGtA0#K>Q@jSYxm)liLVBm%6_r|_yns3#3d-7VjHr$_djh1JxcawZyto=;X)lWI~|60ht`qtnRK%3TsLr zs+btF=e=8|Vs`mr0Rk4X{RmXkg~EPejIQg_Z`WZ+1s z?KgLdSP13Y!cbhO+cFeFb?!k~c;FHio+cE=J6qMBGgaWW zOTq-ebtJB1vFhAlr50FtH867uaQkI2sh|isl~7#hJm?jhOIKqi@9E7$MBuGg={FU4 zu&Ie&ICN3O(T#)%wZ|nEkSA}Y1rV;A*&e!~kwc`&N5UPhp>5&9YxOufW(&AkNg?9w zL)l7cX6BRP_h-pt3<-gZyRX)R6BA`jMOo@n5!6yy{rrfbu$$w>v-_4@Hl?{HGy;!LXzh%K^U&w z_eCGyqURiw@WQM8So4SDp|&9-u$hSKxDg@g)7vC{qs`P+#0xKL3wy$uli421m>OGE zOq#8k8+li!c`UGHi9oCM%65uNSD{5f-sUO)^?!>?;eX!CW95cpvGyS&kg<5SCK9g4 zb=1|31KAd~PmG5WKf6(cb70pNM(pCkIV5ct#K)1Q1+bSp1ipQZCeD?(&^Dz@yuE2x z`1k+&)Wf~2k01#{N+6TBIBle@!G=F>AM71(cufD!PR>TB%$D9P@QXz#8BEa51Hi5W!R@zB5SVol zRAE^1xGscK@^aBWnqm3+77quSJb#TtnstlzCV{7}7*&uwi%pcT{`hwk@O}h8o3K;; zOTSSbd8MEf@))P|?X2!2Qk9+)l43l8Th0@Tz;dv@lO%^GL9;Y@I;)lJ9(((o{++x1Njh%)2BrL zbV_bYnQw+>Q3puMZ_gPUChFch$Dw^jqjDzpn6;DVj0@6E%HJ~Eo;bhLhB2!#%)#Wa z+D0b_diy*~zi5=NqD97;JU zTGZnf2wSrGd}^NCFl;|UTWNmFs@pcbQEhkc9#BrkAnSRld4GMfrSL~+EzWcjIfqSJ zf~*3G2S~%>nYFM-CTUzbyky-0FsghQ~V}Zz<|f%YLiSd@_{3 zddVMdOye{lwA3ZYB(RDKAu~{uDsmI2XJz~x{|9#+OMR^b@23C&002ovPDHLkV1i;= Be#rm; literal 0 HcmV?d00001 diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/87x87.png b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/87x87.png new file mode 100644 index 0000000000000000000000000000000000000000..faaf1df42ab9afdbe1862224c0c67e65d4858a80 GIT binary patch literal 3848 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 KMNUMnLSTaW7*X{A literal 0 HcmV?d00001 diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/Contents.json b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..b51241aa --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,116 @@ +{ + "images" : [ + { + "filename" : "40x40.png", + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "filename" : "60x60.png", + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "filename" : "58x58.png", + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "filename" : "87x87.png", + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "filename" : "80x80.png", + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "filename" : "120x120.png", + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "filename" : "120x120-1.png", + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "filename" : "180x180.png", + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "filename" : "20x20.png", + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "filename" : "40x40-1.png", + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "filename" : "29x29.png", + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "filename" : "58x58-1.png", + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "filename" : "40x40-2.png", + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "filename" : "80x80-1.png", + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "filename" : "76x76.png", + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "filename" : "152x152.png", + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "filename" : "167x167.png", + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "filename" : "1024x1024.png", + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/Contents.json b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/Contents.json similarity index 100% rename from NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/Contents.json rename to IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/Contents.json diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/backArrow.imageset/Contents.json b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/chat.imageset/Contents.json similarity index 79% rename from NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/backArrow.imageset/Contents.json rename to IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/chat.imageset/Contents.json index 79099b29..65f4223d 100644 --- a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/backArrow.imageset/Contents.json +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/chat.imageset/Contents.json @@ -5,12 +5,12 @@ "scale" : "1x" }, { - "filename" : "back@2x.png", + "filename" : "chat@2x.png", "idiom" : "universal", "scale" : "2x" }, { - "filename" : "back@3x.png", + "filename" : "chat@3x.png", "idiom" : "universal", "scale" : "3x" } diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/chat.imageset/chat@2x.png b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/chat.imageset/chat@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..93d859e8b3d414f40b144cc3188f38576df8326b GIT binary patch literal 1209 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 D1k5gD literal 0 HcmV?d00001 diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/chatSelect.imageset/Contents.json b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/chatSelect.imageset/Contents.json new file mode 100644 index 00000000..48d1c275 --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/chatSelect.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "chatSelect@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "chatSelect@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/chatSelect.imageset/chatSelect@2x.png b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/chatSelect.imageset/chatSelect@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..3b8343cb2ea65d0df6784bfe8db1a41c75f3245f GIT binary patch literal 1217 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 RS@!?{002ovPDHLkV1jjY5N7}Y literal 0 HcmV?d00001 diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/emoji.imageset/Contents.json b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/contact.imageset/Contents.json similarity index 78% rename from NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/emoji.imageset/Contents.json rename to IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/contact.imageset/Contents.json index 4bdf5bae..38184864 100644 --- a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/emoji.imageset/Contents.json +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/contact.imageset/Contents.json @@ -5,12 +5,12 @@ "scale" : "1x" }, { - "filename" : "Frame@2x-1.png", + "filename" : "contact@2x.png", "idiom" : "universal", "scale" : "2x" }, { - "filename" : "Frame@3x-1.png", + "filename" : "contact@3x.png", "idiom" : "universal", "scale" : "3x" } diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/contact.imageset/contact@2x.png b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/contact.imageset/contact@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..36db14782a1cbfd2607cee17005b1afc71cfb2a9 GIT binary patch literal 751 zcmVj6@_PZlb=oIr2D-at43c!F>P;RJF6FhMBtvPp3Oxq<6jL}uEa zC0Z%6Y$#lJNfloe%s_Vye=$AXJqxhMV3P4{68MCwjtCxP00V@`&|k3rSgW}6jp8QL zS<3*oAs<3m>RPP0!6a~sq`pCpFv5`H3<|Q@#w28Wy;yMwQnqO z3P$6g`TC{XS!(Vn%C36Q>W#c)ua*4>^bj&65+{K-PjZr2`)O0(~*F8 zM1*t4gZc8&v1!{WlJU1ZL+OdDxo#+fpX4}})5IyC*87Ofb2fF9uAyw_#>iNpcOt9} z851k6a7_(E*or>nSVIoAbypsqxW|%OY~8ajxdpil+=Cp5JrM3HwS>36^3Nx;E)fqP zLn3iDbrgS6Thhg|bq8BL7RS0-bx($)=~WLi%yp4CD+~}nY|8y&{~<$z4Rw(?GjUPO zF|QKtCJe&!$XP8z$dE{!A=6KEGT61F)+>=&5pC<67jFOSMc`_!?)#iKc?aIRwCk?)~g<7Y9j|g~V+NC?w`CntgQftc3i;%~*0US__v&cf;t*-`p(00^u8Xg8G%G z&QajabBBEUVXq62UmygDa!Ycx-L&mWji-wKv`@PG{D5pjLK&^D62*teR{@&EzhcWj z@(52M!Hh!)VHxItr^Kkv)TE&CZIv8Io z5^a%;7M|CymUr8oUp+z&^oW5Y!=v5P0y*&RRqwtlPgh+mue?~U6VN^+oB;bnZqAy92-NL!g6`WN14Gr>{#b(qXFp^6qhoIgarJIM zNH&9(fnqJ4_J?=~_6MK|bMPSS4=%9|N6oa@9|~1H>P6Ze5a6}OKavvr(zWg)e8L|S;zbKhY~r|rV5ToV5(Xd<$iiz+9wr3Ce1}q7B020d+fKOmA8ly45)l+?fmWy8TAeyL2 zIq1R577`I!X2x%5A(Cvj<8<3@lldjhOghtcf4j3Y-#1&p;cz${jam1v7=vAE2Bjn_=EF zla5w`sP}6~wnyISra$!F{BFv19Z`aF}p{!;TXib~3O)a#`WBd2SSg&%o|c z)knfy8DW_9GdQj*?CqbzhOR=jbLMD0I%)7Ci7p^PmhNB0wejX5e*bZbcklmPYL`Mx zcM92zui)#l%JGP+B!TLqJgZPOm|Z!XQVGSSHzvIcIn89&?rt&?d{b5d4aH3r(WVc9 zm@8?}Gl3hu0iTT*#t zqzog$&9cf0y_hrHjcBfV3Tw1hR&K2vY$u&jbc>N-OYTWb`vDaNk4b$MQzdA655{iK zQ3yAuODQi6+f-mGSc+>T!7W|NmS~zV8lp>iR(e%d^In92PIw~FU z{~t~o3U4b%n4QYt@VCUL{XPnw$+2dz-OKz>i+$LuqZ?ePHtaaTVaEwZ!>ULD$77vC zLo312QBlHxp1Nnh)G@bmNQMG9jU>Bl~zPiQgv n%^e}cyy+i-91e%W;fUccK}qD@rEk#=00000NkvXXu0mjffVYCA literal 0 HcmV?d00001 diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/contactSelect.imageset/contactSelect@3x.png b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Assets.xcassets/contactSelect.imageset/contactSelect@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..c9ab56e200e041fc6aebbec7e3a2a0570041dc8a GIT binary patch literal 1200 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 literal 0 HcmV?d00001 diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Base.lproj/LaunchScreen.storyboard b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..865e9329 --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Base.lproj/Main.storyboard b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Base.lproj/Main.storyboard new file mode 100644 index 00000000..808a21ce --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Base.lproj/Main.storyboard @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Info.plist b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Info.plist new file mode 100644 index 00000000..81ed29b7 --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Info.plist @@ -0,0 +1,25 @@ + + + + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + SceneDelegate + UISceneStoryboardFile + Main + + + + + + diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/AppDelegate.h b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/AppDelegate.h new file mode 100644 index 00000000..fa0a737e --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/AppDelegate.h @@ -0,0 +1,11 @@ + +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import + +@interface AppDelegate : UIResponder + +@property(nonatomic, strong) UIWindow *window; +@end diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/AppDelegate.m b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/AppDelegate.m new file mode 100644 index 00000000..5b3feeaa --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/AppDelegate.m @@ -0,0 +1,132 @@ + +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import "AppDelegate.h" +#import +#import "AppKey.h" +#import "NETabbarController.h" + +#import +#import +#import +#import +#import +#import +#import "CustomRouterViewController.h" + +@import NIMSDK; + +@interface AppDelegate () + +@end + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [self setupInit]; + return YES; +} + +- (void)setupInit { + // 初始化NIMSDK + NIMSDKOption *option = [NIMSDKOption optionWithAppKey:AppKey]; + [[IMKitClient instance] setupCoreKitIM:option]; + + // 统一登录组件 + YXConfig *config = [[YXConfig alloc] init]; + config.appKey = AppKey; + config.parentScope = @2; + config.scope = @7; + config.supportInternationalize = false; + config.type = YXLoginPhone; + +#ifdef DEBUG + config.isOnline = NO; +#else + config.isOnline = YES; +#endif + [[AuthorManager shareInstance] initAuthorWithConfig:config]; + if ([AuthorManager shareInstance].canAutologin) { + [[AuthorManager shareInstance] + autoLoginWithCompletion:^(YXUserInfo *_Nullable userinfo, NSError *_Nullable error) { + if (error) { + NSLog(@"auto login failed,error = %@", error); + } else { + [self setupXKit:userinfo]; + } + }]; + } else { + [self loginWithUI]; + } +} + +- (void)loginWithUI { + [[AuthorManager shareInstance] + startLoginWithCompletion:^(YXUserInfo *_Nullable userinfo, NSError *_Nullable error) { + if (!error) { + [self setupXKit:userinfo]; + } else { + NSLog(@"login failed,error = %@", error); + } + }]; +} + +- (void)setupXKit:(YXUserInfo *)user { + // 登录云信IM + if (user.imToken && user.imAccid) { + [[IMKitClient instance] loginIM:user.imAccid :user.imToken :^(NSError * _Nullable error) { + if (!error) { + [ChatRouter setupInit]; + //登录圈组模块,如不需要圈组功能则不用登录 + QChatLoginParam *parama = [[QChatLoginParam alloc]init:user.imAccid :user.imToken]; + [[IMKitClient instance] loginQchat:parama completion:^(NSError * _Nullable error, QChatLoginResult * _Nullable result) { + if (!error) { + [self setupTabbar]; + }else { + NSLog(@"qchat login failed,error = %@",error); + } + }]; + + }else { + NSLog(@"loginIM failed,error = %@",error); + } + }]; + } else { + NSLog(@"parameter is nil"); + } +} + +- (void)setupTabbar { + self.window.backgroundColor = [UIColor whiteColor]; + self.window.rootViewController = [[NETabbarController alloc] init]; + [self registerRouter]; +} + +// 注册路由 +- (void)registerRouter { + [ChatRouter register]; + [ConversationRouter register]; + [ContactRouter register]; + + [[Router shared] register:@"imkit://chat/p2pChat.page" + closure:^(NSDictionary *_Nonnull param) { + NSObject *param1 = [param objectForKey:@"nav"]; + if ([param1 isKindOfClass:[UINavigationController class]]) { + UINavigationController *nav = (UINavigationController *)param1; + CustomRouterViewController *controller = + [[CustomRouterViewController alloc] init]; + + [nav pushViewController:controller animated:YES]; + } + }]; +} + +- (UIInterfaceOrientationMask)application:(UIApplication *)application + supportedInterfaceOrientationsForWindow:(UIWindow *)window { + return UIInterfaceOrientationMaskPortrait; +} + +@end diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/ConversationController+Test.h b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/ConversationController+Test.h new file mode 100644 index 00000000..e08e9af8 --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/ConversationController+Test.h @@ -0,0 +1,14 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. +#import +#import +#import "IMUIKitOCExample-Bridging-Header.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface ConversationController (Test) + +@end + +NS_ASSUME_NONNULL_END diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/ConversationController+Test.m b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/ConversationController+Test.m new file mode 100644 index 00000000..ccd0b372 --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/ConversationController+Test.m @@ -0,0 +1,20 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import +#import "ConversationController+Test.h" + +@implementation ConversationController (Test) + ++ (void)initialize { + Method originalMethod = class_getInstanceMethod(self, @selector(viewDidLoad)); + Method swizzledMethod = class_getInstanceMethod(self, @selector(test_viewDidLoad)); + method_exchangeImplementations(originalMethod, swizzledMethod); +} + +- (void)test_viewDidLoad { + [self test_viewDidLoad]; +} + +@end diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/CustomRouterViewController.h b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/CustomRouterViewController.h new file mode 100644 index 00000000..a2ad9efe --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/CustomRouterViewController.h @@ -0,0 +1,13 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface CustomRouterViewController : UIViewController + +@end + +NS_ASSUME_NONNULL_END diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/CustomRouterViewController.m b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/CustomRouterViewController.m new file mode 100644 index 00000000..e8c880df --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/CustomRouterViewController.m @@ -0,0 +1,40 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import "CustomRouterViewController.h" + +@interface CustomRouterViewController () + +@end + +@implementation CustomRouterViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + UILabel *tipLabel = [[UILabel alloc] init]; + tipLabel.translatesAutoresizingMaskIntoConstraints = NO; + [self.view addSubview:tipLabel]; + tipLabel.text = @"自定义路由测试页面"; + tipLabel.textAlignment = NSTextAlignmentCenter; + tipLabel.textColor = [UIColor blackColor]; + [NSLayoutConstraint activateConstraints:@[ + [tipLabel.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor], + [tipLabel.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor], + ]]; + self.navigationController.navigationBarHidden = NO; +} + +/* +#pragma mark - Navigation + +// In a storyboard-based application, you will often want to do a little preparation before +navigation +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. +} +*/ + +@end diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/IMUIKitOCExample-Bridging-Header.h b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/IMUIKitOCExample-Bridging-Header.h new file mode 100644 index 00000000..61396132 --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/IMUIKitOCExample-Bridging-Header.h @@ -0,0 +1,3 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/NENavigationController.h b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/NENavigationController.h new file mode 100644 index 00000000..76d8f3c8 --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/NENavigationController.h @@ -0,0 +1,14 @@ + +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NENavigationController : UINavigationController + +@end + +NS_ASSUME_NONNULL_END diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/NENavigationController.m b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/NENavigationController.m new file mode 100644 index 00000000..1872d2c5 --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/NENavigationController.m @@ -0,0 +1,40 @@ + +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import "NENavigationController.h" + +@interface NENavigationController () + +@end + +@implementation NENavigationController + +- (void)viewDidLoad { + [super viewDidLoad]; + [self setUpNavigation]; +} + +- (void)setUpNavigation { + if (@available(iOS 13.0, *)) { + UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init]; + appearance.backgroundImage = [UIImage new]; + appearance.backgroundColor = [UIColor whiteColor]; + appearance.shadowColor = [UIColor whiteColor]; + self.navigationBar.standardAppearance = appearance; + self.navigationBar.scrollEdgeAppearance = appearance; + } +} + +- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated { + if (self.childViewControllers.count > 0) { + viewController.hidesBottomBarWhenPushed = YES; + if (self.childViewControllers.count > 1) { + viewController.hidesBottomBarWhenPushed = NO; + } + } + [super pushViewController:viewController animated:animated]; +} + +@end diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/NETabbarController.h b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/NETabbarController.h new file mode 100644 index 00000000..ab07800c --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/NETabbarController.h @@ -0,0 +1,15 @@ + +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import +#import "IMUIKitOCExample-Bridging-Header.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface NETabbarController : UITabBarController + +@end + +NS_ASSUME_NONNULL_END diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/NETabbarController.m b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/NETabbarController.m new file mode 100644 index 00000000..c4647db3 --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/NETabbarController.m @@ -0,0 +1,62 @@ + +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import "NETabbarController.h" +#import "NENavigationController.h" + +#import +#import +#import +#import +#import +#import + +@interface NETabbarController () + +@end + +@implementation NETabbarController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + [self setUpControllers]; +} + +- (void)setUpControllers { + // 会话列表页 + ConversationController *sessionCtrl = [[ConversationController alloc] init]; + sessionCtrl.view.backgroundColor = [UIColor whiteColor]; + sessionCtrl.tabBarItem = [[UITabBarItem alloc] initWithTitle:NSLocalizedString(@"message", @"") + image:[UIImage imageNamed:@"chat"] + selectedImage:[UIImage imageNamed:@"chatSelect"]]; + NENavigationController *sessionNav = + [[NENavigationController alloc] initWithRootViewController:sessionCtrl]; + + // 通讯录 + ContactsViewController *contactCtrl = [[ContactsViewController alloc] init]; + contactCtrl.tabBarItem = + [[UITabBarItem alloc] initWithTitle:NSLocalizedString(@"contact", @"") + image:[UIImage imageNamed:@"contact"] + selectedImage:[UIImage imageNamed:@"contactSelect"]]; + NENavigationController *contactNav = + [[NENavigationController alloc] initWithRootViewController:contactCtrl]; + + // 圈组 + + QChatHomeViewController *qchatCtrl = [[QChatHomeViewController alloc] init]; + qchatCtrl.tabBarItem = + [[UITabBarItem alloc] initWithTitle:NSLocalizedString(@"qchat", @"") + image:[UIImage imageNamed:@"qchat_tabbar_icon"] + selectedImage:[UIImage imageNamed:@"qchat_tabbar_icon"]]; + NENavigationController *qchatNav = + [[NENavigationController alloc] initWithRootViewController:qchatCtrl]; + + self.tabBar.backgroundColor = [UIColor whiteColor]; + self.viewControllers = @[ sessionNav, contactNav, qchatNav ]; + self.selectedIndex = 0; +} + +@end diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/QChatRouter/QChatRouter.swift b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/ViewController.h similarity index 66% rename from NEQChatUIKit/NEQChatUIKit/Classes/QChatRouter/QChatRouter.swift rename to IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/ViewController.h index bc9d74c5..53076181 100644 --- a/NEQChatUIKit/NEQChatUIKit/Classes/QChatRouter/QChatRouter.swift +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/ViewController.h @@ -3,8 +3,8 @@ // Use of this source code is governed by a MIT license that can be // found in the LICENSE file. -import Foundation +#import -public enum QChatRouter { - public static func register() {} -} +@interface ViewController : UIViewController + +@end diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/ViewController.m b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/ViewController.m new file mode 100644 index 00000000..015dc5c1 --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/ViewController.m @@ -0,0 +1,19 @@ + +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import "ViewController.h" + +@interface ViewController () + +@end + +@implementation ViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. +} + +@end diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/en-IN.lproj/Localizable.strings b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/en-IN.lproj/Localizable.strings new file mode 100644 index 00000000..686cbdf1 --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/en-IN.lproj/Localizable.strings @@ -0,0 +1,7 @@ +/* + Localizable.strings + IMUIKitOCExample + + Created by vvj on 2022/10/31. + +*/ diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/en.lproj/Localizable.strings b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/en.lproj/Localizable.strings new file mode 100644 index 00000000..07add498 --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/en.lproj/Localizable.strings @@ -0,0 +1,11 @@ + +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +"message"="Message"; +"qchat"="Qchat"; +"contact"="Contact"; +"mine"="Me"; + + diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/zh-Hans.lproj/Localizable.strings b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/zh-Hans.lproj/Localizable.strings new file mode 100644 index 00000000..c8d3a1a7 --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/Main/zh-Hans.lproj/Localizable.strings @@ -0,0 +1,13 @@ + +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + + +"message"="消息"; +"qchat"="圈组"; +"contact"="通讯录"; +"mine"="我"; + + + diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/en-IN.lproj/LaunchScreen.strings b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/en-IN.lproj/LaunchScreen.strings new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/en-IN.lproj/LaunchScreen.strings @@ -0,0 +1 @@ + diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/en-IN.lproj/Main.strings b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/en-IN.lproj/Main.strings new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/en-IN.lproj/Main.strings @@ -0,0 +1 @@ + diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/main.m b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/main.m new file mode 100644 index 00000000..49b07ea9 --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/main.m @@ -0,0 +1,16 @@ + +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import +#import "AppDelegate.h" + +int main(int argc, char *argv[]) { + NSString *appDelegateClassName; + @autoreleasepool { + // Setup code that might create autoreleased objects goes here. + appDelegateClassName = NSStringFromClass([AppDelegate class]); + } + return UIApplicationMain(argc, argv, nil, appDelegateClassName); +} diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/zh-Hans.lproj/LaunchScreen.strings b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/zh-Hans.lproj/LaunchScreen.strings new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/zh-Hans.lproj/LaunchScreen.strings @@ -0,0 +1 @@ + diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/zh-Hans.lproj/Main.strings b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/zh-Hans.lproj/Main.strings new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExample/zh-Hans.lproj/Main.strings @@ -0,0 +1 @@ + diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExampleTests/IMUIKitOCExampleTests.m b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExampleTests/IMUIKitOCExampleTests.m new file mode 100644 index 00000000..79076fc1 --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExampleTests/IMUIKitOCExampleTests.m @@ -0,0 +1,36 @@ + +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import + +@interface IMUIKitOCExampleTests : XCTestCase + +@end + +@implementation IMUIKitOCExampleTests + +- (void)setUp { + // Put setup code here. This method is called before the invocation of each test method in the + // class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the + // class. +} + +- (void)testExample { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. +} + +- (void)testPerformanceExample { + // This is an example of a performance test case. + [self measureBlock:^{ + // Put the code you want to measure the time of here. + }]; +} + +@end diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExampleUITests/IMUIKitOCExampleUITests.m b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExampleUITests/IMUIKitOCExampleUITests.m new file mode 100644 index 00000000..d0b0e770 --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExampleUITests/IMUIKitOCExampleUITests.m @@ -0,0 +1,48 @@ + +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import + +@interface IMUIKitOCExampleUITests : XCTestCase + +@end + +@implementation IMUIKitOCExampleUITests + +- (void)setUp { + // Put setup code here. This method is called before the invocation of each test method in the + // class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + self.continueAfterFailure = NO; + + // In UI tests it’s important to set the initial state - such as interface orientation - required + // for your tests before they run. The setUp method is a good place to do this. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the + // class. +} + +- (void)testExample { + // UI tests must launch the application that they test. + XCUIApplication *app = [[XCUIApplication alloc] init]; + [app launch]; + + // Use XCTAssert and related functions to verify your tests produce the correct results. +} + +- (void)testLaunchPerformance { + if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *)) { + // This measures how long it takes to launch your application. + [self measureWithMetrics:@[ [[XCTApplicationLaunchMetric alloc] init] ] + block:^{ + [[[XCUIApplication alloc] init] launch]; + }]; + } +} + +@end diff --git a/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExampleUITests/IMUIKitOCExampleUITestsLaunchTests.m b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExampleUITests/IMUIKitOCExampleUITestsLaunchTests.m new file mode 100644 index 00000000..6faa84f1 --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/IMUIKitOCExampleUITests/IMUIKitOCExampleUITestsLaunchTests.m @@ -0,0 +1,36 @@ + +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import + +@interface IMUIKitOCExampleUITestsLaunchTests : XCTestCase + +@end + +@implementation IMUIKitOCExampleUITestsLaunchTests + ++ (BOOL)runsForEachTargetApplicationUIConfiguration { + return YES; +} + +- (void)setUp { + self.continueAfterFailure = NO; +} + +- (void)testLaunch { + XCUIApplication *app = [[XCUIApplication alloc] init]; + [app launch]; + + // Insert steps here to perform after app launch but before taking a screenshot, + // such as logging into a test account or navigating somewhere in the app + + XCTAttachment *attachment = + [XCTAttachment attachmentWithScreenshot:XCUIScreen.mainScreen.screenshot]; + attachment.name = @"Launch Screen"; + attachment.lifetime = XCTAttachmentLifetimeKeepAlways; + [self addAttachment:attachment]; +} + +@end diff --git a/IMUIKitOC/IMUIKitOCExample/Podfile b/IMUIKitOC/IMUIKitOCExample/Podfile new file mode 100644 index 00000000..467e3636 --- /dev/null +++ b/IMUIKitOC/IMUIKitOCExample/Podfile @@ -0,0 +1,56 @@ +# Uncomment the next line to define a global platform for your project +# platform :ios, '9.0' + +platform :ios, '9.0' +source 'https://github.com/CocoaPods/Specs.git' + +target 'IMUIKitOCExample' do + # Comment the next line if you don't want to use dynamic frameworks + use_frameworks! + #登录组件 + pod 'YXLogin', '1.0.0' + + #可选UI库 + pod 'NEContactUIKit', '9.4.0' + pod 'NEQChatUIKit', '9.4.0' + pod 'NEConversationUIKit', '9.4.0' + pod 'NEChatUIKit', '9.4.0' + pod 'NETeamUIKit', '9.4.0' + + + #可选Kit库(和UIKit对应) + pod 'NEContactKit', '9.4.0' + pod 'NEQChatKit', '9.4.0' + pod 'NEConversationKit', '9.4.0' + pod 'NEChatKit', '9.4.0' + pod 'NETeamKit', '9.4.0' + + #基础kit库 + pod 'NECommonUIKit', '9.4.0' + pod 'NECommonKit', '9.4.0' + pod 'NECoreIMKit', '9.4.0' + pod 'NECoreKit', '9.4.0' + pod 'NEMapKit', '9.4.0' + + + + + #fix bug in Xcode 14 + post_install do |installer| + installer.pods_project.targets.each do |target| + if target.name == 'RSKPlaceholderTextView' + target.build_configurations.each do |config| + config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES' + end + end + end + end + + # 如果需要查看UI部分源码请注释掉以上在线依赖,打开下面的本地依赖 +# pod 'NEQChatUIKit', :path => '../NEQChatUIKit/NEQChatUIKit.podspec' +# pod 'NEContactUIKit', :path => '../NEContactUIKit/NEContactUIKit.podspec' +# pod 'NEConversationUIKit', :path => '../NEConversationUIKit/NEConversationUIKit.podspec' +# pod 'NETeamUIKit', :path => '../NETeamUIKit/NETeamUIKit.podspec' +# pod 'NEChatUIKit', :path => '../NEChatUIKit/NEChatUIKit.podspec' + +end diff --git a/NEChatUIKit/NEChatUIKit.podspec b/NEChatUIKit/NEChatUIKit.podspec index f199a175..6dbe13c0 100644 --- a/NEChatUIKit/NEChatUIKit.podspec +++ b/NEChatUIKit/NEChatUIKit.podspec @@ -16,7 +16,7 @@ Pod::Spec.new do |spec| # spec.name = 'NEChatUIKit' - spec.version = '9.3.0' + spec.version = '9.2.10' spec.summary = 'Chat Module of IM.' # This description is used to generate tags and improve search results. @@ -37,9 +37,9 @@ TODO: Add long description of the pod here. spec.source_files = 'NEChatUIKit/Classes/**/*' spec.pod_target_xcconfig = { + 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64', 'BUILD_LIBRARY_FOR_DISTRIBUTION' => 'YES' } - spec.user_target_xcconfig = { 'BUILD_LIBRARY_FOR_DISTRIBUTION' => 'YES' } # spec.resource_bundles = { # 'NEChatUIKit' => ['NEChatUIKit/Assets/*.png'] # } @@ -52,7 +52,6 @@ TODO: Add long description of the pod here. spec.dependency 'RSKPlaceholderTextView' spec.dependency 'MJRefresh' spec.dependency 'NIMSDK_LITE' - spec.dependency 'YXAlog_iOS' # spec.dependency 'AMap2DMap' # spec.dependency 'AMapSearch' diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/mic.imageset/Contents.json b/NEChatUIKit/NEChatUIKit/Assets/NEChatUIKit.xcassets/Commom/audio_record.imageset/Contents.json similarity index 100% rename from NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/mic.imageset/Contents.json rename to NEChatUIKit/NEChatUIKit/Assets/NEChatUIKit.xcassets/Commom/audio_record.imageset/Contents.json diff --git a/NEChatUIKit/NEChatUIKit/Assets/NEChatUIKit.xcassets/Commom/audio_record.imageset/Frame@2x.png b/NEChatUIKit/NEChatUIKit/Assets/NEChatUIKit.xcassets/Commom/audio_record.imageset/Frame@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..af69153c2f5f02db8ee015954028a3df0caaaca6 GIT binary patch literal 1029 zcmV+g1p51lP)SzQ0Qn2RT{=ve3j76_G8Imj4y9v;m+}P>l}js~XZ*^! z>$@I}BU`JnCTaG}2(4GUch7z7SqUL5EG#T6EG+&Xq$m-`$H(4qIP|B}sVk-2#C=OG zB4r=#-;U$NXeZCl&ygqzYdLUucvzcECMO_O!%rWVYdAH*6~U<=l}e?%jzfhV@O|G! zBribvQsfW@!B{OKr6*P+#@G&maUVrdEDFHb0TA~PtrnW+>3%GnfFMP%i|b=!VyXaEk_^YlMtxN_mO6mQT;O(_>gvK+vuKSL zMV2F!jkmYA>#Xsa4(#vm-*Cz38gIP5zIMew1ULk^U1YK?GASFF^O#bx4g%Q_%NziC^0>u6Ll8MLsr4e#3dC&NNNLD6 zO6ozdVl8H3?f^^NI}eI5Xipe`_eyJ#xIP0IuFl57n5DJ72n6>XHhe`|%KFR8OGxdi z9su$WdSNOXL!+cnL8_|@WNK)JN+aY&2QSREgH!HJOtNva3oF8^hBNvH3nsjL`c&8!O{=A}%r* zS(~3D)oOLu(PRi5kz63%o1#1v3PL*LDBmq7{g6_UXMo434Ful9v z`;zs!&wWbAsWi|xj||f0((3`s9&H}d;sg=cTleLTU*6~d)s@h}^^G{7MB?;V`dlT& zqVEaj^+}xrI88}|FN7h8JQi)@y{02d0PFjWF#jYav?1S@6>9Z*z3)3aI}*gatRr88 z&IvrfN8}sO@lccmtRHP}Z+}HeZ1Fz?R&k(jk}n|tnSTHEHcIbA>5Z)hA)QEHT=qxI zGEiBgeEh|JDygTZr&w56SXfwCSXfwCSd@W3abgFhjM6Eyus5G?)w za>-pTBwH>?b}#uw7%i4-`71N4vV@4DD2k#eilQirqA1F5MMW0O*49>?$LHtg+Ux6U zExy0Jyc|9}JlqckgL_#Za}$U{JU%`)E0szEm+v4(1LyTDzs0j5o(*w&i_cB9TD`rv zxERPBC{3V7qfuL0TH3~G(|l@DEVQfupA%T$87wW75-3z4BT5seyD}7Io&@;xuCA{7 zQXqv0L}6g|yKsX&$zUmP8IC^PW`OfA=62{jR*xE3sl4O4amg%J7~sx6&T!JIEuHw?J!aYx`4#31k=_`en^T5Uh>? zV&IQsT@tjY-u3nMfp{>pKpPtyO&kts^6qzZ9W?mp>FMe7yr*Z1h4|M+8~#a|9YYLO zYgTKTNuc%hbq3$h?)^my<6^9eF1VW{6x!OI#hNk+WJc#$63iHlIQSWaaWQRX2-r>d znz3*vi#1IZ$W(MHW>)d3WRVz)I!&;qOfFZMQh39NGZu(xHJ6u{UHOGT>|}h}cWyH@ zv?i^}Qw2&A$HbaX5GRm=U<$%K4C|J9oQq)q?)ic14vKVLPB5tF*s-RGA|(oB-0B9W zOd#1<9zzt~%Ii`dDF_8(<9kJ<6e%v3DpDn>05|49oB_o7l&5hVJ!9fc$wy#ZJP=P( zL}E<(;9Be(fiRW#aM+HojpcmEvHDG&0dtaTm29$r8%Lx7xm?SBZcHGojyw3laeSTE zte#&O5`o~gvDOin36#zfz(4?C2^_t1uxZJlER!Fujwd^+#=X2%o6 z3DEgIgg?n@m1eZtDJjL&nP?Km^-t~g*;Z7U@F2GicEp2}IL6W5$vXqm%5m6tgRF@k zp?CnpU|XB$$TkD`a_)RF69o87uN~HOGo*k*f>=kp-Cy-HsLB)`Ldx z+1Kbmw~TbelzHIP-4;(UkZ0CqwC@y^$v+t3v4U|Oh$j%_y;W&g^cJWM-A#rI$(WDg z2`3HbI?^N($nF#?^fgmMJw7pSBFZMP>hpdvVETM-l@)0c2WflrD~~v&Zk>lxG8pM^ zl3ceBfpz}F#bi7oy_G){>jeU-VIq(!X9MRs@9fzv3l)BolCf9crVZY1CU5&*uevjg zdClSlW|3{DtQ#qx(7wRzvoD@Fu{fG3s|l5~XB`DTj}`7Ar*!*1w z`}a^^(n^|n-`S*oaFdRSF}~}_c#w}$tw)VHWv$@sQ4 z=5=&3>_?wTx;=5FZrX2dZt@*?w3%*h#mDH!^yih8mBIP>c_=?Ic0U+1asIdYD&!yb z1A>P0`hO!uQ4~c{6h%=KMNt$*Q4~c{6lEcN2LPr1A*tR92><{907*qoM6N<$f@WKS ArT_o{ literal 0 HcmV?d00001 diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/camera.imageset/Contents.json b/NEChatUIKit/NEChatUIKit/Assets/NEChatUIKit.xcassets/Commom/video_record.imageset/Contents.json similarity index 100% rename from NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/camera.imageset/Contents.json rename to NEChatUIKit/NEChatUIKit/Assets/NEChatUIKit.xcassets/Commom/video_record.imageset/Contents.json diff --git a/NEChatUIKit/NEChatUIKit/Assets/NEChatUIKit.xcassets/Commom/video_record.imageset/Vector@2x.png b/NEChatUIKit/NEChatUIKit/Assets/NEChatUIKit.xcassets/Commom/video_record.imageset/Vector@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..869763afee6203b5e107c9800bfbcbc6d93410ab GIT binary patch literal 571 zcmV-B0>u4^P)VnM(B8&zoZIz!{aogEp697nt2IG5K-xInZg+^_ ziJHTitqF+tAbx?clRay5&!Z=}M?&ON@v@U*h#ESoMt9~IpvrTy^QWMVRB3ZR?F5u z!m7PI6Btq#Sv_B?@ZP(R6oFLRp6l_&j|s-!(Z>wms$&I1_{!6iF+Z1 z1I{bVA7{^;tOD-%ibGL#NX!C6@IBNW_WW;D0$S@BS_gc+@&gG-)0{XYvZ(+7002ov JPDHLkV1nLL_x1n) literal 0 HcmV?d00001 diff --git a/NEChatUIKit/NEChatUIKit/Assets/NEChatUIKit.xcassets/Commom/video_record.imageset/Vector@3x.png b/NEChatUIKit/NEChatUIKit/Assets/NEChatUIKit.xcassets/Commom/video_record.imageset/Vector@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..d21bee9439b23d35ea256a233af6088474e6488c GIT binary patch literal 845 zcmV-T1G4;yP)0Ly=7z23*Nus=QaITTU^ypGs;aBl-;Q{4W+=&me0rz`8nM_8MLJSAz_rs3YklqCaz?s8kPoKkO zUsC8)51rb14({2Z$8jlXJ5S&U2ibX&iDU-_92n&t4r?}>xpEozeL@L!2oB2M0q9n? znWUk@;NUUst97*l6f)-gJOqbTBaI|Y<+5(Dp1KS>M;i|U9GMV+SwAOXi! z%&~A-r3VxOXK)N0R;kAzz~Kd@E8E2Oc3DS!FERxkhEG! zhd`=FK`JC51mr2L;vlK@`Lz#+B7@+z&8tlWyeY3j$9Oz>qu3sjw84-7xr=_@VQmz& zwS|Q8T&~N2Jft&G=Dd&ehw`g>tycTWpaP+z_moh8GzX*$6%v27Cf76C?e-ZiHl%_I z_x=~F=C_nm{QgXVv?o)1y5>>=1vvlkSad0a*pm*;ZhA~QEX(r7<8fv%hr|rfJ`X!QXb=7a XHmO&q>~F&M00000NkvXXu0mjf7g~Ge literal 0 HcmV?d00001 diff --git a/NEChatUIKit/NEChatUIKit/Assets/en.lproj/Localizable.strings b/NEChatUIKit/NEChatUIKit/Assets/en.lproj/Localizable.strings index a3f2a5a8..1311f81b 100644 --- a/NEChatUIKit/NEChatUIKit/Assets/en.lproj/Localizable.strings +++ b/NEChatUIKit/NEChatUIKit/Assets/en.lproj/Localizable.strings @@ -55,6 +55,7 @@ "not_mute" = "unmute"; "mute" = "mute"; "team_has_been_removed" = "This group was removed"; +"team_has_quit" = "Group chat has exited"; "join"="joined"; "pass"="Passed"; "leave"="leave"; @@ -66,7 +67,8 @@ "team_all_mute"="Mute all"; "team_all_no_mute"="Unmute"; -"pin_text"="pinned this message for both"; +"pin_text_P2P"="pinned this message for both"; +"pin_text_team"="pinned this message for both all"; "session_set_top"="sticky to top"; "message_remind"="open notification"; @@ -106,8 +108,8 @@ "user_select"="notification"; "user_select_all"="all"; -"contact_user"="contacts"; -"team"="group"; +"contact_user"="Forward to contacts"; +"team"="Forward to group"; "cancel"="cancel"; "send_to"="send to"; "send"="send"; @@ -117,18 +119,30 @@ "mdhm"="MM.dd HH:mm"; "ymdhm"="yyyy.MM.dd HH:mm"; -"chat_takePicture"="拍摄"; -"chat_rtc"="音视频"; -"chat_location"="位置"; -"chat_file"="文件"; -"gaode_map"="高德地图"; -"tencent_map"="腾讯地图"; +"chat_takePicture"="Capture video"; +"chat_rtc"="Audio and video call"; +"chat_location"="Location"; +"chat_file"="File"; +"gaode_map"="高德 Map"; +"tencent_map"="腾讯 Map"; "search_place"="Search Location"; -"search_cancel"="取消"; +"search_cancel"="cancel"; "distance_inner"="内"; "search_result_empty"="Not found"; -"no_map_plugin"="未集成地图模块"; -"location_not_auth"="地理位置未授权,请去设置中开启"; +"no_map_plugin"="Map module not integrated"; +"location_not_auth"="The geographic location is not authorized. Please open it in the settings"; "fileSize_over_limit"="Oops!File size limit."; "message_recalled"="message recalled"; + +"video_call"="Video call"; +"audio_call"="Audio call"; + +"call_complete"="Talk time"; +"call_canceled"="Call cancellation"; +"call_rejected"="Rejected"; +"call_timeout"="No answer after timeout"; +"call_busy"="The busy line is not answered"; + +"editable_time_expired"="Editable time has expired"; +"message_not_found"="This message is gone"; diff --git a/NEChatUIKit/NEChatUIKit/Assets/zh-Hans.lproj/Localizable.strings b/NEChatUIKit/NEChatUIKit/Assets/zh-Hans.lproj/Localizable.strings index be1a8703..a9292507 100644 --- a/NEChatUIKit/NEChatUIKit/Assets/zh-Hans.lproj/Localizable.strings +++ b/NEChatUIKit/NEChatUIKit/Assets/zh-Hans.lproj/Localizable.strings @@ -6,6 +6,7 @@ //MAKR:common "ok"="确认"; "send_to"="发送给 "; + //MAKR:message "send_picture"="发来了一张图片"; "send_voice"="发来了一段语音"; @@ -61,6 +62,7 @@ "not_mute" = "解除禁言"; "mute" = "禁言"; "team_has_been_removed" = "当前群聊已解散"; +"team_has_quit" = "已退出群聊"; "join"="进入了"; "pass"="通过了"; "leave"="离开了"; @@ -71,7 +73,8 @@ "team_mute"="当前群主设置为禁言"; "team_all_mute"="群全体禁言"; "team_all_no_mute"="取消群全体禁言"; -"pin_text"="标记了这条信息,对话内容双方均可见"; +"pin_text_P2P"="标记了这条信息,对话内容双方均可见"; +"pin_text_team"="标记了这条信息,所有群成员均可见"; "session_set_top"="聊天置顶"; "message_remind"="开启消息提醒"; "open_soon"="暂未开放"; @@ -109,8 +112,8 @@ "user_select"="选择提醒"; "user_select_all"="所有人"; -"contact_user"="好友"; -"team"="群聊"; +"contact_user"="转发到个人"; +"team"="转发到群组"; "cancel"="取消"; "send_to"="发送给"; "send"="发送"; @@ -121,7 +124,7 @@ "ymdhm"="yyyy年MM月dd日 HH:mm"; "chat_takePicture"="拍摄"; -"chat_rtc"="音视频"; +"chat_rtc"="音视频通话"; "chat_location"="位置"; "chat_file"="文件"; "gaode_map"="高德地图"; @@ -135,3 +138,15 @@ "fileSize_over_limit"="当前文件大小超出发送限制,请重新选择"; "message_recalled"="消息已撤回"; + +"video_call"="视频通话"; +"audio_call"="音频通话"; + +"call_complete"="通话时长"; +"call_canceled"="已取消"; +"call_rejected"="已拒绝"; +"call_timeout"="超时未接听"; +"call_busy"="忙线未接听"; + +"editable_time_expired"="已超过可编辑时间"; +"message_not_found"="该消息已移除"; diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/Controller/ChatViewController.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/Controller/ChatViewController.swift index eef1d8e9..ebfc2e86 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/Controller/ChatViewController.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/Controller/ChatViewController.swift @@ -22,8 +22,8 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel UITableViewDelegate, UIDocumentPickerDelegate, UIDocumentInteractionControllerDelegate, CLLocationManagerDelegate { private let tag = "ChatViewController" public var viewmodel: ChatViewModel - private var inputViewTopConstraint: NSLayoutConstraint? - private var tableViewBottomConstraint: NSLayoutConstraint? + public var inputViewTopConstraint: NSLayoutConstraint? + public var tableViewBottomConstraint: NSLayoutConstraint? public var menuView: ChatInputView = .init() public var operationView: MessageOperationView? private var playingCell: ChatAudioCell? @@ -32,7 +32,8 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel var replyView = ReplyView() private var isFile = false let interactionController = UIDocumentInteractionController() - + private var needMarkReadMsgs = [NIMMessage]() + private var isCurrentPage = true var titleContent = "" private lazy var manager = CLLocationManager() @@ -40,19 +41,23 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel public init(session: NIMSession) { viewmodel = ChatViewModel(session: session, anchor: nil) super.init(nibName: nil, bundle: nil) - viewmodel.delegate = self NEKeyboardManager.shared.enable = false NEKeyboardManager.shared.enableAutoToolbar = false NIMSDK.shared().mediaManager.add(self) NIMSDK.shared().mediaManager.setNeedProximityMonitor(viewmodel.getHandSetEnable()) // 注册自定义消息的解析器 - NIMCustomObject.registerCustomDecoder(CustomAttachmentDecoder()) + // NIMCustomObject.registerCustomDecoder(CustomAttachmentDecoder()) } public required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } + override func backEvent() { + super.backEvent() + cleanDelegate() + } + override open func viewDidLoad() { super.viewDidLoad() commonUI() @@ -62,15 +67,29 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel override open func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) + NEKeyboardManager.shared.enable = false + NEKeyboardManager.shared.shouldResignOnTouchOutside = false + isCurrentPage = true navigationController?.isNavigationBarHidden = false + markNeedReadMsg() } override open func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + NEKeyboardManager.shared.enable = true + NEKeyboardManager.shared.shouldResignOnTouchOutside = true + isCurrentPage = false + operationView?.removeFromSuperview() if NIMSDK.shared().mediaManager.isPlaying() { NIMSDK.shared().mediaManager.stopPlay() } } + override open func viewDidDisappear(_ animated: Bool) { + super.viewDidDisappear(animated) + stopPlay() + } + // MARK: 子类可重写方法 // load data的时候会调用 @@ -133,7 +152,12 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel } else { operationY = rectInView.origin.y - h } - let frame = CGRect(x: 0, y: operationY, width: w, height: h) + var frameX = 0.0 + if let msg = model?.message, + msg.isOutgoingMsg { + frameX = kScreenWidth - w + } + let frame = CGRect(x: frameX, y: operationY, width: w, height: h) operationView = MessageOperationView(frame: frame) operationView!.delegate = self operationView!.items = items @@ -215,17 +239,14 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel ) } -// public override func touchesBegan(_ touches: Set, with event: UIEvent?) { -// self.operationView?.removeFromSuperview() -// if self.menuView.textField.isFirstResponder { -// self.menuView.textField.resignFirstResponder() -// }else { -// self.layoutInputView(offset: 0) -// } -// } - deinit { print("will deinit") + cleanDelegate() + } + + func cleanDelegate() { + NIMSDK.shared().mediaManager.remove(self) + viewmodel.delegate = nil } // MARK: objc 方法 @@ -252,7 +273,7 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel view.addSubview(tableView) tableViewBottomConstraint = tableView.bottomAnchor.constraint( equalTo: view.bottomAnchor, - constant: -86 - KStatusBarHeight + constant: -100 ) tableViewBottomConstraint?.isActive = true if #available(iOS 10, *) { @@ -275,6 +296,10 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel ]) } + tableView.register(ChatCallRecordLeftCell.self, forCellReuseIdentifier: "\(ChatCallRecordLeftCell.self)") + + tableView.register(ChatCallRecordRightCell.self, forCellReuseIdentifier: "\(ChatCallRecordRightCell.self)") + tableView.register( ChatTimeTableViewCell.self, forCellReuseIdentifier: "\(ChatTimeTableViewCell.self)" @@ -350,15 +375,17 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel tableView.register(ChatLocationLeftCell.self, forCellReuseIdentifier: "\(ChatLocationLeftCell.self)") tableView.register(ChatLocationRightCell.self, forCellReuseIdentifier: "\(ChatLocationRightCell.self)") + viewmodel.delegate = self menuView.backgroundColor = UIColor(hexString: "#EFF1F3") menuView.translatesAutoresizingMaskIntoConstraints = false menuView.delegate = self + menuView.chatAddMoreView.configData(data: NEChatUIKitClient.instance.getMoreActionData(sessionType: viewmodel.session.sessionType)) view.addSubview(menuView) inputViewTopConstraint = menuView.topAnchor.constraint( equalTo: view.bottomAnchor, - constant: -(86 + NEConstant.statusBarHeight) + constant: -100 ) NSLayoutConstraint.activate([ menuView.leftAnchor.constraint(equalTo: view.leftAnchor), @@ -373,6 +400,7 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel weakSelf?.view.addSubview(networkView) } else { weakSelf?.brokenNetworkView.removeFromSuperview() + weakSelf?.viewmodel.refreshReceipts() } } addRightAction(UIImage.ne_imageNamed(name: "three_point"), #selector(toSetting), self) @@ -388,27 +416,18 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel ModuleName + " " + self.tag, desc: "CALLBACK queryRoamMsgHasMoreTime_v2 " + (error?.localizedDescription ?? "no error") ) + weakSelf?.viewmodel.refreshReceipts() if let ms = models, ms.count > 0 { - if let messages = weakSelf?.viewmodel.messages { - for index in 0 ..< messages.count { - let message = messages[index] - print("messages id : ", message.message?.messageId as Any) - if message.message?.messageId == weakSelf?.viewmodel.anchor?.messageId { - print("messages real index : ", index) - } - } - } weakSelf?.tableView.reloadData() if weakSelf?.viewmodel.isHistoryChat == true { let indexPath = IndexPath(row: index, section: 0) print("queryRoamMsgHasMoreTime_v2 index : ", index) weakSelf?.tableView.scrollToRow(at: indexPath, at: .none, animated: false) - if newEnd <= 0 { + if newEnd > 0 { weakSelf?.addBottomLoadMore() } } else { if let tempArray = weakSelf?.viewmodel.messages, tempArray.count > 0 { - weakSelf?.tableView.reloadData() weakSelf?.tableView.scrollToRow( at: IndexPath(row: tempArray.count - 1, section: 0), at: .bottom, @@ -421,44 +440,6 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel weakSelf?.showToast(err.localizedDescription) } } - - // if viewmodel.isHistoryChat == false { - // viewmodel.getMessageHistory({[weak self] error,isEmpty,messages in - // if let err = error { - // NELog.errorLog(ModuleName + " " + (self?.tag ?? "ChatViewController"), desc: "❌getMessageHistory error, error:\(err)") - // }else { - // if let tempArray = weakSelf?.viewmodel.messages,tempArray.count > 0 { - // weakSelf?.tableView.reloadData() - // weakSelf?.tableView.scrollToRow(at: IndexPath(row: tempArray.count - 1, section: 0), at: .bottom, animated: false) - // } - // } - // }) - // }else { - // print("queryRoamMsgHasMoreTime") - // viewmodel.queryRoamMsgHasMoreTime_v2 { error, historyEnd, newEnd, models, index in - // if let ms = models, ms.count > 0 { - // if let messages = weakSelf?.viewmodel.messages { - // for index in 0.. 0 { weakSelf?.tableView.scrollToRow( - at: IndexPath(row: count, section: 0), + at: IndexPath(row: count - 1, section: 0), at: .top, animated: false ) } weakSelf?.tableView.mj_header?.endRefreshing() } - - // viewmodel.getMoreMessageHistory { error, isEmpty, messageFrames in - // weakSelf?.tableView.reloadData() - // weakSelf?.tableView.mj_header?.endRefreshing() - // } } func loadFartherToNowData() {} func loadCloserToNowData() { weak var weakSelf = self - viewmodel.pullRemoteRefresh { error, end, datas in + viewmodel.pullRemoteRefresh { error, count, datas in NELog.infoLog( ModuleName + " " + self.tag, desc: "CALLBACK pullRemoteRefresh " + (error?.localizedDescription ?? "no error") ) - if end > 0 { + if count <= 0 { weakSelf?.removeBottomLoadMore() } else { weakSelf?.tableView.mj_footer?.endRefreshing() @@ -506,6 +482,10 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel } func addObseve() { + NotificationCenter.default.addObserver(self, + selector: #selector(markNeedReadMsg), + name: UIApplication.willEnterForegroundNotification, + object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, @@ -515,9 +495,9 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel selector: #selector(keyBoardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil) - // let tap = UITapGestureRecognizer(target: self, action: #selector(viewTap)) - // tap.delegate = self - // self.view.addGestureRecognizer(tap) + let tap = UITapGestureRecognizer(target: self, action: #selector(viewTap)) + tap.delegate = self + view.addGestureRecognizer(tap) } func addBottomLoadMore() { @@ -533,14 +513,34 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel viewmodel.isHistoryChat = false // 转为普通聊天页面 } + func markNeedReadMsg() { + if isCurrentPage { + viewmodel.markRead(messages: needMarkReadMsgs) { error in + NELog.infoLog( + ModuleName + " " + self.tag, + desc: "CALLBACK markRead " + (error?.localizedDescription ?? "no error") + ) + } + needMarkReadMsgs = [NIMMessage]() + } + } + // MARK: 键盘通知相关操作 func keyBoardWillShow(_ notification: Notification) { if menuView.currentType != .text { return } + let oldKeyboardRect = (notification + .userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue let keyboardRect = (notification .userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue + + // 键盘已经弹出 + if oldKeyboardRect == keyboardRect { + return + } + print("chat view key board size : ", keyboardRect) layoutInputView(offset: keyboardRect.size.height) @@ -559,7 +559,6 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel // operationView?.removeFromSuperview() // } layoutInputView(offset: 0) - scrollTableViewToBottom() } private func scrollTableViewToBottom() { @@ -567,16 +566,21 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel print("self.tableView.numberOfRows(inSection: 0)\(tableView.numberOfRows(inSection: 0))") if viewmodel.messages.count > 0 { let indexPath = IndexPath(row: viewmodel.messages.count - 1, section: 0) - tableView.scrollToRow(at: indexPath, at: .bottom, animated: true) + weak var weakSelf = self + DispatchQueue.main.asyncAfter(deadline: .now() + 0.1, execute: DispatchWorkItem(block: { + weakSelf?.tableView.scrollToRow(at: indexPath, at: .bottom, animated: true) + })) } } // offset:value which from self.view.bottom to inputView.bottom - private func layoutInputView(offset: CGFloat) { - inputViewTopConstraint?.constant = -100 - offset - tableViewBottomConstraint?.constant = -100 - offset - UIView.animate(withDuration: 0.25, animations: { - self.view.layoutIfNeeded() + var count = 0 + func layoutInputView(offset: CGFloat) { + print("layoutInputView offset : ", offset) + weak var weakSelf = self + UIView.animate(withDuration: 0.1, animations: { + weakSelf?.inputViewTopConstraint?.constant = -100 - offset + weakSelf?.tableViewBottomConstraint?.constant = -100 - offset }) } @@ -615,10 +619,16 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel } public func didSelectMoreCell(cell: NEInputMoreCell) { + if let delegate = cell.cellData?.customDelegate as? AnyObject, let action = cell.cellData?.action { + // 用户自定义更多面板按钮 + _ = delegate.perform(action) + return + } + if let type = cell.cellData?.type, type == .location { if #available(iOS 14.0, *) { if manager.authorizationStatus == .denied { - showToast(chatLocalizable("location_not_auth")) + showSingleAlert(message: commonLocalizable("jump_location_setting")) {} return } else if manager.authorizationStatus == .notDetermined { manager.delegate = self @@ -628,7 +638,7 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel } } else { if CLLocationManager.authorizationStatus() == .denied { - showToast(chatLocalizable("location_not_auth")) + showSingleAlert(message: commonLocalizable("jump_location_setting")) {} return } else if CLLocationManager.authorizationStatus() == .notDetermined { manager.delegate = self @@ -645,9 +655,34 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel } else if let type = cell.cellData?.type, type == .file { isFile = true showBottomFileAction(self) + } else if let type = cell.cellData?.type, type == .rtc { + showRtcCallAction() } else {} } + func showRtcCallAction() { + var param = [String: AnyObject]() + param["remoteUserAccid"] = viewmodel.session.sessionId as AnyObject + param["currentUserAccid"] = NIMSDK.shared().loginManager.currentAccount() as AnyObject + param["remoteShowName"] = titleContent as AnyObject + if let user = viewmodel.repo.getUserInfo(userId: viewmodel.session.sessionId), let avatar = user.userInfo?.avatarUrl { + param["remoteAvatar"] = avatar as AnyObject + } + + let videoCallAction = UIAlertAction(title: chatLocalizable("video_call"), style: .default) { _ in + param["type"] = NSNumber(integerLiteral: 2) as AnyObject + Router.shared.use(CallViewRouter, parameters: param) + } + let audioCallAction = UIAlertAction(title: chatLocalizable("audio_call"), style: .default) { _ in + param["type"] = NSNumber(integerLiteral: 1) as AnyObject + Router.shared.use(CallViewRouter, parameters: param) + } + let cancelAction = UIAlertAction(title: chatLocalizable("cancel"), + style: .cancel) { action in + } + showActionSheet([videoCallAction, audioCallAction, cancelAction]) + } + func didToSearchLocationView() { let ctrl = NEDetailMapController(type: .search) navigationController?.pushViewController(ctrl, animated: true) @@ -668,8 +703,10 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel if viewmodel.session.sessionType == .P2P { return true } else { - showUserSelectVC(text: text) - return false + DispatchQueue.main.async { + self.showUserSelectVC(text: text) + } + return true } } else { @@ -688,11 +725,37 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel break } } + if index >= 0 { atUsers.remove(at: index) - if let text = menuView.textField.text { - menuView.textField.text = text - .substring(to: text.index(text.startIndex, offsetBy: removeRange!.location)) + if let rmRange = removeRange { + // 删除rmRange后,rmRange.location后面所有的atUser的location都发生了变化 + var atUsersTmp = [NSRange]() + for atUser in atUsers { + if rmRange.location < atUser.location { + atUsersTmp.append(NSRange(location: atUser.location - rmRange.length, length: atUser.length)) + } else { + atUsersTmp.append(atUser) + } + } + if atUsersTmp.count > 0 { + atUsers = atUsersTmp + } + + // 记录当前光标位置(removeSubrange后光标会直接跳到末尾) + var selRange = menuView.textField.selectedTextRange + if let oldCursor = menuView.textField.selectedTextRange { + if let newCursor = menuView.textField.position(from: oldCursor.start, offset: -rmRange.length) { + selRange = menuView.textField.textRange(from: newCursor, to: newCursor) + } + } + + // 删除rmRange范围内的字符串("@xxx ") + let subRange = menuView.textField.text.utf16.index(menuView.textField.text.startIndex, offsetBy: rmRange.location) ... menuView.textField.text.utf16.index(menuView.textField.text.startIndex, offsetBy: rmRange.location + rmRange.length - 1) + menuView.textField.text.removeSubrange(subRange) + + // 重新设置光标到删除前的位置 + menuView.textField.selectedTextRange = selRange } return false } @@ -720,6 +783,7 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel } public func willSelectItem(button: UIButton, index: Int) { + operationView?.removeFromSuperview() if index == 0 { layoutInputView(offset: 204) scrollTableViewToBottom() @@ -727,8 +791,6 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel layoutInputView(offset: 204) scrollTableViewToBottom() } else if index == 2 { - // showMenue(sourceView: view) - // showBottomAlert(self, false) goPhotoAlbumWithVideo(self) } else { // 更多 @@ -782,14 +844,8 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel present(imagePickerVC, animated: true) {} } - // MARK: UIImagePickerControllerDelegate - - public func imagePickerController(_ picker: UIImagePickerController, - didFinishPickingMediaWithInfo info: [UIImagePickerController - .InfoKey: Any]) { - // send message - - picker.dismiss(animated: true, completion: nil) + func sendMediaMessage(didFinishPickingMediaWithInfo info: [UIImagePickerController + .InfoKey: Any]) { var imageName = "IMG_0001" if isFile, let imgUrl = info[.referenceURL] as? URL { @@ -830,8 +886,7 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel let imgData = image.pngData() { let imgSize_MB = Double(imgData.count) / 1e6 print("@@# imgSize_MB: \(imgSize_MB) MB") - if let fileSizeLimit = NEKitChatConfig.shared.ui.fileSizeLimit, - imgSize_MB > fileSizeLimit { + if imgSize_MB > NEKitChatConfig.shared.ui.fileSizeLimit { showToast(chatLocalizable("fileSize_over_limit")) } else { viewmodel.sendFileMessage(data: imgData, displayName: imageName) { [weak self] error in @@ -858,6 +913,19 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel } } + // MARK: UIImagePickerControllerDelegate + + public func imagePickerController(_ picker: UIImagePickerController, + didFinishPickingMediaWithInfo info: [UIImagePickerController + .InfoKey: Any]) { +// picker.dismiss(animated: true, completion: nil) +// sendMediaMessage(didFinishPickingMediaWithInfo: info) + weak var weakSelf = self + picker.dismiss(animated: true, completion: { + weakSelf?.sendMediaMessage(didFinishPickingMediaWithInfo: info) + }) + } + public func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { picker.dismiss(animated: true) isFile = false @@ -884,8 +952,7 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel print("@@# size:\(size_B)B") let size_MB = size_B / 1e6 print("@@# size:\(size_MB)MB") - if let fileSizeLimit = NEKitChatConfig.shared.ui.fileSizeLimit, - size_MB > fileSizeLimit { + if size_MB > NEKitChatConfig.shared.ui.fileSizeLimit { showToast(chatLocalizable("fileSize_over_limit")) try? FileManager.default.removeItem(atPath: desPath) } else { @@ -939,14 +1006,32 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel // MARK: ChatViewModelDelegate + public func didLeaveTeam() { + weak var weakSelf = self + showSingleAlert(message: chatLocalizable("team_has_quit")) { + weakSelf?.navigationController?.popViewController(animated: true) + } + } + + public func didDismissTeam() { + weak var weakSelf = self + showSingleAlert(message: chatLocalizable("team_has_been_removed")) { + weakSelf?.navigationController?.popViewController(animated: true) + } + } + public func onRecvMessages(_ messages: [NIMMessage]) { insertRows() - viewmodel.markRead(messages: messages) { error in - NELog.infoLog( - ModuleName + " " + self.tag, - desc: "CALLBACK markRead " + (error?.localizedDescription ?? "no error") - ) -// print("mark read \(error?.localizedDescription)") + if isCurrentPage, + UIApplication.shared.applicationState == .active { + viewmodel.markRead(messages: messages) { error in + NELog.infoLog( + ModuleName + " " + self.tag, + desc: "CALLBACK markRead " + (error?.localizedDescription ?? "no error") + ) + } + } else { + needMarkReadMsgs += messages } } @@ -1030,12 +1115,12 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel } public func didReadedMessageIndexs() { - if let indexPaths = tableView.indexPathsForVisibleRows, indexPaths.count > 0 { - tableView.beginUpdates() - // self.tableView.reloadRows(at: indexs, with: .none) - tableView.reloadRows(at: indexPaths, with: .none) - tableView.endUpdates() - } + tableView.reloadData() +// if let indexPaths = tableView.indexPathsForVisibleRows, indexPaths.count > 0 { +// tableView.beginUpdates() +// tableView.reloadRows(at: indexPaths, with: .none) +// tableView.endUpdates() +// } } public func tableViewUpdateDownload(_ index: IndexPath) { @@ -1050,11 +1135,11 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel if NEAuthManager.hasAudioAuthoriztion() { NIMSDK.shared().mediaManager.record(forDuration: dur) } else { - NEAuthManager.requestAudioAuthorization { granted in + NEAuthManager.requestAudioAuthorization { [weak self] granted in if granted { } else { DispatchQueue.main.async { - self.showToast(chatLocalizable("no_microphone_permission")) + self?.showSingleAlert(message: commonLocalizable("jump_microphone_setting")) {} } } } @@ -1077,11 +1162,16 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel } func viewTap(tap: UITapGestureRecognizer) { - operationView?.removeFromSuperview() - if menuView.textField.isFirstResponder { - menuView.textField.resignFirstResponder() + if let opeView = operationView, + view.subviews.contains(opeView) { + opeView.removeFromSuperview() + } else { - layoutInputView(offset: 0) + if menuView.textField.isFirstResponder { + menuView.textField.resignFirstResponder() + } else { + layoutInputView(offset: 0) + } } } @@ -1234,33 +1324,58 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel } } + func addToAtUsers(addText: String, isReply: Bool = false) { + // @列表中添加一项 + let anIndex = menuView.textField.selectedRange.location + var range = NSRange(location: anIndex - 1, length: addText.utf16.count + 1) + if isReply { + range = NSRange(location: anIndex, length: addText.utf16.count) + } + atUsers.append(range) + + // 添加range后,range.location后面所有的atUser的location都发生了变化 + var atUsersTmp = [NSRange]() + for atUser in atUsers { + if range.location < atUser.location { + atUsersTmp.append(NSRange(location: atUser.location + range.length, length: atUser.length)) + } else { + atUsersTmp.append(atUser) + } + } + if atUsersTmp.count > 0 { + atUsers = atUsersTmp + } + + // range范围内添加字符串("@xxx ") + if let pos = menuView.textField.selectedTextRange { + // 用replace代替insert(start==end) + menuView.textField.replace(pos, withText: addText) + } else { + menuView.textField.text += addText + } + } + private func showUserSelectVC(text: String) { - let selectVC = SelectUserViewController(sessionId: viewmodel.session.sessionId) + let selectVC = SelectUserViewController(sessionId: viewmodel.session.sessionId, showSelf: false) selectVC.modalPresentationStyle = .formSheet selectVC.selectedBlock = { [weak self] index, model in - var resultText = "" - var location = 0 - var length = 0 - if let t = self?.menuView.textField.text, t.count > 0 { - resultText = t - location = t.count - } + var addText = "" + if index == 0 { - let addText = text + chatLocalizable("user_select_all") + " " - resultText += addText - length = addText.count - let range = NSRange(location: location, length: length) - self?.atUsers.append(range) + addText += chatLocalizable("user_select_all") + " " } else { if let m = model { - let addText = text + m.atNameInTeam() + " " - resultText += addText - length = addText.count - let range = NSRange(location: location, length: length) - self?.atUsers.append(range) + var name = "" + if let nick = m.nimUser?.userInfo?.nickName { + name = nick + } else if let uid = m.nimUser?.userId { + name = uid + } + addText += name + " " } } - self?.menuView.textField.text = resultText + + self?.addToAtUsers(addText: addText) } present(selectVC, animated: true, completion: nil) } @@ -1294,10 +1409,10 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel private func copyMessage() { if let model = viewmodel.operationModel as? MessageTextModel, - let text = model.attributeStr { + let text = model.message?.text { let pasteboard = UIPasteboard.general - pasteboard.string = text.string - showToast(chatLocalizable("copy_success")) + pasteboard.string = text + view.makeToast(chatLocalizable("copy_success"), duration: 2, position: .center) } } @@ -1322,10 +1437,16 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel ]) if let message = viewmodel.operationModel?.message { var text = chatLocalizable("msg_reply") - if let name = viewmodel.operationModel?.shortName { - text += name + if let uid = message.from { + let user = viewmodel.getUserInfo(userId: uid) + let name = user?.userInfo?.nickName + if viewmodel.session.sessionType != .P2P, + !IMKitClient.instance.isMySelf(uid) { + addToAtUsers(addText: "@" + (name ?? uid) + " ", isReply: true) + } + text += " " + (name ?? uid) } - text += ":" + text += ": " switch message.messageType { case .text: if let t = message.text { @@ -1347,6 +1468,7 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel text += "" } replyView.textLabel.text = text + menuView.textField.becomeFirstResponder() } } @@ -1362,6 +1484,9 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel if let messageType = weakSelf?.viewmodel.operationModel?.message?.messageType, messageType == .text { weakSelf?.viewmodel.operationModel?.isRevokedText = true } +// DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + .seconds(120)) { +// weakSelf?.tableView.reloadData() +// } weakSelf?.viewmodel.revokeMessage(message: message) { error in NELog.infoLog( ModuleName + " " + (weakSelf?.tag ?? ""), @@ -1427,6 +1552,10 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel weakSelf?.addChild(forwardAlert) weakSelf?.view.addSubview(forwardAlert.view) + DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: DispatchWorkItem(block: { + UIApplication.shared.keyWindow?.endEditing(true) + })) + forwardAlert.sureBlock = { print("sure click ") weakSelf?.viewmodel.forwardUserMessage(message, users) @@ -1458,9 +1587,14 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel if let senderName = message.senderName { forwardAlert.context = senderName } + forwardAlert.sureBlock = { + weakSelf?.viewmodel.forwardTeamMessage(message, team) + } weakSelf?.addChild(forwardAlert) weakSelf?.view.addSubview(forwardAlert.view) - weakSelf?.viewmodel.forwardTeamMessage(message, team) + DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: DispatchWorkItem(block: { + UIApplication.shared.keyWindow?.endEditing(true) + })) } } @@ -1475,7 +1609,7 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel style: .cancel) { action in } - showActionSheet([userAction, teamAction, cancelAction]) + showActionSheet([teamAction, userAction, cancelAction]) } } @@ -1520,7 +1654,9 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel // MARK: UITableViewDataSource, UITableViewDelegate public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - viewmodel.messages.count ?? 0 + let count = viewmodel.messages.count + print("numberOfRowsInSection count : ", count) + return count } public func tableView(_ tableView: UITableView, @@ -1528,7 +1664,7 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel let model = viewmodel.messages[indexPath.row] var reuseId = "" if let isSend = model.message?.isOutgoingMsg, isSend { - if model.replyedModel != nil { + if model.replyedModel?.isReplay == true { reuseId = "\(ChatReplyRightCell.self)" } else { switch model.type { @@ -1548,6 +1684,8 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel reuseId = "\(ChatLocationRightCell.self)" case .file: reuseId = "\(ChatFileRightCell.self)" + case .rtcCallRecord: + reuseId = "\(ChatCallRecordRightCell.self)" default: reuseId = "\(ChatBaseRightCell.self)" } @@ -1569,7 +1707,7 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel return ChatBaseRightCell() } } else { - if model.replyedModel != nil { + if model.replyedModel?.isReplay == true { reuseId = "\(ChatReplyLeftCell.self)" } else { switch model.type { @@ -1589,6 +1727,8 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel reuseId = "\(ChatRevokeLeftCell.self)" case .location: reuseId = "\(ChatLocationLeftCell.self)" + case .rtcCallRecord: + reuseId = "\(ChatCallRecordLeftCell.self)" default: reuseId = "\(ChatBaseLeftCell.self)" } @@ -1627,6 +1767,22 @@ open class ChatViewController: ChatBaseViewController, UINavigationControllerDel return CGFloat(m.height) } + public func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { + 0 + } + + public func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat { + 0 + } + + // MARK: UIScrollViewDelegate + + public func scrollViewDidScroll(_ scrollView: UIScrollView) { + operationView?.removeFromSuperview() + } + + // MARK: CLLocationManagerDelegate + // public func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { // if #available(iOS 14.0, *) { // if manager.authorizationStatus == .authorizedAlways || manager.authorizationStatus == .authorizedWhenInUse { @@ -1702,6 +1858,7 @@ extension ChatViewController: ChatBaseCellDelegate { } else if model?.type == .video, let object = model?.message?.messageObject as? NIMVideoObject { print("video click") + stopPlay() weak var weakSelf = self let videoPlayer = VideoPlayerViewController() videoPlayer.modalPresentationStyle = .overFullScreen @@ -1810,8 +1967,22 @@ extension ChatViewController: ChatBaseCellDelegate { } } } + } else if model?.type == .rtcCallRecord, let object = model?.message?.messageObject as? NIMRtcCallRecordObject { + var param = [String: AnyObject]() + param["remoteUserAccid"] = viewmodel.session.sessionId as AnyObject + param["currentUserAccid"] = NIMSDK.shared().loginManager.currentAccount() as AnyObject + param["remoteShowName"] = titleContent as AnyObject + if let user = viewmodel.repo.getUserInfo(userId: viewmodel.session.sessionId), let avatar = user.userInfo?.avatarUrl { + param["remoteAvatar"] = avatar as AnyObject + } + if object.callType == .audio { + param["type"] = NSNumber(integerLiteral: 1) as AnyObject + } else { + param["type"] = NSNumber(integerLiteral: 2) as AnyObject + } + Router.shared.use(CallViewRouter, parameters: param) } else { - print(#function + "message did tap but type else") + print(#function + "message did tap but type unknow") } } @@ -1820,16 +1991,42 @@ extension ChatViewController: ChatBaseCellDelegate { } public func didTapResendView(_ cell: UITableViewCell, _ model: MessageContentModel?) { - if let msg = model?.message { + if playingCell?.messageId == model?.message?.messageId { + if playingCell?.isPlaying == true { + stopPlay() + } + } + if let m = model, let msg = m.message { + let messages = viewmodel.messages + var index = -1 + for i in 0 ..< messages.count { + if let message = messages[i].message { + if message.messageId == msg.messageId { + index = i + break + } + } + } + if index >= 0 { + viewmodel.messages.remove(at: index) + viewmodel.messages.append(m) + } viewmodel.resendMessage(message: msg) } } public func didTapReeditButton(_ cell: UITableViewCell, _ model: MessageContentModel?) { - if model?.type == .revoke, model?.message?.messageType == .text { + if model?.type == .revoke, model?.message?.messageType == .text, let message = model?.message { + let time = message.timestamp + let date = Date() + let currentTime = date.timeIntervalSince1970 + if currentTime - time >= 60 * 2 { + showToast(chatLocalizable("editable_time_expired")) + tableView.reloadData() + return + } menuView.textField.text = model?.message?.text menuView.textField.becomeFirstResponder() - let date = Date() } } diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/Controller/GroupChatViewController.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/Controller/GroupChatViewController.swift index 22bd1eeb..f965207a 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/Controller/GroupChatViewController.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/Controller/GroupChatViewController.swift @@ -46,9 +46,20 @@ open class GroupChatViewController: ChatViewController, TeamChatViewModelDelegat if team.inAllMuteMode(), team.owner != NIMSDK.shared().loginManager.currentAccount() { menuView.textField.isEditable = false menuView.textField.placeholder = chatLocalizable("team_mute") as NSString? + layoutInputView(offset: 0) + menuView.stackView.isUserInteractionEnabled = false } else { menuView.textField.isEditable = true - menuView.textField.placeholder = (chatLocalizable("send_to") + team.getShowName()) as NSString? + let text = "\(chatLocalizable("send_to"))\(team.getShowName())" as NSString? +// let attribute = NSMutableAttributedString(string: text) +// let style = NSMutableParagraphStyle() +// style.lineBreakMode = .byTruncatingTail +// style.alignment = .left +// attribute.addAttribute(.paragraphStyle, value: style, range: NSMakeRange(0, text.count)) +// attribute.addAttribute(.font, value: UIFont.systemFont(ofSize: 16), range: NSMakeRange(0, text.count)) +// attribute.addAttribute(.foregroundColor, value: UIColor.gray, range: NSMakeRange(0, text.count)) + menuView.textField.placeholder = text + menuView.stackView.isUserInteractionEnabled = true } } @@ -56,9 +67,24 @@ open class GroupChatViewController: ChatViewController, TeamChatViewModelDelegat public func onTeamRemoved(team: NIMTeam) { navigationController?.popViewController(animated: true) + + /* 后续优化逻辑,暂时不做修改 + if team.clientCustomInfo?.contains(discussTeamKey) == true { + navigationController?.popViewController(animated: true) + return + } + if team.teamId == viewmodel.session.sessionId { + weak var weakSelf = self + showSingleAlert(message: chatLocalizable("team_has_been_removed")) { + weakSelf?.navigationController?.popViewController(animated: true) + } + } */ } public func onTeamUpdate(team: NIMTeam) { + if team.teamId != viewmodel.session.sessionId { + return + } updateTeamInfo(team: team) } } diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/Controller/P2PChatViewController.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/Controller/P2PChatViewController.swift index 8a7dbcb9..aa13d6a4 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/Controller/P2PChatViewController.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/Controller/P2PChatViewController.swift @@ -20,6 +20,16 @@ open class P2PChatViewController: ChatViewController { title = showName titleContent = showName menuView.textField.placeholder = (chatLocalizable("send_to") + showName) as NSString? +// let text = "\(chatLocalizable("send_to"))\(showName))" +// menuView.textField.placeholder = text +// let attribute = NSMutableAttributedString(string: text) +// let style = NSMutableParagraphStyle() +// style.lineBreakMode = .byTruncatingTail +// style.alignment = .left +// attribute.addAttribute(.font, value: UIFont.systemFont(ofSize: 16), range: NSMakeRange(0, text.count)) +// attribute.addAttribute(.foregroundColor, value: UIColor.gray, range: NSMakeRange(0, text.count)) +// attribute.addAttribute(.paragraphStyle, value: style, range: NSMakeRange(0, text.count)) +// menuView.textField.attributedPlaceholder = attribute } /// 创建个人聊天页构造方法 diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/Controller/SelectUserViewController.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/Controller/SelectUserViewController.swift index 34141f4a..8cfc992b 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/Controller/SelectUserViewController.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/Controller/SelectUserViewController.swift @@ -5,7 +5,7 @@ import UIKit import NEChatKit - +import NECoreIMKit public typealias DidSelectedAtRow = (_ index: Int, _ model: ChatTeamMemberInfoModel?) -> Void @objcMembers @@ -16,10 +16,12 @@ public class SelectUserViewController: ChatBaseViewController, UITableViewDelega public var viewModel = TeamMemberSelectVM() public var selectedBlock: DidSelectedAtRow? var teamInfo: ChatTeamInfoModel? + private var showSelf = true // 是否展示自己 private let className = "SelectUserViewController" - init(sessionId: String) { + init(sessionId: String, showSelf: Bool = true) { self.sessionId = sessionId + self.showSelf = showSelf super.init(nibName: nil, bundle: nil) } @@ -114,6 +116,16 @@ public class SelectUserViewController: ChatBaseViewController, UITableViewDelega self?.view.makeToast(error?.localizedDescription) return } + + // 人员选择页面移除自己 + if !(self?.showSelf ?? true), + let users = team?.users { + for (index, user) in users.enumerated() { + if user.nimUser?.userId == IMKitLoginManager.instance.currentAccount() { + team?.users.remove(at: index) + } + } + } self?.teamInfo = team self?.tableView.reloadData() } diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/Emoji/InputEmoticonContainerView.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/Emoji/InputEmoticonContainerView.swift index 126403f4..10c98694 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/Emoji/InputEmoticonContainerView.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/Emoji/InputEmoticonContainerView.swift @@ -4,7 +4,7 @@ // found in the LICENSE file. import UIKit - +import NECoreIMKit @objc public protocol InputEmoticonContainerViewDelegate: NSObjectProtocol { func selectedEmoticon(emoticonID: String, emotCatalogID: String, description: String) func didPressSend(sender: UIButton) diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/Emoji/InputEmoticonTabView.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/Emoji/InputEmoticonTabView.swift index 99938280..eaa66675 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/Emoji/InputEmoticonTabView.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/Emoji/InputEmoticonTabView.swift @@ -4,7 +4,7 @@ // found in the LICENSE file. import UIKit - +import NECoreIMKit @objc public protocol InputEmoticonTabViewDelegate: NSObjectProtocol { @objc optional func tabView(_ tabView: InputEmoticonTabView?, didSelectTabIndex index: Int) } diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/Emoji/NIMInputEmoticonButton.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/Emoji/NIMInputEmoticonButton.swift index e8baa96c..524b4d04 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/Emoji/NIMInputEmoticonButton.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/Emoji/NIMInputEmoticonButton.swift @@ -4,7 +4,7 @@ // found in the LICENSE file. import UIKit - +import NECoreIMKit public protocol NIMInputEmoticonButtonDelegate: NSObjectProtocol { func selectedEmoticon(emotion: NIMInputEmoticon, catalogID: String) } diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/Emoji/NIMInputEmoticonManager.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/Emoji/NIMInputEmoticonManager.swift index 08ea7fd6..132c9ca9 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/Emoji/NIMInputEmoticonManager.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/Emoji/NIMInputEmoticonManager.swift @@ -4,7 +4,7 @@ // found in the LICENSE file. import UIKit - +import NECoreIMKit public enum NIMEmoticonType: NSInteger { case file = 0 case unicode diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/Helper/NotificationMessageUtils.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/Helper/NotificationMessageUtils.swift index 29bfc3c4..d8f171dd 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/Helper/NotificationMessageUtils.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/Helper/NotificationMessageUtils.swift @@ -29,6 +29,53 @@ public class NotificationMessageUtils: NSObject { return "" } + public class func isDiscussSeniorTeamUpdateCustomNoti(message: NIMMessage) -> Bool { + if let object = message.messageObject as? NIMNotificationObject { + guard let content = object.content as? NIMTeamNotificationContent else { + return false + } + + // 转移讨论组的通知 + if content.operationType == .transferOwner, + teamName(message: message) == chatLocalizable("discussion_group") { + return true + } + + if content.operationType != .update { + return false + } + guard let attach = content.attachment as? NIMUpdateTeamInfoAttachment, + let tag = attach.values?.keys.first?.intValue else { + return false + } + + if tag == 18 || tag == 19 { + return true + } + } + return false + } + + public class func isTeamLeaveOrDismiss(message: NIMMessage) -> (isLeave: Bool, isDismiss: Bool) { + var leave = false + var dismiss = false + if let object = message.messageObject as? NIMNotificationObject, object.notificationType == .team { + if let content = object.content as? NIMTeamNotificationContent { + switch content.operationType { + case .leave: + leave = true + + case .dismiss: + dismiss = true + + @unknown default: + break + } + } + } + return (leave, dismiss) + } + public class func textForTeamNotificationMessage(message: NIMMessage) -> String { var text = chatLocalizable("unknown_system_message") if let object = message.messageObject as? NIMNotificationObject { @@ -96,7 +143,8 @@ public class NotificationMessageUtils: NSObject { if let atta = content.attachment as? NIMMuteSuperTeamMemberAttachment { mute = atta.flag } - text = mute ? chatLocalizable("team_all_mute") : chatLocalizable("team_all_no_mute") + // text = mute ? chatLocalizable("team_all_mute") : chatLocalizable("team_all_no_mute") + text = "\(toNamestext) \(mute ? chatLocalizable("mute") : chatLocalizable("not_mute"))" default: text = chatLocalizable("unknown_system_message") @@ -142,7 +190,7 @@ public class NotificationMessageUtils: NSObject { public class func teamName(message: NIMMessage) -> String { let team = TeamProvider.shared.teamInfo(teamId: message.session?.sessionId) - if team?.type == .normalTeam { + if team?.type == .normalTeam || (team?.type == .advancedTeam && team?.nimTeam?.clientCustomInfo?.contains(discussTeamKey) == true) { return chatLocalizable("discussion_group") } else { return chatLocalizable("group") @@ -152,55 +200,68 @@ public class NotificationMessageUtils: NSObject { private class func textOfUpdateTeam(fromName: String, teamName: String, content: NIMTeamNotificationContent) -> String { var text = fromName + chatLocalizable("has_updated") + teamName - guard let attach = content.attachment as? NIMUpdateTeamInfoAttachment else { - return text - } - if attach.values?.count == 1 { - let tag = attach.values?.keys.first?.intValue - switch tag { - case 3: - text = fromName + chatLocalizable("has_updated") + teamName + " " + - chatLocalizable("team_name") - case 14: - text = fromName + chatLocalizable("has_updated") + teamName + " " + - chatLocalizable("team_intro") - case 15: - text = fromName + chatLocalizable("has_updated") + teamName + " " + - chatLocalizable("team_anouncement") - case 16: - text = fromName + chatLocalizable("has_updated") + teamName + " " + - chatLocalizable("team_join_mode") - case 18: - text = fromName + chatLocalizable("has_updated") + " " + chatLocalizable("team_custom_info") - case 19: - text = fromName + chatLocalizable("has_updated") + " " + chatLocalizable("team_custom_info") - case 20: - text = fromName + chatLocalizable("has_updated") + teamName + " " + - chatLocalizable("team_avatar") - case 21: - text = fromName + chatLocalizable("has_updated") + " " + - chatLocalizable("team_be_invited_author") - case 22: - text = fromName + chatLocalizable("has_updated") + " " + - chatLocalizable("team_be_invited_permission") - case 23: - text = fromName + chatLocalizable("has_updated") + " " + - chatLocalizable("team_update_info_permission") - case 24: - text = fromName + chatLocalizable("has_updated") + " " + - chatLocalizable("team_update_client_custom") - case 100: - let muteState = attach.values?.values.first - - if muteState == "0" { - text = teamName + chatLocalizable("not_mute") - } else { - text = teamName + chatLocalizable("mute") + if let attach = content.attachment as? NIMUpdateTeamInfoAttachment { + if let tag = attach.values?.keys.first?.intValue { + let string = getShowString(fromName, teamName, tag, attach.values?.values.first) + if string.count > 0 { + text = string } - default: - text = fromName + chatLocalizable("has_updated") + teamName } } + if let attach = content.attachment as? NIMMuteTeamMemberAttachment { + if attach.flag == false { + text = teamName + chatLocalizable("team_all_mute") + } else { + text = teamName + chatLocalizable("team_all_no_mute") + } + } + return text + } + + private class func getShowString(_ fromName: String, _ teamName: String, _ tag: Int, _ muteState: String?) -> String { + var text = "" + switch tag { + case 3: + text = fromName + chatLocalizable("has_updated") + teamName + " " + + chatLocalizable("team_name") + case 14: + text = fromName + chatLocalizable("has_updated") + teamName + " " + + chatLocalizable("team_intro") + case 15: + text = fromName + chatLocalizable("has_updated") + teamName + " " + + chatLocalizable("team_anouncement") + case 16: + text = fromName + chatLocalizable("has_updated") + teamName + " " + + chatLocalizable("team_join_mode") + case 18: + text = fromName + chatLocalizable("has_updated") + " " + chatLocalizable("team_custom_info") + case 19: + text = fromName + chatLocalizable("has_updated") + " " + chatLocalizable("team_custom_info") + case 20: + text = fromName + chatLocalizable("has_updated") + teamName + " " + + chatLocalizable("team_avatar") + case 21: + text = fromName + chatLocalizable("has_updated") + " " + + chatLocalizable("team_be_invited_author") + case 22: + text = fromName + chatLocalizable("has_updated") + " " + + chatLocalizable("team_be_invited_permission") + case 23: + text = fromName + chatLocalizable("has_updated") + " " + + chatLocalizable("team_update_info_permission") + case 24: + text = fromName + chatLocalizable("has_updated") + " " + + chatLocalizable("team_update_client_custom") + case 100: + + if muteState == "1" || muteState == "3" { + text = chatLocalizable("team_all_mute") + } else if muteState == "0" { + text = chatLocalizable("team_all_no_mute") + } + default: + text = fromName + chatLocalizable("has_updated") + teamName + } return text } } diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/Helper/ReplyMessageUtil.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/Helper/ReplyMessageUtil.swift index 2ce4891e..bc62c91f 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/Helper/ReplyMessageUtil.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/Helper/ReplyMessageUtil.swift @@ -16,6 +16,8 @@ public class ReplyMessageUtil: NSObject { case .text: if let t = model.message?.text { text += t + } else { + text = chatLocalizable("message_not_found") } case .image: text += "[\(chatLocalizable("msg_image"))]" diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/Model/MessageCallRecordModel.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/Model/MessageCallRecordModel.swift new file mode 100644 index 00000000..e5f11880 --- /dev/null +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/Model/MessageCallRecordModel.swift @@ -0,0 +1,76 @@ + +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +import UIKit +import NIMSDK + +@objcMembers +class MessageCallRecordModel: MessageContentModel { + public var attributeStr: NSMutableAttributedString? + + required init(message: NIMMessage?) { + super.init(message: message) + type = .rtcCallRecord + var isAuiodRecord = false + if let object = message?.messageObject as? NIMRtcCallRecordObject, let isSend = message?.isOutgoingMsg { + attributeStr = NSMutableAttributedString() + var image: UIImage? + var bound = CGRect.zero + let offset: CGFloat = -1 + if object.callType == .audio { + isAuiodRecord = true + image = coreLoader.loadImage("audio_record") + bound = CGRect(x: 0, y: offset - 5, width: 24, height: 24) + } else { + image = coreLoader.loadImage("video_record") + bound = CGRect(x: 0, y: offset, width: 24, height: 14) + } + switch object.callStatus { + case .complete: + var timeString = "00:00" + if let duration = object.durations[NIMSDK.shared().loginManager.currentAccount()] { + timeString = Date.getFormatPlayTime(duration.doubleValue) + } + attributeStr?.append(NSAttributedString(string: chatLocalizable("call_complete") + " \(timeString)")) + case .canceled: + attributeStr?.append(NSAttributedString(string: chatLocalizable("call_canceled"))) + case .rejected: + attributeStr?.append(NSAttributedString(string: chatLocalizable("call_rejected"))) + case .timeout: + attributeStr?.append(NSAttributedString(string: chatLocalizable("call_timeout"))) + case .busy: + attributeStr?.append(NSAttributedString(string: chatLocalizable("call_busy"))) + default: + break + } + let attachment = NSTextAttachment() + attachment.image = image + attachment.bounds = bound + if isSend { + attributeStr?.append(NSAttributedString(string: " ")) + attributeStr?.append(NSAttributedString(attachment: attachment)) + } else { + attributeStr?.insert(NSAttributedString(string: " "), at: 0) + attributeStr?.insert(NSAttributedString(attachment: attachment), at: 0) + } + + attributeStr?.addAttribute(NSAttributedString.Key.font, value: NEKitChatConfig.shared.ui.messageFont, range: NSMakeRange(0, attributeStr?.length ?? 0)) + + attributeStr?.addAttribute(NSAttributedString.Key.foregroundColor, value: NEKitChatConfig.shared.ui.messageColor, range: NSMakeRange(0, attributeStr?.length ?? 0)) + } + + let textSize = NEChatUITool.getSizeWithAtt( + att: attributeStr ?? NSAttributedString(string: ""), + font: DefaultTextFont(16), + maxSize: CGSize(width: qChat_content_maxW, height: CGFloat.greatestFiniteMagnitude) + ) + + var h = qChat_min_h + h = textSize.height + (isAuiodRecord ? 20 : 24) + contentSize = CGSize(width: textSize.width + qChat_cell_margin * 2, height: h) + + height = Float(contentSize.height + qChat_margin) + fullNameHeight + } +} diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/Model/MessageContentModel.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/Model/MessageContentModel.swift index 9fe2c65b..feb91336 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/Model/MessageContentModel.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/Model/MessageContentModel.swift @@ -11,6 +11,8 @@ import NECoreIMKit @objcMembers public class MessageContentModel: NSObject, MessageModel { + public var isReplay: Bool = false + public var pinAccount: String? public var pinShowName: String? public var type: MessageType = .custom @@ -27,7 +29,7 @@ public class MessageContentModel: NSObject, MessageModel { public var replyedModel: MessageModel? { didSet { - if let reply = replyedModel as? MessageContentModel { + if let reply = replyedModel as? MessageContentModel, reply.isReplay == true { replyText = ReplyMessageUtil.textForReplyModel(model: reply) if let t = replyText { let size = String.getTextRectSize( @@ -62,12 +64,12 @@ public class MessageContentModel: NSObject, MessageModel { if let time = message?.timestamp { let date = Date() let currentTime = date.timeIntervalSince1970 - if currentTime - time > 60 * 5 { + if currentTime - time > 60 * 2 { timeOut = true } } // 只有文本消息,才计算可编辑按钮的宽度 - if let isSend = message?.isOutgoingMsg, isSend, message?.messageType == .text, isRevokedText == true, timeOut == false { + if let isSend = message?.isOutgoingMsg, isSend, message?.messageType == .text, timeOut == false { contentSize = CGSize(width: 218, height: qChat_min_h) } else { contentSize = CGSize(width: 130, height: qChat_min_h) diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/Model/MessageModel.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/Model/MessageModel.swift index f47d6fe8..45c68297 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/Model/MessageModel.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/Model/MessageModel.swift @@ -45,6 +45,7 @@ public protocol MessageModel: NSObjectProtocol { var replyedModel: MessageModel? { get set } var replyText: String? { get set } var isRevokedText: Bool { get set } + var isReplay: Bool { get set } init(message: NIMMessage?) } diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/Model/MessageTextModel.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/Model/MessageTextModel.swift index 2db36b99..d8222142 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/Model/MessageTextModel.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/Model/MessageTextModel.swift @@ -8,13 +8,12 @@ import NIMSDK @objcMembers class MessageTextModel: MessageContentModel { -// public var text: String? public var attributeStr: NSAttributedString? required init(message: NIMMessage?) { super.init(message: message) type = .text -// text = message?.text + attributeStr = NEEmotionTool.getAttWithStr( str: message?.text ?? "", font: NEKitChatConfig.shared.ui.messageFont @@ -35,6 +34,6 @@ class MessageTextModel: MessageContentModel { height = Float(contentSize.height + qChat_margin) + fullNameHeight - print(">>text:\(message?.text) height:\(height)") +// print(">>text:\(message?.text) height:\(height)") } } diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/Model/MessageTipsModel.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/Model/MessageTipsModel.swift index 4e43e367..5b24c458 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/Model/MessageTipsModel.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/Model/MessageTipsModel.swift @@ -8,6 +8,12 @@ import NIMSDK @objcMembers class MessageTipsModel: NSObject, MessageModel { + var tipTimeStamp: TimeInterval? + + var isReplay: Bool = false + + var pinToAccount: String? + var pinFromAccount: String? var isPined: Bool = false var pinAccount: String? var pinShowName: String? @@ -23,6 +29,7 @@ class MessageTipsModel: NSObject, MessageModel { var isRevoked: Bool = false var replyedModel: MessageModel? var isRevokedText: Bool = false + weak var tipMessage: NIMMessage? required init(message: NIMMessage?) { if let msg = message { if msg.messageType == .notification { @@ -33,6 +40,8 @@ class MessageTipsModel: NSObject, MessageModel { type = .tip } } + tipMessage = message + tipTimeStamp = message?.timestamp contentSize = CGSize(width: kScreenWidth, height: 35) height = 35 } diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/Model/NEMoreItemModel.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/Model/NEMoreItemModel.swift index 449493ed..0b1518c3 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/Model/NEMoreItemModel.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/Model/NEMoreItemModel.swift @@ -1,6 +1,3 @@ -// -// NEMoreItemModel.swift -// NEChatUIKit // Copyright (c) 2022 NetEase, Inc. All rights reserved. // Use of this source code is governed by a MIT license that can be @@ -20,11 +17,20 @@ public enum NEMoreActionType: Int { public class NEMoreItemModel: NSObject { // 单元图标 - var image: UIImage? + public var image: UIImage? // 单元名称 - var title: String? + public var title: String? // 对应的单元类型 - var type: NEMoreActionType? + public var type: NEMoreActionType? + + // 代理类 + public var customDelegate: AnyObject? + + // 动态事件 + public var action: Selector? + + // 自定义图标 + public var customImage: UIImage? } diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatAudioLeftCell.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatAudioLeftCell.swift index cec68640..03acf188 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatAudioLeftCell.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatAudioLeftCell.swift @@ -10,7 +10,7 @@ public class ChatAudioLeftCell: ChatBaseLeftCell, ChatAudioCell { var isPlaying: Bool = false var audioImageView = UIImageView(image: UIImage.ne_imageNamed(name: "left_play_3")) var timeLabel = UILabel() - + var messageId: String? override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) commonUI() @@ -69,6 +69,7 @@ public class ChatAudioLeftCell: ChatBaseLeftCell, ChatAudioCell { if let m = model as? MessageAudioModel { timeLabel.text = "\(m.duration)" + "s" m.isPlaying ? startAnimation() : stopAnimation() + messageId = m.message?.messageId } } } diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatAudioRightCell.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatAudioRightCell.swift index 3c32eb97..d0c1dfff 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatAudioRightCell.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatAudioRightCell.swift @@ -7,12 +7,14 @@ import UIKit protocol ChatAudioCell { var isPlaying: Bool { get set } + var messageId: String? { get set } func startAnimation() func stopAnimation() } @objcMembers public class ChatAudioRightCell: ChatBaseRightCell, ChatAudioCell { + var messageId: String? var isPlaying: Bool = false var audioImageView = UIImageView(image: UIImage.ne_imageNamed(name: "audio_play")) var timeLabel = UILabel() @@ -81,6 +83,7 @@ public class ChatAudioRightCell: ChatBaseRightCell, ChatAudioCell { if let m = model as? MessageAudioModel { timeLabel.text = "\(m.duration)" + "s" m.isPlaying ? startAnimation() : stopAnimation() + messageId = m.message?.messageId } } } diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatBaseLeftCell.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatBaseLeftCell.swift index 5fba75b9..9a70b02f 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatBaseLeftCell.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatBaseLeftCell.swift @@ -4,7 +4,7 @@ // found in the LICENSE file. import UIKit - +import NIMSDK @objcMembers public class ChatBaseLeftCell: ChatBaseCell { public var avatarImage = UIImageView() @@ -127,7 +127,6 @@ public class ChatBaseLeftCell: ChatBaseCell { contentView.addSubview(pinLabel) pinLabel.translatesAutoresizingMaskIntoConstraints = false pinLabel.textAlignment = .left -// pinLabel.text = localizable("pin_text") pinLabel.font = UIFont.systemFont(ofSize: 12) pinLabel.textColor = UIColor.ne_greenText pinLabel.isHidden = true @@ -213,7 +212,7 @@ public class ChatBaseLeftCell: ChatBaseCell { } fullNameH?.constant = CGFloat(model.fullNameHeight) avatarImage.backgroundColor = UIColor - .colorWithNumber(number: UInt64(model.message?.from ?? "0")) + .colorWithString(string: model.message?.from) if let avatarURL = model.avatar { avatarImage .sd_setImage(with: URL(string: avatarURL)) { [weak self] image, error, type, url in @@ -246,9 +245,15 @@ public class ChatBaseLeftCell: ChatBaseCell { contentView.backgroundColor = model.isPined ? NEKitChatConfig.shared.ui .chatPinColor : .white if model.isPined { - if let text = model.pinShowName { - pinLabel.text = text + chatLocalizable("pin_text") + let pinText = model.message?.session?.sessionType == .P2P ? chatLocalizable("pin_text_P2P") : chatLocalizable("pin_text_team") + if model.pinAccount == nil { + pinLabel.text = chatLocalizable("You") + pinText + } else if let account = model.pinAccount, account == NIMSDK.shared().loginManager.currentAccount() { + pinLabel.text = chatLocalizable("You") + pinText + } else if let text = model.pinShowName { + pinLabel.text = text + pinText } + pinImage.image = UIImage.ne_imageNamed(name: "msg_pin") pinLabelH?.constant = chat_pin_height diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatBaseRightCell.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatBaseRightCell.swift index bfb55187..42d3c03c 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatBaseRightCell.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatBaseRightCell.swift @@ -6,7 +6,7 @@ import UIKit import NECoreIMKit import NECoreKit - +import NIMSDK public protocol ChatBaseCellDelegate: NSObjectProtocol { func didTapAvatarView(_ cell: UITableViewCell, _ model: MessageContentModel?) func didTapMessageView(_ cell: UITableViewCell, _ model: MessageContentModel?) @@ -252,7 +252,7 @@ public class ChatBaseRightCell: ChatBaseCell { // avatar nameLabel.text = model.shortName avatarImage.backgroundColor = UIColor - .colorWithNumber(number: UInt64(model.message?.from ?? "0")) + .colorWithString(string: model.message?.from) if let avatarURL = model.avatar { avatarImage .sd_setImage(with: URL(string: avatarURL)) { [weak self] image, error, type, url in @@ -284,7 +284,8 @@ public class ChatBaseRightCell: ChatBaseCell { if model.message?.deliveryState == .deliveried { if model.message?.session?.sessionType == .P2P { let receiptEnable = model.message?.setting?.teamReceiptEnabled ?? false - if receiptEnable { + if receiptEnable, + IMKitClient.instance.repo.getShowReadStatus() == true { readView.isHidden = false if let read = model.message?.isRemoteRead, read { readView.progress = 1 @@ -304,7 +305,8 @@ public class ChatBaseRightCell: ChatBaseCell { } else if model.message?.session?.sessionType == .team { let receiptEnable = model.message?.setting?.teamReceiptEnabled ?? false - if receiptEnable { + if receiptEnable, + IMKitClient.instance.repo.getShowReadStatus() == true { readView.isHidden = false let readCount = model.message?.teamReceiptInfo?.readCount ?? 0 let unreadCount = model.message?.teamReceiptInfo?.unreadCount ?? 0 @@ -333,16 +335,22 @@ public class ChatBaseRightCell: ChatBaseCell { contentView.backgroundColor = model.isPined ? NEKitChatConfig.shared.ui .chatPinColor : .white if model.isPined { - if let text = model.pinShowName { - pinLabel.text = text + chatLocalizable("pin_text") + let pinText = model.message?.session?.sessionType == .P2P ? chatLocalizable("pin_text_P2P") : chatLocalizable("pin_text_team") + if model.pinAccount == nil { + pinLabel.text = chatLocalizable("You") + pinText + } else if let account = model.pinAccount, account == NIMSDK.shared().loginManager.currentAccount() { + pinLabel.text = chatLocalizable("You") + pinText + } else if let text = model.pinShowName { + pinLabel.text = text + pinText } + pinImage.image = UIImage.ne_imageNamed(name: "msg_pin") let size = String.getTextRectSize( - pinLabel.text ?? chatLocalizable("pin_text"), - font: UIFont.systemFont(ofSize: 11.0), + pinLabel.text ?? pinText, + font: UIFont.systemFont(ofSize: 12.0), size: CGSize(width: kScreenWidth - 56 - 22, height: CGFloat.greatestFiniteMagnitude) ) - pinLabelW?.constant = size.width + pinLabelW?.constant = size.width + 1 pinLabelH?.constant = chat_pin_height } else { pinImage.image = nil diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatCallRecordLeftCell.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatCallRecordLeftCell.swift new file mode 100644 index 00000000..9171d6e2 --- /dev/null +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatCallRecordLeftCell.swift @@ -0,0 +1,41 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +import UIKit + +@objcMembers +class ChatCallRecordLeftCell: ChatBaseLeftCell { + public let contentLabel = UILabel() + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + commonUI() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + } + + func commonUI() { + contentLabel.translatesAutoresizingMaskIntoConstraints = false + contentLabel.isEnabled = false + contentLabel.numberOfLines = 0 + contentLabel.isUserInteractionEnabled = false + contentLabel.font = DefaultTextFont(16) + contentLabel.backgroundColor = .clear + bubbleImage.addSubview(contentLabel) + NSLayoutConstraint.activate([ + contentLabel.rightAnchor.constraint(equalTo: bubbleImage.rightAnchor, constant: 0), + contentLabel.leftAnchor.constraint(equalTo: bubbleImage.leftAnchor, constant: 8), + contentLabel.topAnchor.constraint(equalTo: bubbleImage.topAnchor, constant: 0), + contentLabel.bottomAnchor.constraint(equalTo: bubbleImage.bottomAnchor, constant: 0), + ]) + } + + override func setModel(_ model: MessageContentModel) { + super.setModel(model) + if let m = model as? MessageCallRecordModel { + contentLabel.attributedText = m.attributeStr + } + } +} diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatCallRecordRightCell.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatCallRecordRightCell.swift new file mode 100644 index 00000000..0d710927 --- /dev/null +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatCallRecordRightCell.swift @@ -0,0 +1,43 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +import UIKit + +@objcMembers +class ChatCallRecordRightCell: ChatBaseRightCell { + public let contentLabel = UILabel() + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + commonUI() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + } + + func commonUI() { + contentLabel.translatesAutoresizingMaskIntoConstraints = false + contentLabel.isEnabled = false + contentLabel.numberOfLines = 0 + contentLabel.isUserInteractionEnabled = false + contentLabel.font = DefaultTextFont(16) + contentLabel.backgroundColor = .clear + bubbleImage.addSubview(contentLabel) + NSLayoutConstraint.activate([ + contentLabel.rightAnchor.constraint(equalTo: bubbleImage.rightAnchor, constant: 0), + contentLabel.leftAnchor.constraint(equalTo: bubbleImage.leftAnchor, constant: 8), + contentLabel.topAnchor.constraint(equalTo: bubbleImage.topAnchor, constant: 0), + contentLabel.bottomAnchor.constraint(equalTo: bubbleImage.bottomAnchor, constant: 0), + ]) + + activityView.removeFromSuperview() + } + + override func setModel(_ model: MessageContentModel) { + super.setModel(model) + if let m = model as? MessageCallRecordModel { + contentLabel.attributedText = m.attributeStr + } + } +} diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatLocationLeftCell.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatLocationLeftCell.swift index 1f9d0496..43038c2f 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatLocationLeftCell.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatLocationLeftCell.swift @@ -5,6 +5,7 @@ import UIKit import NEChatKit +@objcMembers class ChatLocationLeftCell: ChatBaseLeftCell { private lazy var titleLabel: UILabel = { let label = UILabel() diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatLocationRightCell.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatLocationRightCell.swift index 6c036746..31f39d9a 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatLocationRightCell.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatLocationRightCell.swift @@ -5,6 +5,7 @@ import UIKit import NEChatKit +@objcMembers class ChatLocationRightCell: ChatBaseRightCell { private lazy var titleLabel: UILabel = { let label = UILabel() diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatRevokeRightCell.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatRevokeRightCell.swift index 2c3223bd..61e2010a 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatRevokeRightCell.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatRevokeRightCell.swift @@ -57,10 +57,22 @@ public class ChatRevokeRightCell: ChatBaseRightCell { } override func setModel(_ model: MessageContentModel) { + if let time = model.message?.timestamp { + let date = Date() + let currentTime = date.timeIntervalSince1970 + if currentTime - time >= 60 * 2 { + model.timeOut = true + } + } + if let isSend = model.message?.isOutgoingMsg, isSend, model.isRevokedText == true, model.timeOut == false { + model.contentSize = CGSize(width: 218, height: qChat_min_h) + } else { + model.contentSize = CGSize(width: 130, height: qChat_min_h) + } super.setModel(model) label.text = chatLocalizable("message_has_be_withdrawn") reeditButton.setTitle(chatLocalizable("message_reedit"), for: .normal) - // 判断可编辑按钮的隐藏,只有文本才可以重新编辑 + if model.isRevokedText == true { if model.timeOut == true { reeditButton.isHidden = true diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatTeamMemberCell.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatTeamMemberCell.swift index 65f727fa..a9315cc1 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatTeamMemberCell.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatTeamMemberCell.swift @@ -69,6 +69,6 @@ public class ChatTeamMemberCell: UITableViewCell { headerView.setTitle(model.showNameInTeam()) headerView.backgroundColor = UIColor.colorWithString(string: model.nimUser?.userId) } - nameLabel.text = model.showNameInTeam() + nameLabel.text = model.atNameInTeam() } } diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatTextLeftCell.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatTextLeftCell.swift index 97314f0b..cf17888d 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatTextLeftCell.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatTextLeftCell.swift @@ -20,14 +20,9 @@ public class ChatTextLeftCell: ChatBaseLeftCell { func commonUI() { contentLabel.translatesAutoresizingMaskIntoConstraints = false contentLabel.isEnabled = false -// textView.isScrollEnabled = false -// textView.showsVerticalScrollIndicator = false contentLabel.numberOfLines = 0 contentLabel.isUserInteractionEnabled = false -// textView.textContainer.lineFragmentPadding = 0; -// textView.textContainerInset = .zero; contentLabel.font = DefaultTextFont(16) -// textView.autoresizingMask = [.flexibleWidth, .flexibleHeight] contentLabel.backgroundColor = .clear bubbleImage.addSubview(contentLabel) NSLayoutConstraint.activate([ @@ -41,7 +36,6 @@ public class ChatTextLeftCell: ChatBaseLeftCell { override func setModel(_ model: MessageContentModel) { super.setModel(model) if let m = model as? MessageTextModel { -// textView.text = m.text contentLabel.attributedText = m.attributeStr } } diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatTextRightCell.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatTextRightCell.swift index c9e21f05..66e3e35d 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatTextRightCell.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatTextRightCell.swift @@ -35,7 +35,6 @@ public class ChatTextRightCell: ChatBaseRightCell { override func setModel(_ model: MessageContentModel) { super.setModel(model) if let m = model as? MessageTextModel { -// textView.text = m.text contentLabel.attributedText = m.attributeStr } } diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatVideoRightCell.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatVideoRightCell.swift index 06a8039a..67f1c102 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatVideoRightCell.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/Cell/ChatVideoRightCell.swift @@ -89,7 +89,7 @@ public class ChatVideoRightCell: ChatImageRightCell { override func setModel(_ model: MessageContentModel) { super.setModel(model) if let videoObject = model.message?.messageObject as? NIMVideoObject { - if let path = videoObject.coverPath { + if let path = videoObject.coverPath, FileManager.default.fileExists(atPath: path) { contentImageView.sd_setImage( with: URL(fileURLWithPath: path), placeholderImage: nil, diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/ChatView/ChatInputView.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/ChatView/ChatInputView.swift index 9f84b028..2139f66a 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/ChatView/ChatInputView.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/ChatView/ChatInputView.swift @@ -34,7 +34,7 @@ public protocol ChatInputViewDelegate: NSObjectProtocol { } @objcMembers -public class ChatInputView: UIView, UITextFieldDelegate, ChatRecordViewDelegate, +public class ChatInputView: UIView, ChatRecordViewDelegate, InputEmoticonContainerViewDelegate, UITextViewDelegate, NEMoreViewDelagate { public weak var delegate: ChatInputViewDelegate? public var currentType: ChatMenuType = .text @@ -43,10 +43,12 @@ public class ChatInputView: UIView, UITextFieldDelegate, ChatRecordViewDelegate, public var atCache: NIMInputAtCache? var textField = RSKPlaceholderTextView() + var stackView = UIStackView() var contentView = UIView() public var contentSubView: UIView? private var greyView = UIView() private var recordView = ChatRecordView(frame: .zero) + override init(frame: CGRect) { super.init(frame: frame) commonUI() @@ -67,9 +69,7 @@ public class ChatInputView: UIView, UITextFieldDelegate, ChatRecordViewDelegate, textField.clipsToBounds = true textField.translatesAutoresizingMaskIntoConstraints = false textField.backgroundColor = .white - // textField.leftViewMode = .always textField.returnKeyType = .send - // textField.leftView = UIView(frame: CGRect(x: 0, y: 0, width: 20, height: 40)) textField.delegate = self textField.allowsEditingTextAttributes = true addSubview(textField) @@ -98,7 +98,8 @@ public class ChatInputView: UIView, UITextFieldDelegate, ChatRecordViewDelegate, button.tag = i + 5 items.append(button) } - let stackView = UIStackView(arrangedSubviews: items) + + stackView = UIStackView(arrangedSubviews: items) stackView.translatesAutoresizingMaskIntoConstraints = false stackView.distribution = .fillEqually addSubview(stackView) @@ -244,7 +245,6 @@ public class ChatInputView: UIView, UITextFieldDelegate, ChatRecordViewDelegate, public lazy var chatAddMoreView: NEChatMoreActionView = { let view = NEChatMoreActionView(frame: CGRect(x: 0, y: 0, width: kScreenWidth, height: 200)) view.translatesAutoresizingMaskIntoConstraints = false - view.configData(data: NEChatUIKitClient.instance.getMoreActionData()) view.isHidden = true view.delegate = self return view @@ -297,28 +297,6 @@ public class ChatInputView: UIView, UITextFieldDelegate, ChatRecordViewDelegate, return true } - public func textFieldShouldReturn(_ textField: UITextField) -> Bool { - guard let text = textField.text?.trimmingCharacters(in: CharacterSet.whitespaces) else { - return true - } - textField.text = "" - delegate?.sendText(text: text) - return true - } - - public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, - replacementString string: String) -> Bool { - print("range:\(range) string:\(string)") - if string.count == 0 { - if let delegate = delegate { - return delegate.textDelete(range: range, text: string) - } - } else { - delegate?.textChanged(text: string) - } - return true - } - func buttonEvent(button: UIButton) { switch button.tag - 5 { case 0: diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/ChatView/ChatRecordView.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/ChatView/ChatRecordView.swift index 7881dd02..d6345e72 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/ChatView/ChatRecordView.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/ChatView/ChatRecordView.swift @@ -78,7 +78,7 @@ public class ChatRecordView: UIView, UIGestureRecognizerDelegate { } func clickLabel(recognizer: UILongPressGestureRecognizer) { - print("location:\(recognizer.location(in: recognizer.view))") +// print("location:\(recognizer.location(in: recognizer.view))") switch recognizer.state { case .began: print("state:begin") @@ -88,8 +88,10 @@ public class ChatRecordView: UIView, UIGestureRecognizerDelegate { case .ended: endRecord(recognizer: recognizer) case .cancelled: + endRecord(recognizer: recognizer) print("state:cancelled") case .failed: + endRecord(recognizer: recognizer) print("state:failed") default: print("state:default") diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/ChatView/NEInputMoreCell.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/ChatView/NEInputMoreCell.swift index b87f6014..bfaef7ac 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/View/ChatView/NEInputMoreCell.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/View/ChatView/NEInputMoreCell.swift @@ -46,16 +46,16 @@ public class NEInputMoreCell: UICollectionViewCell { lazy var titleLabel: UILabel = { let title = UILabel() title.textColor = UIColor.ne_greyText - title.font = UIFont.systemFont(ofSize: 12) + title.font = UIFont.systemFont(ofSize: 10) title.textAlignment = .center title.translatesAutoresizingMaskIntoConstraints = false return title }() - func config(_ itmeModel: NEMoreItemModel) { - cellData = itmeModel - avatarImage.image = itmeModel.image - titleLabel.text = itmeModel.title + func config(_ itemModel: NEMoreItemModel) { + cellData = itemModel + avatarImage.image = itemModel.customImage == nil ? itemModel.image : itemModel.customImage + titleLabel.text = itemModel.title } /// 获取大小 diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/ViewModel/ChatViewModel.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/ViewModel/ChatViewModel.swift index 3a29ddfe..fd31137b 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/ViewModel/ChatViewModel.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/ViewModel/ChatViewModel.swift @@ -30,6 +30,8 @@ public protocol ChatViewModelDelegate: NSObjectProtocol { func updateDownloadProgress(_ message: NIMMessage, atIndex: IndexPath, progress: Float) func remoteUserEditing() func remoteUserEndEditing() + func didLeaveTeam() + func didDismissTeam() } let revokeLocalMessage = "revoke_message_local" @@ -38,9 +40,11 @@ let revokeLocalMessageContent = "revoke_message_local_content" @objcMembers public class ChatViewModel: NSObject, ChatRepoMessageDelegate, NIMChatManagerDelegate, NIMConversationManagerDelegate, NIMSystemNotificationManagerDelegate, ChatExtendProviderDelegate { + public var team: NIMTeam? public var session: NIMSession - public var messages: [MessageModel] = .init() + public var messages = [MessageModel]() public weak var delegate: ChatViewModelDelegate? + public var messageDic = [String: MessageModel]() // 上拉时间戳 private var newMsg: NIMMessage? // 下拉时间戳 @@ -58,6 +62,8 @@ public class ChatViewModel: NSObject, ChatRepoMessageDelegate, NIMChatManagerDel public var isHistoryChat = false + public var filterInviteSet = Set() + init(session: NIMSession) { NELog.infoLog(ModuleName + " " + className, desc: #function + ", sessionId:" + session.sessionId) self.session = session @@ -154,26 +160,85 @@ public class ChatViewModel: NSObject, ChatRepoMessageDelegate, NIMChatManagerDel ) } - public func queryRoamMsgHasMoreTime(_ completion: @escaping (Error?, NSInteger, - [MessageModel]?) -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function) -// NIMIncompleteSessionInfo + // 动态查询历史消息解决方案 + public func getMessagesModelDynamically(_ order: NIMMessageSearchOrder, message: NIMMessage?, + _ completion: @escaping (Error?, NSInteger, [MessageModel]?) + -> Void) { + let param = NIMGetMessagesDynamicallyParam() + param.limit = messagPageNum + param.session = session + param.order = order + if let msg = message { + if order == .desc { + param.endTime = msg.timestamp + } else { + param.startTime = msg.timestamp + } + param.anchorClientId = msg.messageId + param.anchorServerId = msg.serverID + } weak var weakSelf = self - repo.getIncompleteSessionInfo(session: session) { error, sessionInfos in - if error == nil { - let sessionInfo = sessionInfos?.first - // 记录可信时间戳 - weakSelf?.credibleTimestamp = sessionInfo?.timestamp ?? 0 - if weakSelf?.anchor == nil { - weakSelf?.getMessageHistory(self.oldMsg, completion) - + repo.getMessagesDynamically(param) { error, isReliable, messages in + if let messageArray = messages, messageArray.count > 0 { + var count = 0 + var datas = messageArray + var readMsg: NIMMessage? + if order == .desc { + weakSelf?.oldMsg = messageArray.last + readMsg = messageArray.first } else { - // 有锚点消息,从两个方向拉去消息 - weakSelf?.newMsg = weakSelf?.anchor - weakSelf?.oldMsg = weakSelf?.anchor - weakSelf?.dropDownRemoteRefresh(completion) - weakSelf?.pullRemoteRefresh(completion) + readMsg = messageArray.last + weakSelf?.newMsg = messageArray.last + } + for msg in datas { + if let object = msg.messageObject as? NIMNotificationObject { + if let content = object.content as? NIMTeamNotificationContent, content.operationType == .invite { + if weakSelf?.filterInviteSet.contains(msg.messageId) == true { + continue + } else { + weakSelf?.filterInviteSet.insert(msg.messageId) + } + } + } + print("message text : ", msg.text as Any) + if let model = weakSelf?.modelFromMessage(message: msg), NotificationMessageUtils.isDiscussSeniorTeamUpdateCustomNoti(message: msg) == false { + weakSelf?.filterRevokeMessage([model]) + if order == .desc { + if weakSelf?.addTimeForHistoryMessage(msg) == true { + count = count + 1 + } + count = count + 1 + weakSelf?.messages.insert(model, at: 0) + } else { + if weakSelf?.addTimeMessage(msg) == true { + count = count + 1 + } + count = count + 1 + weakSelf?.messages.append(model) + } + } + } + completion(error, count, weakSelf?.messages) + + if weakSelf?.session.sessionType == .P2P { + if let nearMsg = readMsg { + weakSelf?.markRead(messages: [nearMsg]) { error in + NELog.infoLog( + ModuleName + " " + (weakSelf?.className ?? "ChatViewModel"), + desc: "CALLBACK markRead " + (error?.localizedDescription ?? "no error") + ) + } + } + } else if weakSelf?.session.sessionType == .team { + weakSelf?.markRead(messages: messageArray) { error in + NELog.infoLog( + ModuleName + " " + (weakSelf?.className ?? "ChatViewModel"), + desc: "CALLBACK markRead " + (error?.localizedDescription ?? "no error") + ) + } } + } else { + completion(error, 0, weakSelf?.messages) } } } @@ -182,78 +247,73 @@ public class ChatViewModel: NSObject, ChatRepoMessageDelegate, NIMChatManagerDel [MessageModel]?, Int) -> Void) { NELog.infoLog(ModuleName + " " + className, desc: #function) weak var weakSelf = self - repo.getIncompleteSessionInfo(session: session) { error, sessionInfos in - if error == nil { - let sessionInfo = sessionInfos?.first - // 记录可信时间戳 - weakSelf?.credibleTimestamp = sessionInfo?.timestamp ?? 0 - if weakSelf?.anchor == nil { - weakSelf?.getMessageHistory(self.newMsg) { error, value, models in - NELog.infoLog( - ModuleName + " " + self.className, - desc: "CALLBACK getMessageHistory " + (error?.localizedDescription ?? "no error") - ) - completion(error, value, 0, models, 0) - } - } else { - // 有锚点消息,从两个方向拉去消息 - weakSelf?.newMsg = weakSelf?.anchor - weakSelf?.oldMsg = weakSelf?.anchor - - let group = DispatchGroup() - - var moreEnd = 0 - var newEnd = 0 - var historyDatas = [MessageModel]() - var newDatas = [MessageModel]() - - var err: Error? + // 记录可信时间戳 + if anchor == nil { + weakSelf?.getMessagesModelDynamically(.desc, message: nil) { error, count, models in + NELog.infoLog( + ModuleName + " " + self.className, + desc: "CALLBACK getMessageHistory " + (error?.localizedDescription ?? "no error") + ) + completion(error, count, 0, models, 0) + } - group.enter() - weakSelf?.dropDownRemoteRefresh { error, value, models in + } else { + // 有锚点消息,从两个方向拉去消息 + weakSelf?.newMsg = weakSelf?.anchor + weakSelf?.oldMsg = weakSelf?.anchor + + let group = DispatchGroup() + + var moreEnd = 0 + var newEnd = 0 + var historyDatas = [MessageModel]() + var newDatas = [MessageModel]() + + var err: Error? + group.enter() + weakSelf?.getMessagesModelDynamically(.desc, message: weakSelf?.anchor) { error, value, models in + moreEnd = value + if error != nil { + err = error + } + if let ms = models { + historyDatas.append(contentsOf: ms) + } + print("drop down remote refresh : ", historyDatas.count) + group.leave() + } - moreEnd = value - if error != nil { - err = error - } - if let ms = models { - historyDatas.append(contentsOf: ms) - } - print("drop down remote refresh : ", historyDatas.count) - group.leave() - } + group.enter() + weakSelf?.getMessagesModelDynamically(.asc, message: weakSelf?.anchor) { error, value, models in + NELog.infoLog( + ModuleName + " " + self.className, + desc: "CALLBACK pullRemoteRefresh " + (error?.localizedDescription ?? "no error") + ) + newEnd = value + if err != nil { + err = error + } + if let ms = models { + newDatas.append(contentsOf: ms) + } + print("pull remote refresh : ", newDatas.count) + group.leave() + } - group.enter() - weakSelf?.pullRemoteRefresh { error, value, models in - NELog.infoLog( - ModuleName + " " + self.className, - desc: "CALLBACK pullRemoteRefresh " + (error?.localizedDescription ?? "no error") - ) - newEnd = value - if err != nil { - err = error - } - if let ms = models { - newDatas.append(contentsOf: ms) - } - print("pull remote refresh : ", newDatas.count) - group.leave() + group.notify(queue: DispatchQueue.main, execute: { + var finalDatas = [MessageModel]() + finalDatas.append(contentsOf: historyDatas) + if let anchorMessage = weakSelf?.anchor { + let model = self.modelFromMessage(message: anchorMessage) + weakSelf?.filterRevokeMessage([model]) + if NotificationMessageUtils.isDiscussSeniorTeamUpdateCustomNoti(message: anchorMessage) == false { + weakSelf?.messages.insert(model, at: moreEnd) + finalDatas.append(model) } - - group.notify(queue: DispatchQueue.main, execute: { - var finalDatas = [MessageModel]() - finalDatas.append(contentsOf: historyDatas) - if let anchorMessage = weakSelf?.anchor { - let model = self.modelFromMessage(message: anchorMessage) - weakSelf?.filterRevokeMessage([model]) - weakSelf?.messages.insert(model, at: historyDatas.count) - finalDatas.append(model) - } - finalDatas.append(contentsOf: newDatas) - completion(err, moreEnd, newEnd, finalDatas, historyDatas.count) - }) } - } + finalDatas.append(contentsOf: newDatas) + completion(err, moreEnd, newEnd, finalDatas, historyDatas.count) + }) } } @@ -270,8 +330,8 @@ public class ChatViewModel: NSObject, ChatRepoMessageDelegate, NIMChatManagerDel if let messageArray = messages, messageArray.count > 0 { self?.oldMsg = messageArray.first for msg in messageArray { - self?.addTimeMessage(msg) - if let model = self?.modelFromMessage(message: msg) { + if let model = self?.modelFromMessage(message: msg), NotificationMessageUtils.isDiscussSeniorTeamUpdateCustomNoti(message: msg) == false { + self?.addTimeMessage(msg) self?.filterRevokeMessage([model]) self?.messages.append(model) } @@ -313,8 +373,8 @@ public class ChatViewModel: NSObject, ChatRepoMessageDelegate, NIMChatManagerDel .isMessageCredible(message: messageArray.first ?? NIMMessage()) if let isTrust = isCredible, isTrust { for msg in messageArray.reversed() { - self?.addTimeForHistoryMessage(msg) - if let model = self?.modelFromMessage(message: msg) { + if let model = self?.modelFromMessage(message: msg), NotificationMessageUtils.isDiscussSeniorTeamUpdateCustomNoti(message: msg) == false { + self?.addTimeForHistoryMessage(msg) self?.messages.insert(model, at: 0) } } @@ -378,8 +438,8 @@ public class ChatViewModel: NSObject, ChatRepoMessageDelegate, NIMChatManagerDel weakSelf?.newMsg = messageArray.first } for msg in messageArray { - weakSelf?.addTimeForHistoryMessage(msg) - if let model = weakSelf?.modelFromMessage(message: msg) { + if let model = weakSelf?.modelFromMessage(message: msg), NotificationMessageUtils.isDiscussSeniorTeamUpdateCustomNoti(message: msg) == false { + weakSelf?.addTimeForHistoryMessage(msg) weakSelf?.messages.insert(model, at: 0) } } @@ -398,11 +458,9 @@ public class ChatViewModel: NSObject, ChatRepoMessageDelegate, NIMChatManagerDel } } completion(error, messageArray.count, weakSelf?.messages) - } else { completion(error, 0, weakSelf?.messages) } - } else { completion(error, 0, nil) } @@ -412,55 +470,19 @@ public class ChatViewModel: NSObject, ChatRepoMessageDelegate, NIMChatManagerDel // 下拉获取历史消息 public func dropDownRemoteRefresh(_ completion: @escaping (Error?, NSInteger, [MessageModel]?) -> Void) { + getMessagesModelDynamically(.desc, message: oldMsg, completion) NELog.infoLog(ModuleName + " " + className, desc: #function) - // completion(nil, true, nil) - let option = NIMHistoryMessageSearchOption() - option.startTime = 0 - option.endTime = oldMsg?.timestamp ?? 0 - option.limit = messagPageNum - option.sync = true - let isCredible = isMessageCredible(message: oldMsg ?? NIMMessage()) - if isCredible { // 继续拉去本地消息 - getMoreMessageHistory(completion) - } else { - // 不可信拉去远端消息 - getRemoteHistoryMessage( - direction: .old, - updateCredible: false, - option: option, - completion - ) - } } // 上拉获取最新消息 public func pullRemoteRefresh(_ completion: @escaping (Error?, NSInteger, [MessageModel]?) -> Void) { +// var message = messages.last?.message +// if message == nil, let tip = messages.last as? MessageTipsModel { +// message = tip.tipMessage +// } + getMessagesModelDynamically(.asc, message: newMsg, completion) NELog.infoLog(ModuleName + " " + className, desc: #function) - let option = NIMHistoryMessageSearchOption() - option.startTime = newMsg?.timestamp ?? 0 - option.endTime = 0 - option.limit = messagPageNum - let isCredible = isMessageCredible(message: newMsg ?? NIMMessage()) - if isCredible { - if anchor != nil { - // 搜索历史记录进入 - searchMessageHistory( - direction: .new, - startTime: newMsg?.timestamp ?? 0, - endTime: 0, - completion - ) - } - - } else { - getRemoteHistoryMessage( - direction: .new, - updateCredible: false, - option: option, - completion - ) - } } // 搜索历史记录查询的本地消息 @@ -485,8 +507,8 @@ public class ChatViewModel: NSObject, ChatRepoMessageDelegate, NIMChatManagerDel weakSelf?.newMsg = messageArray.last } for msg in messageArray { - weakSelf?.addTimeMessage(msg) - if let model = weakSelf?.modelFromMessage(message: msg) { + if let model = weakSelf?.modelFromMessage(message: msg), NotificationMessageUtils.isDiscussSeniorTeamUpdateCustomNoti(message: msg) == false { + weakSelf?.addTimeMessage(msg) weakSelf?.messages.append(model) } } @@ -637,6 +659,31 @@ public class ChatViewModel: NSObject, ChatRepoMessageDelegate, NIMChatManagerDel if msg.isDeleted == true { continue } + if NotificationMessageUtils.isDiscussSeniorTeamUpdateCustomNoti(message: msg) { + continue + } + if let object = msg.messageObject as? NIMNotificationObject { + if let content = object.content as? NIMTeamNotificationContent, content.operationType == .invite { + if filterInviteSet.contains(msg.messageId) { + continue + } else { + filterInviteSet.insert(msg.messageId) + } + } + } + /* 后续解散群离开群弹框优化 + if msg.messageType == .notification, session.sessionType == .team { + if team?.clientCustomInfo?.contains(discussTeamKey) == true { + return + } + let value = NotificationMessageUtils.isTeamLeaveOrDismiss(message: msg) + if value.isLeave == true { + delegate?.didLeaveTeam() + } else if value.isDismiss == true { + delegate?.didDismissTeam() + } + + }*/ count += 1 // 自定义消息处理 if msg.messageType == .custom { @@ -802,6 +849,26 @@ public class ChatViewModel: NSObject, ChatRepoMessageDelegate, NIMChatManagerDel NELog.infoLog(ModuleName + " " + className, desc: #function + ", pinAccount: " + (model?.pinAccount ?? "nil")) var pinItem = OperationItem.pinItem() var items = [OperationItem]() + + if model?.message?.deliveryState == .failed || model?.message?.deliveryState == .delivering, model?.message?.messageType != .rtcCallRecord { + switch model?.message?.messageType { + case .text: + items.append(contentsOf: [ + OperationItem.copyItem(), + OperationItem.deleteItem(), + ]) + return items + case .audio, .video, .image, .location, .file: + items.append(contentsOf: [ + OperationItem.deleteItem(), + ]) + return items + default: + break + } + + return nil + } switch model?.message?.messageType { case .location: items.append(contentsOf: [ @@ -818,8 +885,6 @@ public class ChatViewModel: NSObject, ChatRepoMessageDelegate, NIMChatManagerDel OperationItem.replayItem(), OperationItem.forwardItem(), pinItem, -// OperationItem.selectItem(), -// OperationItem.collectionItem(), OperationItem.deleteItem(), ] @@ -831,8 +896,6 @@ public class ChatViewModel: NSObject, ChatRepoMessageDelegate, NIMChatManagerDel OperationItem.replayItem(), OperationItem.forwardItem(), pinItem, -// OperationItem.selectItem(), -// OperationItem.collectionItem(), OperationItem.deleteItem(), ] case .audio: @@ -842,10 +905,10 @@ public class ChatViewModel: NSObject, ChatRepoMessageDelegate, NIMChatManagerDel items = [ OperationItem.replayItem(), pinItem, -// OperationItem.selectItem(), -// OperationItem.collectionItem(), OperationItem.deleteItem(), ] + case .rtcCallRecord: + items = [OperationItem.deleteItem()] default: if let isPin = model?.isPined, isPin { @@ -854,13 +917,11 @@ public class ChatViewModel: NSObject, ChatRepoMessageDelegate, NIMChatManagerDel items = [ OperationItem.replayItem(), pinItem, -// OperationItem.selectItem(), -// OperationItem.collectionItem(), OperationItem.deleteItem(), ] } - if model?.message?.from == NIMSDK.shared().loginManager.currentAccount() { + if model?.message?.from == NIMSDK.shared().loginManager.currentAccount(), model?.message?.messageType != .rtcCallRecord { items.append(OperationItem.recallItem()) } return items @@ -899,17 +960,20 @@ public class ChatViewModel: NSObject, ChatRepoMessageDelegate, NIMChatManagerDel } // history message insert message at first of messages, send message add last of messages - private func addTimeMessage(_ message: NIMMessage) { + @discardableResult + private func addTimeMessage(_ message: NIMMessage) -> Bool { NELog.infoLog(ModuleName + " " + className, desc: #function + ", messageId: " + message.messageId) let lastTs = messages.last?.message?.timestamp ?? 0.0 let curTs = message.timestamp let dur = curTs - lastTs if (dur / 60) > 5 { messages.append(timeModel(message)) + return true } + return false } - private func addTimeForHistoryMessage(_ message: NIMMessage) { + private func addTimeForHistoryMessage(_ message: NIMMessage) -> Bool { NELog.infoLog(ModuleName + " " + className, desc: #function + ", messageId: " + message.messageId) let firstTs = messages.first?.message?.timestamp ?? 0.0 let curTs = message.timestamp @@ -919,7 +983,9 @@ public class ChatViewModel: NSObject, ChatRepoMessageDelegate, NIMChatManagerDel model.type = .time model.text = String.stringFromDate(date: Date(timeIntervalSince1970: firstTs)) messages.insert(model, at: 0) + return true } + return false } private func timeModel(_ message: NIMMessage) -> MessageModel { @@ -965,6 +1031,8 @@ public class ChatViewModel: NSObject, ChatRepoMessageDelegate, NIMChatManagerDel // <#code#> case .location: model = MessageLocationModel(message: message) + case .rtcCallRecord: + model = MessageCallRecordModel(message: message) default: // 未识别的消息类型,默认为文本消息类型,text为未知消息 message.text = "未知消息" @@ -1006,14 +1074,19 @@ public class ChatViewModel: NSObject, ChatRepoMessageDelegate, NIMChatManagerDel private func getReplyMessage(message: NIMMessage) -> MessageModel? { NELog.infoLog(ModuleName + " " + className, desc: #function + ", messageId: " + message.messageId) - guard let id = message.repliedMessageId else { + guard let id = message.repliedMessageId, id.count > 0 else { return nil } - if let message = ConversationProvider.shared.messagesInSession(session, messageIds: [id])? + if let m = ConversationProvider.shared.messagesInSession(session, messageIds: [id])? .first { - return modelFromMessage(message: message) + let model = modelFromMessage(message: m) + model.isReplay = true + return model } - return nil + let message = NIMMessage() + let model = modelFromMessage(message: message) + model.isReplay = true + return model } private func getUserInfo(_ userId: String, _ completion: @escaping (User?, NSError?) -> Void) { @@ -1277,6 +1350,7 @@ public class ChatViewModel: NSObject, ChatRepoMessageDelegate, NIMChatManagerDel if message.messageType == .text { muta[revokeLocalMessageContent] = message.text } + messageNew.timestamp = message.timestamp messageNew.from = message.from messageNew.localExt = muta let setting = NIMMessageSetting() @@ -1298,6 +1372,25 @@ public class ChatViewModel: NSObject, ChatRepoMessageDelegate, NIMChatManagerDel } } + public func refreshReceipts() { + if session.sessionType != .team { + return + } + if repo.settingProvider.getMessageRead() == false { + return + } + print("refresh team id : ", session.sessionId) + var receiptsMessages = [NIMMessage]() + messages.forEach { model in + if let message = model.message, message.setting?.teamReceiptEnabled == true, + let unreadCount = message.teamReceiptInfo?.unreadCount, unreadCount > 0 { + print("unread count : ", unreadCount as Any) + receiptsMessages.append(message) + } + } + repo.refreshReceipts(receiptsMessages) + } + // MARK: NIMConversationManagerDelegate // remote diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/ViewModel/TeamChatViewModel.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/ViewModel/TeamChatViewModel.swift index fd58f73d..f3c9de99 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/ViewModel/TeamChatViewModel.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/ViewModel/TeamChatViewModel.swift @@ -5,7 +5,7 @@ import Foundation import NIMSDK import CoreText - +import NECoreIMKit @objc public protocol TeamChatViewModelDelegate: ChatViewModelDelegate { func onTeamRemoved(team: NIMTeam) @@ -14,7 +14,6 @@ public protocol TeamChatViewModelDelegate: ChatViewModelDelegate { @objcMembers public class TeamChatViewModel: ChatViewModel, NIMTeamManagerDelegate { - public var team: NIMTeam? private let className = "TeamChatViewModel" // override init(session: NIMSession) { // super.init(session: session) diff --git a/NEChatUIKit/NEChatUIKit/Classes/Chat/ViewModel/TeamMemberSelectVM.swift b/NEChatUIKit/NEChatUIKit/Classes/Chat/ViewModel/TeamMemberSelectVM.swift index a50a0110..4e224587 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Chat/ViewModel/TeamMemberSelectVM.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Chat/ViewModel/TeamMemberSelectVM.swift @@ -5,7 +5,7 @@ import Foundation import NIMSDK import NEChatKit - +import NECoreIMKit @objcMembers public class TeamMemberSelectVM: NSObject { public var chatRepo: ChatRepo = .init() diff --git a/NEChatUIKit/NEChatUIKit/Classes/ChatConfig/ChatUIConfig.swift b/NEChatUIKit/NEChatUIKit/Classes/ChatConfig/ChatUIConfig.swift index 117e917a..82aa3051 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/ChatConfig/ChatUIConfig.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/ChatConfig/ChatUIConfig.swift @@ -39,5 +39,5 @@ public class ChatUIConfig: NSObject { public var messageColor = UIColor.ne_darkText /// 发送文件大小限制(单位:MB) - public var fileSizeLimit: Double? + public var fileSizeLimit: Double = 200 } diff --git a/NEChatUIKit/NEChatUIKit/Classes/ChatRouter/ChatRouter.swift b/NEChatUIKit/NEChatUIKit/Classes/ChatRouter/ChatRouter.swift index eac23609..7f7706c2 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/ChatRouter/ChatRouter.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/ChatRouter/ChatRouter.swift @@ -28,13 +28,17 @@ public class ChatRouter: NSObject { guard let session = param["session"] as? NIMSession else { return } - if let anchor = param["anchor"] as? NIMMessage { - let groupVC = GroupChatViewController(session: session, anchor: anchor) - nav?.pushViewController(groupVC, animated: true) - } else { - let groupVC = GroupChatViewController(session: session, anchor: nil) - nav?.pushViewController(groupVC, animated: true) + + let anchor = param["anchor"] as? NIMMessage + let groupVC = GroupChatViewController(session: session, anchor: anchor) + for (i, vc) in (nav?.viewControllers ?? []).enumerated() { + if vc.isMember(of: GroupChatViewController.self) { + nav?.viewControllers[i] = groupVC + nav?.popToViewController(groupVC, animated: true) + return + } } + nav?.pushViewController(groupVC, animated: true) } } diff --git a/NEChatUIKit/NEChatUIKit/Classes/Common/ChatConstant.swift b/NEChatUIKit/NEChatUIKit/Classes/Common/ChatConstant.swift index f8a856f2..f40a3c5a 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Common/ChatConstant.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Common/ChatConstant.swift @@ -7,6 +7,7 @@ import Foundation @_exported import NECoreKit @_exported import NECommonUIKit @_exported import NECommonKit +@_exported import NECoreIMKit let coreLoader = CoreLoader() func chatLocalizable(_ key: String) -> String { diff --git a/NEChatUIKit/NEChatUIKit/Classes/Common/NEChatUIKitClient.swift b/NEChatUIKit/NEChatUIKit/Classes/Common/NEChatUIKitClient.swift index 9378dfef..6e98fc13 100644 --- a/NEChatUIKit/NEChatUIKit/Classes/Common/NEChatUIKitClient.swift +++ b/NEChatUIKit/NEChatUIKit/Classes/Common/NEChatUIKitClient.swift @@ -4,31 +4,21 @@ // found in the LICENSE file. import UIKit -// import AMapFoundationKit +import NIMSDK @objcMembers public class NEChatUIKitClient: NSObject { public static let instance = NEChatUIKitClient() - override init() {} - - /// 获取更多面板数据 - /// - Returns: 返回更多操作数据 - public func getMoreActionData() -> [NEMoreItemModel] { - var moreAction = [NEMoreItemModel]() + public var moreAction = [NEMoreItemModel]() + override init() { let picture = NEMoreItemModel() picture.image = UIImage.ne_imageNamed(name: "chat_takePicture") picture.title = chatLocalizable("chat_takePicture") picture.type = .takePicture moreAction.append(picture) -// let rtc = NEMoreItemModel() -// rtc.image = UIImage.ne_imageNamed(name: "chat_rtc") -// rtc.title = chatLocalizable("chat_rtc") -// rtc.type = .rtc -// moreAction.append(rtc) - let location = NEMoreItemModel() location.image = UIImage.ne_imageNamed(name: "chat_location") location.title = chatLocalizable("chat_location") @@ -41,6 +31,26 @@ public class NEChatUIKitClient: NSObject { file.type = .file moreAction.append(file) - return moreAction + if XKitServiceManager.getInstance().serviceIsRegister("NERtcCallUIKit") == true { + let rtc = NEMoreItemModel() + rtc.image = UIImage.ne_imageNamed(name: "chat_rtc") + rtc.title = chatLocalizable("chat_rtc") + rtc.type = .rtc + moreAction.append(rtc) + } + } + + /// 获取更多面板数据 + /// - Returns: 返回更多操作数据 + public func getMoreActionData(sessionType: NIMSessionType) -> [NEMoreItemModel] { + var more = [NEMoreItemModel]() + moreAction.forEach { model in + if model.type != .rtc { + more.append(model) + } else if sessionType == .P2P { + more.append(model) + } + } + return more } } diff --git a/NEContactUIKit/NEContactUIKit.podspec b/NEContactUIKit/NEContactUIKit.podspec index 8b247ab8..fbf614e0 100644 --- a/NEContactUIKit/NEContactUIKit.podspec +++ b/NEContactUIKit/NEContactUIKit.podspec @@ -8,7 +8,7 @@ Pod::Spec.new do |s| s.name = 'NEContactUIKit' - s.version = '9.3.0' + s.version = '9.2.10' s.summary = 'Netease XKit' # This description is used to generate tags and improve search results. @@ -24,9 +24,9 @@ Pod::Spec.new do |s| # s.source = { :git => 'https://github.com/chenyu-home/ContactKitUI.git', :tag => s.version.to_s } s.pod_target_xcconfig = { + 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64', 'BUILD_LIBRARY_FOR_DISTRIBUTION' => 'YES' } - s.user_target_xcconfig = { 'BUILD_LIBRARY_FOR_DISTRIBUTION' => 'YES' } s.ios.deployment_target = '9.0' s.swift_version = '5.0' @@ -34,6 +34,6 @@ Pod::Spec.new do |s| s.resource = 'NEContactUIKit/Assets/**/*' s.dependency 'NEContactKit' s.dependency 'NECommonUIKit' - s.dependency 'YXAlog_iOS' + s.dependency 'YXAlog' end diff --git a/NEContactUIKit/NEContactUIKit/Assets/en.lproj/Localizable.strings b/NEContactUIKit/NEContactUIKit/Assets/en.lproj/Localizable.strings index 7cda82eb..b3b869a5 100644 --- a/NEContactUIKit/NEContactUIKit/Assets/en.lproj/Localizable.strings +++ b/NEContactUIKit/NEContactUIKit/Assets/en.lproj/Localizable.strings @@ -7,6 +7,8 @@ "alert_tip"="tip"; "alert_sure"="ok"; "alert_cancel"="cancel"; + +"account"="Account"; "noteName"="Nick Name"; "remove_black" = "Remove"; @@ -14,6 +16,7 @@ "mine_groupchat"="My Group"; "save"="Save"; "input_noteName"="Please enter nick name"; +"birthday"="birthday"; "phone"="mobile"; "email"="e-mail"; "sign"="What's Up"; @@ -22,6 +25,7 @@ "add_blackList"="block"; "send_friend_apply"="Contact request sent"; "validation_message"="Verify message"; +"no_validation_message"="No Validation Message"; "clear"="Clear"; "agreed"="Added"; "refused"="Rejected"; @@ -31,12 +35,10 @@ "select"="Select"; "select_contact"="Please select Contact"; "user_not_exist"="No contact"; +"no_friend"="No Friend"; "chat"="Chat"; "message_remind"="Message notification"; "clear_all_validate_message"="Wether to clear all verification"; "sure_delte_friend"="Wether to delete Contact?"; "input_userId"="Input user ID"; - - - - +"space_not_support"="All Spaces are not supported"; diff --git a/NEContactUIKit/NEContactUIKit/Assets/zh-Hans.lproj/Localizable.strings b/NEContactUIKit/NEContactUIKit/Assets/zh-Hans.lproj/Localizable.strings index 7d493222..aa63bba9 100644 --- a/NEContactUIKit/NEContactUIKit/Assets/zh-Hans.lproj/Localizable.strings +++ b/NEContactUIKit/NEContactUIKit/Assets/zh-Hans.lproj/Localizable.strings @@ -7,6 +7,8 @@ "alert_tip"="提示"; "alert_sure"="确定"; "alert_cancel"="取消"; + +"account"="账号"; "noteName"="备注名"; "remove_black" = "解除"; @@ -14,6 +16,7 @@ "mine_groupchat"="我的群聊"; "save"="保存"; "input_noteName"="请输入备注名"; +"birthday"="生日"; "phone"="手机"; "email"="邮箱"; "sign"="个性签名"; @@ -22,6 +25,7 @@ "add_blackList"="加入黑名单"; "send_friend_apply"="好友申请已发送"; "validation_message"="验证消息"; +"no_validation_message"="暂无验证消息"; "clear"="清空"; "agreed"="已同意"; "refused"="已拒绝"; @@ -31,8 +35,10 @@ "select"="选择"; "select_contact"="请选择联系人"; "user_not_exist"="该用户不存在"; +"no_friend"="暂无好友"; "chat"="聊天"; "message_remind"="消息提醒"; "clear_all_validate_message"="是否要清除所有验证消息?"; "sure_delte_friend"="是否确定删除好友?"; -"input_userId"="输入查找用户id"; +"input_userId"="请输入账号"; +"space_not_support"="不支持全空格"; diff --git a/NEContactUIKit/NEContactUIKit/Classes/Base/ContactBaseViewCell.swift b/NEContactUIKit/NEContactUIKit/Classes/Base/ContactBaseViewCell.swift index 9e0f5d7e..6dd817fa 100644 --- a/NEContactUIKit/NEContactUIKit/Classes/Base/ContactBaseViewCell.swift +++ b/NEContactUIKit/NEContactUIKit/Classes/Base/ContactBaseViewCell.swift @@ -29,6 +29,7 @@ open class ContactBaseViewCell: UITableViewCell { name.textColor = .white name.textAlignment = .center name.font = UIFont.systemFont(ofSize: 14.0) + name.adjustsFontSizeToFitWidth = true return name }() diff --git a/NEContactUIKit/NEContactUIKit/Classes/Extension/ContactImageExtension.swift b/NEContactUIKit/NEContactUIKit/Classes/Extension/ContactImageExtension.swift index 55d91ee2..90494e69 100644 --- a/NEContactUIKit/NEContactUIKit/Classes/Extension/ContactImageExtension.swift +++ b/NEContactUIKit/NEContactUIKit/Classes/Extension/ContactImageExtension.swift @@ -6,7 +6,7 @@ import Foundation public extension UIImage { class func ne_imageNamed(name: String?) -> UIImage? { - guard let imageName = name else { + guard let imageName = name, !imageName.isEmpty else { return nil } return coreLoader.loadImage(imageName) diff --git a/NEContactUIKit/NEContactUIKit/Classes/Team/Views/TeamTableViewCell.swift b/NEContactUIKit/NEContactUIKit/Classes/Team/Views/TeamTableViewCell.swift index e33d9708..c0dcf7cf 100644 --- a/NEContactUIKit/NEContactUIKit/Classes/Team/Views/TeamTableViewCell.swift +++ b/NEContactUIKit/NEContactUIKit/Classes/Team/Views/TeamTableViewCell.swift @@ -89,7 +89,7 @@ public class TeamTableViewCell: UITableViewCell { avatarImage.sd_setImage(with: URL(string: url), completed: nil) } else { // random avatar - avatarImage.image = randomAvatar(teamId: team.teamId) +// avatarImage.image = randomAvatar(teamId: team.teamId) } } @@ -98,7 +98,7 @@ public class TeamTableViewCell: UITableViewCell { return nil } // mod: 0 1 2 3 4 - let mod = Int(tid) ?? 0 % 5 + let mod = (Int(tid) ?? 0) % 5 let name = "icon_" + String(mod) return UIImage.ne_imageNamed(name: name) } diff --git a/NEContactUIKit/NEContactUIKit/Classes/UserInfo/UserInfoHeaderView.swift b/NEContactUIKit/NEContactUIKit/Classes/UserInfo/UserInfoHeaderView.swift index 5a6b8101..6f94033d 100644 --- a/NEContactUIKit/NEContactUIKit/Classes/UserInfo/UserInfoHeaderView.swift +++ b/NEContactUIKit/NEContactUIKit/Classes/UserInfo/UserInfoHeaderView.swift @@ -12,6 +12,13 @@ public class UserInfoHeaderView: UIView { public var nameLabel = UILabel() public var titleLabel = UILabel() public var detailLabel = UILabel() + lazy var lineView: UIView = { + let view = UIView() + view.backgroundColor = .ne_greyLine + view.translatesAutoresizingMaskIntoConstraints = false + return view + }() + override init(frame: CGRect) { super.init(frame: frame) backgroundColor = .white @@ -61,6 +68,14 @@ public class UserInfoHeaderView: UIView { detailLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 8), detailLabel.heightAnchor.constraint(equalToConstant: 22), ]) + + addSubview(lineView) + NSLayoutConstraint.activate([ + lineView.leftAnchor.constraint(equalTo: leftAnchor), + lineView.rightAnchor.constraint(equalTo: rightAnchor), + lineView.bottomAnchor.constraint(equalTo: bottomAnchor), + lineView.heightAnchor.constraint(equalToConstant: 6), + ]) } required init?(coder: NSCoder) { @@ -77,7 +92,7 @@ public class UserInfoHeaderView: UIView { avatarImage.sd_setImage(with: URL(string: imageUrl), completed: nil) nameLabel.isHidden = true } - detailLabel.text = user.userId + // title var showName = user.alias?.count ?? 0 > 0 ? user.alias : user.userInfo?.nickName if showName == nil || showName?.count == 0 { @@ -90,5 +105,7 @@ public class UserInfoHeaderView: UIView { .count > 2 ? String(name[name.index(name.endIndex, offsetBy: -2)...]) : name } } + + detailLabel.text = "\(localizable("account")):\(user.userId ?? "")" } } diff --git a/NEContactUIKit/NEContactUIKit/Classes/UserInfo/ViewController/ContactRemakNameViewController.swift b/NEContactUIKit/NEContactUIKit/Classes/UserInfo/ViewController/ContactRemakNameViewController.swift index 10e95fae..e36dbbf4 100644 --- a/NEContactUIKit/NEContactUIKit/Classes/UserInfo/ViewController/ContactRemakNameViewController.swift +++ b/NEContactUIKit/NEContactUIKit/Classes/UserInfo/ViewController/ContactRemakNameViewController.swift @@ -12,12 +12,24 @@ public class ContactRemakNameViewController: ContactBaseViewController, UITextFi typealias ModifyBlock = (_ user: User) -> Void var completion: ModifyBlock? - var user: User? - let viewmodel = ContactUserViewModel() - - lazy var aliasInput: UITextField = getInput() + let textLimit = 15 + lazy var aliasInput: UITextField = { + let textField = UITextField() + textField.backgroundColor = .white + textField.clipsToBounds = true + textField.layer.cornerRadius = 8 + textField.font = UIFont.systemFont(ofSize: 16.0) + textField.translatesAutoresizingMaskIntoConstraints = false + let leftSpace = UIView(frame: CGRect(x: 0, y: 0, width: 16, height: 0)) + textField.leftView = leftSpace + textField.leftViewMode = .always + textField.delegate = self + textField.clearButtonMode = .whileEditing + textField.addTarget(self, action: #selector(textFieldChange), for: .editingChanged) + return textField + }() // lazy var rightBtn: ExpandButton = { // let btn = ExpandButton(frame: CGRect(x: 0, y: 0, width: 60, height: 44)) @@ -59,26 +71,18 @@ public class ContactRemakNameViewController: ContactBaseViewController, UITextFi } } - func getInput() -> UITextField { - let textField = UITextField() - textField.backgroundColor = .white - textField.clipsToBounds = true - textField.layer.cornerRadius = 8 - textField.font = UIFont.systemFont(ofSize: 16.0) - textField.translatesAutoresizingMaskIntoConstraints = false - let leftSpace = UIView(frame: CGRect(x: 0, y: 0, width: 16, height: 0)) - textField.leftView = leftSpace - textField.leftViewMode = .always - textField.delegate = self - textField.clearButtonMode = .whileEditing - return textField - } - func saveAlias() { // guard let alais = aliasInput.text, alais.count > 0 else { // view.makeToast("请填写备注名", duration: 2, position: .center) // return // } + if let text = aliasInput.text, + text.count > 0, + text.trimmingCharacters(in: .whitespaces).isEmpty { + view.makeToast(localizable("space_not_support"), duration: 2, position: .center) + aliasInput.text = "" + return + } user?.alias = aliasInput.text if let u = user { view.makeToastActivity(.center) @@ -115,13 +119,13 @@ public class ContactRemakNameViewController: ContactBaseViewController, UITextFi } */ - public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, - replacementString string: String) -> Bool { - let text = "\(textField.text ?? "")\(string)" - print("text count : ", text.count) - if text.count > 30 { - return false + public func textFieldChange() { + guard let _ = aliasInput.markedTextRange else { + if let text = aliasInput.text, + text.count > textLimit { + aliasInput.text = String(text.prefix(textLimit)) + } + return } - return true } } diff --git a/NEContactUIKit/NEContactUIKit/Classes/UserInfo/ViewController/ContactUserViewController.swift b/NEContactUIKit/NEContactUIKit/Classes/UserInfo/ViewController/ContactUserViewController.swift index 37718ca9..716a89eb 100644 --- a/NEContactUIKit/NEContactUIKit/Classes/UserInfo/ViewController/ContactUserViewController.swift +++ b/NEContactUIKit/NEContactUIKit/Classes/UserInfo/ViewController/ContactUserViewController.swift @@ -111,60 +111,66 @@ public class ContactUserViewController: ContactBaseViewController, UITableViewDe if isFriend { data = [ - [UserItem( - title: localizable("noteName"), - detailTitle: user?.alias, - value: false, - textColor: UIColor.darkText, - cellClass: TextWithRightArrowCell.self - )], [ - UserItem(title: localizable("phone"), detailTitle: user?.userInfo?.mobile, + UserItem(title: localizable("noteName"), + detailTitle: user?.alias, value: false, - textColor: UIColor.darkText, cellClass: TextWithDetailTextCell.self), - UserItem( - title: localizable("email"), - detailTitle: user?.userInfo?.email, - value: false, - textColor: UIColor.darkText, - cellClass: TextWithDetailTextCell.self - ), - UserItem( - title: localizable("sign"), - detailTitle: user?.userInfo?.sign, - value: false, - textColor: UIColor.darkText, - cellClass: TextWithDetailTextCell.self - ), + textColor: UIColor.darkText, + cellClass: TextWithRightArrowCell.self), + ], + [ + UserItem(title: localizable("birthday"), + detailTitle: user?.userInfo?.birth, + value: false, + textColor: UIColor.darkText, + cellClass: TextWithDetailTextCell.self), + UserItem(title: localizable("phone"), + detailTitle: user?.userInfo?.mobile, + value: false, + textColor: UIColor.darkText, + cellClass: TextWithDetailTextCell.self), + UserItem(title: localizable("email"), + detailTitle: user?.userInfo?.email, + value: false, + textColor: UIColor.darkText, + cellClass: TextWithDetailTextCell.self), + UserItem(title: localizable("sign"), + detailTitle: user?.userInfo?.sign, + value: false, + textColor: UIColor.darkText, + cellClass: TextWithDetailTextCell.self), ], - [UserItem( - title: localizable("add_blackList"), - detailTitle: "", - value: isBlack, - textColor: UIColor.darkText, - cellClass: TextWithSwitchCell.self - )], [ - UserItem(title: localizable("chat"), detailTitle: "", value: false, - textColor: UIColor(hexString: "#337EFF"), cellClass: CenterTextCell.self), - UserItem( - title: localizable("delete_friend"), - detailTitle: "", - value: false, - textColor: UIColor.red, - cellClass: CenterTextCell.self - ), + UserItem(title: localizable("add_blackList"), + detailTitle: "", + value: isBlack, + textColor: UIColor.darkText, + cellClass: TextWithSwitchCell.self), + ], + [ + UserItem(title: localizable("chat"), + detailTitle: "", + value: false, + textColor: UIColor(hexString: "#337EFF"), + cellClass: CenterTextCell.self), + UserItem(title: localizable("delete_friend"), + detailTitle: "", + value: false, + textColor: UIColor.red, + cellClass: CenterTextCell.self), ], ] } else { - data = [[UserItem( - title: localizable("add_friend"), - detailTitle: user?.alias, - value: false, - textColor: UIColor(hexString: "#337EFF"), - cellClass: CenterTextCell.self - )]] + data = [ + [ + UserItem(title: localizable("add_friend"), + detailTitle: user?.alias, + value: false, + textColor: UIColor(hexString: "#337EFF"), + cellClass: CenterTextCell.self), + ], + ] } tableView.reloadData() } @@ -235,7 +241,12 @@ public class ContactUserViewController: ContactBaseViewController, UITableViewDe deleteFriend(user: user) } if item.title == localizable("add_friend") { - addFriend() + if let uId = user?.userId, + viewModel.isFriend(account: uId) { + loadData() + } else { + addFriend() + } } } @@ -334,6 +345,15 @@ public class ContactUserViewController: ContactBaseViewController, UITableViewDe NELog.errorLog("ContactUserViewController", desc: "❌add friend failed :\(err)") } else { weakSelf?.showToast(localizable("send_friend_apply")) + if let model = weakSelf?.viewModel, + model.isBlack(account: account) { + weakSelf?.viewModel.removeBlackList(account: account) { err in + NELog.infoLog( + self.className, + desc: #function + "CALLBACK " + (err?.localizedDescription ?? "no error") + ) + } + } } } } diff --git a/NEContactUIKit/NEContactUIKit/Classes/Validation/ViewController/ValidationMessageViewController.swift b/NEContactUIKit/NEContactUIKit/Classes/Validation/ViewController/ValidationMessageViewController.swift index 7e38f67f..4b626437 100644 --- a/NEContactUIKit/NEContactUIKit/Classes/Validation/ViewController/ValidationMessageViewController.swift +++ b/NEContactUIKit/NEContactUIKit/Classes/Validation/ViewController/ValidationMessageViewController.swift @@ -19,17 +19,20 @@ public class ValidationMessageViewController: ContactBaseViewController { // Do any additional setup after loading the view. title = localizable("validation_message") + emptyView.setttingContent(content: localizable("no_validation_message")) // viewModel.getValidationMessage() setupUI() weak var weakSelf = self viewModel.getValidationMessage { - NELog.infoLog(ModuleName + " " + self.tag, desc: "✅ getValidationMessage SUCCESS") + NELog.infoLog(ModuleName + " " + (weakSelf?.tag ?? "ValidationMessageViewController"), desc: "✅ getValidationMessage SUCCESS") weakSelf?.tableView.reloadData() } viewModel.dataRefresh = { + weakSelf?.emptyView.isHidden = (weakSelf?.viewModel.datas.count ?? 0) > 0 weakSelf?.tableView.reloadData() } + emptyView.isHidden = viewModel.datas.count > 0 } func setupUI() { @@ -63,6 +66,14 @@ public class ValidationMessageViewController: ContactBaseViewController { SystemNotificationCell.self, forCellReuseIdentifier: "\(SystemNotificationCell.self)" ) + + view.addSubview(emptyView) + NSLayoutConstraint.activate([ + emptyView.topAnchor.constraint(equalTo: tableView.topAnchor, constant: 100), + emptyView.bottomAnchor.constraint(equalTo: tableView.bottomAnchor), + emptyView.leftAnchor.constraint(equalTo: tableView.leftAnchor), + emptyView.rightAnchor.constraint(equalTo: tableView.rightAnchor), + ]) } func clearMessage() { @@ -71,6 +82,7 @@ public class ValidationMessageViewController: ContactBaseViewController { weakSelf?.viewModel.clearAllNoti { NELog.infoLog(ModuleName + " " + self.tag, desc: "✅ clearAllNoti SUCCESS") weakSelf?.tableView.reloadData() + weakSelf?.emptyView.isHidden = false } } } diff --git a/NEContactUIKit/NEContactUIKit/Classes/Validation/Views/BaseValidationCell.swift b/NEContactUIKit/NEContactUIKit/Classes/Validation/Views/BaseValidationCell.swift index 5dab715a..ed7c487a 100644 --- a/NEContactUIKit/NEContactUIKit/Classes/Validation/Views/BaseValidationCell.swift +++ b/NEContactUIKit/NEContactUIKit/Classes/Validation/Views/BaseValidationCell.swift @@ -5,6 +5,7 @@ import UIKit import NECoreIMKit +import NIMSDK @objcMembers public class BaseValidationCell: ContactBaseViewCell { @@ -61,20 +62,34 @@ public class BaseValidationCell: ContactBaseViewCell { var nickName = "" var teamName = "" // 设置操作者名称 - if let nick = model.sourceName { + + if let alias = model.userInfo?.alias { + nickName = alias + } else if let nick = model.userInfo?.userInfo?.nickName { nickName = nick + } else if let source = model.sourceName { + nickName = source + } + + if model.userInfo == nil, let uid = model.sourceID { + let user = NIMSDK.shared().userManager.userInfo(uid) + if let alias = user?.alias { + nickName = alias + } else if let nick = user?.userInfo?.nickName { + nickName = nick + } } // 设置头像 - if let headerUrl = model.userInfo?.userInfo?.avatarUrl { + if let headerUrl = model.userInfo?.userInfo?.avatarUrl, !headerUrl.isEmpty { avatarImage.sd_setImage(with: URL(string: headerUrl), completed: nil) titleLabel.text = "" - } else if let teamUrl = model.teamInfo?.avatarUrl { + } else if let teamUrl = model.teamInfo?.avatarUrl, !teamUrl.isEmpty { avatarImage.sd_setImage(with: URL(string: teamUrl), completed: nil) titleLabel.text = "" } else { // 无头像设置其name - if let name = model.sourceName { - showNameOnCircleHeader(name) + if !nickName.isEmpty { + showNameOnCircleHeader(nickName) } else { if let id = model.sourceID { showNameOnCircleHeader(id) @@ -114,6 +129,8 @@ public class BaseValidationCell: ContactBaseViewCell { titleLabelContent = "\(nickName) 通过好友申请" case .addFriendReject: titleLabelContent = "\(nickName) 拒绝好友申请" + @unknown default: + titleLabelContent = "\(nickName) 未知操作" } } diff --git a/NEContactUIKit/NEContactUIKit/Classes/ViewModel/ContactUserViewModel.swift b/NEContactUIKit/NEContactUIKit/Classes/ViewModel/ContactUserViewModel.swift index a5c0801d..ec9ef843 100644 --- a/NEContactUIKit/NEContactUIKit/Classes/ViewModel/ContactUserViewModel.swift +++ b/NEContactUIKit/NEContactUIKit/Classes/ViewModel/ContactUserViewModel.swift @@ -36,6 +36,11 @@ public class ContactUserViewModel: NSObject { return contactRepo.isBlackList(account: account) } + public func removeBlackList(account: String, _ completion: @escaping (NSError?) -> Void) { + NELog.infoLog(ModuleName + " " + className, desc: #function + ", account: " + account) + return contactRepo.removeBlackList(account: account, completion) + } + public func update(_ user: User, _ completion: @escaping (Error?) -> Void) { NELog.infoLog(ModuleName + " " + className, desc: #function + ", userId: " + (user.userId ?? "nil")) contactRepo.updateUser(user, completion) diff --git a/NEContactUIKit/NEContactUIKit/Classes/ViewModel/ContactViewModel.swift b/NEContactUIKit/NEContactUIKit/Classes/ViewModel/ContactViewModel.swift index 5680fdc7..ff40e3c7 100644 --- a/NEContactUIKit/NEContactUIKit/Classes/ViewModel/ContactViewModel.swift +++ b/NEContactUIKit/NEContactUIKit/Classes/ViewModel/ContactViewModel.swift @@ -15,17 +15,13 @@ public class ContactViewModel: NSObject, ContactRepoSystemNotiDelegate { public var indexs: [String]? private var contactHeaders: [ContactHeadItem]? public var contactRepo = ContactRepo() - private var initalDict: [String: [ContactInfo]] = ["#": []] + private var initalDict = [String: [ContactInfo]]() private let className = "ContactViewModel" var unreadCount = 0 var refresh: RefreshBlock? init(contactHeaders: [ContactHeadItem]?) { - NELog.infoLog( - ModuleName + " " + className, - desc: #function + ", contactHeaders.count: \(contactHeaders?.count ?? 0)" - ) super.init() NELog.infoLog( ModuleName + " " + className, @@ -49,10 +45,10 @@ public class ContactViewModel: NSObject, ContactRepoSystemNotiDelegate { func loadData(_ filters: Set? = nil, completion: @escaping (NSError?) -> Void) { NELog.infoLog(ModuleName + " " + className, desc: #function) - initalDict = ["#": []] weak var weakSelf = self getContactList(filters) { contacts, error in if let users = contacts { + NELog.infoLog("contact loadData", desc: "contact data:\(contacts)") weakSelf?.contacts = users weakSelf?.indexs = self.getIndexs(contactSections: users) if let headSection = weakSelf?.headerSection(headerItem: weakSelf?.contactHeaders) { @@ -69,6 +65,8 @@ public class ContactViewModel: NSObject, ContactRepoSystemNotiDelegate { weak var weakSelf = self contactRepo.getFriendList { [self] friends, error in if var users = friends { + NELog.infoLog("contact bar getFriendList", desc: "friend count:\(friends?.count)") + weakSelf?.initalDict = [String: [ContactInfo]]() if let filterUsers = filters { users = users.filter { user in if let uid = user.userId, filterUsers.contains(uid) { @@ -83,33 +81,55 @@ public class ContactViewModel: NSObject, ContactRepoSystemNotiDelegate { return // return contactList } + + let digitRegular = NSPredicate(format: "SELF MATCHES %@", "[0-9]") + let azRegular = NSPredicate(format: "SELF MATCHES %@", "[A-Z]") + var digitList = [ContactInfo]() + var specialCharList = [ContactInfo]() for contact: User in users { // get inital of name var name = contact.alias != nil ? contact.alias : contact.userInfo?.nickName if name == nil { name = contact.userId } - let inital = name?.initalLetter() + let inital = name?.initalLetter() ?? "#" let contactInfo = ContactInfo() contactInfo.user = contact contactInfo.headerBackColor = UIColor.colorWithString(string: contact.showName() ?? "") - var contactsTemp = weakSelf?.initalDict[inital!] - if contactsTemp == nil { - contactsTemp = [contactInfo] - weakSelf?.initalDict[inital!] = contactsTemp - } else { - weakSelf?.initalDict[inital!]?.append(contactInfo) + if digitRegular.evaluate(with: inital) { // [0-9] + digitList.append(contactInfo) + } else if !azRegular.evaluate(with: inital) { // [#] + specialCharList.append(contactInfo) + } else { // [A-Z] + if weakSelf?.initalDict[inital] != nil { + weakSelf?.initalDict[inital]?.append(contactInfo) + } else { + weakSelf?.initalDict[inital] = [contactInfo] + } } } + digitList.sort { s1, s2 in + s1.user!.showName()! < s2.user!.showName()! + } + specialCharList.sort { s1, s2 in + s1.user!.showName()! < s2.user!.showName()! + } + for key in initalDict.keys { - contactList.append(ContactSection(initial: key, contacts: (weakSelf?.initalDict[key]!)!)) + if var value = weakSelf?.initalDict[key] { + value.sort { s1, s2 in + s1.user!.showName()! < s2.user!.showName()! + } + contactList.append(ContactSection(initial: key, contacts: value)) + } } - let result = contactList.sorted { s1, s2 in + var result = contactList.sorted { s1, s2 in s1.initial < s2.initial } + result.append(ContactSection(initial: "#", contacts: digitList + specialCharList)) completion(result, nil) } } @@ -141,19 +161,26 @@ public class ContactViewModel: NSObject, ContactRepoSystemNotiDelegate { } func getIndexs(contactSections: [ContactSection]?) -> [String]? { - NELog.infoLog( - ModuleName + " " + className, - desc: #function + ", contactSections.count: \(contactSections?.count ?? 0)" - ) - guard let sections = contactSections else { - return nil - } - var indexs: [String] = [] - for section in sections { - if section.initial.count > 0 { - indexs.append(section.initial) - } - } + // 根据用户列表获取导航标签 +// NELog.infoLog( +// ModuleName + " " + className, +// desc: #function + ", contactSections.count: \(contactSections?.count ?? 0)" +// ) +// guard let sections = contactSections else { +// return nil +// } +// var indexs: [String] = [] +// for section in sections { +// if section.initial.count > 0 { +// indexs.append(section.initial) +// } +// } + + // ["A"..."Z", "#"] + let idx = UnicodeScalar("A").value ... UnicodeScalar("Z").value + var indexs = (idx.map { String(UnicodeScalar($0)!) }) + indexs.append("#") + return indexs } } diff --git a/NEContactUIKit/NEContactUIKit/Classes/Views/ContactBaseViewController.swift b/NEContactUIKit/NEContactUIKit/Classes/Views/ContactBaseViewController.swift index e1aa3868..aac9390a 100644 --- a/NEContactUIKit/NEContactUIKit/Classes/Views/ContactBaseViewController.swift +++ b/NEContactUIKit/NEContactUIKit/Classes/Views/ContactBaseViewController.swift @@ -7,6 +7,18 @@ import UIKit @objcMembers open class ContactBaseViewController: UIViewController { + lazy var emptyView: NEEmptyDataView = { + let view = NEEmptyDataView( + imageName: "user_empty", + content: "", + frame: CGRect.zero + ) + view.translatesAutoresizingMaskIntoConstraints = false + view.isHidden = true + return view + + }() + override public func viewDidLoad() { super.viewDidLoad() diff --git a/NEContactUIKit/NEContactUIKit/Classes/Views/ContactTableViewCell.swift b/NEContactUIKit/NEContactUIKit/Classes/Views/ContactTableViewCell.swift index 809e7ef9..ea7e106a 100644 --- a/NEContactUIKit/NEContactUIKit/Classes/Views/ContactTableViewCell.swift +++ b/NEContactUIKit/NEContactUIKit/Classes/Views/ContactTableViewCell.swift @@ -94,17 +94,19 @@ public class ContactTableViewCell: ContactBaseViewCell, ContactCellDataProtrol { titleLabel.text = user.showName() nameLabel.text = user.shortName(count: 2) -// self.nameLabel.backgroundColor = UIColor(hexString: user.userId!) - if let imageUrl = user.userInfo?.avatarUrl { + if let imageUrl = user.userInfo?.avatarUrl, !imageUrl.isEmpty { + NELog.infoLog("contact p2p cell configData", desc: "imageName:\(imageUrl)") nameLabel.isHidden = true avatarImage.sd_setImage(with: URL(string: imageUrl), completed: nil) } else { + NELog.infoLog("contact p2p cell configData", desc: "imageName is nil") nameLabel.isHidden = false - avatarImage.image = nil + avatarImage.sd_setImage(with: nil) } arrow.isHidden = true } else { + NELog.infoLog("contact other cell configData", desc: "\(user.alias), image name:\(user.userInfo?.avatarUrl)") nameLabel.text = "" titleLabel.text = user.alias avatarImage.image = UIImage.ne_imageNamed(name: user.userInfo?.avatarUrl) diff --git a/NEContactUIKit/NEContactUIKit/Classes/Views/ContactsSelectedViewController.swift b/NEContactUIKit/NEContactUIKit/Classes/Views/ContactsSelectedViewController.swift index 14c3a10c..e0d6cd5b 100644 --- a/NEContactUIKit/NEContactUIKit/Classes/Views/ContactsSelectedViewController.swift +++ b/NEContactUIKit/NEContactUIKit/Classes/Views/ContactsSelectedViewController.swift @@ -46,6 +46,7 @@ open class ContactsSelectedViewController: ContactBaseViewController { // Do any additional setup after loading the view. title = localizable("select") + emptyView.setttingContent(content: localizable("no_friend")) // setupUI() // setupNavRightItem() @@ -56,6 +57,7 @@ open class ContactsSelectedViewController: ContactBaseViewController { weakSelf?.setupUI() weakSelf?.setupNavRightItem() weakSelf?.tableView.reloadData() + weakSelf?.emptyView.isHidden = (weakSelf?.viewModel.contacts.count ?? 0) > 0 } } @@ -94,6 +96,14 @@ open class ContactsSelectedViewController: ContactBaseViewController { tableView.topAnchor.constraint(equalTo: collection.bottomAnchor), ]) + view.addSubview(emptyView) + NSLayoutConstraint.activate([ + emptyView.topAnchor.constraint(equalTo: tableView.topAnchor), + emptyView.bottomAnchor.constraint(equalTo: tableView.bottomAnchor), + emptyView.leftAnchor.constraint(equalTo: tableView.leftAnchor), + emptyView.rightAnchor.constraint(equalTo: tableView.rightAnchor), + ]) + customCells.forEach { (key: Int, value: AnyClass) in if value is ContactCellDataProtrol.Type { self.tableView.register( diff --git a/NEContactUIKit/NEContactUIKit/Classes/Views/ContactsViewController.swift b/NEContactUIKit/NEContactUIKit/Classes/Views/ContactsViewController.swift index de876d23..bff4da75 100644 --- a/NEContactUIKit/NEContactUIKit/Classes/Views/ContactsViewController.swift +++ b/NEContactUIKit/NEContactUIKit/Classes/Views/ContactsViewController.swift @@ -107,7 +107,9 @@ open class ContactsViewController: UIViewController, UITableViewDelegate, UITabl } public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - viewModel.contacts[section].contacts.count + NELog.infoLog(ModuleName + " " + className(), desc: "contact section: \(section), count:\(viewModel.contacts[section].contacts.count)") + + return viewModel.contacts[section].contacts.count } public func tableView(_ tableView: UITableView, @@ -120,7 +122,7 @@ open class ContactsViewController: UIViewController, UITableViewDelegate, UITabl cell.setModel(info) if indexPath.section == 0, indexPath.row == 0, viewModel.unreadCount > 0 { cell.redAngleView.isHidden = false - cell.redAngleView.text = "\(viewModel.unreadCount)" + cell.redAngleView.text = viewModel.unreadCount > 99 ? "99+" : "\(viewModel.unreadCount)" } else { cell.redAngleView.isHidden = true } diff --git a/NEContactUIKit/NEContactUIKit/Classes/Views/FindFriendViewController.swift b/NEContactUIKit/NEContactUIKit/Classes/Views/FindFriendViewController.swift index 77dee4b4..4c1af9b4 100644 --- a/NEContactUIKit/NEContactUIKit/Classes/Views/FindFriendViewController.swift +++ b/NEContactUIKit/NEContactUIKit/Classes/Views/FindFriendViewController.swift @@ -5,34 +5,18 @@ import UIKit import NECoreKit - +import NECoreIMKit @objcMembers public class FindFriendViewController: ContactBaseViewController, UITextFieldDelegate { let viewModel = FindFriendViewModel() let noResultView = UIView() let hasRequest = false - let searchInput = UITextField() - lazy var emptyView: UIImageView = { - let empty = UIImageView() - empty.translatesAutoresizingMaskIntoConstraints = false - empty.image = coreLoader.loadImage("user_empty") - return empty - }() - - lazy var userLabel: UILabel = { - let label = UILabel() - label.translatesAutoresizingMaskIntoConstraints = false - label.text = localizable("user_not_exist") - label.textColor = .ne_emptyTitleColor - label.font = UIFont.systemFont(ofSize: 14.0) - return label - }() - override public func viewDidLoad() { super.viewDidLoad() title = localizable("add_friend") + emptyView.setttingContent(content: localizable("user_not_exist")) setupUI() } @@ -79,6 +63,7 @@ public class FindFriendViewController: ContactBaseViewController, UITextFieldDel searchInput.font = UIFont.systemFont(ofSize: 14.0) searchInput.returnKeyType = .search searchInput.delegate = self + searchInput.clearButtonMode = .always NotificationCenter.default.addObserver( self, @@ -93,14 +78,6 @@ public class FindFriendViewController: ContactBaseViewController, UITextFieldDel emptyView.topAnchor.constraint(equalTo: searchInput.bottomAnchor, constant: 74), // emptyView.centerYAnchor.constraint(equalTo: view.centerYAnchor) ]) - emptyView.isHidden = true - - view.addSubview(userLabel) - NSLayoutConstraint.activate([ - userLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor), - userLabel.topAnchor.constraint(equalTo: emptyView.bottomAnchor, constant: 9), - ]) - userLabel.isHidden = true } public func textFieldShouldReturn(_ textField: UITextField) -> Bool { @@ -119,7 +96,6 @@ public class FindFriendViewController: ContactBaseViewController, UITextFieldDel func textFieldChange() { if let text = searchInput.text, text.count <= 0 { emptyView.isHidden = true - userLabel.isHidden = true } } @@ -136,10 +112,8 @@ public class FindFriendViewController: ContactBaseViewController, UITextFieldDel let userController = ContactUserViewController(user: user) self.navigationController?.pushViewController(userController, animated: true) weakSelf?.emptyView.isHidden = true - weakSelf?.userLabel.isHidden = true } else { weakSelf?.emptyView.isHidden = false - weakSelf?.userLabel.isHidden = false } } else { self.showToast(error?.localizedDescription ?? "") diff --git a/NEConversationUIKit/NEConversationUIKit.podspec b/NEConversationUIKit/NEConversationUIKit.podspec index dc953f57..623dbfd0 100644 --- a/NEConversationUIKit/NEConversationUIKit.podspec +++ b/NEConversationUIKit/NEConversationUIKit.podspec @@ -8,7 +8,7 @@ Pod::Spec.new do |s| s.name = 'NEConversationUIKit' - s.version = '9.3.0' + s.version = '9.2.10' s.summary = 'Netease XKit' # This description is used to generate tags and improve search results. @@ -34,12 +34,12 @@ TODO: Add long description of the pod here. s.resource = 'NEConversationUIKit/Assets/**/*' # s.public_header_files = 'Pod/Classes/**/*.h' s.pod_target_xcconfig = { + 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64', 'BUILD_LIBRARY_FOR_DISTRIBUTION' => 'YES' } - s.user_target_xcconfig = { 'BUILD_LIBRARY_FOR_DISTRIBUTION' => 'YES' } s.dependency 'NECommonUIKit' s.dependency 'NEConversationKit' - s.dependency 'YXAlog_iOS' + s.dependency 'YXAlog' s.dependency 'NIMSDK_LITE' end diff --git a/NEConversationUIKit/NEConversationUIKit/Assets/en.lproj/Localizable.strings b/NEConversationUIKit/NEConversationUIKit/Assets/en.lproj/Localizable.strings index ea450d01..8a06b04e 100644 --- a/NEConversationUIKit/NEConversationUIKit/Assets/en.lproj/Localizable.strings +++ b/NEConversationUIKit/NEConversationUIKit/Assets/en.lproj/Localizable.strings @@ -16,15 +16,16 @@ "search"="Search"; "search_keyword"="Enter the key words"; "user_not_exist"="Not Exist"; +"session_empty"="No Session"; "hm"="HH:mm"; "mdhm"="MM.dd HH:mm"; "ymdhm"="yyyy.MM.dd HH:mm"; -"voice"="[aduio]"; -"picture"="[picture]"; -"video"="[Video]"; -"location"="[Loaction]"; -"notification"="[Tip]"; -"file"="[File]"; +"voice"="[aduio Message]"; +"picture"="[picture Message]"; +"video"="[Video Message]"; +"location"="[Geographic Loaction]"; +"notification"="[Tip Message]"; +"file"="[File Message]"; "internet_phone"="[Audio_Chat]"; "video_chat"="[Video_Chat]"; "unknown"="[Unknown Message]"; diff --git a/NEConversationUIKit/NEConversationUIKit/Assets/zh-Hans.lproj/Localizable.strings b/NEConversationUIKit/NEConversationUIKit/Assets/zh-Hans.lproj/Localizable.strings index bbeffbf3..8b4c288f 100644 --- a/NEConversationUIKit/NEConversationUIKit/Assets/zh-Hans.lproj/Localizable.strings +++ b/NEConversationUIKit/NEConversationUIKit/Assets/zh-Hans.lproj/Localizable.strings @@ -16,18 +16,19 @@ "search"="搜索"; "search_keyword"="请输入你要搜索的关键字"; "user_not_exist"="该用户不存在"; +"session_empty"="暂无会话"; "hm"="HH:mm"; "mdhm"="MM月dd日 HH:mm"; "ymdhm"="yyyy年MM月dd日 HH:mm"; -"voice"="[语音]"; -"picture"="[图片]"; -"video"="[视频]"; -"location"="[位置]"; -"notification"="[通知]"; -"file"="[文件]"; -"internet_phone"="[网络通话]"; -"video_chat"="[视频聊天]"; +"voice"="[语音消息]"; +"picture"="[图片消息]"; +"video"="[视频消息]"; +"location"="[地理位置]"; +"notification"="[通知消息]"; +"file"="[文件消息]"; +"internet_phone"="[音频通话]"; +"video_chat"="[视频通话]"; "unknown"="[未知消息]"; "appName"="云信IM"; -"message_recalled"="消息已撤回"; +"message_recalled"="此消息已撤回"; diff --git a/NEConversationUIKit/NEConversationUIKit/Classes/Conversation/Controller/ConversationController.swift b/NEConversationUIKit/NEConversationUIKit/Classes/Conversation/Controller/ConversationController.swift index ea83ebc7..90e41191 100644 --- a/NEConversationUIKit/NEConversationUIKit/Classes/Conversation/Controller/ConversationController.swift +++ b/NEConversationUIKit/NEConversationUIKit/Classes/Conversation/Controller/ConversationController.swift @@ -106,6 +106,14 @@ extension ConversationController: ConversationNavViewDelegate { } items.append(addFriend) + let createGroup = PopListItem() + createGroup.showName = localizable("create_discussion_group") + createGroup.image = UIImage.ne_imageNamed(name: "create_discussion") + createGroup.completion = { + weakSelf?.createDiscussGroup() + } + items.append(createGroup) + let createDicuss = PopListItem() createDicuss.showName = localizable("create_senior_group") createDicuss.image = UIImage.ne_imageNamed(name: "create_group") @@ -190,6 +198,7 @@ extension ConversationController: ConversationNavViewDelegate { if message.messageType == .text { muta[revokeLocalMessageContent] = message.text } + messageNew.timestamp = message.timestamp messageNew.from = message.from messageNew.localExt = muta let setting = NIMMessageSetting() diff --git a/NEConversationUIKit/NEConversationUIKit/Classes/Conversation/Controller/ConversationListViewController.swift b/NEConversationUIKit/NEConversationUIKit/Classes/Conversation/Controller/ConversationListViewController.swift index 7c3de52a..8f320252 100644 --- a/NEConversationUIKit/NEConversationUIKit/Classes/Conversation/Controller/ConversationListViewController.swift +++ b/NEConversationUIKit/NEConversationUIKit/Classes/Conversation/Controller/ConversationListViewController.swift @@ -12,6 +12,18 @@ open class ConversationListViewController: UIViewController { private let className = "ConversationListViewController" private var tableViewTopConstraint: NSLayoutConstraint? + private lazy var emptyView: NEEmptyDataView = { + let view = NEEmptyDataView( + imageName: "user_empty", + content: localizable("session_empty"), + frame: CGRect.zero + ) + view.translatesAutoresizingMaskIntoConstraints = false + view.isHidden = true + return view + + }() + override open func viewDidLoad() { super.viewDidLoad() setupSubviews() @@ -48,6 +60,7 @@ open class ConversationListViewController: UIViewController { open func setupSubviews() { view.addSubview(tableView) + view.addSubview(emptyView) view.addSubview(brokenNetworkView) NSLayoutConstraint.activate([ @@ -57,6 +70,13 @@ open class ConversationListViewController: UIViewController { ]) tableViewTopConstraint = tableView.topAnchor.constraint(equalTo: view.topAnchor) tableViewTopConstraint?.isActive = true + + NSLayoutConstraint.activate([ + emptyView.topAnchor.constraint(equalTo: tableView.topAnchor, constant: 100), + emptyView.bottomAnchor.constraint(equalTo: tableView.bottomAnchor), + emptyView.leftAnchor.constraint(equalTo: tableView.leftAnchor), + emptyView.rightAnchor.constraint(equalTo: tableView.rightAnchor), + ]) } func requestData() { @@ -68,8 +88,14 @@ open class ConversationListViewController: UIViewController { viewModel.fetchServerSessions(option: params) { error, recentSessions in if error == nil { NELog.infoLog(ModuleName + " " + self.className, desc: "✅CALLBACK fetchServerSessions SUCCESS") - DispatchQueue.main.async { - weakSelf?.tableView.reloadData() + if let recentList = recentSessions { + NELog.infoLog(ModuleName + " " + self.className, desc: "✅CALLBACK fetchServerSessions SUCCESS count : \(recentList.count)") + if recentList.count > 0 { + weakSelf?.emptyView.isHidden = true + weakSelf?.reloadTableView() + } else { + weakSelf?.emptyView.isHidden = false + } } } else { @@ -77,6 +103,7 @@ open class ConversationListViewController: UIViewController { ModuleName + " " + self.className, desc: "❌CALLBACK fetchServerSessions failed,error = \(error!)" ) + weakSelf?.emptyView.isHidden = false } } } @@ -169,7 +196,10 @@ extension ConversationListViewController { extension ConversationListViewController: UITableViewDelegate, UITableViewDataSource { public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - viewModel.conversationListArray?.count ?? 0 + let count = viewModel.conversationListArray?.count ?? 0 + NELog.infoLog(ModuleName + " " + "ConversationListViewController", + desc: "numberOfRowsInSection count : \(count)") + return count } public func tableView(_ tableView: UITableView, @@ -178,9 +208,11 @@ extension ConversationListViewController: UITableViewDelegate, UITableViewDataSo withIdentifier: "\(NSStringFromClass(ConversationListCell.self))", for: indexPath ) as! ConversationListCell - let conversationModel = viewModel.conversationListArray?[indexPath.row] - cell.topStickInfos = viewModel.stickTopInfos - cell.configData(sessionModel: conversationModel) + if let count = viewModel.conversationListArray?.count, count > indexPath.row { + let conversationModel = viewModel.conversationListArray?[indexPath.row] + cell.topStickInfos = viewModel.stickTopInfos + cell.configData(sessionModel: conversationModel) + } return cell } @@ -215,25 +247,6 @@ extension ConversationListViewController: UITableViewDelegate, UITableViewDataSo model: conversationModel ?? ConversationListModel(), indexPath: indexPath ) - - // 删除cell - if let stickTopInfo = weakSelf?.viewModel.stickTopInfoForSession(session: session) { - weakSelf?.viewModel - .removeStickTopSession(params: stickTopInfo) { error, topSessionInfo in - if let err = error { - NELog.errorLog( - ModuleName + " " + (weakSelf?.className ?? "ConversationListViewController"), - desc: "❌CALLBACK removeStickTopSession failed,error = \(err)" - ) - return - } - NELog.infoLog( - ModuleName + " " + (weakSelf?.className ?? "ConversationListViewController"), - desc: "✅CALLBACK removeStickTopSession SUCCESS" - ) - weakSelf?.viewModel.stickTopInfos[session] = nil - } - } } // 置顶和取消置顶 @@ -355,6 +368,8 @@ extension ConversationListViewController { extension ConversationListViewController: ConversationViewModelDelegate { public func didAddRecentSession() { + NELog.infoLog("ConversationListViewController", desc: "didAddRecentSession") + emptyView.isHidden = (viewModel.conversationListArray?.count ?? 0) > 0 viewModel.sortRecentSession() tableView.reloadData() } @@ -365,6 +380,7 @@ extension ConversationListViewController: ConversationViewModelDelegate { } public func reloadTableView() { + emptyView.isHidden = (viewModel.conversationListArray?.count ?? 0) > 0 viewModel.sortRecentSession() tableView.reloadData() } diff --git a/NEConversationUIKit/NEConversationUIKit/Classes/Conversation/Controller/ConversationSearchController.swift b/NEConversationUIKit/NEConversationUIKit/Classes/Conversation/Controller/ConversationSearchController.swift index 70d9506b..c959a9db 100644 --- a/NEConversationUIKit/NEConversationUIKit/Classes/Conversation/Controller/ConversationSearchController.swift +++ b/NEConversationUIKit/NEConversationUIKit/Classes/Conversation/Controller/ConversationSearchController.swift @@ -151,6 +151,7 @@ open class ConversationSearchController: ConversationBaseViewController, UITable let tableView = UITableView(frame: .zero, style: .plain) tableView.translatesAutoresizingMaskIntoConstraints = false tableView.separatorStyle = .none + tableView.keyboardDismissMode = .onDrag tableView.delegate = self tableView.dataSource = self tableView.register( @@ -279,6 +280,7 @@ open class ConversationSearchController: ConversationBaseViewController, UITable ) as! SearchSessionHeaderView sectionView.setUpTitle(title: headTitleArr[section]) sectionView.backgroundView = UIView() + sectionView.backgroundView?.backgroundColor = .white return sectionView } diff --git a/NEConversationUIKit/NEConversationUIKit/Classes/Conversation/View/ConversationListCell.swift b/NEConversationUIKit/NEConversationUIKit/Classes/Conversation/View/ConversationListCell.swift index 42585b6a..8dac7f95 100644 --- a/NEConversationUIKit/NEConversationUIKit/Classes/Conversation/View/ConversationListCell.swift +++ b/NEConversationUIKit/NEConversationUIKit/Classes/Conversation/View/ConversationListCell.swift @@ -10,7 +10,7 @@ open class ConversationListCell: UITableViewCell { // private var viewModel = ConversationViewModel() public var topStickInfos = [NIMSession: NIMStickTopSessionInfo]() private let repo = ConversationRepo() - + private var timeWidth: NSLayoutConstraint? override open func awakeFromNib() { super.awakeFromNib() // Initialization code @@ -52,11 +52,12 @@ open class ConversationListCell: UITableViewCell { ]) NSLayoutConstraint.activate([ - redAngleView.centerXAnchor.constraint(equalTo: headImge.rightAnchor, constant: -3), - redAngleView.centerYAnchor.constraint(equalTo: headImge.topAnchor, constant: 3), + redAngleView.centerXAnchor.constraint(equalTo: headImge.rightAnchor, constant: -8), + redAngleView.centerYAnchor.constraint(equalTo: headImge.topAnchor, constant: 8), redAngleView.heightAnchor.constraint(equalToConstant: 18), ]) - + timeWidth = timeLabel.widthAnchor.constraint(equalToConstant: 0) + timeWidth?.isActive = true NSLayoutConstraint.activate([ timeLabel.rightAnchor.constraint( equalTo: contentView.rightAnchor, @@ -160,6 +161,12 @@ open class ConversationListCell: UITableViewCell { timeLabel .text = dealTime(time: timestampDescriptionForRecentSession(recentSession: rencentSession)) + if let text = timeLabel.text { + let maxSize = CGSize(width: UIScreen.main.bounds.width, height: 0) + let attibutes = [NSAttributedString.Key.font: timeLabel.font] + let labelSize = NSString(string: text).boundingRect(with: maxSize, attributes: attibutes, context: nil) + timeWidth?.constant = labelSize.width + 1 // ceil() + } } // backgroundColor diff --git a/NEConversationUIKit/NEConversationUIKit/Classes/Conversation/ViewModel/ConversationViewModel.swift b/NEConversationUIKit/NEConversationUIKit/Classes/Conversation/ViewModel/ConversationViewModel.swift index 12e94056..109a0a05 100644 --- a/NEConversationUIKit/NEConversationUIKit/Classes/Conversation/ViewModel/ConversationViewModel.swift +++ b/NEConversationUIKit/NEConversationUIKit/Classes/Conversation/ViewModel/ConversationViewModel.swift @@ -8,7 +8,6 @@ import NIMSDK let revokeLocalMessage = "revoke_message_local" let revokeLocalMessageContent = "revoke_message_local_content" -// let firstInit = "first_init" public protocol ConversationViewModelDelegate: NSObjectProtocol { func didAddRecentSession() @@ -23,9 +22,10 @@ public class ConversationViewModel: NSObject, ConversationRepoDelegate, public var stickTopInfos = [NIMSession: NIMStickTopSessionInfo]() public weak var delegate: ConversationViewModelDelegate? private let className = "ConversationViewModel" - let repo = ConversationRepo() + public let repo = ConversationRepo() var cacheUpdateSessionDic = [String: NIMRecentSession]() + var cacheAddSessionDic = [String: ConversationListModel]() override public init() { NELog.infoLog(ModuleName + " " + className, desc: #function) @@ -43,18 +43,46 @@ public class ConversationViewModel: NSObject, ConversationRepoDelegate, NELog.infoLog(ModuleName + " " + className, desc: #function) weak var weakSelf = self repo.getSessionList { error, conversaitonList in - weakSelf?.conversationListArray = conversaitonList - print("get session list : ", conversaitonList?.count as Any) - conversaitonList?.forEach { model in - if let recentSession = model.recentSession, let sid = recentSession.session?.sessionId { - if let recent = weakSelf?.cacheUpdateSessionDic[sid] { - if let time1 = recentSession.lastMessage?.timestamp, let time2 = recent.lastMessage?.timestamp, time1 < time2 { - model.recentSession = recent + DispatchQueue.main.async { + weakSelf?.conversationListArray = conversaitonList + NELog.infoLog(ModuleName, desc: "get session list : \(conversaitonList?.count ?? 0)") + var set = Set() + conversaitonList?.forEach { model in + NELog.infoLog(ModuleName, desc: "get session sid : \(model.recentSession?.session?.sessionId ?? "nil")") + if let recentSession = model.recentSession, let sid = recentSession.session?.sessionId { + set.insert(sid) + if let recent = weakSelf?.cacheUpdateSessionDic[sid] { + NELog.infoLog(ModuleName, desc: "cacheUpdateSessionDic fitler sid: \(recent.session?.sessionId ?? "nil")") + if let time1 = recentSession.lastMessage?.timestamp, let time2 = recent.lastMessage?.timestamp, time1 < time2 { + model.recentSession = recent + } } + + if let recent = weakSelf?.cacheAddSessionDic[sid]?.recentSession { + NELog.infoLog(ModuleName, desc: "cacheAddSessionDic fitler sid: \(recent.session?.sessionId ?? "nil")") + if let time1 = recentSession.lastMessage?.timestamp, let time2 = recent.lastMessage?.timestamp, time1 < time2 { + model.recentSession = recent + } + } + } + } + NELog.infoLog(ModuleName, desc: "cacheAddSessionDic count: \(weakSelf?.cacheAddSessionDic.count ?? 0)") + weakSelf?.cacheAddSessionDic.forEach { (key: String, value: ConversationListModel) in + NELog.infoLog(ModuleName, desc: "cacheAddSessionDic key: \(key)") + if set.contains(key) == false { + if let recent = weakSelf?.cacheUpdateSessionDic[key] { + if let time1 = value.recentSession?.lastMessage?.timestamp, let time2 = recent.lastMessage?.timestamp, time1 < time2 { + value.recentSession = recent + } + } + NELog.infoLog(ModuleName, desc: "cacheAddSessionDic : \(key)") + weakSelf?.conversationListArray?.append(value) } } + weakSelf?.cacheAddSessionDic.removeAll() + NELog.infoLog(ModuleName, desc: "conversationListArray count : \(weakSelf?.conversationListArray?.count ?? 0)") + completion(error, weakSelf?.conversationListArray) } - completion(error, weakSelf?.conversationListArray) } } @@ -182,13 +210,13 @@ public class ConversationViewModel: NSObject, ConversationRepoDelegate, // MARK: ==================== ConversationRepoDelegate ========================== public func onNotifyAddStickTopSession(_ newInfo: NIMStickTopSessionInfo) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", sessionId:" + newInfo.session.sessionId) + NELog.infoLog(ModuleName + " " + className, desc: #function + ",onNotifyAddStickTopSession sessionId:" + newInfo.session.sessionId) stickTopInfos[newInfo.session] = newInfo delegate?.reloadTableView() } public func onNotifyRemoveStickTopSession(_ removedInfo: NIMStickTopSessionInfo) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", sessionId:" + removedInfo.session.sessionId) + NELog.infoLog(ModuleName + " " + className, desc: #function + ",onNotifyRemoveStickTopSession sessionId:" + removedInfo.session.sessionId) stickTopInfos[removedInfo.session] = nil delegate?.reloadTableView() } @@ -202,25 +230,64 @@ public class ConversationViewModel: NSObject, ConversationRepoDelegate, NELog.errorLog(ModuleName + " " + className, desc: "❌sessionId is nil") return } - NELog.infoLog(ModuleName + " " + className, desc: #function + ", targetId:" + targetId) + NELog.infoLog(ModuleName + " " + className, desc: #function + ", did add session targetId:" + targetId) + DispatchQueue.main.async {} + if let object = recentSession.lastMessage?.messageObject as? NIMNotificationObject, object.notificationType == .team { + if let content = object.content as? NIMTeamNotificationContent { + if content.operationType == .dismiss || (content.operationType == .leave && content.sourceID == NIMSDK.shared().loginManager.currentAccount()) { + NELog.infoLog( + ModuleName + " " + className, + desc: #function + "didAdd team dismiss or leave noti" + (recentSession.session?.sessionId ?? "nil") + ) + repo.deleteLocalSession(recentSession: recentSession) + return + } + } + } + weak var weakSelf = self - let listModel = ConversationListModel() + var listModel = ConversationListModel() + if let sid = recentSession.session?.sessionId { + print("session session id : ", sid) + if let model = cacheAddSessionDic[sid] { + listModel = model + NELog.infoLog( + ModuleName + " " + className, + desc: #function + "didAdd team has added" + (recentSession.session?.sessionId ?? "nil") + ) + } + cacheAddSessionDic[sid] = listModel + } listModel.recentSession = recentSession if recentSession.session?.sessionType == .P2P { repo.getUserInfo(userId: targetId) { user, error in if error == nil { - DispatchQueue.main.async { - listModel.userInfo = user + listModel.userInfo = user + if let model = weakSelf?.sessionIsExist(listModel) { + NELog.infoLog( + ModuleName, + desc: #function + "conversation session user : " + "\(user?.userId ?? "nil")" + ) + model.userInfo = user + } else { weakSelf?.conversationListArray?.append(listModel) - weakSelf?.delegate?.didAddRecentSession() } + weakSelf?.delegate?.didAddRecentSession() } } } else if recentSession.session?.sessionType == .team { repo.getTeamInfo(teamId: targetId) { error, teamInfo in listModel.teamInfo = teamInfo - weakSelf?.conversationListArray?.append(listModel) + if let model = weakSelf?.sessionIsExist(listModel) { + NELog.infoLog( + ModuleName, + desc: #function + "conversation session team : " + "\(teamInfo?.teamId ?? "nil")" + ) + model.teamInfo = teamInfo + } else { + weakSelf?.conversationListArray?.append(listModel) + } weakSelf?.delegate?.didAddRecentSession() } } @@ -229,20 +296,41 @@ public class ConversationViewModel: NSObject, ConversationRepoDelegate, public func didUpdate(_ recentSession: NIMRecentSession, totalUnreadCount: Int) { NELog.infoLog( ModuleName + " " + className, - desc: #function + ", sessionId:" + (recentSession.session?.sessionId ?? "nil") + desc: #function + "recentSession, didUpdate sessionId:" + (recentSession.session?.sessionId ?? "nil") ) - print("did update last msg : ", recentSession.lastMessage?.text as Any) + + if let object = recentSession.lastMessage?.messageObject as? NIMNotificationObject, object.notificationType == .team { + if let content = object.content as? NIMTeamNotificationContent { + if content.operationType == .dismiss || (content.operationType == .leave && content.sourceID == NIMSDK.shared().loginManager.currentAccount()) { + NELog.infoLog( + ModuleName + " " + className, + desc: #function + "didUpdate team dismiss or leave noti" + (recentSession.session?.sessionId ?? "nil") + ) + repo.deleteLocalSession(recentSession: recentSession) + return + } + } + } + if let sid = recentSession.session?.sessionId { cacheUpdateSessionDic[sid] = recentSession + if let model = cacheAddSessionDic[sid], let recent = model.recentSession { + if let time1 = recentSession.lastMessage?.timestamp, let time2 = recent.lastMessage?.timestamp, time1 > time2 { + model.recentSession = recentSession + } + } } + if let _ = conversationListArray { for i in 0 ..< conversationListArray!.count { let listModel = conversationListArray![i] + NELog.infoLog( + ModuleName + " " + className, + desc: #function + "update session id : " + (listModel.recentSession?.session?.sessionId ?? "nil") + ) if recentSession.session?.sessionId == listModel.recentSession?.session?.sessionId { -// conversationListArray?.remove(at: i) listModel.recentSession = recentSession delegate?.reloadTableView() -// delegate?.didUpdateRecentSession(index: i) break } } @@ -252,8 +340,11 @@ public class ConversationViewModel: NSObject, ConversationRepoDelegate, public func didRemove(_ recentSession: NIMRecentSession, totalUnreadCount: Int) { NELog.infoLog( ModuleName + " " + className, - desc: #function + ", sessionId:" + (recentSession.session?.sessionId ?? "nil") + desc: #function + ",didRemove recentSession sessionId:" + (recentSession.session?.sessionId ?? "nil") ) + if let sid = recentSession.session?.sessionId { + cacheUpdateSessionDic.removeValue(forKey: sid) + } if let conversationArr = conversationListArray { for i in 0 ..< conversationArr.count { if conversationArr[i].recentSession?.session?.sessionId == recentSession.session? @@ -266,7 +357,7 @@ public class ConversationViewModel: NSObject, ConversationRepoDelegate, delegate?.reloadTableView() } - // MARK: ========================NIMTeamManagerDelegate========================= + // MARK: ========================NIMUserManagerDelegate========================= public func onFriendChanged(_ user: NIMUser) { NELog.infoLog(ModuleName + " " + className, desc: #function + ", userId:" + (user.userId ?? "nil")) @@ -299,7 +390,14 @@ public class ConversationViewModel: NSObject, ConversationRepoDelegate, } } - public func onTeamAdded(_ team: NIMTeam) {} + public func onTeamAdded(_ team: NIMTeam) { + NELog.infoLog(ModuleName + " " + className, desc: #function + "onTeamAdded, teamId:" + (team.teamId ?? "nil")) + guard let tid = team.teamId else { + return + } + let _ = repo.createTeamSession(tid) + delegate?.didAddRecentSession() + } public func onTeamRemoved(_ team: NIMTeam) { NELog.infoLog(ModuleName + " " + className, desc: #function + ", teamId:" + (team.teamId ?? "nil")) @@ -320,4 +418,16 @@ public class ConversationViewModel: NSObject, ConversationRepoDelegate, } } } + + private func sessionIsExist(_ model: ConversationListModel) -> ConversationListModel? { + if let array = conversationListArray { + for index in 0 ..< array.count { + let m = array[index] + if m.recentSession?.session?.sessionId == model.recentSession?.session?.sessionId { + return m + } + } + } + return nil + } } diff --git a/NEMapKit/NEMapKit.podspec b/NEMapKit/NEMapKit.podspec index 1baf0da8..9e922ab0 100644 --- a/NEMapKit/NEMapKit.podspec +++ b/NEMapKit/NEMapKit.podspec @@ -21,10 +21,12 @@ Pod::Spec.new do |s| TODO: Add long description of the pod here. DESC - s.homepage = 'http://netease.im' + s.homepage = 'https://github.com/xushandong/NEMapKit' + # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' s.license = { :'type' => 'Copyright', :'text' => ' Copyright 2022 Netease '} s.author = 'yunxin engineering department' s.source = { :git => 'ssh://git@g.hz.netease.com:22222/yunxin-app/xkit-ios.git', :tag => s.version.to_s } + # s.social_media_url = 'https://twitter.com/' s.ios.deployment_target = '9.0' diff --git a/NEMapKit/NEMapKit/Classes/NEMapService.m b/NEMapKit/NEMapKit/Classes/NEMapService.m index 19f2bd90..f99f4a98 100644 --- a/NEMapKit/NEMapKit/Classes/NEMapService.m +++ b/NEMapKit/NEMapKit/Classes/NEMapService.m @@ -42,6 +42,7 @@ - (void)setupMapClient { - (void)setupMapSdkConfig { // 初始化高德SDK + [[AMapServices sharedServices] setApiKey:@"46a3a36bb9d26934a26c6ce2b04aab6f"]; [AMapServices sharedServices].enableHTTPS = YES; } diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/add.imageset/Frame@2x-4.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/add.imageset/Frame@2x-4.png deleted file mode 100644 index 0f6ea9a661a32177a8ce2b670d9e8532bbf557b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1405 zcmV-@1%mpCP)F8B!|KS4~4%lL%2<%pjk5Ca92t5|RjxksIx zim}NPM0o@G;3}h^>2&Y1%d$Hwb|rxh;XA;N=4ZR7dwRa^1-Qc<{@*|t5mwf%f=2Z) z12E64J|uu?UVK{m__>8ZO(1L%!r!2Ey;`yBFaivvz>;N6Pkeg3+Khs3NHqSlQUIcvjJ{<1OCSw>`kK4Cu3|95ij)Zb^s5 z3V&%sUaL$VdwNkJ&a+$PugqqP^oYv8SL_<3Kq>{+Hmp6vuAh)nrRwWn>W~7@U%XsY znq;l{;O|6WR}Xi$ldh9U0ms+R@ef2S_!9}5I-{1;3LeJl=FSoeQ4Csyi0a)*dRDuz zU_U5GfUxlViv4?&dS+PR1xE+FwRTR=$eP}7@-BI2lKIzKAnY~-x?DZ5OK<~N+uSL! zC5ryL61Y>QU+0gT))Jz6A?+o#vi?&6l|J^`Y=!$KD;O={ z?!F5GI!P;8IeFuJc%0X{tb^&o>Ez_8Y z0%E$L@BeoA>z^J zgdF+}qC&XebOyfhJG;Fmj2Xggy=PSTZMc6TItBCIQ)kML#YRY|jEgWxG%wM>dtPCh zU>euey4Ekmc9@oD+kP{WG#M1Q9CRHUbZ_bqulIl$d@kSxJ&3G<_yhlY05K35n6XA= z^N@&*#sNo=QV+X^$pW(Lj;4|a^s|D}dZF9jg$hoC`8^??n8syD*PstX254WA?Fu3a z@Xi0(OBb_W9QQbb7*t%}Et&en=RLO(;j0I`B^Utg|M|-nHpBg3(24TTYJh#q26fk94$7%PIjj1OHs+#gXO3IDh)gn3!@ zb+npiW}^W6mko?fCT<#tbeSK=@G_$UTqUqC7s0|HR+!)$Ri$d$a5t7e@^nn_Zp83iQvXWRHGKx=ATepxn+jlGFGZVv1UELl~bymZu% zx@*w)<91&VTUI%1G``NxK0Rj}eeWzJC5}f=;NyqJ3EUvo)_01e@Mr%Ag6%hzy?WgE zzICC~5APd~9?#up@#my1=iw%maD@-v>|Dw@+X_=wJg zsa!9N;LX9_%yn}UvC+Lr2D_7$J;zT@q!O zm_CrOYnHi~o2ra6P&Tp7sbrUnUx=gPO0+MfOM8GbHB>s}DPsI&bUj)^S?=+zZx0a+ zM)#TZ1rsl=-P{-1J;R3BX_vN9RU6VY{wX0j8F7N00000 LNkvXXu0mjfO!J!v diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/add.imageset/Frame@3x-4.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/add.imageset/Frame@3x-4.png deleted file mode 100644 index 4d47a42425b0cc9cc47689965e7558f7d6583112..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2033 zcmVCMVx9mSY?tk#3fbY1o8=pa6cSaG?ZQq_jyc5~ zbBcUIRWTr*Aj%U&smcM{(sX*(5@`X}4H|gh^DO#g$x^McM3C6fFb?MDof0Zm|prk%&Nv3*&}| zBKNF?B!r4pp!t|tQ!oi;luo7GigW12 zCeY&QMvm{ciNPPH&TsmKL@a+bE)R-^26u&pKTTN~Y|1%-c#FIS{R7;annYVa?-olC z1F;CSyqYTzid?`cha^P)i&UdpjA0g9THBcCAL{Ft?i?a0?(aNahaTxkAT>LUo!}pQ zn~dfZTbTW)Kb9c@7VkgIB2j_W(ENX@o=Upi%aH3@AZ2gHge^|m=P(Z?*y1->gg&5p z6n~IS-=W7t?v!Y@TamgFC`6n?OUn7(KKLk|C_B|e>p380JqMLY6ExM0lbM1pU~zu) z7l)qgZ5MLz5oo=T+2ys3Joltc$3dPA$4-D>C`>^_EQp9Q$be$b-A*94_P2{az(?lQ zpD)YP*Kewkk#!!yi&v*_PQE^R`8z})l0bLYa`TAdk-NPmP96pXok;9!&0L+j@$c(b zm5Sl5%mr#Yfvtt*dj?IMHcF&x*Jm#9^Uid(qrjOf*KYh;J*pVlBLRl6IC&qtb2y0N zw6X0WVcFF@dG?~sFcRqAYHp6*{yUv*NKjL=6%05QH5d4YqqnG~kiA|sz-Sg@_rBn6 zQ+`gIQ@L_F#j%(NlJz)48R{9AS2wmersVt#yqMo5`QFU+kaS39C zJ@PjkKr2{6JRd{lW5vfa<*>SjnrSZz6$p_w-EAbO=QU0zo|nLW%hFOV12IB`Tb{jDKz`8b3qu>?bkUoT3X zK%nOzC=dtCzjOS}GgsWUr=K)FYgEBCqj9gg6?BbOAiL|ihZlxh{Xs@8R#m{Rvn_0x zX$4BXOL>f>Bzyrwj*4cw+pJ?Nt2LPi@By?FnEvQ{5Q+1SKY`xDCjzQWinB%Qb7_|vgmf7lH^sl83zWl0R)|l7 z())l-$grmiVRVxVqq8(qXN&gvv;y(Y#B zt0}EJ*Erk}6(Llx3e%7@yevtnMQ#Kf3Ca+X6Np5tONAiVflaL9!&o2;7^i+TCS-|6 zNDUIkj!S_oLqh0{G}|1f9m4YvftF3Utde`7CpTpVUGW+=r0ZabK)(xRqyB8C7~MDH zygxXtbWL|^fRUzu`1^Z-NYVx90+XyNhdb1#bv9bEy8rZX=(XK|ATHTmpar`y+6hQI z#P|(5{2mT=Yn`c~16@wA)Y~w<4MMEBTGC;$lVQM)ak(o{1ZszAKo63hi^PdHJ~V7_ zSl8>63cZon3e=qNhBmB#a+6_!R|KAy+(<$69%Ro#-kj3V_aL6U94}dgkb}JN;D{p9 zp{r@qG@mqxsMNW~yC*ydx+YMdlW|$}G#X?A1{I5}JMOj=$?gU68)i|mlBS?&B(_v& zW2csUGBjZ^uF$1MxA~+f>}?mToy!une26=>gre!m4)cOBA9h`+K)QU=-4!*S<3mU} z%Rd&>664&2j9lmxM9cO#rgzhqU=*rR-4lg$r-SRKQcjfyJPfNV7nCG#|Fly)2)o{B zHSgDpAYvKG$D&o!ly)_jOvF(bhdZ=oB&!<*7*Lj1Hay!QT4g(1ruQ(eFgrS`)TgI! z9`m65*6|NjS=+T6@cO872m^!?hXmw32iV3v+bxvAkVrL(uZ~_;e9PMSEe(=LT5(hr z?oQzmL?CjN>y>Y2DpphVBD~nyJ}4sD+ad&ds%=%OXK%Z38zRzOAvuRV#!ti>zsh#C z;jKZm(C^tTXs3~~JA&kFH;K=#g7(V8R(^|L%vn94st}9YPYOc$IVmCD#4V0}J@kNG z{(n|=@0*zp45)Ou#J0aSe+ZE*FYswfI1HyuHsfu0334I~wW9 z=i`*`b^BFp8|qqnxRg(%56cqO_=B-n@axIh diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/emoji.imageset/Frame@2x-1.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/emoji.imageset/Frame@2x-1.png deleted file mode 100644 index 072e58ff09bd8fe21c19f21fb76020e4aca42e9f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1488 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 oyNRe9hBr8h`#04Hd2f{+v&*|yz> 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 diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/mic.imageset/Frame@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/mic.imageset/Frame@3x.png deleted file mode 100644 index ada47463eb8f89a6b0407257f37bed9a31a5638b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1801 zcmV+k2ln`hP)o8WhRj8R!W@&h;vLzZSFn!trc|s zz55U56~P8uP1$F6hu!VQEZi+KfodyjXFhJ#;T~#h@9CpDL}YP!-63S5OrhD`dY{mZ zX1(5l3{j8)i%aVpe&UF0#1Th$Cdc!6?)jr2+J!DSkTI!SkhoS+;gKm2yVRXYE)~YY z(!&ZWePlFudL?~5ODjsw(}*MNHRODHY&6ehZAGaIWC5;@ZX-dvprHvV z&@0gAKSm#y+G9q0UL+!~~iZnaFgLC zTnP(OplqWl_H*Y!I)uyxN;_W7I{rnAK>%+?w|Ob#OTXhZuaKH;#eYUCH>Ri9^`_S{bCeZS*} zIgr_?TM&~-0`))bdt676$JAZi6;Q&~SR*HwoQZG46b#Qtd$dhTXM)^|7cf0PV7~y_ zSdhD5XY>@47VNlJ+45hVITap|v=gFVuzJjKz?>R&F8jF1*W|B4h$i3JA$z#ev z>*8WXoC^4gR6NI%VJrzpVpp+?C*UKFtoH{kDU~d>YPO-qCL|zob%*?tZ02V$o~}=< zu2@)JYqF)?^}iyW4hZ+HzHardL0hij-h=a|0jCCvd%vKXM(zmq_nvN7eV@~(xcF@dGG*GUP4~Re=n9Tgl%`E%`*k;MkN2swzMY^M<^g}nz2fw z-iL(5N))>#T?ZprBZ4!j8<&>}aJSgFWi%7Sk>@ZicG~KaSOU3LMBbNmyYUGVQqOiC zZCYB3i628Uj@<&Ro%&|b0djv%V4s`qJp6e)&GL7m3bWesgCqWFD&wtm+AGnWu%2S! z{=*6k22~bSdYMT*TE|T~Evp$;d^L=Z63o#aZJ#FgyuSt{Kt3fHC?&m%@q*DrdPi-= zDQjifs6SM)%79nKbQi;xP%gwd^2x9}Y_&J0EuKhRqgY#Vs+_KROxmqJB^GH0CAt?q z)(anT_%UEDZo#M@79`})S1(U*-ugiVu8i$Koa2kme{=Ku*L+MHGC~5fH5BJ7bKgZU z{{>QD>MGa8mGw=YFAD1FQ~$m~T&i>q8-&U?Np;1U5X|F}N*VA(k=W%B@Sscj@ian- zFol0%mEGD2`m`Z!afHbS|;To)7H;Ip*G~+Q_I=$mClMu_nIqDn)z2 zq{RO2BMFInu}S>#>i3tozWwfyd$hMW6e-P>2pJRpdaa~?-g&a!f{dBT7l%9$t-^51 zB575;B%ZGa+$(-w(g*d7zwjAlrr)eO9CZKg7s?z^D;$K%9Di(%H|7FBhh6inWaaLM zcFH>Vtk6H5r6{A!R3Jahah*Gjy0cw@kA!^bIfPuG5ORS+xO{<7zaHBJJcEyjOBcw} rB#GX;nMTQqQ<XHIk>Kn00000NkvXXu0mjfh@nlC diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/photo.imageset/Frame@2x-2.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/photo.imageset/Frame@2x-2.png deleted file mode 100644 index aa7702f73cdd3a7d99950ff44f2d5f4a32e42408..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1099 zcmV-R1ho5!P)$SK~#7F?O9!J z+CUJVSrhWms!DG_Pf%`9=LAhp5T}9)P^CJw@1gJgail6m0=47>r6-8F0XadrLGxHj zveOv{lMOh=5Nh+lCn5G%%01;f4smRUUnYrnKmo?Y1 zKz%ocdIaD@CZHk$J`a0WS|5CCdL47cj0G&R_5ta7JLvcA6R!aoqFg)l_?+KJTOscA zSI3-JGdqy%uz8sW4>HCmPmQpR5pJ#GHb(_b+L$Lp4wgWv;@TQjF`!qi{dUvyAtNlL zfY7Tjl$g>A2bDT1SL@x;wm!(hVhbs-HDq=|uxBO^_E<4VcDs-=RMLf|$~#*GHHJDw zbQ*TVD&ks@GLlv zPXs+smoR9xygnqvLM$}ezIw6s7dv3oCu8&;=Cu>IR{|Ur?#bROfWoxzTESWH=oYW7 z)ma(nlGdm5a?C;sjCp>q^qLt-b5KiMSgPOt^1;7rkHe>(L;Q{lRJSa=Sj9o5oO1PW z5Vv-zOgt9YpSP}5t-I`HpChK^AkNwG`UDt|0|M<(U>STW-;Dh}gONb`lg}I!LEl*aez^h9A$SgNjaUr@_In8wTd&~&J^B0`C z`s~-|q^UbiZ^AaDpb_@dy3NH}AQV1qUsEBzVR}1bdi(XV;yU3xQ)T03C-u|1iY_0- zOm7zRJKqJK6X|1wyQLJ_H*(I%ZO>6LL%phq&w<_F=Mx{bk zT2GYFnC|Hd?wyIpZuUgnDox)H5o-Y{3m_r>m+qo8t=@`}qbo_u{{-S1L|6;mMSjxV2LrM|+1~Pb**IjQ79+@}TV1o^!@ehNvdyiqc RRL=ka002ovPDHLkV1n@T`)U9H diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/photo.imageset/Frame@3x-2.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/photo.imageset/Frame@3x-2.png deleted file mode 100644 index c9c54c1f11f85302058439dd688e2349f3c32e4a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1623 zcmV-d2B`UoP)9nDnjDkaPsPoSPaIKet6Fna@j z>{N{k?`?O)nh=thkRXYhuZjZlUZVNZuV44q4M2tr88T$ZkRd~c3@$(jiE6!GEPMq` z<)8>D!|)Yc8@fISb53A_-tE+@Lg6|hmLbJZO7)~tXMeSIBgp(G398oWS|0HI>N~}2V6*mH z8HK!Z8R|=cIs%4rc8i7rRm733kgHgq8k2IZ+tzz-=jA=Gh@+~LKLxVYJ<^+yUR-?G zX_yLN-+mAUR_Lwgc7o>;LxdkEzAG?OPL73>qk|?W>`flUpS?Q}p43RmOGys!seml0h|PjF zw;T2Row&&%9Ma}ju_AAJ&k1o_5aMRDR^NvdA{K%^)EfJ=>m5>1;F-Xp5Y04_6q%s+ z+x3bP&FsCkva-Vf1{%plXh=X{E4*PDjo0kcUJ|Ql}0vfUWb@Hz*Emi6)LDb<;gv{-U6 z)>w!nA^vUCgk3Pl~}1rq83g2!R85)=h&HHAAoR}VMf30lVg zkOlPEG9|)52w{F7V_{xtv}tH#Mf5F1L?Q@csf5)4pD6=c5TAsUMmvPAR40r4dM8+r zufmLEEu0{hN))=Q0i4&dbMLed44469zi04^{G&F?<<80aN@1?CP|4LI$3rS1i)p=H zmaDUp;{;n?=g*I;eBChTEzE*=S-Dw`Wi>0Oo9{Gq>{s!-!4X$l|wuwi(2PSu7^XDI|nbV&T+CE zBEl>&)|dMeJAhJ;OUyG$Ws52Ruv0djV;lrR!V#Dta=>TZfOcZ_GK$m6ph`f?BDT~jI zxdn<;I5a5xUUMUfh5ID$Tz1Sgl4cT^q^atvL<3TSxhJb*OIal$y-7rsxJ=YdfpdPu zvt{#LZk|jb0xvPjv{U!v6)%Lj7f*sL?brTYO|}K69FDeM^psb;`=milY{MK8r?rjF z4puRze_o+H3G(zoO6D$5$cg4C?hqr%Lz7BgQY4(JwqPlQCX`wy6|?LdQ$l(Mw!YOf zsz#o3!3|zE42sz{yas)p^!>8*jfT^XaW~wa-yC0pxZrOEdQ&YfF9Ln8nmnaq1}=M( z@2NtB0$hU7r%c%hT22bx7r@oZe~0-{#kV8?<#4dF1ZEO-?+h6-WXO;qLxv0~#D5O~ VQ7~zc%VGck002ovPDHLkV1lD|@0tJr diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/sendMessage_failed.imageset/sendMessage_failed.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/sendMessage_failed.imageset/sendMessage_failed.png deleted file mode 100644 index 46d65710919440f25d4ca1355bc170374445d068..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2373 zcmV-L3A*-)P)Px-|4BqaRCr$PTYZdNRTcl8H}mdnp`pQw^ke5ux82RWS^5zLKWIXOLck&<3MiOB zqotCvM6p06YK(}nRz6x=rP5%5h&7^AqeQ?WMcW|O5R_VW-eddWyxC%_(uTwq=FZGJ z=I(aM&YSmU-p8~wwD+&gn|pruoZr3o+;h)8OE}3Jo#gi86alAJz)8-)aoqxT_k`&# zs(o6DdYP$@7`=*rChQ{OA-B%EH0VS5;WzgkuX#D91pG61+SDU%Z9$6gaR#mcFgc`Q zuM_Y@o$>T(T6*h@(vg3Kl#AT0;{@z5aHbA%3xO{H=wp#J@)h7M1ln4GTszmnq0V5A zqI8r1E34lGqFVsuJE`P2EE~*g%yRWdox<-30mYoSidY%0X8m|H+Q!6d3MIKI>1c@w zC>r`&0(~)xA`BcMU>}(Gf#?hXlfZn&(Z4fcu^9Y=f>Zrc*#3U~5)oi!#giZ`Y_9-6 z%S;;>_(zT8zE=C#o*_)v#iumjlMH;QEjHsRvn(%b+b^I)Yyygg7$S@wWB$zY0hh2b z4g9pPRQ+2V1&fA$EE;;`A*V;!Xm-=`YJ`O{c1k;!rI#0d`J& zhZ$eMFK0!GhyJRacg9x$ECO<@M>be~ovFyZPj zaY85pEF-fuAjsKhI`XdFPPhjFmoAl}~xjm(!d@apm3UC^?Ar}F)%Sn7t!TK!qy@SAy{UD(`` z0Clku5HI+G6RtB$a${tLjjoFr?jL+l5oj0Zowt-Rk(y1US~n!}Z+h~ERaBmiTx>Bviy;13$&4h>l8nYcp*N4_UC z0Y}f)VXpv_JHJq>sbevAvkdVQ0M`cqJZd^}QEYIv0s^8|a#P)Y*=AoSSnN(;NSgMX zR}np}<&s`;t*p2Qgxh_M?7*F3$PoQ?;FYGybKQ>?hHHQHe)lE7&gn~-=|OMjyd%>D z)RWCn=5}Jf$JYrGEiaTR_a?ztvX&t#D#C8qzQkY1m#R%p-IoB%5Z?pvmBxLP%tMc1 z*@k{SgVZ)?Y6M=CcdCyjCBQbsP6p2L;M{FG@{VvTAS*U8;YyDqd8y#YbCW7p%w{ej zV&w>%8Z%v5C|5Qo9m6kaLyTYL%krvF1XzanEk<8*#<#zlj(mS&<+{aOXn5Hd$HhEz zSnfzVhTjT^M1XB%)-(71iWNm!5z%KxN+VlOFrXy8iBT=&rv4R0_xc<87$oKjI2VRE*&eBb$Bd<=R zp_-*^W*HN&YS^Ppx8}>0hBR56aco0u_dcl+@JQZ~pN~X9F{iI0re#e+%pWw%)feL^ z*RW5s`cfvkO?@Ng`^<9nfy9_SnLO&O5-ttRWn9}|mVPO-;Q9c|5Ne64rP|Plcy+#1 zy)~(_$3p(qthmc1e8Y>~Md@ilRVIO3Ajl68_&`d}%8sdh%O*;S?leSy z8c?h@BpQkFmwZ|JK9GhnWaP@qxb5u+4aP$$!hLZQt#*$-kL&bT?+sA-+eB$`WsGfz zl?*i9qEb@6uWvv86UJa~AHPVm-AuI_$IgkLG2^p74m;VyhyvU>waZBBu37~R$;u>Q zv2BQl8Tj0IgE1Bs87^qp;FzK)M>pq6O&G_iDeov5>&as97 z^?4BB%9E~y~$D?n#8xszbxT{58F;dY~M+i{I8K=c!Vw5zE zhx$s@myQJ)>fys>{x%Ul;y?4zi=`41;N#Kj0N;<4w$9vJu{%M;?wMVNthtMW%VI`H ziIY!AOn{Zup99f_K8C(Qg!@rXt&3azt>T3m^I{@W7a8A&jicj6E{+=0H#q@qOXfx@ zKb~jC^RC8EoztRbP*si8YUw$3B2#1SJb;zq4e4zkmlvrh$}69k06Uji$jniWFI6Ht z)MN-z4}e^hEfb{}DhM|*0Seg4>Pw-jIe|G*42a+N1S*yuGh*)ybjf;V0K@|f%!+SZ zOUVJXzCG!=%Jce>AUTLJI1 rp~v(XJW-7cqt~ew5Qe39bD#eMve%_sy00000NkvXXu0mjfm2Pq? diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/arrowDown.imageset/Contents.json b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/arrowDown.imageset/Contents.json deleted file mode 100644 index c7958429..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/arrowDown.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "Frame 214@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "Frame 214@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/arrowDown.imageset/Frame 214@2x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/arrowDown.imageset/Frame 214@2x.png deleted file mode 100644 index 92db4e7c2591789a2b3a23b14c567a0dcdc85586..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 338 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2=RS;(M3{v?36l5$8 za(7}_cTVOdki(Mh=8XF{Fa=?X-=&%?1Ll`xkRat%zvoGt^iq z(O@~Vp-omml-Yp6#Pi%F=@g;+I}0XO3r*7e@t>2s_}N!R&PoMCtp!Y4ALN;i7v4C1 z{PVlU(%3)|)>pgScusFhn58x)wKGxT5X-jQ!#3y3?rzhawan4SvatM7_4Wm;v{E9| zu8TN08a|zJwN%!B!TaisN4Cz{q+uMP;MNrUFVsQlpzeRo0~04qVdre|@HowRcxK19 z+T#{|7UwVDyR81IMdfJ@gjvx g(ZjW(fol(=y5@Yv6@5RMfL>oo1K-6l5$8 za(7}_cTVOdki(Mh=d*=r5rzdVd+FcVwQ%bJnQ zcni!tdzVcAAmZxidwGJ& zIva_$hXx0Ji_cp2vhd9@j}24V_r>3pp78wV{_8=4)t^dZgCnQ4-~Y@O5?U&KqSgA* z%s=1uRI|jkeq(#w)iII%;Pk-Gj)=;FEV&0g4<@iLS2yb8(5o!SRO{<}Fok{kbfIvi z9ZwyvM7{87X|d^uJJagoak6>A(K-FQJ??++{~nX5SvjHL-W}Hl>5c5mZ4&PC|9GDqDgy4 zqu+u#*8a{G7kOn4itcJuzM-tx;1tv&U-Rd3`GbSrbv8~MzMBniSqM7aaW*?Pr!8@Y zqQ=rUTd(zR-BwYvB2kF#*o{YXlC#$?pK|Y5;hk{nV-M!Ub0`YEyz@^i;Lfr#=K>)m z3-0V49Ns&)iY1yfeF9!w{9Mdi`sMwPH-gQu&X%Q~loCIA~X Bcf0@q diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/arrowRight.imageset/Vector 87@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/arrowRight.imageset/Vector 87@3x.png deleted file mode 100644 index f7365d80e647129260e980428ddaf9570d6e3935..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 341 zcmeAS@N?(olHy`uVBq!ia0vp^B0#Lj!3HF6+I0&9Db50q$YP+F1qd^`PBTmZ3NjW4 zxjQkeJ16rJ$YDu$^mSxl*x1kgCy^D%f92`o7*fHw_S$LQCIXjFS@opx0*HaPJVFc)x_Y}#|!r~h~>W*Q0Mu4Kt@zaTnXmCr=j>31-#p z+PR4BY?IU$4zEBl4ab`b;-ZZ*Aw1IpL}xf(P2e(ZG`s>t6aK#9Y4f>UviM!yJ=UH? zk-OT<4SwZ5SwH9SAvcz327)IJ-cS%vZWLO>;k8j`#lcAn#JZcr-thBW7U%Wh*A?6J h%FM)|Rwv?w_(|KXGbJ}3V+Q(~!PC{xWt~$(69BwUfIR|>pg9rN=@BKEJQqs_~ zRcy%=0sSCFmY&BPGZy$MOh10NUEtDoLpFn*JQe!q7b@s6+MT{$>g(({hi%HK>8YMT z22;+|=K%uk4U3Dk7VTX;rzzvT)^VjShUYS?WSTXYwp@Gh$=2oNt#{kRj=NqqIcRgf z!M9C&>4Nvw5^WD(&wnPq{?VS#Sq*zXG`BGFBpeW)TYFKv`nP5S&|?gqu6{1-oD!M< D+0Jyy diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/arrowUp.imageset/Frame 214@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/arrowUp.imageset/Frame 214@3x.png deleted file mode 100644 index 1201d4abeb47a3252addc039577fb1d891cc1533..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 408 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTC&H|6fVg?393lL^>oo1K-6l5$8 za(7}_cTVOdki(Mh=nmd$xE%apidtC9bPsvjtjf0yYRd{U7AzI{AK6rJ?-iq7Vlu(Fty>O9B})!OXVM zgjs6V7C)ubcCFjYoH6SdA74aRg7iJpFIYwwZ>$(gTe~DWM4f&Y_yn diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/backArrow.imageset/back@2x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/backArrow.imageset/back@2x.png deleted file mode 100644 index 84a02c6148a5806ea57c80dbebf6d9b6081fce67..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 370 zcmeAS@N?(olHy`uVBq!ia0vp^B0#Ln!3HF!eAAKuQk(@Ik;M!QVyYm_=ozH)0Vv2= z9OUlAuO|PI8({BaEU5?d_+QJj8IJCT&Z}{yK;pnSSl2OVQouPAjT}AbS7lk5GtSN_1 zxvn(#lHgyqX6xP;+_f{h4b{?{t0O`~Rk>{r-I>D^WMJfR)I)*Ynq}t=J&l8Aj+)O{ zoj2GUi2PsczE_o7~( z&U!m(*-P&0^ScBKrq9qgGdV&-M?Pu62ECR=5477BY}l&cYVN4Hi`(mh^Mvk64t!p0 zD>ZiiUiEs{5oXozIy>b8J8xOazlyRfPtUEKS^3+-wqM}D-rU>In7>bcd$F=MbQ>^; O7(8A5T-G@yGywpd|A`s^ diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/backArrow.imageset/back@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/backArrow.imageset/back@3x.png deleted file mode 100644 index fb9071046893577611758a28dbf2954776d41204..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 467 zcmV;^0WAKBP)_}qa4ebxr=ZbrDjEf2pusQ}8U$ma-Y_=m1yi6-m#C|Yf*^Vrh9=9h zN9Y$Ta|)c6fj~#AYpWkre`g(v1*Gq#OxLzwz_?R5q4)a8$W#OU-Z0)lF@yvZF!Mu8NM68mxwx0Wd*ehEXi1rAHUP1+Ai9k8;rsT3FLQjg& zf{Iubp_sTSc>)arE9KqW5F88)70k*Scix_ z@>~Hat|wny4jIDJ*e}?`T=9{t;R=6FeQRc7moE<|P!))wj?G6+>O5=LwFIOPhf^Ir zU<2P5*F(e?{JWbH8e@JKqo;`KHom8E-i}xC8^8>pGH0KFNB{r;07*qoM6N<$f|Q?Z ATL1t6 diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/delete.imageset/Frame@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/delete.imageset/Frame@3x.png deleted file mode 100644 index 60648a9d70a822bbdd057c740a8066d3f3acbc33..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1217 zcmV;y1U~zTP)eR-b8c>^>NU1-4Uz_gp!C!fA`~oko{dA+fW7!0kb)dD7q{w##(?9ukGGB1mvUn z8D19*FpOY4uoYq@;LQK;Mb*TYf&C}$!$IM%i+tq!elz5n2jbgs3lM9J#2TF<)}Xu( z{_@YChFE`hTjUiotIZnM-@STs-p%_qQ-HdR`sQX`W(5!$h~UL;oB7!aOd4_@wgRi; zB2~bvH~(}I9S^n$LiFG_ckj=X_csv-tor=7aGNYJT!lD(uo&1&F%UuhV(Z8&Bqk)V zm%QSJfN9V+VOxRFI(_|b|K_VHV%LHC2iSI~D}8qE^?IEveVkcf%uXL{fOsXz*{LRJ zum;59@3pVO4aAjbCp=0XV*xt*i1f5*A1tIprU(1(qpkzgDJ4QkljBGqd##%ECBzDg zAjCt@yJ*Y=jKOJx4cL6_xt)>zbmgzL2qjO{`So!pNc!N2|1aJiBoht~^e0XFqeHNO zkiGAT)skl`5ewuM>H$P}A1p9U;{nSCZ(73T`xng!%!R~86D-K<(p_ft3$LA@Xw3Ce zNtz~HjtpGX5*jyEl2VovqXZ*$xjAsR4O3p6<{~z{VuFg z#aRim*~0UX7O)9Q?broCVBix}fK{ta=^eY!m@pz{4q#1WEtNK#o&CW4kr>xahqKpt z+a23#Y{oz`Q!H(PH1e%l|HcBM?`uPw8IZX7IXTkV zke{_*5TPY|+XGERa!CSnTcegMq>~p#JJ2;4B^S|B2b9FLk3goeZ8HJl!oz*{;WPa` zOC`(?wU<^_&_G>-{9GSh+d`Ve->gnL6QIFtB0h$#2M^}sZz;Pv`}S@W-v+8EEmCqv!kX<6-7!Pyo3Vx2hqV zTZm3C&F2?kdC|RLm(nsjo8v5(S!x27P-~1i>dO^q;c|RFiwW`Yy7n@;xG3BdN+K2l zrY-h9l1@rh_aqCJ43tiy&os0po}iLC$J8n5dj64MoK_n>F!**kp%<28qjj+K_aeE0qV z_lL=6&dhnv#BIUFnsEF>f(90hr4^_TMUB{gEae#uYaxoIy2rn9_`D-se3 z(|_ref;!{hm(EwN>T;4um19%~FAY>HfHD9HsU`;d!2}HniMdxn8t~2Q)kzk1qULPc z9z4GkeViRF5lQ`{G)NGckLctd(sBJK@8nB!OJ%nOdHxmhX*=Bkvn#V`Eaq~71j7|$ zPeD5iW@=hKo01X~6~O}qpZwj)Nyz)q9@Ox!Z^P-qnr(SMH?MC`^o&4<&a`{}2vQAh1Ri4if7S3B(=xrgySwe? zz3c?59Dgkj#44A8fx#{xZc%%?0SS+xJw(r`T{D^6fIazP%2-3<2v54r<7Cm~6}rhn zt;P9ORiMG{NE$=(i#-hF>=)}5=Ab%eP!Jh@O-EBx(>%~gv7?&XllnW8>;P;|4G0ft z2esE6YK`3XyzX@wL&5t4S**0Un-0>>N$%n6Zx!|&@1|L0^Qk#02D}WkGX6A; zF977ol7QyA%8JA>nJ8e^_Y&CG6^0SJK{`cK(#G*w3509rveVY+8=}fhW*DxtD*u-{jM2@Tl^JBKC7RpC1ieZX7hW z=PVq0Nwb$7`{u5ON})i>{7_#Xh9eSrQghyzsMKJLsGA?R{(iV->Z16_U)}&V$0Q?@ zbaE1|`G|JXs>Juhy-J|>hZ(iLMsVnZb1SsNVX=8Wx>cV-RGjB!LN0*x-w@fz(zNkW zmn2;NhU#S7v|z>`bOE9jxxB{{;~Vcs`Fw#Cmdi|}N(V2N^bg~NU-bX3f2?%Z&h&j{ zYWP>EWL7oa$Ko4$Z|Z7ka%LPFYXv3qmO_Oq8Fn;j0Y3GZGVw$*Ilt$D+4+bWZEWD} zuEicr72Pfrj|I$oSg@=^#pBy0X*-z5rPuf`fYz~AFBJe7c&pJVYPGm>4K59IO{n*T zvOdAVsS!LQSz_9E9v@k+zGpQKVZugX%dl09B|Hp1`}*v$?;98hyscWRpdTV*z}w$3 z^4)DXOuZww@0!{#l0$3n>TW(1i{`+mM@t8G`lh`0lElQsTy<9B*Mc}stV+Mr9UwWU zfEI2?1Nzs1+!TI>F0kNyz~sHScbwZ(A4uoChPw6|k2^_B;wFZERDiJxh@B-+of;sJ zo$5j_s)9Z-H%C&6GR;=&gUTo1;El+#GT-4UQF^~1V3fskM6<|dpt=%ZsQx9Jj9BgT zV^qQ;xWTxmqJEUpOPqg|IwL&CAdSo(!v{fhDKN10$J}`|uL@VcBGA;< z9tI7VU+v7THA^YcarOT}Mi)U%i7O*PHUsoEQ&4Sd5vjCE5#W$GthRZ7gPv~QOa-lY z${AI1)tRDYX{0&=G68)9?E4T1gdokzF_qBlSRX;sVpszn;{&R5*0%-#-vW`q4fIya z@v6rjwIV-k*rY44+44J)-}Ge8GZHEiaO_hR1W`+m!bGErcKv~tyX6G704>?FSZ};477WYY%)n!^78T>uKh$Tt;^_3V>nX{nv#i3{!d_AHGVTjp z3!N>??q7H^o)X@S@VEMLzENh#*Z zQ_|U4Fp@;9IBQRTZiLEEYE4|dJepa#*tlRV*5-9EHZ=DL37TWRcOP6 z2=Ydn>A6egM91o3pDSwfuZ@QF2b?dI8`(=MBInUB2M{S-0j+H5uNR^mO{=SnwSDt) z%dvH@?5gAbV#Z;fn$7(|8PY`T*H{Ctd=>r!6~DF)pP&BSq2Ib!hW;faKdJ3-3fugN z>BJ&5gR!NFe@#P-@@c#RD^n`es45iyJe=6=XY2#ulXD0_I{mz@g{UuL8jXByicUw4 zNMl(NJpi2pR;p)NMy)l$mMi%>M5&;PWu90qp(o#_qy>4TIKDWB*bO`Z(=i(1;wU(5 z*w3a6DEFo1<~Vk%nbyM0qukuks{3mq7*3AQlSNuqBt5G0u)%Wf7=dn=NAwvR&D?(+ zD(I|d-}+I&n_~WOeT)zr_6If6ev2!=)xXogbA<^92ghZ_eLjMT92yG2EcW_?jwLK$ zD>LRJgN;u}7FBK^Z^5WF!55UOvv1t1PcA*$Y|8o@xJ1bFo|Oc}ZVp;wdX3qQ4-WZ5 zz?EelfoGS;uvyt}F-;#FbTrDZs+YU2k|nER)QXEHef>Ty-2s)0P@!iLY~D{Y(o17^ zGGTVnr3)1dioIC3hQ|pN$aBP?)9W-51T>a^Wn~4eKc6_0=o_%nUZ;zo+Itx@@ogrN zS+*xUxnHYNU*}J?NpLd)qx7pC)y;$-siL2Ag$+@CFlVmAI3IoJ)zQ4!C6-Ez45|s8f@ZPa&IRefGSA8*F*LdzJgjoKA&Cl0Aj(qKXrNPTeoU@f(88e z_L3Xb6fY^nq>wHG7dd`&qn)JeSr@crU;oNV*wP`HVip3p#^G~H82So@Vn=)(?s8pp zJsRBYnMLjhY>u>xz}*DtFG_N4-2F-oy4J01-w^o~q;6dRbX#oQN+z9RBnGsuka8!l z-q`K5u_WF%>4<;}{|2I@@R&3j2obI^$nN%nVjYQX^%n zw8lm~3RniPS=b!rGqAs%-0S8``F2@UgdQ0T-D{wzA1t;m)!#qXuYFmyS}xpmNgFE8Q2hyA~cO6w_M=#J-M)eO_j24O&|eeA1%WN+^W7ss{=y$6xZ!%qj=d z&4aIxiP@;}>9sj3=X6obZQ_Pl4nohy__m4@UCO;Ga$+S|IB}Z9$_6|>MGYp9P$QR_ z<81wQaQme;Brwx>e8uYKD9WXNB)VVo0AX>fT*S-lDU^wmHrMk#^$Aa9VQZ;3Wr8gQ zEZ@5Tba_tcbkgTP%=QqTj2>XNwzLd&KoT~D=_IATxER9Ja~TiUDpGFkl?&y+xMh|w z_U9cQ+~zIfOQEzpd_p|9Q53RU%k16l6BC#x(r_MttknVKJ{jZ1XUs{bscvCG_f$pG zyS~jRCP{>9@x{zwEy2&STf2-Q4(kdA_73u(gv8k@Cfl8OtXL+SB1N?32QWaLz!g4c zQ!YeYPf57aZ5eorlaI#4wlRD3Ey=e=avA1&xAl6Mg86lBGoj9TJ--GxyvUU^#=Keg zD==ncsu4Dc#W<5}+01BXQjmWyTcO{qeuz_vEJV?t3Ul!!jneOUV z>j2&b?cBFu8sYCRyVrFnsSS{s^mQx9Mcs;Lvg3B-tg;Z&nhPm^Qr6U@|C0S_Pa{F# z@*|7CLpSVPt#3skUIcKTh3A&wR=7lsw$o}O8~gqP{8hV8`mbNo6Q%W*Iv^Y&?R3}P zH3fFwGHZ0gL^_V@DMnZDuIUfVuZ*AYblJm;790ho$$wd^9f(C07o`N0)GVuQx=?$^ zi>#P%Rrp2+BoAcfx_5bfjn^*)1eY^Q6MKkE&TW0uWcsCSb^xZ9aBWm*X)@W168NAi zWPYj#a_NTB;w%w-W00Q;s_bE7I-G?4`n4>WJQuU&Ex{;a5y~6v<6%<;!j;@brG76T zH$xx9+r0T!$ZfoAzWdj&YA-W-lgL-hasI>}51DQ)ptt-7!igNVU!!5zb)m{4+gG~a z*RrlfL{4&%-yd`>g#jeT|CsFCn1|;D62Q0_&E5B#RCY2EU#4S0d;6)f-7lKDQ79Um z@LG2Te?ZAG2~IS@QK2wbpV*mG&}KLVqpRgliF%$i&J++|xq+b~+%lQe9)Cd2b787! zZ{7ZY1VhsLxn=&S^hS?q#8@6d_v3%Ff}>n#HGxecN6n~d%PPr&it1;-w^0-5<%f*F z$xlX^>5)tkpU8Tcjxo&(4PDn{$}P&I`UMIXp43hnr#d7JFzuyVCQHg@4d8X)0$u~!5|8w z%YUm896DCiA%<3e&t~>T`@YkJi?g@`v zS+Mrrck3JdaCvjUul%lCIzl&Wfm;qmSZz{p99lV0My!uFx&pB+8eGQ~t)D`pGYRM4 zNoGzX5tLRKDVbtbbCQS-3oqF;MK$l&OT!=^%K76KW7hr?!8Q5QnXK!1BO4Y_S=GT~&o7^??kT`y z9p2&xiR7-#61A2u44>LMJpEoo5i%!okmUFybVH6h6^4Q3y{{6@#?6^vZXbnWei;S?U>SKMH>q}-1Lfia7^ zot{5z5gISy;SY%fqW=W=rjs0|`PmID`xKF7;quOUB9cO`R_-f)azKCxh~AKbP^e)! zCa5C}9&BA^(wm2d;+?rvtWY<41aq*r5eS0(=bG!{zL(7DtFhvvjQGP?(fxUJ8<5pF? z4dRx_CZ`5yshUGS&Erg!_c|^(YPR!H z{)%oy1fuI-Hbl(H`(HCrea@ME{JQ9t^ONAtLvDM5z z{lnE=hx0z7$PSE(BWnj(JJ2v(@HoatRG66$pK6pvP`skw^$!~(!!sS)mQDNPaw?|p zyWq9(v}ki6rq=G7ZwCD6nK}I`)A?!cb`8E(v&upRf?r+m3|-BS2oTsWyH>KD3ex}= zZIan7`$oK1-nbd>9d^_o zB|4Rpk#L@8+Ke)w!q!0ddmmPR3tjY+t8H1-E0bwxPPj>Hk2-SskUbW`JukL#UF(fN zt;hdnx6ZROM0c(O123v$!=>#;T|h}Jx8Es_m_T1R1ZEe0NeMQs}H>I z=eO$hG$XCcaJW~Y9QL}6vW&ob#bM-i*>wLIzU7g_m!B+^b#x&V668q-e zRzY`&2EWJlK1@2;eQ_I#6t9P zJoJwxk_0=|1p;JP0cr#Sjw|;oF`9l{l1%HNddleF;g23l!QQ70!6<#AX1%xEANNB0 z@y~ba(xWX_AGP49JM?>*koGgNbKmDH!;3&QeL}d5VCq zKQRPJnYc+a+1Ped&XCvtEey(zfTEKg^QUD2`cBe*e{-IdM5%a8JJak|+YeCsu(VLR z43AN3VN7?Gbk>|#Z~MQfW-VKDimam0TVX+1J9KwSyHWDDtDgVD2Ob9Rqb3Bq@s1Rd z;y%!ir_&<&$*$%v>13||#(%`+CYjS6TNIHKa{llkaz3LBoO-F$H5Ns*)esk(Ko_@`E337v~l5icq`B`J`cmiOt(JXeAZB2d?{%`&eIc2Sr~ zQ#yL^yP@5q>w~vN4BUpHX&46{aLG>8GwpX)ZxW^4L#3UK``z2a_@@eOH_;jM4DXHq z-;|i)DR18~$}a>XlBI5)%jlz+^UzQ2efk>of80>7%;VZ;8gf@)B^hqG3tY}T6c|T2 z&vH{8e?8XH)D`#xefSoYC(0;v2;A(Z$(sEv>y)U3i;u~c!WRiXVhZ{9kEOasX?G$l z+Malp))I}xuMKaXp8X3qhdxx6V=c9BeyO^!rc1e)Fkx*-FCm0k^_M)dr0s^257aSF z=_>+gMMbSSlW75z!b?JqjxM`?3cX4i6R_zKhpl9y3LfDO%T<54>t)slyXC*8d)``$ zEF=lKuPK;^qt+gNf~q)n&Mv%)6_1NQ8${=AA!|RLIXye~%*^C51osK`TvZT@YB|{a zdZNbX23ww?3ce4clnV=m3h3L1D4}n&0Dn|B;f=N@JVQ#y-$ZlEmwe*o>-Ic%otc2M9+lHtW6+;QmP!`Z)L}Hs_jB$)wpM*x7nmN_Jw}=>ZYXIL}SyL_Z4< z=&k;}T?wy0D%9E8`C)=QatX#>fWEk-P+ZXCN+@egy2LS2*3j%59vMD6&6Uo|C3fHa}!hWZ6-O~WolZI z<-YWdPiW?$w=Ql+W3L}`^3ArMURa0JxVP&ObDU|Lt5uL|^L>Xo&C*K4(sGB8AWux` znG#0v8RZAv5<`clHPNdqO&JLbmq}6diu&Jzvt>bbLD0L9G~o|fh@5$IF2A`NFb&wg zppnBdrP>(n#_z_gkFd7TyU*gtfSA}e830{Z2tw)xdBTI~3tnjvDv(24} zcRxM5ONSH8gEV9mJOyQM=h9;F|GkV@oU!OxIR;*V#t`ZI50xZ)p3P~ZHGE&CDS7hC zoO{x;b*<-&(Ss1@1qg@tYwq=oQU7{h_x_+Gdp`$i;@Ghh@UZaSaIK=^xu^JL6JO+R zx)!5sP(f7nT*!LNh7jyU)+=eRgA(^s%hva|5HHS6Z`?(v=lSDMnOn6(YP*>vSJE2KwJ?i=M*~b#){D`%w&;6Rq zV<#ZFbyyAXEW%ZSRo&WI`q@lm>M>E@zgM5Z*h$5kq|1fK)i~Yh0%Cak*MM@z3hveY zvBVG!-mpfF%&XF`ktbCkKxrk~fUD!PgGy9^R|}K!etceIqI~+-ZRsL zXMxnGW2D)z@5+ptBJYtcv0AptVeJ=9>zM~4I-OTROw|)qBiJat=PDx6s~A~*2-q}6 zDjGeI3N_1}b+^Ck=H$=^*Z~^qs#*xt}i}o~N|D&8q<>Zw4mC1uaXASIZ%2@Mk9~ z><)w-zoT;%0T%rphDMLLA>@!+`7OF11-#Rptu)(zU|A?xHTQ(|H?S+Oq&I!UOf` zyeTK1$NvhR27*C~W|>sg*E8`@qnzE3{c6t$i3}XG?w0sZ7;;j`D}hq|6YRVTh(OMd zA6VngH_u*Al?o>dLvsz*za&(Id{rEcFij$8p)|l9xQF01@2YjlXbMw1KaXeo7(zyT zQXWR@49@R!P7}!!Vxp?o)#m>3Z@+vZpI8lNo8rgFKkjXB#w2@W5Z9r|2Uf40Sc$h2 z?%ty+CQ}jv0g9jn1J{jt%N1^p;4eR$ZImV@bHw2r=Xc4wKQ<&UK`vvDM(j(tZwB&* zlLs@2=Z7-HauS@{VVWJ++s}esEXcODT|(@J5cN}mxfGNB5IgugY$B-nuL(^4#CNUG zWJUEO91d&rMqv9>a*Q_TCovQK$rWzl(<4xiYy@53EJ*09`}3`@ACD*9Af>g~ChB4b z+^YQHu?6l5cDxz-J-j>EfG}X!9)))To#3ag>Acb#erkTa`(Ek2%vbu}jGS5%xWI-6 zqYiCm{Tt(jd0q$i<8M1XnELKex762%Xv0ydD>NuENs6n^=!^1;9~N3QJ!n>WRF~l@ zkPd@oPu>0%4U)j2Zzg3z58S^JzfKBTvkVBXZ^rx)vF6d5P#>ujZMzVgYS|u_Jsv#% zAwxcUo=8AxCiTme{;+y|b<5KCB7=NOBXt~SlPNCr){uV~CXrVIJFyGf^6^}4wUk!J z3M#a#)MG}Ga{Ub=c;8u+MK=os_s|Yx>ecT{g#Y*3EcNx{sgsePJ~x$%$;t$<2GXyp z?c{8)B6qIv7LYRJBny+fe$w}NJZBQQTqH5e!{;l@4R=3lB^QQ|pS|z+I!V0KEYW6{ z^f22*`_qAq=~WFcN9X4w|2l#Ga;MB|_f`2i2l0+s?lIP&(YKUfzFn>?4n@mIJ`bj! z6|JmV^w#bwJit9W9uCKIk4@_wDxceT351K=g2oK`d!G|27H|b1=DN0rmm)5=fvX&# z&&H8w;=`2Pk}UFSodQ-^%tTdF;tT$8AAQHPN6FE~w`2Tsl6U~8z{l3zL5M?4j&O%P z?HbS}%aKj#@;U^ryz(W;y>AF{e;e##*{{6~S<;fX+Iy_gWza_`u7ZLFfp*dF@=rbx z<#E;j{)(KEF=ny>)v8my?qUeurP_Rz3CeoXXzgI*Kr|b1?wO&TfOourHY8NA{;AUt zLW$TtYUagg_u>z$8Zm1OTi5;?+1?uqJ@n0P_-kveLL`7Xm9~avnS8Kwgod+m&4NeR zxzuXBVqGR=zGbPX2J8V~xDAeZhJ3smA+@-}+3QQOytqIDi|?a)aeL}tx*Qb`16cmv zWuRL;53j{i^GKxZ*T2!aJ1#%_#`_L`0P$w=OcOcs1PAGm#vqeY(Z(K=9uIi1fb(qr zo?d$ZpYqN6rz8EdM1`&)VgiM=+o3v3l*__BAc0$^g+IYn$eeiw(fqcmMElT~gm&kP z+k@l3)fdgb(b-fuPOcipB=4?bJmSC}aOt))mBpz0i4Opvb?#XXI4o&igNxWea}{$l z289t1wB5-qe8vu+YPL&zRdc8ZLbAV+G=`g=Sg%Zq@okiWbn^;oST_ zb=p6-`s=LR+@h5&M))Xd20!m>LLH`Jjq^j1w?1>ZEsI6cS&Gj2EL{t+L324iqnPp( zd7A|?_8UFU{cYq2Nx8K)H0NzD+bz@W?~)1h#{bbl6<+!&LZ&sLX{_|99ay6kfJo-! z|672kFkXyDQ4V_F_dVWs13ePA)G1j|_dq};{EJ2<8++zb`&z5AakKMq2X0)Y#by3s4FP!?9dk5Xzw(}+dmpCGDMdz zG4mj#zcOCcZ(DtfT89t4drS%))x_0!L!PuK+f#df?aMroLHF#Zeo?b&J5oQbfc7KJ z{zauyTTF7_Qv`O-J@wl;sV1MHzkPt3Q{CV}D0VuNoDavV0kmnzP{DKcATuPS2TPO@ zw)ysI3u(pPZ#bFD($8l-X?(aQM}qA>%+^3-r&hO>!Y&%KktQ$-zhr- z8-_%0k4{dM1$kxVX5zo+x<7rAUo6K;)4$?b_RN7Aw(D|k)IusccZ&IrySjMH(3d$&M}-X$^D+(DT%#lKYqN)C}05Nf5`-rjWQPn zW?XJx{uz*mCdq{d0AOBdGspt1`X3PUW0La{DfE~rl=8k7v)|a7DD6hbnmzBgT&A5k zwWZ4kTRTzxQk5NKSh<}VBeg<#0eHz!8^}n_ z{1pLjGrhNYcRc?s0d4zcT4G4(JVY^W)}(VqN#;$E$nBNNbmm1`fdH#FA>FB@fD}U9 z{4ey>gyk`vn7@*ck09kvM_v|`8Fy)X_p|#azPLwJjl9M}7?lJUGy7!OkY2jt1sqsd8k$B2LhV$SrZa*kkY3^bn07hr~6Fw;FSMXbP>SQ`rDqdL>_ z1opQp1aO}U8zODlL*M_|M856B5|tsN+**7MN?Xw}vdQlfF3veFKKzeT!vstU?KQ(H z(_bGnjrfW4lL>XwnzOcL+KWZ~1!R3=f1v$;;Pt({&e8BDI( z8ZZPi+U#J6!3{}4Mn$?((ir?d9f!|v diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/memberPlaceholder.imageset/Frame 1016@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/memberPlaceholder.imageset/Frame 1016@3x.png deleted file mode 100644 index 4403d35dcccf4c5cc265ccca0e43405a50f4c05b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16070 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 diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/rolePlaceholder.imageset/Contents.json b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/rolePlaceholder.imageset/Contents.json deleted file mode 100644 index 28819b06..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/rolePlaceholder.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "Frame 1018@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "Frame 1018@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/rolePlaceholder.imageset/Frame 1018@2x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/rolePlaceholder.imageset/Frame 1018@2x.png deleted file mode 100644 index a4cb4bd3c5ef23e43f23b5529ac476ae9b373b22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13666 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 ALjV8( diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/rolePlaceholder.imageset/Frame 1018@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/rolePlaceholder.imageset/Frame 1018@3x.png deleted file mode 100644 index ac3d242943a20a71e1c58ef9e629650fc5526034..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21856 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

JF&*>wOpO{w{G`*Fi39k5W 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 TL!E&@)Ef{LZRH9@%i#Y2a89&! diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/search.imageset/Frame@2x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/search.imageset/Frame@2x.png deleted file mode 100644 index 510d989f4b441887fe29f9169a7653d01e1d9068..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 814 zcmV+}1JV46P)eo}K~#7F?Uqq) z(?Af0XV$4*fePUUK0m@r+X3pzcH*qeidS3tK-d2T&ZN6M*#qmwP zn*xx8lOJ$w!qWcs5oA=PqH2;WoUrdcelDijPXTbYA0`70uVDd6BxKoSY@t<4v%dl$ zYtQ5bnf;5stu`#ESj7#w6H-BH2bconasxN{P}2o0A&G))Nd(N>4{aAr0TksX#vv># z1xc+?sLUhq=Ow~p_)oe5z*Q}w)&x&rS?N)A)TH~y0Ff1SMLlb@pa8>E`W$To0QX#m!k6F^lRX^0vFPp^UUovTbw6l98_Ef16|*a z18&EJ!KB5~km~U;?*7~1WY!$1Lxz>G=fyb<$m4M#{uQ^=PD^tSB(0$1>Y;9MM0O_c zI7g(y^~Ybk0Le8`Tbhx5xw?xM`C=RYh&Sdzm>tRZzyYLo5ou?}AEfMF{C!}Nvw=g- zxkN7wBGaKXfeF49)L=L&GC8YX@}ADz=Mp`3ewGH286b;HAZ`@E1VX_L>%iL#If*xt sZOx}^XU!?XZAc=~I_Xs4UUyBu0kQ2%+GOBnNdN!<07*qoM6N<$f&@HlYXATM diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/search.imageset/Frame@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/search.imageset/Frame@3x.png deleted file mode 100644 index a4c9a4c537781f3820ef8029496d12d29939a607..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1132 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 R>%UEf;nm1*)~iBZ1-%dMiJ`_*ifdmv7y^ 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 Y18n4wAY4v#?*IS*07*qoM6N<$f@M3phX4Qo diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/addOther_icon.imageset/addOther_icon@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/addOther_icon.imageset/addOther_icon@3x.png deleted file mode 100644 index 08dce66175586f53c56053b4a8d699d0dccaaa30..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3495 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 V>hT6oX|VtR002ovPDHLkV1lGxnf(9& diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/addService_icon.imageset/Contents.json b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/addService_icon.imageset/Contents.json deleted file mode 100644 index 14b9694c..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/addService_icon.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "addService_icon@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "addService_icon@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/addService_icon.imageset/addService_icon@2x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/addService_icon.imageset/addService_icon@2x.png deleted file mode 100644 index 4d10a406e45dd72faf3e0cb106a9b4b1e6418e14..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1235 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 x+EpxYteo+|hk4xwWm_8#bH7no|O4Z~*`S diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/cell_arrow_icon.imageset/cell_arrow_icon@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/cell_arrow_icon.imageset/cell_arrow_icon@3x.png deleted file mode 100644 index 1ebc9e368ad5d47334c98769dc0840f28a84ddc7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 355 zcmeAS@N?(olHy`uVBq!ia0vp^B0#Lj!3HF6+I0&9Db50q$YP+F1qd^`PBTmZ3NjW4 zxjQkeJ16rJ$YDu$^mSxl*x1kgCy^D%|KaK47*fHw_S#wACIb=n58=BS!Yy91v4|zG zm>=*x;+eu?Zg7XQuhHFn#oCKY4o=(0|4;nZ^$(|;4|_A3^?fo=jWmmTeNDpH=kgV1 zeKTCyNRpnH-7j~83;3MR)_yWYKB{55+GUp;5( ztVV+}3F&(MUn$o5>%ZNfYsT0-BS>6K;_$J;HzyuQeT!sP)a+qNGBD{l8lb@H-4v1| x`XnK6LN}`;=QsAc{P=RcXPf4j>2p5&#Fpx_wbm=o&=nX444$rjF6*2UngGbng*E^H diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/chat_message_receive.imageset/Contents.json b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/chat_message_receive.imageset/Contents.json deleted file mode 100644 index a706fae8..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/chat_message_receive.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "chat_message_receive@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "chat_message_receive@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/chat_message_receive.imageset/chat_message_receive@2x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/chat_message_receive.imageset/chat_message_receive@2x.png deleted file mode 100644 index 1fdd05b019dc6dc7ea665eb1e12794efb0c29d0d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 983 zcmeAS@N?(olHy`uVBq!ia0vp^CxAGHgAGV(um5!#NO2Z;L>4nJh^c}wqi2xH2cRHh zage(c!@6@aFM%AEbVpxD28NCO+y5mD5UgvfdM*bnwpMy>7{F z=YFuTb51<-z1ri=%#HIuy}a|f@XN)=^}Y?o{^~D}s~mgfc=2`bBW_Cxo?pV1?p_Kz zc9bk}{C-bWjL9+lO|)pXUTYn5NC6clEOHSxRr16r|GBHjwSO7aFt9f=@G&vUurOJ0uoMVzJWvog;7D%?N7s2=4Pgge zI9W2xITw{_Fht!@ap~q~J-}&rt9c81pc+TPB+*;aFL&se+tmqrGhRpuYh9hV`o90{ zlD+y2Vj*t|3|{y@`|cQ|#m=-KEwgd!bon#Pmj70ixBpf=AZ>W6CgTkA$Bik$2UV0yqwJ`hA{hCa}I}vtuN)v42l2Z3`U6B2D>CN$HmsVZ-^k_>-?v`Ad2wCV4Z#OZrpW7qC@^0Oyp(M z>)7+WBj~T$j-u56Q(pU-&zc)sIuN7Zx{j%+FNrlFN>Iv#DzXV>cTqPSe)%MDQ_T%Tfs?&QH by%be2miu}pw|EvXA2N8l`njxgN@xNAt%{(R diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/chat_message_receive.imageset/chat_message_receive@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/chat_message_receive.imageset/chat_message_receive@3x.png deleted file mode 100644 index 8d74569ff854f31020eb0b99b319b0f0f2125386..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1539 zcmd^9`#0MM6#vE&LP~9Vq7{u=J*FsaJ-U@4)haC=sd$7Ywt3YeD$^iF)M;t0wYCwZ zLOQk3C^k~WiF&kUj3|)vL=*)8tPg)Q$T8*tA{c~F!U8Zrac z!F~YndkJDa4h8_Q+kyUmXEGsbS!`HL|1SCqO+wl++iU$WUsf{()Z53P|iiIVpW>Ho;SpdHjP)z?P@}x`4L&PS0#{!;E495lkvZ8s^qHEGa>dik=>V2 z!K%50^v#uLHJrAP^eQ5x%(ld6Wl8sRuCU+RubDo?z;mt8)O)s(-SMcBR{YvQ4A@LF+dAql%byu?Abl<0M+OHLNCfyy?dx~H z5+T+T6-*eSXpe-E=Md>@I>|6Cy35GHHq%|9h@xIl9sQ5O|0nR>js~w&z=o$=uO4Qg z-rLck&A^bYhz=44k+eh5Q3~&2VeLH+Fhk78m9oeQ5uf=AdFAWPKM;cZyed$3bTl4Z zSBH}niZFT*Ig^i0ag?dsq!t%8s{md7tOup3^N@+Scyf|v$mX02-g=W;QXmROU-;t%(s`*o4d?uh{*NRXQd1lJn#aTG_4pNL; zu%qWDIg38fwia32ee$$Z&#!w&`MR{aoythdZ2tKVdezR7M!RCQS=LqypV#0hpKv)I zfHdol|GVvi`;tHvca7R5(Vf+6wDX&;wMvNx)@u|NBk3&-re5WKsfz`Q^p(GwlD+Y`q!gK=BBHvdsGmhF)*^T#bNDIV2mmweC< ze|k~09MVWzbuH7C%NDy0d8sN4cb3`|P4pS4?^^4i-8FA2B}~Q`Rd#1$mBor#PtKKa z#hJYg0GJaz~saS*aw)QWo_RB6qsWSR@Or(^Ll3y<3;hN7B~6-_f`-qO@h2E$)4W3#wR? zigEnBs=F1pqnquX)-;yO;+HO3Ri)avN3*kChfkLnDDP{shSB^ZP?pkw;5q+ zr*~|zp^_U%y+xrlcS^e~89nEMq}627unA{(y4nJh^c}wqi2xH2cRHh zage(c!@6@aFM%AEbVpxD28NCO+ohlDX`Pmn#p$6$UTtBL2QL7U={mI(n>>%ZGoM%=p2oZGXp z_W%7QOGVuN6rX#WZTLz2%J)9+qe+EvdqQ#!+VyUat2x=B$!V}>&qT(f8ft24Vtc<| z6>te{xOllgc(-aUw7FVnYmBZO!w(sMggLnTv zvFgbGnaeog)3IAuE7Uok{CQN<`daaT>B$QoOrFmDn8!ZFAj|4%#*jjUDcZUvvR`p{&#CzW8W-huoO5iYwW+w=zd_* z7Wq3r>!P@m(>)smMcEH_9}nIdcR!rDbD!M5Ir<`8^A8=|t8$>DBfYO+$`66FFT@@3^_V*MDu9x+*xn(dDE`=FV9X zn-vZScpSFaKO<)5?04^#pVhKY>RPxZYV9h+w29o^KlCeaay{>P>v+h6SH@$viP*<& zNxf&5mDg&9c9~j%cY+3n?5Gt@Q4|n5EJP(ECPYqr*EToN%tC>vWF)7wa*`P4R!sDFPc@Dtf`@i%@Btm> zWUPN}R)bq6&A1d6yiEmc8qLG@#$KB!D)RVx9esNCjl=TKT{BxCEMfl4SNiCe<`m3^ z_!F^<&pUd1d&#bf>c#Tba8pIvz_UdaA8tHGMQ?}@A3T+ipvEqLjvMlnaLT_mA|(&O z#G^s=>xRQY5h2A169#8%wOam^pmpeCw==Ye9q~6$bFuq|b-|51Bn(B@Ee;lcqs~UB zkOa9;okvE?=w(Em43_CZ<-#Zm?Um<^bag-hJF{-+Wy$Suqah`yag_ez2WjaXVTy4RO+D5Pu_&rAAO5KWI(O8R1Z+-ZkXP^sj z5_pGP`9{UU7ZbdO#FukRL#O`-2A~vo zpiAug1L{0*4uAWvK*;Mfw8)fGg|f)J%PG{YZr;kk`OkPg+DeJtIJX_p6Nax!VH95i zMcT&&${Lh@9B$o{iHa&$lc-{=TB?n;zYwk9GR&}m5fHlpsaSSvP7mJl}XcUYIWoo8jV(e`IHmT#Vk%$ zBlXM)RMR@~Sv*eI0+iXM6@}IsW{f=ho{zUr{+%u(I=PbIl5N&=6T0y1tU&tqv^=b3 zg(!;_k9-CI0%%$5$hA1Gc`~Mq3*ri5U~2QGRHV^Op*~-Rz*3ye~jxz zWC%TqVlTJ2P z6gEMq0>L~st-3X7G6=3^7qoqdm&;tEn&Dsz-wTh}fxUAnOQfCcI_hJ_YR|BnYfGws zq`NP3TouL$;Z`0=yxlTUC+#X@EvC~r@1zvPiK_Uj5m;(i_S0RjWXNN3+|&0|*X$a-udLIvjBG&{lq8-H#mv#!;hFgxFXU^9L%&ky+_au3D}$M9on`cyUw z?6O_H(Nendt|RUr`Sdg#<=YpkDmccYor#c~@H}RNT$-Hxv4UOUfc6Myp#5-2yTn0j zQ^`~q!8M9NVaLTRACZtjMty^R=7AvhRreVg^)HML)QkWC diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/home_addChannel.imageset/Contents.json b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/home_addChannel.imageset/Contents.json deleted file mode 100644 index a22aefff..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/home_addChannel.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "home_addChannel@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "home_addChannel@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/home_addChannel.imageset/home_addChannel@2x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/home_addChannel.imageset/home_addChannel@2x.png deleted file mode 100644 index 9abd0ae8840930a7f734e4ad8a0ef705460b3566..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 352 zcmeAS@N?(olHy`uVBq!ia0vp^G9b*s1|*Ak?@s|zoCO|{#S9E$svykh8Km+7D9BhG zLpIKTeZp1`t+`b1 v$4ogSDzc*Wx4%l6C%5Fxvu@2HlkFKk#5xDR`NX{f7yt~Ou6{1-oD!M``W z$lZxy-8q?;Kn_c~qpu?a!^VE@KZ&eBId4xF$B+ufw=*35S{wviS7)gdE_Z*xQOx{N zWzof!9ZvZVSb6e#IMoc)Cn}#2{Kc`$Sn}HABRti zd?p`Vq`6W8h%)bh*cN(nBh$IChF8V?!sO)64sHVmlQW3Who9yYriO ztN%UQ7ISPD*V~q5i{=RB+q-?tY7s6q5&T*wsy(0cNNC~w_V5s6qbqIm1*UIN{+8;L zjO?OkA6$|Jq~$O2H=W^s^m@iMn`vTZw}cpGWJHI)7rL~_sN8uv_sfUt)~z;W{K5F> XOW53_S`Q6?!OY<4>gTe~DWM4fGZL;f diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/home_setupServer.imageset/Contents.json b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/home_setupServer.imageset/Contents.json deleted file mode 100644 index e1e19aa6..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/home_setupServer.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "home_setupServer@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "home_setupServer@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/home_setupServer.imageset/home_setupServer@2x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/home_setupServer.imageset/home_setupServer@2x.png deleted file mode 100644 index fe69cbbedc9fd542af0216c0d154e3b66e7d1e34..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 247 zcmeAS@N?(olHy`uVBq!ia0vp^NvP9Yf-^fQvn_o7Dn@fiX3y;k8X0aYTy+=Gkf5bCoZgFkh$@ykV*l)d#r%!?IV(@hJb6Mw<&;$S~YgecM diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/home_setupServer.imageset/home_setupServer@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/home_setupServer.imageset/home_setupServer@3x.png deleted file mode 100644 index 14953f2ac29d8c0a3ce138a63eb7c0d37c53bdd0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 312 zcmeAS@N?(olHy`uVBq!ia0vp^#z4%;!3HGfJBU04aSA*liy0UcEkKyjb(&!UP>``W z$lZxy-8q?;Kn_c~qpu?a!^VE@KZ&eB{#j2K$B+ufqf-s}nhZqR?pJ59$67S08}z98 z&2tG?xAfY{*f;Oc)QQSpIQqJn>|Ste$(;UO)mP#FYxi5%16ZC-dcHF2#kJ4M``=Ya zuxLnM6UtZS6-W7R7SH@-ut)f4SZTOyp}L3V{{xn@`ZTJ;zXLtS;OXk;vd$@? F2>?ZLcNG8t diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/mine_create.imageset/Contents.json b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/mine_create.imageset/Contents.json deleted file mode 100644 index 951fba53..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/mine_create.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "mine_create@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "mine_create@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/mine_create.imageset/mine_create@2x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/mine_create.imageset/mine_create@2x.png deleted file mode 100644 index 9841dbdfd1f571efe020aec0e04ed593e42e7381..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1675 zcmV;626Xv}P)sd`LOge_c#3l^^kuC*MKzhVsGGyrmy|6fffCLgq zzq&X{@#abk1mX|~`kTeFY(oH=7Kq$xn))?gAni~aWLuh~sTd?xZwGP8u_(h0ottZP zTSI{yzZJ`9PdISr>)lXSASYXKKu%-KX$CnM&eqFrHDi#|&p}E9aGEl2o~v+egSCM$SI-igIz75qd6LW=Jxyda62+-Q^$L zF_w;)@x=Lme-B@6{D`QWdHe;uK?l>@)kDv{hfru@f&%tjxfOL++;ScX24-%^?-VGyl9VsNV#rWY^Q7P@01kwu^b)+<{|McI6v_uZjx1wb-I95dS z=`Lk1rkzJbnoZq(6eqm<&$zLp9*t5s$Fk4<{0_=+78~R^O{RG_IBy^V9C&9>yc;Ep z)MasV6_;=Pf#ld3;9%{#n3Y3BK0N+@ax5*VaZm>(V zG(tP2!L|m_p(Yvx@AB$UgG}J1=c7h9Vun+2WtJ(QP4pYADwtnZMyvwy5P`>N_4vr= z`t|K1rq{nkD?mZo{tGb?)(UR!-9d|B#%e)4Cj0oeZ>lEfInAGT=Zz}oad<4(Is(~6 z5=gAkSFvR>wxUW)DvvuV2e!(wvBfTCqJuxSy~b(YM28v(lg46p9v%GA#2Uq*J`>n2 zrePPyr!?o|hqnlz8eXf{jO-|jvxWo-J8jC@(C_d%qMQtFsp??b_V;{p(!6C~B6G?i zAuiuorzwwq6t?~j^mE*SeYqz6pT&Ttt2A>>(v|jqKlh__a{!fQl$NF;P2Xz+G z2n~7X1oky{Gv^x}Al=K`miJ&Z&u-Si!F4a@fk4vDM5ua(Hp4WA#tiR6X)MNWreD2y z0h-qICTl-9tMCRXRh&$IU2LKJ!@Y8xu}Z zUWo%UiZWPR`xg)bPO+;2({{6Pze&YTv?i#kR;=2@sTY>XdUirr^Khq4bgq(_Nqf0p*s?>pS}LKo`iaBTUe(ZgXK*y8LQH78Gqo<( z6v*ve54U&UNVaXbUOj8wbulNR+oNb(tno&5tPK|qo%#iP3T=lyRV(h4)6~i;J&1RF zDk;=&5oX;sH6&13xL)9b*tC~sO3P_V942txyi=m7&8M%>jsr6Hb?TR3R{a!0(0Q>y z1Ds!UESrkXr2HFqvSHr{6aD2TPE|C=r3_jNlaBGAE>(%L_Xm;N%^=}&Dt~0GVXK)7 z`$CfgPlH0r3i1v?D7C_ro{E?tv2>dJ)*-~3h!bAFvav$rDMO_&9&^pr&A3G==RV)Q VM0@kOjpTKnJxeU&y3qHj$fMZx&4WP+H8 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 UIp1~r^Z)<=07*qoM6N<$f~j@k+W-In diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/uploadPic_bg_icon.imageset/Contents.json b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/uploadPic_bg_icon.imageset/Contents.json deleted file mode 100644 index 83eb1daf..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/uploadPic_bg_icon.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "uploadPic_bg_icon@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "uploadPic_bg_icon@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/uploadPic_bg_icon.imageset/uploadPic_bg_icon@2x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/uploadPic_bg_icon.imageset/uploadPic_bg_icon@2x.png deleted file mode 100644 index b5cbc9ab8f6d990b6a31429ca0f18c4f1cdc81b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4759 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 lN+5jwY4{vD#;e%$_y=eghULwa{Ax9n}+R( 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 diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/upload_camera.imageset/Contents.json b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/upload_camera.imageset/Contents.json deleted file mode 100644 index ed6c29e2..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/upload_camera.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "upload_camera@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "upload_camera@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/upload_camera.imageset/upload_camera@2x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/upload_camera.imageset/upload_camera@2x.png deleted file mode 100644 index 5b7ae8003e5b608f521cbaa4e59841f3ffc41134..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 719 zcmV;=0x1=)AFm`jetqj_1vnZ{EzjF~LZd=Og#i9l;0@)hk{t%6U0scl z&?VP?e12Xm?t82es55i8bSJbUzdTU_<_Y!yfj$zr-oC#AzTbFXY8v$Q#$f5LSj6$J zD9qRw3_jWwU0oXxy^ya%njYt=q+*-ltC?s4&!0S_al;WtM9>Z<@);o(NrOIn31(Vs z?g#_U9u0jV)H{AJa!H*ZOP7lyCow{~C)!@l@(JB8zQIU`m6HW`9=KG@WQp?92OHN= zmOjkhS;Z;(>~iSG+7?F40ZUt+Q9;4Q;*-W zwqPwl0>2)2sln?*_002ovPDHLkV1m&S BIBWm_ diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/upload_camera.imageset/upload_camera@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Home/upload_camera.imageset/upload_camera@3x.png deleted file mode 100644 index 988ac8388f9472db618240a399dfd9976d582b2f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 889 zcmV-<1BU#GP)&&YXa70vrh}C*IiR0Kfr)hYhx5P$oApC%{={5k(?5FgNfv z!s<@-*pr|{0lTYu`1=;NY`LfXx@xMcs|I)`5R}+yw5k-xU0AygUB<>z`>gkI2mvZW zbCFSWfq+nah8=V@zB?t{s)p-s)ky|u^Xr-4yVpWmQ z(yUn^u&T_WC0et<*Qzl*+4<1f=aBstWkZy_di@69zkU6()UcZ$oLd+~$!!B7LWLsQ zA*z0yD8h zmt^gjXS#A<@G7tIcL~kX#tH(mg0Q&zXUOT>=eyFkeA^(Zaa7$#0A{Y++`CW@E*8Vs zns%Q9!7{@djaD)xI?xsz!lG&UOFTWZV;d%G&bfCfr&VRLx5bUvFFQfAwJCK@V2VL!J9-bwG5ni9K#c_(CZhb zG@;X%@D6rDp>&z0sW|j6Nszyq03OJh6|R8zo*jL>y$f|B84 z`5HWsx~_JgWf8m%=u+3MG@E-~E9^s!&#JynEb%@1)7UMP#44gHJP`{e*iDp0>|b?| zM_pm_XHoJw1m&K`(>4^&p|y`D_4l1F0^y455Y~?LDhz~Hz1dbTRk~|xbP!ZCBWo#R z%eJ6|6X~uA1=LeOwrsaPb2Sn5W~Zwq(h;tJJu6cl4o;4;CB_sFez?GsK#`C_3&va_ zJf^7`{jW;6yW3i))o7FZFx621qYR;c&FBu!^K-1Fge&nC3fy3Fgl;nZOP;I#=|8JI z(RByU>paTki7PyDa-lS}uF76|{ij4GxzIcsau>{cR@fdgtZC%5;kob&4*?+Ib}B5Y P00000NkvXXu0mjf?Vyd? diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/Contents.json b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/Contents.json deleted file mode 100644 index 73c00596..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/camera.imageset/Vector@2x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/camera.imageset/Vector@2x.png deleted file mode 100644 index 09bc30be1f5b931171840510d2d2ee08d904c28b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 611 zcmV-p0-XJcP)2i2g%;ibczR%$zGWi3k)V_!)%JZrxIJIsC8-xqFgeM+9rVeekDD#-j`tejkjO3`imlt(C1ZF>$#h-_W8}4M^}gd7nW|?pnUAf`z72 z4ak?w#vAtWYm^nx17B-8-2lTs2!uW6nnpF?QD4SwPz?}oR|&T^AZ0XyKpF&}HH~2# z;$fVop{uZ`2`qKM)K*`T^!le@=n!90y9UUgG-2k xiYg#;=ixl;9gGF}T|dRg$>z-{WA5-WzX!}Mri57FhJ644002ovPDHLkV1oa}4eI~^ diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/camera.imageset/Vector@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/camera.imageset/Vector@3x.png deleted file mode 100644 index 1d28b755ae3e34960399d0b40ececad1ba26e589..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 774 zcmV+h1Nr=kP)5O0_h04Hb=4GQf`5)P2$0>OO=QCg|y2E9SjHzb44^6Y?uWw!+zysFKbUYeDfJi{I-D%uY>IXc+TECEZLP3BTd>@`6B9TpJ4^%PxYb0K9 z_COW0zeeJPz~$k0$K3<-nE|STsPW|Kv*g>?FWY*-D{d)I>$c*F}l-FqbOek3RT4Q(p*V#E#Voae9X1te*+$1qPb4_ z^TYf4B8sAGgKnGMD}@RWEPyp{ooG4RX1;_Y?jfYyXK8DQ5;)@S0g(5+rVNrb@CX&bVCU|Jdk8T%P!S5` zJUQ+Hi1wSEj;s%KJ0TpAoCEdRPwc}pSw#rkK?p(K0@-LY2t+nzCoxg@_Wg%f@I+S9 z3X2?hGDm!FdqgNnW<%{Doi@}>k7!m#MA0Ohp+sd?wj#?0P%J^o%#Z}CwRH^>a6 zb<~SjS`Xt}(rmj0@2ymy869}QOHp6YG&9<49e3xl;i#oxnyYy~HmL8UFAo zAcrX=dmvrup_;)L_k0dL$3s_Qx2y&HRT<_sP*ME+0baJ=U$-q&RR91007*qoM6N<$ Eg0^E!V*mgE diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/count_header.imageset/Contents.json b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/count_header.imageset/Contents.json deleted file mode 100644 index 6a4d508b..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/count_header.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "Vector@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "Vector@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/count_header.imageset/Vector@2x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/count_header.imageset/Vector@2x.png deleted file mode 100644 index 4721c521bdeeff22f49aa4288e815d6db85ebd47..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 416 zcmV;R0bl-!P)2UU;ERE;c_Bpg4Bh zsGpPNKMr}_U;j>cX14XmhAG{6mihp_roUAGY0`D&80Fo&JoSxBfCu%P4PEQ}+a zGir>*w{B|6B0~$G@gaWus{uJtbst}xFL5YZPbg&;K#0KOJg6!v!PK|e6iE^lPC_Z= z!0Yv|nMYU9Su{jLttz3fU)2xQ``a=}lJbvGi^Nf1)r#(n67z`)0-OK5Z6>oU@Zi6y zi2!?`#cQmG+($3nSEeE55b$T5Kx1@Axcgf+(7jOIy+B9k#(V&Pon%B1Fk)c<0000< KMNUMnLSTXkyQQ!I diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/count_header.imageset/Vector@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/count_header.imageset/Vector@3x.png deleted file mode 100644 index b00bd55e14d15387fcc186767719653f310c4d0a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 568 zcmV-80>}M{P)jD=AKOCE%#)+XsozdtOg zk~l~SE1!NaEFr6~5GWxdEWclU7U6YZkb|tkL>MC@I$xb|i0s0NzS?$DgX3M*t$-A$ zprcE-e3WFP{f|kq(Ii?#N~!hH3SVBFwN!gNz!+{+E9V`ZmC>uNy5(9NP;beNEBCAp z1B{nMOuU^ew(1~pG9N6eZAK)c-c&@bG}~$SFfO(4`vv6p9Sc@bJ@o=Fw3v)21o0Tt zkI?fxqoG5ILb-#YZHeopi$ll!BAIZ{tNy(je+kde8x~wkJ2+NE9}`n|)mii-9A{|n z9X1(Ca03viv-ksM!cT)iF^YtrW%s5NhiX0PRVwEp#ih-W{kC>l&DFtEpsANwp+jf@0000=?5-vat2Z)!>1w!To z2_-Z!1yO9X^Z3TH5jN}Dg(6BZ-)gio`<{MpcK&GJ4$&ox$CZsrwZP2Jl{t%tX;Kd8 zXIR_cuXmEdz_7PzP79pPF=rU?>9g7sRX&XD5$pQitCw%$f`MUg>);$jm=Rw~mcx}w zH50P55IQr1)g8>6rNer?JHt+3kPZb$CDact5*TC_l5tX< zcKafi%YVgkoH0+PwzpFc93TRNmha^+F!tZTc@*J-(KMTuld`Q(AKRVW@`HD(a)&YT zuy#qcjZ$jt)SHw*U{LOU9(zsSgL8X|Q%=h9^78WXx`N_A8^g>^Qg@ZiA{hx9yDtLz zNBz#+h8!Jnwu6a))oL~UqsK@1mK7#?qtxs#n35}j8Vd}3g=q1-&u=3*N8pq#=bC+R z-jf4_E=)s|X?3obN~2ng3kZho{OcK8l};S1xLZ*|K@mkd3kwVA^F2SD}T7>5BDZGmwveS3)K0bujJ4?A^-pY M07*qoM6N<$g0fISw*UYD diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/dot_image.imageset/Vector@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/dot_image.imageset/Vector@3x.png deleted file mode 100644 index cbafa396f21cd247bc9f83d53e11cb71e94a8585..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1179 zcmV;M1Z4Y(P)!-kV$5LGsec!>bF|SEAL-x;4?w=dvh)q_(FPD z6rw2s`3fiDR<&9>z(-(MS5HN=*&u^4u?ivlKHIE&Q8ZntlXX3-*8)&>oP6c6yn~H1vRNqcn`sZ>k_j; zkQzUxlh}^N$wYK{qf~0x6iVWfV{g3->`9FuA`MHDxFnb;&l~peB}TjC7{WRjh%mG| z?3yGl^Qq6~i!bQ&pSCDluRd703N48yHag}5A7Z{l3I zJFlPy#ezCkDXl$NS;7dgb$RiNxk7P~7B16ca=^Cr`~G*=Zs7l&?JXpL<1#J!b3T}n zLO#Kes7Oq&SMJxqfa@|ziG()~3xvQTm~dU(#2J(VPhC*rY+T&L85fv18yB4}_JOR1 zlQ<`F$&(4x!Js)ATHnb_;*#b(Q=(>5P_J)$erl4qT8Xm~R-JfcnHu+a6<99Q;qUGK zSO50f4eANtpHq(FO#HE4Ua5e|-tIQJu9Iuv?ZpmsNnMIvoh#Gc&UUR;S#^b0nMCj9 zRkcD^{8lZmEF&R%JI`vZ$|BQt_0V?xS}m_GzpwNM=zEnRq)$!v11(Nb*k7mT=U+{P zk4lX5@+`VsH@jR1AH(HvI2;a#!{Kl^91Kp4ndWi<1yeM7(c?szffl6sBh=bo_wlLd zRFu+RygrgN2#tKI=kHX}OgzPhDq5q8{-ftAQDCJg5Wpxf^P7cO?Bm*`M(LRsH5R|1 z@$eL_{5PbW>D~jg0f8A>LBIb!HF1%itrNL!bRmWQj*OT z@#a`OM!Vn{%#I&>kMHD*NW$Tfcp`>z9eJI=H=gn~d&b1*URrbN0x;3D$822GD8?nT zg+RBtRf0^1XP&|Xuwc0Kvu@Fh<$O*}y8W<%8inQ3iHcMaZwhb|UK*Apaj_F;4oO_? z#93KyfS)+?TN?-)1D&kHfaAYW)Pm zxJ;0{yZfwh_3HJP)W1=?5-vat2Z)!>1w!To z2_-Z!1yO9X^Z3TH5jN}Dg(6BZ-)gio`<{MpcK&GJ4$&ox$CZsrwZP2Jl{t%tX;Kd8 zXIR_cuXmEdz_7PzP79pPF=rU?>9g7sRX&XD5$pQitCw%$f`MUg>);$jm=Rw~mcx}w zH50P55IQr1)g8>6rNer?JHt+3kPZb$CDact5*TC_l5tX< zcKafi%YVgkoH0+PwzpFc93TRNmha^+F!tZTc@*J-(KMTuld`Q(AKRVW@`HD(a)&YT zuy#qcjZ$jt)SHw*U{LOU9(zsSgL8X|Q%=h9^78WXx`N_A8^g>^Qg@ZiA{hx9yDtLz zNBz#+h8!Jnwu6a))oL~UqsK@1mK7#?qtxs#n35}j8Vd}3g=q1-&u=3*N8pq#=bC+R z-jf4_E=)s|X?3obN~2ng3kZho{OcK8l};S1xLZ*|K@mkd3kwVA^F2SD}T7>5BDZGmwveS3)K0bujJ4?A^-pY M07*qoM6N<$g0fISw*UYD diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/dot_image_disable.imageset/Vector@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/dot_image_disable.imageset/Vector@3x.png deleted file mode 100644 index cbafa396f21cd247bc9f83d53e11cb71e94a8585..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1179 zcmV;M1Z4Y(P)!-kV$5LGsec!>bF|SEAL-x;4?w=dvh)q_(FPD z6rw2s`3fiDR<&9>z(-(MS5HN=*&u^4u?ivlKHIE&Q8ZntlXX3-*8)&>oP6c6yn~H1vRNqcn`sZ>k_j; zkQzUxlh}^N$wYK{qf~0x6iVWfV{g3->`9FuA`MHDxFnb;&l~peB}TjC7{WRjh%mG| z?3yGl^Qq6~i!bQ&pSCDluRd703N48yHag}5A7Z{l3I zJFlPy#ezCkDXl$NS;7dgb$RiNxk7P~7B16ca=^Cr`~G*=Zs7l&?JXpL<1#J!b3T}n zLO#Kes7Oq&SMJxqfa@|ziG()~3xvQTm~dU(#2J(VPhC*rY+T&L85fv18yB4}_JOR1 zlQ<`F$&(4x!Js)ATHnb_;*#b(Q=(>5P_J)$erl4qT8Xm~R-JfcnHu+a6<99Q;qUGK zSO50f4eANtpHq(FO#HE4Ua5e|-tIQJu9Iuv?ZpmsNnMIvoh#Gc&UUR;S#^b0nMCj9 zRkcD^{8lZmEF&R%JI`vZ$|BQt_0V?xS}m_GzpwNM=zEnRq)$!v11(Nb*k7mT=U+{P zk4lX5@+`VsH@jR1AH(HvI2;a#!{Kl^91Kp4ndWi<1yeM7(c?szffl6sBh=bo_wlLd zRFu+RygrgN2#tKI=kHX}OgzPhDq5q8{-ftAQDCJg5Wpxf^P7cO?Bm*`M(LRsH5R|1 z@$eL_{5PbW>D~jg0f8A>LBIb!HF1%itrNL!bRmWQj*OT z@#a`OM!Vn{%#I&>kMHD*NW$Tfcp`>z9eJI=H=gn~d&b1*URrbN0x;3D$822GD8?nT zg+RBtRf0^1XP&|Xuwc0Kvu@Fh<$O*}y8W<%8inQ3iHcMaZwhb|UK*Apaj_F;4oO_? z#93KyfS)+?TN?-)1D&kHfaAYW)Pm zxJ;0{yZfwh_3HJP)W1;;d73WK2Hd0rI;F)EM{X0osUsmmPEB`IMJryK@Bl68noPH2IV=ffV_RDwO$DW`Q*Miz+hv zRBC~Y_=_qs_*5c+toe&7QuvgVKpo~Us*v)jSb=K0yK|gl9!C_$ocW>rV5wz0VxZ&^ zN1S0d-%PjPSazEpo2QSZO^E(Qk%po5MxX&O1Q z;t-pn@1nTI2F3;2^0#BB)nP1)Yc}rOg=vfnw77T!X}Ps_8>TTX(8irA(n719X)H`J zA88?TH%(UsihFzi1A(#xeiLJ3FpY76PEAiDE#ng>VH)ECz4YP?(o#G>3)2`EX!_I? zo_qEgB<1Xxm#ySwR!sWsx86+jvJ)cJC>GDb2KJIwu_Ar*?RWU;=U>|Pqme`6=*q*0 ztjQ|H_mj{Br4J<1nuwB{agOJW;OXfpoECmXQ&KCUkUyNyPql82LAOA*5z}M!gqv@< za>RQO$10963~akydu&BfZ1w!XG%Vjg&`6_ji`44y4n22+pHl+qK7+ zTp6oEAyi`B+nqNh_LCXfv@5u>wV$ujW{`Eqp4Dt%;iR z%F4~e2`BX@F`KoZQDNX@+^Xu;^nUHyW8a*%n{)lgQl;Qj9Q*u>FSQlAPQNgdStzl) zDmGWWmOdmkG>9@sQ=&$y`kNh0vC~Sok}L)cydu+2TA=7}7CRifi7;?VGX10l@;q0>3v#M= zKCI$-gH@THiE@aLb1Bt3osfsp?~zELeN*f9Q6xrBg0Ef^XQ6SUhzeY`khyn~(L9YR@D58p|0L8>}N806?CQgKnIz&W;MSFVGk5{Om+j;=H8tFkNCK{C}bx@W3! zk(9crHq|nf3TdiQ$c_$%p6{_Gq$2ZS7Qa?2J&bM+nb1Fv@CGZ8>!!jvM6KeuBA)#{pVF8R? v;1LRpVT43s4l1;x8wL5YiK*11haUa`4}4zauwWHk00000NkvXXu0mjfh~%TP diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/id_group_header.imageset/Group 389@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/id_group_header.imageset/Group 389@3x.png deleted file mode 100644 index ade594324d4671e74e7a58b10bd292a393aad18c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2078 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 diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/id_group_sort.imageset/Vector@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/id_group_sort.imageset/Vector@3x.png deleted file mode 100644 index 6c56fd15f9d53f4702fc6a396155a18768c51cb2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 497 zcmV`<*IA*#AFZ zn4$)r<+6o}l}V|6!?rG11}K~3+_dz;62SJDC(^9s*GxoEa=ms{xQ1#c5@Q(ekj3|n z0R2z7HVyPpk-{0~z`Ve~>Fb=YG4hlfrkgQuqUa5T}+m*9r)voXzPu%0`t6)wl%az+!fe6Qg%fPP#I@& z32J5uyCPQdR#!?hXR4gHgO?etv~QZouJoNLx$3`GU<5mh+ZBC8@B}?^BzD^uNI~L; z8V*S90TEOof!cVO+1P2)*omEP?Ea-_ZSSu4m)Y5`v4A0!-z(=O$Q&SK0Wk{#4FF-Z za_g9)uV{cNXsvSAli>tQQ}0wgd) zrp7kuvIu%q2@5I*70B!!?BFcu2vRwt#<&INUjy@%7U)- zV$&)cup&kNgV?vCN6&T?xeG zdmh~6_(c2J(cj~s;zr)09g}q8v0f0|+L!IXI#L2{=>%jTLAb+U3({6oWYa-S@@JpT#c$scE7O`a{!I?n?JO@^d+?!KrTyQO+!J{~EXZ-EY&+f(|Kwcb9$>_Ub zeev}p9Q`|v45EK8)+pd;ipH8y%SlRDVJk7zYl68s9z0NVz_FYr7Swi&cCo*p&vX+7QWqTi zpOssflJ4DBl*)eHtrLzV1lXJ^K*u?)Kty?vwckJBkU%-r1*e!O@}NMy2Zfz-h1R}# zxE!j`Vg4y!v{w>zPWd#|fP}@q=UI={25g<8oDE1=D4edKQrB8somna&;s;1dG+6DK zrAp_cp3MSxHJN$f>Y`iRW;M6i6Ex@n4^d3^(zvpeOIce)yt*rmAF z{32Vdfe}`Y*C5JunmA3+DZ~c-`3;&*O8tt34FQ`%reA8DCpiSX8f3LjMGm4fC{@cv zwkTT+V2f8R?Ll-uwGP#ErWP_oeq_?t$fPba&R_(0VNHF8aOg8cVYtr_{{fy)+xlve R1k3;c002ovPDHLkV1mHzuJr%_ diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/invitemember_success.imageset/invitemember_success@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/invitemember_success.imageset/invitemember_success@3x.png deleted file mode 100644 index 15801fcc54802048e0502fe2d822bc8a94a2daeb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 943 zcmV;g15o^lP)8@B}?^BzD^uNI~L; z8V*S90TEOof!cVO+1P2)*omEP?Ea-_ZSSu4m)Y5`v4A0!-z(=O$Q&SK0Wk{#4FF-Z za_g9)uV{cNXsvSAli>tQQ}0wgd) zrp7kuvIu%q2@5I*70B!!?BFcu2vRwt#<&INUjy@%7U)- zV$&)cup&kNgV?vCN6&T?xeG zdmh~6_(c2J(cj~s;zr)09g}q8v0f0|+L!IXI#L2{=>%jTLAb+U3({6oWYa-S@@JpT#c$scE7O`a{!I?n?JO@^d+?!KrTyQO+!J{~EXZ-EY&+f(|Kwcb9$>_Ub zeev}p9Q`|v45EK8)+pd;ipH8y%SlRDVJk7zYl68s9z0NVz_FYr7Swi&cCo*p&vX+7QWqTi zpOssflJ4DBl*)eHtrLzV1lXJ^K*u?)Kty?vwckJBkU%-r1*e!O@}NMy2Zfz-h1R}# zxE!j`Vg4y!v{w>zPWd#|fP}@q=UI={25g<8oDE1=D4edKQrB8somna&;s;1dG+6DK zrAp_cp3MSxHJN$f>Y`iRW;M6i6Ex@n4^d3^(zvpeOIce)yt*rmAF z{32Vdfe}`Y*C5JunmA3+DZ~c-`3;&*O8tt34FQ`%reA8DCpiSX8f3LjMGm4fC{@cv zwkTT+V2f8R?Ll-uwGP#ErWP_oeq_?t$fPba&R_(0VNHF8aOg8cVYtr_{{fy)+xlve R1k3;c002ovPDHLkV1mHzuJr%_ diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/lock.imageset/Contents.json b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/lock.imageset/Contents.json deleted file mode 100644 index 6a4d508b..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/lock.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "Vector@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "Vector@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/lock.imageset/Vector@2x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/lock.imageset/Vector@2x.png deleted file mode 100644 index ad1ba57cb4be554c5c128f58713994b18bf1d190..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 672 zcmV;R0$=@!P)C_y4fxGN|-sF&c6ekAI6 zZtqZRxgj++1eEhNGn%=__jP7WC;-2I+t{j7+khGbc4o^F2mu-N-XFBOMeI;6$zbeM z5r36o1NjJR}nO>*2U=;&?2>T4p%{Ba~AS1CAVa9+>MKx^F+1BAa>iBPC*< z$j=_L2CInNLNV@C7AMra)>H=!^8A zT#)l`kf$RPN9Yw+z%%YM;+2Y|OrJ?FljC0x>rh(}Auils%aK`)Q%Y`#7|USeIV=6v zSO&VnkrElY#QG6>`}-4h{7zo8VEZ$$4iBx(KpwkIJNW~|?#GeKbEba)0000P diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/lock.imageset/Vector@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/lock.imageset/Vector@3x.png deleted file mode 100644 index 9de1ccb2c84dcc5b9e8209bccfab80bb0c8f88a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 921 zcmV;K17`e*P)J^9I6>hABqC4}N)n%-a01{2q&I*Q5Ka(CRidI+2{%Y@;3HV#4`6$z zvjJ2)B*yV>l}ODaMT%$r@p|@SX4VK9X}5cMxuhCG(7FOFB2b>q`UeE)^05mD7Xisj zr&4kuBM4KXh2@sj0n0di7L=fX(!CiI*5Sp;|4Syd(SLVep40#O|c~~z8+Fo1WV+=4tXxRdY9j? zFS%O#2o{SkTLLwOXenun#UwFBJf-P#2@2&3Qpz}~{72|L@xG|rN diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/member_header.imageset/Contents.json b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/member_header.imageset/Contents.json deleted file mode 100644 index 798a6cec..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/member_header.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "Group 390@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "Group 390@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/member_header.imageset/Group 390@2x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/member_header.imageset/Group 390@2x.png deleted file mode 100644 index fe976b464a4feeb9951326fec3d26d7ebc63a7a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2175 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 diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/searchServer_noMoreData.imageset/Contents.json b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/searchServer_noMoreData.imageset/Contents.json deleted file mode 100644 index 0c85eb3f..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/searchServer_noMoreData.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "channel_noMore@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "channel_noMore@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/searchServer_noMoreData.imageset/channel_noMore@2x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/searchServer_noMoreData.imageset/channel_noMore@2x.png deleted file mode 100644 index b392057d4e3987a652cf148eadf2e09441fc7855..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13633 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 oC({VnRCZyUQnqa}7}|{gA3)t)z)e~ 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 Q(EtDd07*qoM6N<$f^e4mRsaA1 diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/servers_noMore.imageset/servers_noMore@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Server/servers_noMore.imageset/servers_noMore@3x.png deleted file mode 100644 index 9178c9ef4773e3e4a34f9e82a08205f565485eaf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26499 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

-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 diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/Setting.imageset/Contents.json b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/Setting.imageset/Contents.json deleted file mode 100644 index 6a4d508b..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/Setting.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "Vector@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "Vector@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/Setting.imageset/Vector@2x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/Setting.imageset/Vector@2x.png deleted file mode 100644 index c6650106378db03b00104de499323b0c67a7ab27..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1007 zcmVXV#&$%=3NfYBQnNB+QUhbbeGv|NK1t0;1LYQ&sAB16A9gqNY>AYSDbAY&m zh&ht7RIf&5(-YSaTutON%6FzfqRQNkv#n?we@(kX$*JWbYR zoRh%y;&zA#mDmnMy#Z0#8$h>Ki@IvX{1Z@uo`Vn}PmqoqcTTiqTFqF2qgx}CumBcE zUy@vVe-Jg}I*7Oi|HN0T5Wr$ddmt*h4zU93)pu<^^VF32@Ibi+db7y?GJQ^!H8}#EEJir|= zfCRk($gPKWp&dohAENS`VU`Fv$m0vc$E5u;2>D!^JIB0>8^y3fC_>Oed$s+Fp$`jX zo5YkjCV-5t9})$J2bB*q*C+q6bq@kruJ1=Buta4)10j9@=wArBkX!Y`D4M*6*4}wd zr?$VF14mvJ!xe$z*w}IG?Gm7^d|G&?kV7F_e3UH2fhT1E2^jhxZh%j+>Ck<6H=Ue>!$uEofa~h3_v6;B zPDg`dtCK)Pm&aii6}-U_!L#;kI}_=B)5HM4Mc~kx1jn16?Fdyg4J*5Zc;uOE?+Sk7 zmAA7%DcdkIcstPS(eoH4ANJW1KYOE?d1ZCVjxG>O7Uu3$HY&#DXN#xH7`paB!q$U( zvU!<&%p?nAOF9CRZ(52}j|2)lGKoW=u8_1k9g5~=Gx-AF4lxv|=h8RtL9;QHZjE;# z0-HOc(l$YIX#%)W~1H$2du@87kM2KtoX;cQMoPj7J*Bot;EU@DL+0*KBJyXW9)Llg zfVhWV7vDk3fzQ&WdH#CH7h721CI{Vztn@OFWb2d6+$V&{r!*NA*rrLjnWBS(V9Z zX8izUd12fH`94NsHHh4X83Y-+&Bta-lCfB&s0A~KVt!@X)>y0ugD%V>gptqcyQc6F zap%P%u+ikCF%~-jF9$OT-ZO1!9$8egxW;M9k%o8-d0+5pd_QK{_bWI-!{ z8#*a@B{^*u5qiv!mDDpQDcn~qHw+F)QBss&t;lv@!1`7tkQ-YCI|3#;Za)6KHL1bI zwx4H4-{BgPF{-7g963_#PuqSe1N0Q))6OVWYQ(5Y$})lmh*cZWx(aGOIarz2W~$iI zhM)K5=xls(KIOuoYR$uX6)f4@-mS{e-h=oAM~C}slir*tHhk!bPCm5I5gTQ{B-f8W zq8Lsmd0?5_FX(dayKk0%lM6LO=pw`;XdWI^AOT+d^SpEa!S^~Cg*cy+@O>?!iuwD? z=P#v?n{UC}XXTQpK+LOB-sIy(GwevJ4`Q{_NXQ8sv9VowXNj~e>{q(HMFOBQ1b z9O+{wFC)*3J!Egg7`>pokc4r-$XQaPa^Q-BR9%cDj04Gwb3~4*nua~qg%lYq4vY)* zN$65Ak$Tn}Ko?TPb{pj;c<+-_5trc*oF}SQpA+k3MXLQ{w4bnKr;iRGLG)g* zV^rHxpj311EF*f@W#g4efp z#e4(HQNoXo4iCo8A5#lhUDQjhE5)-#(hzf3ToZ13zZNS7p$Ha4SwfN3`p;W_QHtLa zuqTj6A5S~hb9Er4C=36pjY~4R&NQ=4V`NQiZ2fZPYLc@y$(cK1lXms&ug!6JF)Ouj z!9n0V#I{|Ea!QPL1jN9up`+MP(AD7+y!K*3N9+O2O#wJx8G}7L}p3 zX$Mj!eij_qlp7qT?#cCHZspx@hfZ leX+oP+#4J7m^h0Z@do!TPNfYmPLKcq002ovPDHLkV1i%Aw+#RQ diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/allow.imageset/Contents.json b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/allow.imageset/Contents.json deleted file mode 100644 index 4bdf5bae..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/allow.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "Frame@2x-1.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "Frame@3x-1.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/allow.imageset/Frame@2x-1.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/allow.imageset/Frame@2x-1.png deleted file mode 100644 index 091a686d3f3cfbf05b324233bf5d6bb404aa1083..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 329 zcmeAS@N?(olHy`uVBq!ia0vp^G9b*s1|*Ak?@s|zoCO|{#S9E$svykh8Km+7D9BhG zwieH;2LFCM`|IT!arU|qN52K z?p#x;S(|j_`302?%on_+(xtLLbVxd0P4M)0Ig$G!;?1`8m5U#DsqR{|^_s%gT_4_k z-IcI+0dMKieND9)yU)ZJYG*hJmOSg?W!nAXueo}T!H>RO$&0m*XzII6b=3KGJ(h9J Wsg;6NJkg+lV(@hJb6Mw<&;$TdB7vy@ diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/allow.imageset/Frame@3x-1.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/allow.imageset/Frame@3x-1.png deleted file mode 100644 index 2c806fb81c411007bbc2d660781d195a448d3007..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 463 zcmV;=0WkiFP)#5GH_2&&>uf0ZBLL2pORR)PC4OjY3t2*sbeG zy#Fb!pVFVAq%i9Y`ZH(v)LtJ1 zv_Uc$Z@*K=ReRVE1IX$>`F*(V}Sd?D*!0EY}$w&~bNo%6fi zg!O^c9keOg#ri_(4&FWeVC6d?Ur8BfK9CeeQ4}@2z5ytI|H@d@=iLAR002ovPDHLk FV1hQB!#w~1 diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/allowSeleted.imageset/Contents.json b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/allowSeleted.imageset/Contents.json deleted file mode 100644 index 5c4d3b18..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/allowSeleted.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "Frame@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "Frame@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/allowSeleted.imageset/Frame@2x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/allowSeleted.imageset/Frame@2x.png deleted file mode 100644 index 95a388e864de11a2a5db751486a89793cf7e1953..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 232 zcmeAS@N?(olHy`uVBq!ia0vp^G9b*s1|*Ak?@s|zoCO|{#S9E$svykh8Km+7D9BhG zmF{Fa=?c_k-1_K@!ZAMNH2O*(?HkKs{ zjGV`HYaFJfCEk3;{%g|jH}`gxr8$1cX6QL{E@xTWq)y9%jk71kOtUf-Rs75)p0;*p zY;gM4*0bkNG)bBtW!`o6O|Qsa@g*v)S<<$eS609G`1)UGa#m_zh<>%lWgd3!CjVk4 YmZg=MAC7OE0dxq1r>mdKI;Vst0CX!(hyVZp diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/allowSeleted.imageset/Frame@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/allowSeleted.imageset/Frame@3x.png deleted file mode 100644 index 198fa556b5cc4c43f42157bf488b4cd1b2bbb419..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 299 zcmeAS@N?(olHy`uVBq!ia0vp^S|H591|*LjJ{b+9I14-?iy0UcEkKyjb(&!UP>``W z$lZxy-8q?;Kn_c~qpu?a!^VE@KZ&eB{sB)H$B+ufw^w}y4=V_?J)9cAIZ;4!YJmFI z0QQLioNJpsRQ_8il-3N$-}cQr+^T^tRIBoQEoJ*fwq7 z>Cty*>g!D!IfYMB7H7XY8RqO~mXo~k>O{>OmnRtBxIB?DhrN|2VSc~~1~KlJw+}v2 qsMU_JS(1NbU#{E+51<2ds^c3zupCzSJLN9WFAScpelF{r5}E)ooNuuJ diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/bgImage.imageset/Contents.json b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/bgImage.imageset/Contents.json deleted file mode 100644 index 7ee51000..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/bgImage.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "image 86@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "image 86@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/bgImage.imageset/image 86@2x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/bgImage.imageset/image 86@2x.png deleted file mode 100644 index 90ae27994fa879b44ff794babd962e4673973ca5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 152038 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

YP>(9;I0I`G=-D=#q@5MYs}ZPvccCKJl3s`AzJ_ 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 diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/bgImage.imageset/image 86@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/bgImage.imageset/image 86@3x.png deleted file mode 100644 index 9715babf051d721b038548c0bdb23ccba0a483eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 303404 zcmV)1K+V62P)9jz1L?C_n0ywaz+jSvVa;70=+GNtJUi6|DnMr2- zq6hs3y~YO|8mVTH6uSmikyQW+Ljp+ToDq>RdU%A-cRFYH`qr?|KIdL{zmW(e zP|ZF-q`TjH&OUqIYkh02Z-tlslmC4zdOafk7lv?qe^wOAg8!BLA->@Mgg}As zEBLce6!KX;;rpjkDpyvi==Z4}k7+tQ(dYS|P;jaI5AVQtcqXDO{KFOao`8D_xgYo8 zXEhq>{rDW8;obauxxCCjODm_A`>Nqc>e*jgqhe{9s*@AGZ;9))LUA(T`i$gx{M}nx z((?HJnxCDX9CH~%X&dTa*t_K7dY|08C+(XKhtj5^Kj3@%MErYQ*YXTMOe>c!OZm9h z+gU6Pq)z>f3v_(%4)MHlg2^E6@mE2bREUdk_U;2y7!Mlp(Rf_y9zC)j& zO;t6KdQOjy_?~s?7ydxzM$LU$aX(a(vCIh>Q*N*HpR{LL`X*LU?$z;Hq0!?<)Z?;N zuV1I7t!@5pMB}|DGHw)f9#khIes(|s{fTkqdZ8T{qq?f48vP3wbZ!hWZYT0=xw0%{ zD)WKIW3qq5@2_RdmoHx8`f)!#+L7-ETU)ex<2pU~^FN_~^nd-Y=>DVoR7@vyfy>z9 z`d!)Hq75FeA&pJGoHa9ovrI%l#>n~iPqx}gD1|=_>f`0}& zKAzD2-jU4r?TZ^+wVFQp=nl7MK+Ir7k zy!*}cUtxP?iFMnlQ@1_y`uDUpEixAQy*|FpXLb6nU9Z{ksIoE5$D{dsvFo(=JngtG zHV;ql%X#luWGqg*3U5o$vgeIcS@sqxE856Urc)#vj|p25Fh z^Qf~Hv43L^!KqX5*@O9BV$QRyASV%jH|BGyif8XFbL*4(Q_C6@=<6cM7b34%U9b;F zlQU!=vpQShy7yYWhI|Hg$H?WJR1Tl%{%)MHCAY0KS;{|;v1(Pegxq4^7kq9M_?f+< zHc<-ot4t=r9zVg)K<$2wk><@nUw`xVa!PMo;F7*Ava_h!AJDIU7NpzlobYGR7dXS~ z)Ms_7kB>`|7xi^=)v0|tPFikL@7CGaxi6ieenzzVnDCn6`ch8?rox1PBb3Bf||LeOe(Q|NNZ1MRN{Y=d{GN)SH z-$kpxW#9DgWn8u2@p)D2_c93njP18_4t2DKbXr)S$~i@$_5O5kZ1;b2Pe}cT@x#vZa-_>Dq3EUW@}KSYXXi|N8j|l-^#Xex)?N4Ve)WG7)~!#gNB3%-xBmN_`vSGk zCcmdQIXo1_whYSxfMAd!CW9?l0blr11%FBIfx=yLLvWwmgy&d^mhQo`=yU)(JkgTC z&B}K4*_sQ77z7NqeKvaXSbz!{Or9tLl<-EA#-Ath2|zEt(4Gpqo)4 zpj1yg5PgMmc>n=q)dvSselUOsKndzv?(Wj^m8;S|0j{u_a`*PRtW^d9!s?0uEeBk$ zioc7~It@{ezXJ#r`SbDdBYvL2CI&VDa$vFH9izv)G9Cin@L^F;O6?N{r~tM}e`CzB z@G)*SQOiM3HUn7%7!R&P51~wCw4QJqmudZ_R~U?WUgpK4x4%Qb^bh{Gw6eWT7p5cP z-lA3Rv+Fl5(J%kvtNgx5@4t7Sj=AmM{?51Qoge*xR{0&Tz48j(U{L9V-*YlLp)Y;; z6?$<0K)yR+K<4h9+w}1ML+{uNZr`M@^5J}+fxRDo_a=S#{zo$X-}vGi z^q>4MevjUN=N5hN?uYd9Yp?L<*x&(-;_$3={IOB_#IJsG1^=gUbp>8pKq&l=;pzen z^R7j~f_#%t{p|;3_}O;&%=p{YR@9qA^R)Y)K~3oM?uzsJ{wHZ`>OVPzXFva}KzaLSEN%-(B%pA@JjyH))lPagUxH(Z==_+GjoMh`}2y-DNh2?(gl>!2ugSVc_L;Ghvy3 zIA+vr&edbJ@=_F}_o? zFUAmMn>bBz^>;Ng1d)T{`qsL8w~lok?bHf$%KdEeLSeuYKqD<&!CeO=x(nm1^VUI{ z=rug$Yz!1Ao^tlil%K}W_H*>@f*Xg{WA@$za>*WSm_YO=D9snYceajaU*7hg#(wfN zAWE1s0FFh@GeUK*)6N?2qg3EI7ejJEgqnIdOdcdytQ8PbEJ}bWQ0O59v0_{^Kmi~} z02v@rtmNbKu)J#C3&9R|wQ`7u1}sDl4ww){_Oq^IGokr{w*{1b5^It^BY+Jy4gph0 z02rAlsGnJ~pp@gEtP{R>%s@rtO%6hrFJJ%%xEH`me{EeS7wUla!84;$KuIiG*f{vv zYBUzG0v;#<&%+Z2eS>;2(p|`g$AAfMvH)^i2n(Z;fJW#`5@4%VuNZ8mD3fbC<$I3l zKsLq!mp=ih!=JGUkU@w(4K_EVAMn{^Z%=@Zl0h5+kpwUa0#M+0@l;{}1Y@S-*wa2o z+r=8k;1;*5g4)j;bOm6A#~ghLphtv6Y}_&nBMmNI79dC`l6pl60L69f@nHk67TNCL zImEz+gLCpO%pnS?-%AF|fYgr}=!tuerHqo>C;g)5p?KR&hex)*2YEL@B$+>WKZN4r zBSrfeY|{f1<9?|1>S;d@wl45z+@}mUp^osJDp!|f9Ln`oTE29d4j7#I8-b3qc6PvGMyX^>HeKZd{}Pq zAsT7t;X}I20MMn2D{P^7o<`h;o%=gn#$7&i_vl~!tA9x^eBn*n-F-v{hevep-hCQy zeV)7aA{`w?dhYu3((kuE{DcM=TW-Vl_9hL)3c^TwucRY>Zouw zecx&A>Z1HVP2gi8B_Xx}j*ubvUPjj|q}ztmuFujg%u%sy0nBx;F0bmGzG^j zNapiwy}JD~dr#9h?eBjY3fMyZ)mcZ~b+&lDtiQtiI*7LspGEE!(5{=Fv#`8j4YuAt zXKfV*xS!UC?k&=N|7U4e?Sfy(+mr7jwV@2!19CqUks9Zi*1m9{&+Cjnh`H5FL7JpQ z*c$Sd$-aa$3f?7Rjnwzzd@M506}MsrJ45AMwtB^UY_s_tyney0sI`bYb>Q!K;I@IFmXcdyX8-`hZE z+~?Kx-6>@4sDBz-!YNlV#~WrAq&t8AQ9beWdN=d6xu3E%-CXsYlAo?FcH`{(yLDP< zTPsh0wN7g?RxOP|+NuV2!T<)cBLb%%N?>j`_Gc#`n@AzNXgjM(7XUtY4cpz8wr zOKp=J@)o?G(Y7N7U8HOnL;>CgY#9umjCuX=|28kNF^)y>UZ3wB9@C@8Pw03EePdO| z^5Nsh^k?7v79BHC^3qE$^XDsc%yQ}e;XYm8yg_5G8$4Pzwk~mLg?i^qdg9Fxph$BW zN372*vs^D89MekAT+}n_eCe}%3s7fs;{rY2-I4Wv0)waZjRYx3f7RTs9*y~ZQT8H| zcT|;nE%=#GXI@P*+Gdb zLDgAxubbn6(V4^fIjaCrn32=G zoHoehPe(ge@-sV=k((oj+8#^#TpX z+MeptlDM-9`V`T>VmflNo2lz@)%_8?P<#UaG3r+`!+xkSWpr zCLS_aa2Dbuzz0HqJT%BFUn{U82ew(DqygfQGSFwOBcyKdnqd$?1X1Zt^-zJA4(f=% zd#tecH?~+PInvdR#cqpDK$FUZH7;-bMbJSHC!iAoFOEQrwoWpbeMS20EO-icylF1rqcjA2qK;nQ2?T) zD_5vGIuVdYyj|d-gnmYQte?@I!R7@Et0HN$2 zT-C2$|Eu)Fx8J6}{dazk58H~Z9>)yIOn5Ap>B_aM^xX3o>62Surtf{{FX&5ey~T&; z65YDV;0ptD>+4&5K-RR({c!)@r}W^?9lChwA}#T_EG_kDWBr0C8JGwISZTRkD||Rl zp)?ewSWU2aCz$sFhOzbZ_=L+_rc*bdv?SCQgD+?cgi3sy1R_d8cbb#pF*Cni(cHR|AXWsk_*K>h7gVEo;H2j} zeN(th(`j?B?4|EZw>T4}a8xlWnSuf3WNP6#xquh#J_ntAtZSXStuX=KU#W-dTI8uJiWuwoKDiFBEb#t1!<~;1+4S$UImZkYC}M z4zIOo6wnX<0O}(Q0U&Fi@C>W#RAtKL04(9)%-DAjkX25QgaOt@O z@P<0hwk`hVB#-`eNrt(AL+nnp1W&uk^fXRrA!V0U@aMfO_%hKHMwvJ#yxi zdX|ZiAlsutTW-qFyVxwW)7Pz?bGGTHci~3@()@j)Eh`qmjWX81p<8~Sb3Jj=G?-t% z{CNj`yImf$|FrI>yz82At7CKirT5J26S4D_&bKjATc_}Hn!mg9TFB*(On>OUd!8{g z2W0ZkeICvOa=a{;E27LXQ_{t|!uVXI;|d*2`Mc20sYHpdbfAhx83qs|D4PgAYC&~? z1^)ygwXmLG0*m~_<0xlphd^y%L=>8^C3Blo&l!Z}49KluQjP%&!uKMfHUj|ygy%%s zkZm-kqzgjM8{|azTGSOS3Qvs1h>JD27O$YPKS;bfT?H}$N?3%p!GxanCqNAe;W6Mu z!fT|SY88?p0f;fx*!Yozj_C$dGXM}L%F`lkgWw1yy(rbC(Bj5}^wARa0h|H!7>{IQ zckdwY&*&jyhV}_y!V0`he$;1NsMKUYkMjjpqiGuNCL?p*+#j9x~-w8($gB1W~ z#M1`hUzlgMzeCll%6gU9sv@g55VJRZwy zY~d(nzJ2iFhxCo#{Y~kQ%?lUB`vxImN8k?Pengz`27^r>fB1n|3V@GX|3A8qq?$t>lg#+oU z8cSjVL4qnw?ztPSPWZhvWl=nAV&}%xs3B#~CxfnmLOoq7TOR^k zL=pgGX{i)hFY@nWc&77n12zOshR5Qq3{PaX&$1lcm*01G9?@f#3%9nn1+01TmFHPD z8`93b2eiDrtOm;QkRI~i&)s;QK4MvLu(nRClbZGpPiTyH7d@HFbyVXgwYpd)}Y z6Qy@JfVcO9`?Q3*aAo@}mqHGmOe<-V7STlaJ;Vt=mYUDS{emP@Ei)P=M0c6~u zK@9*S^=lQo_&j!fltRdq@1_kZS2ugDd`=CR5~6!kWFFapOp&Gr)WDo#J*Y0Iqol_M zOo@vbXYzAg>(Lk_>KstZ>T3da>l|x-#`apX&*D#bhQ}G;Bs8F2ChO-IpJFb-j=3lX zn9j^<|8-`6#hLqa(5bnn``!G%=Uy3-bK3od%OC!Cm^CD-XH@4b%YYj^(+i>qD|q1E z779)V4VCZ*1*A}~5&;%~R-;q{V2b5_sRoSbqHsPzAK6sODuwI=(bUbcMZH%6vQcjtoN0) zRy|x1ixFee3acoRQipagwj;Y(5{)CXllSOdZi?j0i&)_McX;yz>LyI!4Yo6N0R z`?wNxAApL4P>mE^F)cR%D*%ynvKQn47&c*qECm|y2G5&113U!|5CKXk^>>;kwi@tm zc#_mk>Sc=?^@rD!c&6|NLd07l)N9%Jct+~+0xy=HTHWBm0$@kbc7&vGf=E&!LN zY*_%;k8dVIR@gJ5XbZ)GTQ|Ir!ZJvE2aJs|S_lwl(wA`+p>`C-v#GX_Du8A9Ctg1$ zoCZZ>q|Ws*h?&O<-Who?<_bc{5c1?}b@}phwEg@Idhw-~=tTx*u3g%u$M+x54}S0w z{SSZeZ)wQ&|FvKLWqSVQS7__%HQHn#Z+Gv2-v8i_>1$v8CE7n2()#+QxCQR=p$?+7 zwXJPY5I(+ji(Y;8bz0wCqK`g0l>T1@(KG+tdAP&iPfY^`mbSMp(s%#jTLgQ+2k*Z} z_xaGiaNz>I_WGMdYb(-sLk9K8*5z;u;@zN$89*lID=j|A?d(%^2 zrwMf3O?lR;ZU<2jTAQ}qU*`h$EHLx4xSqv(bHL&!DyQ|^&!#_4yHwHgLpQbnr2qMP z*4OFd?*dou+4AhJE&w#Y4o^GgU6HBz<8;t57av7b2s4#X;#>94PvIwGTy*ajYQl8{ z*eQC}v$hWrwe~Nf9E2p54}uDjbwk*{hINslm#{}uBs^q2 z7{Rg=mru<*yHz&LpIgu1IQ!hLpSS&RuEAkODVlle%yLe@a&M<>1!oFneJ)>K5YCk; ziKwjl;Sc)3iuoy)^99X#2i2Rl2oe(4h3y?>v!ukgDk# zlIy1XPHB75GV2xxCv0#uj><9D7bL$*=&NfQb(PhS!WLD|$8Ye;E)s`_T~YT6;lPA! z$oHsMr0xg4$LL^;S1-@Oy9fX zoOk5%rM+ODQcR%*wA+`hGKwN2)y3yAwsy;=&LIJ4{&n>8*^6IrOVBgN&Vvk)3Dqgy zE#YiQv9{%-}`qxQKA8`Og(%gv?gBVo+#Kr04@lZKvdzR)*$C#n^1a*XHpvU1(Xq`-8^K{ zq!$Z$b0By~jqte8v4SAt?E=)fpS(BlJhD5LwPr#Ra#{cpAndC(bY{Xzw{E`bDWf4r zwE#KdMvP4ip)MfVm6&@A+cAzBc@Mw0AJ)|q!w8V!3F0AF(JcHD-sQ3AWno0X4QZfe zlwvdzM7hra8`(6SmD~UheAkl@pJjD(gpjZ>0yE|7!82rJVGU4Z?ru@DLung(5}Fkz%149#EP7LCkw^{6UD z$d!XwHamcCL5O(k(L{hSykCiwW6JO)z!rls&H(^#s8DVyu*3Z}IZ^WE>1eE0$bL`Q zxho+rR&Yqh5C9Sw>$zXYVP62DTH=8V3yb2hhX)e>-CJIzu@Of12g`K0&p^xLJvzL& zOs?N@1y!IXOsp3r1c(Z<#m{mK_!=X#Cko8Nwye&v_n6f4Xw zAMQ7A-{v{9Cg4xaWp7=&N{1&?ag*J;bWw7BI?QWTD}K06OcN>!jR8wQvYjCzZ^Bwbfn%WzOC>7Rlt$&Z5(} zj?QjWF~%9mI9Y>h4Nc2G(~YM&+`zRk1KvC%K;yGqr)|V}{Xb6&t@l^{cT)C#23O1N z6+&Jj7tQ;mnEPBS6UWb)qVn^4%~eQ)omsi^PO&3!gj1hC>uOup=G7&1%ErI;8vaSI zmJl=N``Ro@jRi5gzg7=RF#zQ4h(^c~nhYTlY82E@rZIFjV&+UA6h(@w_wQ=6oK=;1 z_`1La%@Nk}L`)nc6v4|?c_SncNR&vCQM8Ow!WZmaRr9W7smqmUACD|^TuN3HGS}&h zTP9M*V-m7`ZDucDz*A-cqK*LlCG8b{5~v-MgtWO5?>$L%Mdbt_7#+98}hF3uapUxs3JVMOAWta zfMt1gAjujgm3qS9cgUFVU>=J62yT^1y|Q^u9<%Z8{)0!f^Z2pw{(+Bamkn?C*=RQC z4QLAQmp&Wv_yxxd%p5ULbHZ}$0r*~^SFn*5Kua`_{+f*QNhli_91;U$P>zpa_UfJ* zW&zxmPRAgI<3e>V=oi*K6MhH6vD}!dYu1dY2K+jh8Qo*RfQ*n06Xf7t*@RW<#$zC9 zLVnL!H@40qW$P_AYqqQGE^-xf`JZCa5nEt5C3xsmkfu@e!?~bC2yH;dy%=H!$Rxnn zLV$!u!Z_MObcnG5;!~X^asp+~p2w=gHf!R%I+BgK%YCwMR&@hr`2H8NzUiEaxfjn* zdYuKx_#CCVGE4ruRX!azvm-ih4$XSFYj&q`{8BY8di%#3H0waDe( zH2$8V^E~8&URi2tTPV#nE6?JkBH50DW(*ilG|e#t2awAemx_`hQA%O$o+a>7@DLa! zo8|I)$}u9qOH|jp295N4HS`4@97_5+6wm?S0myC3{)%`~04O-VeM_pba=X;A3&zNvMl{2zyv@f#LIGB zde&Y^8$B6OeK3(Rnj9WT{o&c;0Goqd0u&Wx`d!{-VLUdAU{U-Wr7l{qP(4%Y{Vv1DZuVCX1~J9vBgt7{sz#fP+{M&~w-dEQDmlZ;WR z<#3xZCX*v2NCrXkLk3b#Ha6(`bJys`^Dog-IiTI6J$mk?FEA)FqCfxUkLU^a!AI}B zO_N6t>C3xe}(?pKmDil{U82_9zFUUe(rfX9@Vsebi&}xBZ>@|+-H#Izy0t2 zTe^Dv1^R`zUJ#4TzyH&3(vQCT7j(eo{Q5WkI(^}dH$~X^<*$964`4p<5BB7+T3T8b zx7H_T3n zgr(3f(se4jY*!mMg-%t!av{KFk*nV?m9Hnu9OFumhl#ZagQ)`^coWa8Sk~9(|iv@(dFkV8=L(1wE7=!uU;HJ@J7lrHvm3D^e4ngNU_KDioY$2(oRg)F{ zWMDJ^F*j;ihxzzN4N-DWnr6R=1}H1op<85Qz1R8B?9aKvngbUtFZ@&iqR+l^-0wCk z*8%8R3?M1ysY=uVj_k(J1um#tR-9iGlYQmPh*=*PqLA*1lrnZ1%yX&&f1c-0b7Mwm z9NM2Z0A2oZNRcI}U6cW!**L~r4yPc|38DF*b;X#S(HThLc}UNG&x$CfcD)CR_@ct0~ygJU0Y9 zun;EjpWu0f%}CZE(oh*8qs8H1z={y-BCLfsyU~+7R3VcSE5ZO?N-ImeG2n#)#r*J) zrVJuTn&{x66H!1N^`a>S@m7H#7-LMmpi#{f?< zf<+-!wux4aP8g7x%1i^XZ&8(Leu)5PfEGT3=St0E0l*A1QaNvoj2Iq0Q9W#G6Mhi_ z1xEXFZB^2SyT#$~)-6fFJ=nfPtJkh_8^AR)GB2=Fz&HR{6YkTES6-#{mtKmedn8h zPTzU^ZF=vckLdAZKCH(TTT`a=$_rdJ19AWI|NBqr&;R^S>E_LA^sWE!r}W<2-=pi- zZ_w}lXMdlr@Vt5Z2XE7F|L*Tm!F_nJ_k>=5^9AXT|L`Z@qCft3e?Wij8^1%Bp1VNb z{15-0mU+%@UAjb9u3Y85nMxl%cl|0|++L=;cMlhE177TMOMJd*r0?53J;=^EoT^VJ^}?M<_Y7j72<>&cAX2`ezMpXdUuYmx0`hls+$P z+{@;$nH8qu)1RXMkzS|GMF(bbve@oD`8q!9a;`7^Jr{zS-_PR~dDfs--^+z7vSLF&&SBt|k` z3^_3Ea|t;p)FVweGh##F8`221tayc1+UnI74&}aBo42zoZ$-0i{oVzMTo=7k{}xKl ziZPPx6EKoRdtc+Ylbsvkj5VNb52my^XtfBKQhknl>9aZu7P;Ju%z>&dKr4Gfts*)u z>%t`ab}wH)5^|R9C7yxrtV_a+CRHk@`Ptp8&hDQmd7R;i(g4z>B+1}9jWz4ZQczF? zAdMJ9`TQBN4198;$tW<_K6vjv`o&-QRmsw{veqL+=N}!P(BaXc1QH^1QqARDym*BU zSq>et?70Fje93gw6XMlKTtr2%#+N4+~A=|eD6d&h={6ezgF)Lvh`yi zOx^WP(LGf5J1?)J{Oeu5XEx6z`HebZG@+xtpE<5^MqX^~Vj(7g!_cQw%d#ndYMqKx z07_jav+_s+p(u|W$>wlEt|;|&0=T-yj07wNZPS8#PZuokP2K^Sx~Nmy@0I~^PFodJ zYQUA?z@1f(o?<(k3&@;yFU{Liysu8bs{xX7c{_H>=#nGP?lXQyq;k_d&W$-$>&?x5 z4RG_UE&+JV!6BEae4mB>+yl@85Th{QBUL>6GUJP93i`q^p5~Il>s|}2J5Tp z{ejF!JXQdjq5&#O4#sWU+ER-EN=4tprLlI4YS4@emijxG*9^RG1oY}JNqTRBg%463 zz#DD@03q=d0?>uS2|^UwSx=0}Oojexs;TV&tcYijguUl8VLkyg60aA4 zCku z2C1VX&7j5oJJ{S}&~25DAKa(C58spe9bUgq_doqaz`ZyA%l{pZ=`n*{L$OkngHql# zWRUFelaHjV=YQj`iW}?muY7@CeCbu0CjeM(-@HxV`olk<@BPKMrQEN5<9FGrQq%W- z@I$)w<9DPk*I#~>zVSDIk6wLwi$3`1iLABfU)p5L%Nl+7?#J~04}V0TeDr~g>tJ=A zg#q0(R=IE2*1^VqOvB+s$cK-Q(f>pb@7<%zSD$Nd05p3vE}}d&3ZHIl^MDy~3(ggl zV%DR?)9-ak&o)k)Rdzyi=sjyiZ;@+ONT5^y{yeUE%Aj9A3y{X^(Gmhk1#7o_p9Ng~ zJOE2S>uVwJgX-*lYUYA^%*=u^F3_E?5H14Tc$xXT^E%|f&QJQTrrbCqEV?yP?gM-g zHM3w2=B7-pW+QfGNk2F23u<;%)A4>A|&ZhIgcN@zvYKD3Nf zS|7XTTyF?k2*4S#VMGMZo{}IdV8(_Yybs0}_m;``xDaOd<3L%4n9vfsm1OnV?Ju7v znDQ*II>t7zWtX={jH#7>cG`KDWd<`qCI|I!oj>k{jcbuTJNrz3uAI=mB>Pe%@isx# z0g6-%Rt#C51n?oAC+q9_O#fI$c@apb_|NOs6R<83=lCfYjN% zZqTktJ(a9Z_*}~4zB^%KrOL8>Iyl-Kt_JX&wwDb7%(dH)Pa;R zs|d&JJ2F7ytmWMWW~8dVH<%Zmdbs3@J7wUm0zuloX1~d=?wn7aGV+J6yViPf?At*A z@2f@5!Q9KSj&0)?DQHt?fP$A#S=*(JrUE8#i<-Zk6n+s<=1keGJy`9}y3a!g_i>0# zxLWH9=fCQ_&sy*FVnbuZaT%#eHX={7=8;#%_paEPJ6@*$Y^{q-M$SQ)NbT-+Z&5F& z2PGT4DNwp=^S;nf6(g48&yMfk6A~>61G0EdsXYJQXXO^44wP`s>a(P=lw&0zO;f}L z5NF&jQ;Sl0ChsI-+iI$Wy5Q%KOgjv!EHQ9VSqvor24pXi&?I<(z`LT<)YSkl1i%oc z@+yT4k$HOHS(J(TqpoA~(ty&Bl+VGkJe}-3lzWALh1BZ>0E2kT;NTiJVLbxKFc1UJ z4FzKm9`i)90~MPv$@Bz--?LF6H8l^Gv`K(3u-#+q;kg9h1z}qZCSh0y41(cjA-p)XlJqY1b;IGm z(NDMs^`fDnnG*5_@QG`8qVC-~;VU6jbE0SQ^x-k?qN zMcV%27ll`5wD(vtJ_Yc#Z~-R|AJFR68+5>B6exoyD^ii8zt$Om>GM2;x61$X|Mq_o zF!Oi+-anwrH*N@+w{h*7a1-s{yF)d9x4Lza-h2Oj+Pm{9)eKs#AS{W$|KP)qX=(M# zl0tFw;xc{k!Cm^3Kl&s3!~f5JO_wfTrQi9_{yts4a)s{Qxl7ldf05vgzR4DxI`-(n zgNNb*F2!0eT6x-$u_h|S%^mGkk1IW{^yI%1Ui0J zS8MF%2Pe*L2Eb1rB-?G;TB{psx%*}MELE*zXU zJV67sf~Zc5uY;}-)fUwAfA*3&?-hI^+B*X^;UOZ+kb%*Z%7xY2U7dw4jwIGw4JV4s zm{QcVJqMbmIHzD7s=#;ClXr+x7A@Ssde8eW6Ajy{k^EA&6bn^=lvGp{9EtCs#w&-& zLb{suFs|EPLr*ieVxXjSjmJY#tjl6qy#F+!E7<=_A#2r8m%K%kGQg?_Q})FvQ{d-p z6@P{+Z=C;r+Rxd0Vj3(9%QLxKeia3cWyxui{2>8@)F{6ao}R6n7D01Tq)t2g+x04n ze%f1d<*U`2BDCgMUQz}bX*gi*SwDHLF&Hsozyu-YMLEFR=+VO+8Zqc088lh0MaD{y z>aMP=QJ>|n`wt#4=yH|kbwLjv?$hDnk;u`I!_-5qq(_kZxWY(X4KI|@NWG=e4tTo^ zcpa~9Y)E=+ft*U?YqVOsrxMl?en(2{73eQ4^CGP_cx?Jhs{$TPxQ-fj9wZAJ)&`Wf zF|x8kj}httB?b3BsZF6Z%vYW(Z9`E2CyG2DLPsg4#(TKxC!{uzyV0&9UTBeLNBU=+0q3mFJO}Kr7k=l}_daP>&8lc3B zrKw)$dj^t189XOYxO)k3v1hrQDQ~8t!1o4RCkI=a%urCihrGE?4)+Jj-JV5Of9kCkW)ye|8D;tABaud4v2*^@>}q{|=_vLXTSQbOK=2!YcHj~(9w&K`Jm z1n&RU>(9%$A>0df)fDR7hkJY6pGYN+RG*q!)YHm&h!S{Q`aCZ%A3)G79!>DB!YNQ0 z@u7VN;7JIJ&GOL`HvPUFn6QTM=_SXA>>tMOqb{pcS!6wK&v<`lYY@BK^j1{1wYI0zqNKz+8`x4-RN;b5q_6@1@F#tAVHU z?>%H0qw}wM?t=3+uh#F`;pRV_6pbi$%C+Z;g65u1c2GafrZ{_V^Irdck@89lN64Sc zy;Yv>TI}?VvF`M(g$9kK65EP`#JoEZUJl3@I?E6bW#ZJw=F7 z^lMdSLaTmKW1mWe3Djvll6sQVPJ*e#jA9`!00iU&qLwKPeH9yVvJwv;7l0du#b2xz zQ~kS)!Mt#6-k<`e1of8LlFy1_0b^3EEW;29N1c#Gl97*^HyN_R$e4Ko1Y1jzc%TP< z3EWqS$CQ?3M8yUKr4F#4*-W$g^_qUNds=FOculCG0-2!@o*`Z=<{=3=LJT<8=M6^Q zp3}I>f$< z07X@2R%<)UCOqfH$e_t%Jz$vv#Qc-7h8lZloP?+uStsf(-d09OG9GdNAj2gRQNa6S zWy!3$HJuzB2{%u#za-%~xbRFRVcoU#?_`Yk_C-pXOvmyr811AS?mwi9Zq27OUx+lc zqG`2T`deo>X;vWewcEMWGYt=!ce8ka6|MC2%`A*ErU(I)wD7j>A(P`L(nc>W_2}e? z<-vL^dvsxjHMC>@$pP)|K9)UTZ~us{zxXm8oQ!Di$rB;wU0Yk1#0prK$Wpn)Mp}Ho z&!EVFL7C$buSd8}YAd2ksR9nb_IQzyV0ophD#PvY%@xre3RQxE=-w)SiV;yp2@BqO!; zUm3_UELoV0jSzf|*P4aWSslNhzDzeBucGg64SwQ#07^3NZ*$NL?{iu-#E0-I*k5I=91VOK- z{UG&Y-hX=T#_W4-p6>5N&0e1K%C$UGLrA=4ZSFZrXTErj&7o?Dr+`jE&Y$Z=_7m+@ z9<_>=;CxXySv1*^&U=LD9XgA9viY#G3J^pphy$VrR`8yZ_5!^HSBY#$nlc$46qjCl ziMEk0nh%hDw$$H+s~#(@(~~3VD0tu0Mi5N3@_C5JTK0`3R~cu#$nK_~%3&pd zPgz&?u1bK1f&r$AG&_(Ihm}T(ObT-Jl=xSIYXy|i%?$klVW*PMY6Dt=5Cm(#t_#S5 zI-D@rG-hyRfUzr@4G*3=9@-@n4548RF7y~s>Y2w0JZb9jl$7c|h*A*E6DgDih6P=$ z5^FE@Cjo=vL;)&ohms|y<;@Qv1>wX(jCvAg){`+1a0~*@#f#E*?-Kwr8s1b$*|Kp8 zne&Q%7D+g9dSOigD$*=aMctzzTS#i~-7t`aaR4}nYqH1dfalukwJk_GN;nLVuGGvC z=wkuExSk+C-hAT?T0#o#{S&shobaK)LN{K0MTD{2ckj~4gNGEC72G-wk7PZ){FPs# z7hbq7)|(&x=!bOc=6iJa<6HDM{?>2P+VTdi4EP^gQI@z)D{HHC$d;ae_eXz9+n1lC z|NlS!f6<%2{&jl!3(wQ~#tI!B9AZ18O&0v76Lod<)bW+MP-@1GS`Kyy5%u`IOb7YZ zK5|+>Oc76gDz=pC`C!OAl={?KEC49XFQ-wy7QMn}w35s($BztJs7yaNl0tq?yK_X| zN}#8x;;H2=e9w%aIRE)1Y-EphU7!76?LK+xl_~8{bG0o>vwfV`hbXkbfkoccfQgxK z8#~s#bH^wq4~(v`n>;qWj9_APp+Z+}>#bI;)hwos^{4fgOz1nmMlM^0BxH%|i%`be zz=AV-D5Nr6nTy6$+qkfs&?$gLCRiq*BqU+UdP&bu2$+SoS(JgyJ$a@UmI0%JXL^?V*+!|~RG3GfOXx6U5HXLdF{HM8Hgp%wkaMNm<5Hhw9Hj?74$qs*oe2&3@$M?`?t@nrk_H_ zbwh@Y7-)hsX{y;f>!|hX30H`QXbDe7U5Xct_(dc@FbY5=&&qkGUMg(03BU znrvV6b)B6THh0|v16MWG3|;uFjJ87ozyugm>31p$H+7$yVFnq8)Q;EO*WS%yww1@U zPU`4$#@g<6^*#%21wBC%p;7Jqj_7+)8PEK*TVxp5;HCwWe>Bu!&pJYyc?6+$LdlgsNMvMfU>EGIM2!?G;O z8DSi21!qM!Fo0UU)9N%v&3rC2Gikp`F58SH4erNLOw3$^kB^O~-4zwrGl0|EDv>{@WbKX$$TGIS$x) zKes{XknSr|q0QU8SWl%M^7>MKI$HCK&?=%U`}w%Wb|+cALmK}$ClgjapQr;6$tju6 z3MIw%b~RqW?Mpb#DqVw=o&S`{Tp>SOL)#N(2ApX%DKsZyz8^$N@`j*^Jd`9l7S8Jf`BChS&%?f#Y*n#g)MsS@)cTRkY$QDvNC)7+ux+& z?k-#8HIxOwj`En47W&S>0b4<$q}Hx&L~Y{&C@|=2NDPH^2$H3smca)2AdQN87#R-? zo{@!!i6!1Uy_7AeG*1ifPyjWaaVX038WtmhmdBO_&6ptREaipm%u$gA7VzLW*N*IH z01FUfY8*HC8{QcjK4ijCHBCG;Iyyz-&5_Je;_1S5fTxIg+rUeS0>YJg4VkiAY)TbE zB~%K3dyIJB$#<1>OhUhq;R$~)Gk^pjf~^KprV#-Ps%S*XRXI%FDg_y#Tdi)H0JN0o zd1@0*n-b0Q3EoJO@~_{wCYBZ!R*GkkglUPVO=*ij+XTP|z*k{BJQAjLq#qlvQ7R1X6NaL@ zW$EHJ*Y7Izw=dEj3lw*6enczWu9vPoN7t^sNE@pgw8VhupvV2h|JLgb9^*&!&;P|g zr<38BmKh-Y;#sX|ZAmzg*hgS%oQ(2@O4o#|VIjt5;P)D~{tjFboy)q6E6 zFjebWD?mw6%yyBVS0;g{vReHcl?*k6OcAorU8qlrgi$-XK-e^Q{#-Jd$HAbMH8~fq zL&z!>C=G0AD-!x}Y}GZkUzPzU-d_D&Ey1J!63&UBUMujzkWppX4%U8v3=+mv$4vP& zuLb@$tr{{{SL6(ROLY{1xwbmV$C_%^$5!;h+QqG+30I2xPQ0VC@NfJ+9x0ayJBc@+@z~_Ro6bf3UFMJ^V+hSy*7^-NLf{dDRL-l&phJx%7V{IK z#VETpkVq}Ab*qmOzkmP&(G<|aKnmps1ZN*!4gd(=BRId^lCAcii0Geq?jbHQJ<%>%4IJs<1h(9vS*f&t&4rvK@dA zc)7qkC?sB*Lc)O#4-XhrQJx}zV`J{4oku%#$nwubjAylk9#L(invlIQXIcIn30O6x zBar!WS-1~lP?}M)PHWBPlE(=}t9Q|GV#ExfC0D*|LrLFYZ53Gty`Vf6pl7JafV4Vh zduTf}EVRa@z1GS4GX0EQuQ@Ft*ji}5vG>Jj`nuj*r2Qz{bJG2k=B_Kc?P`S9?`_bd zQ{VjIh2+g9gwzcmA+7fAd7k%Or|iz$&t*;rUUE5XZd>fi4K_35k$o3v_IV#~UkhEs zOCvwd2|MbH8MQ|IbO9!$^*sAs=LnwrSsf_@O0=v5kXeQ>2P4uuTXSGeUo~H)zR33o z{n05igwu~!%H~4o8V-JfD_dJJuSZsJohLgYvh&Dv6T2s$uQ+2plrCm6L@$`Pfmpun z#iFQ-D^4MyJq3thOZ6H6#|gYo4tE~WF28c+>NR@q%5!wgsPF!*TeSP>Et-smqWqSU z)>+eHYdv|RWMxzoa|VC_KtOSo%t(X2cy@?q2_H(eWqFE2*|yBxD=PR=sW(88BWdQY z>Y&GHyr(I(p^RE6iKNFC!r)`|f)LMwS`TOl7M5vAvN#DiFi=p0Y%@1iEGh5c!r4A2f}f1Keq#QmFIBi!d20-4EY8r zhZ)LrVF(zzzh`A7@$6IvRDk~nUK(U6{Gx$U(c2c)iw9}F9o#{Eq^%PE#nuK88w;ti zc^~B&d4hW)^~^KI1TTz(kU|fd%w8k9SC%Qt1ue}OcHE@J=6b-(YrxU&9e^MrzRk zQFQ33rEz++CVhJQqmSrQo+F!E+Y+XAfq}{auNM$21H{Do5gr?!@5suvbL$h@dvKTM zdm-=Lx_FVFy+n8J?9$6G4rq00jbA&IdAEJ}G7HKZw6U>4fA+`!Kf3XS*XW4r^wCGR zMR>V!{jva3M<7v@j0B~)eHQ}iltQ$NtWINb(eH^Mxd`AAf8rf%PMLnFhql+i3=orD zXMHzwuZKn2?Kz^IZP)bkd4)_a`7Cuj>mdI5Y;#^OA1j|D&%VyhJm?Brr{0>~6FSPr zPjX?T&L=?(NtkoNSOie7MzX3mN_Z|SHE*)dGU4WF*LLoOrFDwwcbB9*lS3*yQ^vdP zO6xE-LSi;L%{yaTmLtAF#+4Bw5u}ko`L9qI@J|d zYO1c`5?as36ojwfJS)puxH<&EK^R2*-Jv% ziIQ@unSy*CH`aMv0J)Y1%AEp_Uy)__Z#+95d*-tsJe1&LnM`Z>H=1g~3xok3939bc za)*vVo4_(GJZDaZC+c0#G97+Dg17o0(&N3y0*D+9kA*n6Hdzuiotgo-dp;?jAtfL( z|1QR}RAEbnYvp<03(z*zXo0!~c2b71%wNxK+2;H!zcpr?VT^G`Sxx0S=tA9R7nH{` znI`RvS-bqaKkrOxff1d0=7t=~rsCXpEpYDnT2~;pBPX2I-JP=a`P?mO&LjExoc%9- z=Z~g+bN;(11UhRfgzg|x)2HqFw10MgpZP4EpP}{nys{fHytAh4vylIte?D)_Og5l% z=6@seG>^2}k$|toudaBIzo%PvSI(66pMf(W2cM$u&+bi#oli5^n5PMO76r46Aj}0J zAplRDTLuTgBUW}#o;;Sg<7IySGApDneeo??W~Ke{-A`%E8(}dp?+>AYx4}ygA%E(Jzl$v z=FSA=UA!Gi2~Cnz)d=^H2NcYaa=>3=hcm)wtfw2Ri=&`czJLKlDcmJlZGyR2nb!=$ zio`=iLaYWFW>hL68xG=XJP}V3PYqsK{Idc_wS+$P5dK4!Iiap>?S^zXOQ;zHEVDRB zp8$BUP%VHeOWPNP_s0)@wKOXEacy2q^8T>`3en4VWgOQ$Y!q@%GA6rpr4q z_oPi@*(AZCv&5i@SVMSR;UOmBULYxkKrlX*XO^y95zZnPE~m#Qnu=XKrh2jta6fp0 zH0}2jI^us@FTPC2Cque-@4n2f9>C4>vZA5s<`j& zKRKqWS1z-KQ-u?Fg&}peTQ3Cw6l-EB0?Uf5_0Q)zFVl)=Y&kE}(;`=cj(g$M+CdjR zn4fZ={)w*~IP$|k(Bc9YE=_NHR@py)*Q{l0j$7zrNr4u)QaYZN5Z699i*$e|MLJOH z`{{JC(7(JLIoKpM35(9>Mi}h=lzpkD1?IDYv0|AKK+c)bx$grbED13ybuf?Zb>&ZWMF8u>HwoXLY#d$ZMcWObI%Czooi zdNPgue2?n=Tv_I-l0l(<(Np5nk`$dOi=^Ob2$6;$O{WT!z<5$k#{vPsxCBC5a2CpJ zK)aAI07k1q`B&;nh5ORwB$HPJ7{U1tgNlJ9HH=DG|7o8o|4Eg3-8k5QIU~Rg8x@yV z3L$W=CYCG$vJ^ybGVUIDYG?#Yde-M3fFJBTxTh>v(^}O87Bw{KP2S)Cx z6P`j5N#V)(QKucTRlm85>l@4R{XX(kGx)c>qMREi zhb$8>^&~SA#$lJ`tSQhj2Czm5Kbo8f*mTIC%o2|$$`VN zkJVS0D|s>=%4&ohi}@wv$^G0DPa_9FV{2aI{apJ#5Zik~0wd}=DRRD6-7~Oq&#$7$ zcq{A-%(yzvJuX7CH$_L5TMDo5J)yO~CmonhQ+(&VtF?d34+{zT*_rCrsOai_c>ovK8Ddk z=ODMw%5ZKLh(vK7c-S6$S*y0s5jAs@vUzYeq?otM-|sbP03m6^X=T}-?Z%UCKYBP* z%AD8XdGWD1e=#(DkN*}P3mn?@T;!SuzT~rb-aK?qyS#lZgM^(KIVhft0scL>s*v>t zN~wk|>4xT99rzsK7T7$IK6uPZtXSY#fgY@GNl3{NE1VDR-D4o5rmwOk|KO#U=!ft9 zi0<6{h!3P=@qVeRkrKJGG7E(?N*d{X6?*L8s7&bv87s(jh3IvuZy_p$PE_z=RLUs> zWgY~>=xqrH@`0VIbpyZy8BwA4#2~xZ+9<=ORnvEd#}U2oH-W_busiveeY#Nh0?fs8SRX8YV&qTr*K82Crn$ z5NdOBsG&cFx@>BSa!RqS@;>tnszDYfd^&}MF985TJg$0=9BF@N2c%@Q67XhXvE-%x zvrr;{3cZzeIiNxI3y&wyq{V|oU5M2^mZaVNW%(T(H9{taap_xDD4UEJFU%F;6avQ! zgBswN0g!>W^w!ptm>6IS!nNS>Bm~S8nICW|1(B_Iy+n=S7sBL(s%j`3!g_qX@STtg zL*PMZmGIQ`l+T7#V6QCYIe27*@C@^KbS%%J4+dMCwE4zW$+C3m;w2f|yLax=+NCQr zoeb+iLdlR`JR*(teY!urOEHaD z-=`05ek^Tz@r^Iin{U2Bzxmr=6Jo~q-@ir6{X#fuPL75mKrbz?3PIce`yj zk6u~QBB@J#uAhGoEp(+#Dji0)p%pZHC{p{N|EyO1dCGA9{n_=UXLK!IkRQmo0Pr-I z2;4=tFMoE|Li306gNc$*+PbHFHtndZdPb3$v1AnG?Dwt1yjUnb@a(wH&gbG>pwV63 zDG8||Np>WvelTtfD_BE%Eet@~Y%FpPs;H1g>HbDrApPD-&VdCeW~w8U$taPvDhW!i z^iu-7X2&wWg5MJKr`IcS%b3vIax14Mu3e&(vhwsCj)uL}!mU;aKy$iBfLps=&}_P9 z)_Po)`S+QC<~k7ngVkHlooLFad)A;vMb@sS&I-Ud`DUeOmVp@-5#J0EJ~a~C#%If(>A`6lxZrx zGgu6LO&b1Dk}DGKNfUyNpO69v89RU$6L>O9$ccuAFM|U_$oGRd0E^HsJbw726mMVD z8lflfoZyp|&rSwXs5H<;!+Y>ftnYqA2yZ1k766u}St?X_BcEC_haMaIMiT{P%DN{W zD7}6Zua~HkLb3rN^N)Mwq!1=E%Bf6PX&Ap4*%Y`bed5(*WRn&5?^4r8wT`1J?kE@G z$BCQ9l&?l_!1p{V^q}0gV zMj{O1T8!c?G#rj;NoWtEWL7$4`EUEmn)JzVQqf(OnN~Kp;D{_h%n{3?%WOCv!_x=_ zdPp4*;wecOlca&*`2x8QKn;vdq_1kB92>ILLK^**7~!5aV9Q8+`U zG&`8pdM#|#2)H8K^3bAUjOU5}+6Ta2!2tIXES0ne_8f4#}!fpMeM>a|d)+n{(afCPt?(1VXZ zF;GLZ;q-Y^y!^@+==p2cX@iyLK2O%+qdi*XL-cq$l61s}w{A*CAOJY>V#J1SZqgb* zJKB9r!<~l$ybQLs1bC?=lXxgCR zi+ce{rYjYoq$;&%)Up_J3wuJ}2-qb83@P7`l_~2QmJL3PWqw)zp$^!0#G}fT69G$v zC~>MkE%ZqavVn$06_QGDB8P1>_fQX01E_d->l5zNbq0a9r96Ou@OW9ec#)RjMFY~f z-CYgYay6h*g-5-!U{za_wA!1m{S}$(_-@R7dh?wh(lG;+Afvwg%U`3D`}brHt~__0 zYGl0PF_dgx+|Nh%?uwV#`YW%{op;`$FTC{?xckt_$%t;>`jo3()9YV+lYZ^jzeekq zE^^uL)9?KC-=i=8!dsG+>HF{ffHu}v>CLbI2JIi5$e3?$I=!u7%=h-uY8Gz@OrZi?|I?F>^RI&+D9{ zV!`psxF+RC3v?*xJg=qC`Uh@52FFb%2}muC_&} zna{;}~B?*(Yh-A zG!L{Suvz!`{uHgwdh|84uu^W(c=J&9xd?=w-X(ob7V+iERY8s7TepRMq8Vi<2cLbd zi+4wrw==fuXI1cL6&r~ec);>UWqUM%=R^UaJXEbV5>iPH5#8FEk6U|=q?r4t9u$@N zYga~~KZ5t_bYgrgrG$7?ah3YjK*?<7`BDjy#k-}K&I@F=LOApoi4gc_9Z~}+c?s}4 zp}2=wN?GptCWbVGW*PsQ^iQ8sCYBhdssA0o?V-QGF9+k9aTmo{r(rEc(TFKSlzOfd zX`KpRP4EmwrO2O7_$qx>HG2oj9}JdS^GFPir{pJ3dqA?>)@godsMgu*w3Z>ZMW6#l z`J(KeRYWuwl#vyOby}#*DA~5Og3?bKwxi+qN5^A2X4&+B)YmzD~YLp>Uc_vDebckkfbrMn?2LHnbg1=nytXzl?Y)y9epR< ztmTc8T`|t~e+W5X66cRm-nJN%$3tFTVV-{(D|=E-pZbcrucA!B&C~vtow?Xo>LPjI zxjfeeMeLUrsL_5G&14B{dCqj}<;KF;23ZpCPxsw4dk$*58iM9|;E0FTCZlED1}hTL zu-DlDz4ThUzs?AiV|Ir5S=q=rA+_Dl3?I)$#cKtFX3tM~x6QG(;U;@;_7c(kvU&x3 z-YF`S3#%hPyDVkxtk0;l_j$7xo4Rym>_xBE>IvbL{f=5?cl96jYV@_;fcQzKvU___ z{1J003M~{zQg0J?NjWQ#4NMSMH_*e#a26$i|?@H5z1ID;MB>#0#&KblG zONOSg66Fe@FjYWA_)aVg3!D7G#~(=+pTUI-5;}yG&j3&W;J|YMJpe@(N<2Ui04~C_ z(pwUOyTT_3;(-AG@pBL!FnNkzYy?{z?kLBIY(a8sy{_M}paDPv+$Mcw58C1b7(6e1 zo0#Zl{1_^a2!IX=-wH+Y$_WVZ60enkrN}E%_94k;gfJ}Qpg{`2;e!X#Pw>zIs3U2U z`M`6KgnVJv9s;GLw(89>Oq@9<4<9g4wJNOj07sDKS$Jl6v*>Sb2>62()C7(ivW?7L zJzeO>*n>VclzWyeiJlNqj zuh>c~Y`k=XuQA>%yzPGPyL{h$$!vA~7rshcZ+@AUWc&-d&wcmkd*9)8bCChS2jXo5 zplQIsG}&VC=f%My+KkqE@bV0cGqd%ISwxR)kU83>uG_cc?bBS<;;=+=YKzYV52#RbL(S# zsslp-j3SlSF8_Q*`B`5Jjn}#NJ-d1XAZx!XbU>?+2?4<}^q8BeXU?Gc;Lhpqj7e#l z5!x0>9bMIy-kCCslLId5YTvWN%kpVI1)vvxu}ZVg zS-3`4;RGO1dQ+H-iFWnK7AOTEg*fW7&Qq79M zO9s41w1j0pXx>$O|L{HIX%>286;ex^3X-be)h*>I7;lKk5Y|`j*rXzQKCzpzP ze98JYP}(On?DK4323VZnLIwhO=fqau7vf<>Ws$NMiHC=^5$9}Q6zQm7i!BjUuP=tY zLOe%msvAMM?znHmcmi1u`Ex><2 z%`!CL%rvS8t{SPTG!F{P1nQS&_{cI!**^(o0!R>iept4cphmAL0Jca10*Rs2IZZr+ zhXG@rQnvOCKEYFdV-Bjk?uMmBPqE+`-5lJaS)jUgwU(l%hpkh{l7q*R#=FwA@EEWC z{l~Piu}McfzV~+SQ`jwOYx|PyGf!9sy8U2G+t&v4@h3OwF@rW0k0X{g`1LSG2Pelu zxC}0#dNP!EOhqmq84!y)4`pn70^URgOr>usndg`>O2}DI9_CX>I_M&KPn2PXWD zl=j8MFGfV&?$P&k0EHOmoQ-v=d-{yJ-ZG?pW$1-1Y3ge6$(x3v0mjakX8m1ggh%7q z((I|)q|B&t>X?VtAj_S(%pGaLnbNeCTK$qOc-z-oa#gD;`5~Qo+mM~?(LT5LG)HYV zXR>p}L5#Lkm%pw7WE@19CsRKaFcaGHTvvXr>NaeU`fO&u-ZNNE6v z4imU&ru6}Z!+l!1prJ_;k^|kg8l;0z!;j!GvaADQ?w{}^f#NS=Q$~2JfJH4HB9qa` zEDE88vh^=)YUquG1C7*!Ww4~)AqGGQaV!8K2nS;&)RjXU*_X^Byn5}rW;cQ-h@4d# zmygf-OUkhm*Cs|{Tr0=RWGuo6`Uo2sKnc_Vyebp!CxAghNL&>5+*I7Q5hCN+qG~6( z%@m9%AxatoCKI7hqG2HgMjMQSM)-vwe3eQ{E2*t*hr!rQ_V@S}2DK{l{;`EcCMZZB z!di1ui6={MeT@Z$z8+$*h?#d0uC*6l;<>@#1%r3J)fF0SF$lQ2Cifr%7yzaI#sx`p z9g)qcpO%%BHIb085d(XVxE*~7O+zS@@EM_Qp6;7BXLxE!MyHikI=X#}CJY7&-wXqc zm_Pdrjz~zB7-V`)RxS)1;*<|T5Ih#Z4WJ?b7P!$qVUVUqy73F!w9lZ(3b<)_oa)CD z-M^4ILegnJNnvph_y1h#^1+|}3B7jxd3xg)UZx9|w`u1w+EmdV3nBmPzxl@u-h7F^ z`m4WAS1)bTxBl(FqT=L$roZ`XG`2(j@URl#1z8E6aC?s60mp~h`g)&EP8je!8A@OE z7UXC-|5~J+QvjKGwuMEFFoB-#$jCO>c*b`>r&rr!;pxXH_33AO{PVv$2*FvP+_Qf1 zys6g`G{}`-7v4>DSODN^AJ{5hC;*-b+2K6Fwr(j-ejerJQ|Eg-`dbRPeQDn`zk5<- zTBN`2nLe_-O`Cd5t7%JcZ@u%3s|5;Bd%EV|^UU- zE~0c9xIxWPC@HM-Z6p7ez=>Q~?+EU#-_5gvI)LBYD-d-pcP*9HLxZ1k51e^TIDMF< zKP=Q*cvURK#06OO(y&^w_F1R0R0;s^3xaqiQ@dZ<-?qHECzBPL(u7O@M$f9G>7^ml zDGXVNvWcZ2I5|IONwJV_10!sYq zvHV%rO$d>Do#Y@mo<}`;?%9LzCzC}}`-vLx1xmexnn3{=DEP>(=p1Wh8UqEGP>0E+ zM}2tw5;c}!$$-@e_IaP@w%lNgA{2}6v+>+BB%Jc079CpP3|U?EcS|V_&;+4y+~$W5 zAF*+FQ^M5fG_9LOl8wKKujGoY@3FPd=WfHp{C-IuCf>8L>0i%2 z6>MJ%IRHy%$wy}oPFO$yIIW1ebHnP>^01h9(}GuwvkG*2PX|Pxc)IL1v;Q`KWy*Y< z+aIU(k%J-vZe~D;gCH@S-LBbp#8clx`QD6nW++JlT71Fh_j&vD@SR_Nm?P(e=DT_I zJ@4{&CecDGtpHjA<7efKR-4Jd3(we>0Tp?My3_Wl)b6t?9~PgBpXCa+Uvz7bLXsqj{jY@Vbf778RiRcd7{p;hDehmmV8O+DXiEst(E%Mj+My?( z-l9)_@O`@ZqaV<<*I%ROUVfQ3)E;eJ-lUgae~ES5b-MfBd+JI#(XbPE%WS^#Dy^{+ zD(ReA5gzl#dhqdwO@&374weF04}9^`DNEbaf`lD~tWi*sr=rxa%4hJJ@YK?^6Tl+t z5rZ28@RJPsO7beK_eMA>kSC)+(L21Y7A0P($}kb(>ZjUATF zOWv;;t!k@>hKuzDJdxDoq+Bt0r+5@G;33{d45CaJ_!~WXqyQJfxk_~h2k(psTRjbF zlQEfSdTx01VAJfu!^J=-dM9MT%kXHS2MYcS}mo4aj@A{1IyF0{8Y&cMb7yvl{#W)==8rJv1PvXx=~L^NmFX__=eKpX?u%S!Dw)Molv6Zr-qw}v z`BXeRkVZiMkh|^A_EFbkDYOJcpUdg)InOoawbz8Vr)d72KQz?GUP&295dCLN)>@of zVy%q^m7DVEtN>M1i|*W4gl2xK_1XzmOIhFj{vhpzqO_aGfm`v#YAyugno&Rq>Pk0` zm@FY=r?n}om02p4fZoGrRfj80iPifnvFI!Rms*yUEFXK2WIN>V_t>}su}-o(@;d>* zobcIjgaibV>UJdI4@Z2?AX5*{#6B{*aGgdBb|Wn=JSVW{Kt2SKs05E_M@qjUBnDYr zJnN5o%}j+*y^_A_>scFACV|rJ8FXqRX%zueLPvG4EzCv7bl29P<6aQeinR>&?Q7U6 zDkGdF6wjEmMQe`1$g~7bJ^)hA`%)B^UV3UIlCFHVC#3l#={acGi(G~f9vasL(9R0y zgU*fKK*tf|HLdCdq+vV&{!By=S1%9D38b~wtVB`yT|!~!iqExD>Y?*pLxYxKOey;5 z9C5-`_fjF5i&g7P(lak6Fhfa>>ueqx_lWR`=-E82)ng{w{l=}G)}eqxNEr@5#?B{P zs58!F-`f;)>8H9gqtep2P!< z>o}a$vW_t>k9MEX78`ay`0!(T^n~R;{_cq9?~uzHPHW+d8S^~*^wT^1v*LB32{O=U zwE#0qDI-=<}Z z-C08LFkaLs_0FwRWMPQSCg5idrGutf+wHZUZfwaS%^BtAXKQbuS@60k&p_zPJWA8p z+doHU&jE5m_IoSCR|Yh+&P$qA+P$y*^7WYHgw}iQIVS}n=Rj+F8?_Yt_L6CTmUU(B z9n=7BvmKyq(mqmP+xknYQ#YWJ;T66oNZWkB@%=P5fP`men`yiK?R`{LRST5$amD@) z5O<07pV3GSz;ZsBS6^kGiRil(HcryIK$UXdYA-D4u13by!t zsc%C_z$L}l0x@v)I$=<$&iUUNfa9OF`YV6N>uaAS50=;==e6(KS^HuNGjBjI(@*mE zXZ=yQTunGU4(==n3CU1;EqfJD@P6@v>AfpvJu^RSd~2sp`-|wDau@J z1LX&}vG?O370_s;n-7-*!Zf5^M#|^WlikLvCR&PZSF+9P2!M|$_(q@%4;CRQ9;6j% z94=9bj4_rySYoHr=KxmlEr2_KNt&r)st2Q`PWLtxW=)FYNdjizqFv*6_j-{zUP^cp zyqqGyH?HS|fkp**rXoBEuoP{Rb@FB-r-nrk-dnO55dt`w%3NCB+@d~jauv4$o(WIUveoF`&JNwY^C=y2owl#tpby@8pLQ=@ zrWc=oo-Q&-dYRW02$b*Ldq_XHdz;?+$}dWI-|}jYg_qm3zP>?A%WL%T{v#HYPU!lL z=U51Kfl%kAZ|D%Dq+Vr_HbQs3mTA)7D8iEh))}u}*6aSK-+mFjp&8Vni6k-Y}V_a~0qKl)Zk>LR+TV z_FzD20(E;zo(ZFlC`|krK->v{4J#WN_2m3CW!sfRAEV07fq{X+Qu9KUsi~b4Q1TAh z_yB5Dg#KzO-3g8OYyep-nSiNY36+F0^(K7xSiL|&APObF&$7x2GSvw;T`heq%CCT3 z0JkSJ9G%cIpA&uC{{@tRA;#)6=&QkE1)OHVc`|f=65&)Zn8NxcNTwjP1qz!hXA0ox zISnujB(-B9=^seHc>m)5USHD&cV<-kuN1ygs@E+woE~ys0T{3lx{v^E1szbM(iBGl zZmK$sPvuIroU0@cBu}tFQn#Yi3^w)HWq>GYokOn{kdO>)_H!o@6DQd@q_ri@sB7|r zK?&>oLSpS_ms)7+44AJoWi(&MO8hKU58D1B3Dh;^Au9kC5aI+dM8eZx@TwXBC}e^* zLWC%~JYBR_vHaKOr`FdzkEC7*3)B9HvEkT~03-)7ZH+?taBe4WkJsDZ<=^E1OQg)N zAx0y$)OC#TAzy##*tK&XZ5mI;30$hJe>6D)sYer+15e)RL_^TvDFh?W@^T>_yO?&P z;Y7w>%I`Bcb2O%dWA)sI_byUYKYF~&O5>QG91iITJY9Hvr#wHw4K#swI@T-p1!TR1 z!iP}(q9=PKRrYTFY?}H@L5oCJ>xxzKJPT>P1mBa~t0~mfHd2^@&O8Csb3-@dXfja) zFi`5}MhAB;qnPf=&s_)8=dEGN%5L#%%so%sGCxN-rTkpW6z;6N5F4v~0^LJqOvu+! z(|w%++a7WbinTx%JL~72!R-c7YG>1)=Dqq@XV3GqIs@c#g?a8fx?N#1s!x+5`}TbA&<=o4$C` zL=7=oGB21)fs&%ui7ljEWzmrM8E}D&PVjO8Ac9aE02m5>7*Y;E0$>CFVF18&0^zgl zSt@9f3{?Rs5BvJebT}3c90!WD;;i_y(l2QqferL{(2Xy}1)xwkF{8Qmq7LQ>BpIs= zd@7vNrf3v!cfpoPghd<_2thvyDAQ{^i;(UdJ?rVDqY0a`VVL)W9AM^Y6g(t~G^B`J z(YHkfucitajxe{7vC6!Ugf9p6nO15!1#mDmAkJOMZ8LRmDj{FSqVAOjCIqQ_D6|d$ zV`O6za$|LyPFAx*Q%D2ss|{eP5x{KOHKcz^&E_H@Z3z8aHjkk~35Nlyfk;|H0V~V2 zH8p|MEt;kFpNxyO=YZ>di@}(OJNIdFa>$?x&vh1NcJAG$-4EWUm)`smz44_tXp84R zj|A=SKcU_G_XM0=TSvP06!hJ0opf*tESgCO2yLuqbWL z$Y*>L#sKV1o|#K50r2dpa;0ECAk+HY51Kf8PyTmTp>H3m&EcQ_c$#Z5uwW4-zb!1Z zw&<=f@jt=qR3IX@1%{uOYo1`%o~N#kdYdw-keZLeOctJ|tfoH}n?GlNA51B;a9YYN zi!S_$&=Xo=E=dRonk5d(^^gGw6}nXEtIW$r?(YQyVl@MxWWkwEB@}cz(Qt|--YaJ< z^hCaQsntg)KIGkF^QMa?VB%eq1bXNmQ%p1~pzMzsDB~as-UJU7SovTD2S|e60O$hn z1)d(Tn8Q#pvAsF39GX(4g_!Cw68A@g!C3hVH*cU~zFNTlN@Q9}4O8Q`#_j0@! z^LWVT^a;x|kcBGaof!!zV+I|_HEf(f`S<8HlSGwp3?F4Xs5LRJB5LJ;&lO1{0x+7gwX@$#Rn`U2$36|fh$ty0b)|y8ga4ug)aofyMCBAw zg)J9^8$c#F=?^vEIZ)#kTUQh+Q+(aqGI>kr=GRjjsV+vKt) z_0Dq+L0_}!kj>s3{QQmG+gl4PW`N@&SLi6rQjAWbX6?-j|L=+l^W+VR^UJe$d6=6U zPU=t_FcM8^uT!5Ix*^}gOR*(qNAr43{9opElYr|g)xp=YXN8+5AIH>>4e)bn|M>uQ z=3fKISo`z7^_O(YjsCgyPrgsiyf@4m0=v>!ci){;$lTAo9^EmW_s--oNYvV^bNTQz zT`6DJJw33j+mcm6CxgaF!~0-KLrZ$DcoQC6yhz2ROOjbAMixf+=ic!N9jvU; zVC{lzn!{a2!k;{r!)xc=A6xdCpd2G>%IhLzY@{eSz?H~l;(}reP^7f%ITP@8030&! zjdE$#>N7DVyeE7wK$!p}xuT4#Gzb zsmc0XguzlNx1xoFNoZKq?}d+mG!s<0vMysJDaT34l1Jc8da|p$HJcl{unh>4Di-E8 zOPUo-z#WhrbKB5Iw?6rZ=lMPh`2)K4^2@Zsio@QahKs=^9rasg@a6c)KJD#1p|#Zk zz4q!Gw9269-s2+~m*e9@x_|EuU4Cwxu3o#upiYn8`N8}2BA0h@drQw=3l9<3b8sO z73qG~{rh}RnZL|e_n>JBPoLxUS-`J0$k%)pT0$^&+D8jrvqaIK?WzqZQUX{#FAy>l zq6e*3&vu|1zojwg~Xd1(8y3ogip;vO3a9Vkq|%)#Bl zL77THnW=@@qWqGLLr@?AlDOB663=oyhNBc_rItBL!jy!HLTMA_ZX)3`C>L(qDu!0l z&Xbd|07)vms;30XfJY6uD~e)BN{6puHz)_5M95BA52BFX!h5GMAZG|8mSn2bkRH4b z;iJeZgZCl)VtHkt9!+Mo1PIkH3#kV&pcHrIzc>n zrj5ed?4?b-e(L{hazklDdg)5QdZN|AAc1*xCfNeuny_JO$Of?9RKv>9o?zi@RSwEv zE(j=7i(y1$pcos%)8G{hjm+j@UX3sz|DBq*hKyeb>bVuvZAX(inJi=fTv5?U)`Wf( z9+Fh~Jf*ppEADk@f(d67w$|PdW)%#nrz=-65p{b=R7#B+n=q`}WR9Y40EEgynqp3- zoRlR>{iWW{wLTjfqejg7!q=K`L)A?tAb^0_TZG6tsMTH9mY=&pJ&9@!b?zby3>;1bD0!=uX)biz4m+m2r#4v#UJ!>Vgd+PzJ*I z9_4kdXO}>BX3-h*{;c<(sZ(S>Pt_Yb@6F4M_I>QsxBGXuo?Sg9c)4}mdQbN`Tss?pg*VT!hJLBtU^rba-I&>Sb|VmO89!+Ukza!hfGQwL~w03 zmuPXz<%0?!kYogcdnO2g%k>1z2pOVRVN`4UOwNH%l-kdt8Mhsg(*c0?3paa-<$a zmBdo2x0ku2!p+@Mh9m4qynQ6pjmP>Z3Q@FsxWw8w<3h)Nd7%Bo6SFTXGzA2tTmtX%f9q&A% zeFpt*e*7uj`hWo{2El&eORv*gUwVVf9n%Nz-=RGQg04Jwjqcyyp+k6hv5-8ltYynQ zcP?zLn{dYfOwbhP09tyy&Q2yHa!WhL7X;pj5`^`vG#(rUIOAFS=giegBRKCsA(}Y| z(`IEEnsV3j=Adk@&!U+BBv(6oPWvE#n!5b-fThppIu)3CM%NGk2F*STyV8|Oq}o@1F)snSEU&1 zT1o90Ojv@a+%g{tQ&G+Ylrhp(fV8-097c4+ZvrTTF2VN-jPUckpRSZE;*o-S9PAGT z2#}D4s2+G!=(*yeT5SovWfu<3ys1@cN$p3d3&LRB5-uJ$@RAV^Q_m8l3S-FmLdwQ? zB6}>UFet{CpvtQ3;X!#@re+Axy)6iU0&h;KgPkX155KZ-pjbDVhCGbrg!fx;Q=pCr z{UFH<(-+TO06SwI8}WhxVLn%9dAub1E|gg)vJ(mC?Mt}p*47pSI0NZ#c-deaU6@Ab zl4kPJcZ*Rbw7n<_n~#+kR%!uvZXP+GjDMgapc!4$4q-W`xXsYW_f?r04I{^G(Op-xV^Yl`NcDIhHiFb^=A_>@!0)-a;0KoE6Q`WtP>?|EnyBRxbzLR#$7zkl0NPlZ<=-q49uaO883q1zTR*3^y|;c)~ihapm3v8QItk5?p#ZS@yv+FCH8q_1-5h50i3+-yguD* zsb^g=6P;#&3bd;z&UwD+>qxWZNPl#J6#a1ScX4h7oA1JT3XSc*Gaw65`n+4mu5Qx? zd}r^^+tu?F%QS5)Dovx*L!+wUi4sLgt_uYP(6QhKL8@hB2t{RIDNc4wtpPx=vSF5#3{j_AUfK{*HQE;&lM)-qPk4^{%aIefqVA z39+zK_Y|Cf8*mg7SOyWM14*;JgisC195m5MUKqE3p&l%f1qVc~L5W`76U9AK6qZ+F z-rBMS373h5;s~I{6Z_=eJqf+SW-Xbd)+PcRAyW_(ba-6!S2r|VCMy4lSYJ>tNy{88 zThNJka+J%fO3)b84V@(0(?I$ZUKQeb;qiLe;1`lX39<7Uw=3K^5}s40ROawT0sw;h zDkDFZ31XHH^#ECwlj`LDeR+p?FbzU_r-Vd7&_<|`0Vx`)Q`=09tw|<|zK|vN6KQh6 z?JbQ=5@jI$wuF6|5&{6OHV>P^yj+G1I@C^9Tu&27mXHp(z5;9!5=wQsmo(<6cfYbt zzLdTOC?m66xOoQVwZz~I<~oE@0C+-B>?_x-ueG^&a=nKPqFnl=UlDE{bvK_#T5W>o z4EN#Wa8C(;VL?PFAllV4;S=dJF^+KiUR#w759G$8>|hRUU!oJP2eL9;;JLs4;w$v^ z-~JuwBMh+g=qq1-g{Drb!4KVlLGH=ayw-9@u8NhWe0N=5mrMb+I>My%w*5b8Ap%FN>L1 zT1*ONJ~!rVO6@&}W}b=Ec7=Vm*ZJkn^MVPT1K}?_;BwmK8A6)B;~Ze(r!_V|-D_r^ z#k0e-Lde^^xM$QN{R7Vy58)8+j%jV&C+f2igNDJBmF|65_waC0A+4|wf`I`Fs^~y@ zk?^2(Usl9Fz~nt&IS@2TOc5@j1T|mR$RjcaJ1=tgjh) zN(GUy=d<*}$}IPH=m}T@PzK{BJZ1d%rHdB@Y&bePVW8_s%3DWvz$Jh_Q86ymFDl`@ z3ynT6weeima3W-@;M!1`!4+6)0ahAk<3vkAt;ls@;n2;=G967bz{XP627NC=-=OeJ#-pSVIyjTCTO%%Z z5KnnYeBV&zU*>-W9-c`9&P2`q;%6QHsvKzXeyrnM!C&vwFu+*YJ;ByOR5ey)8w<-S zdl`u7YfUWZgTxIespVr~U|^6$9^iFZSug4KttY&emT7ZqiB>mxzX6bX=YbIR7I#0T zmF*3BbZ{hl&N9o_!qZ3yt30tS2po+;$)IDF>CEIv@!KhMPXfm!!u&Dc@clrDzj z)U!EhN~F(<_gESnBT=q05Y0e?1YKEwifpbvO)@^hv6qx1Q{v1si}LpdQ|@Ae9ypfb zGt1>01yfEx2ToIvpXC)of|FVw<{-noI>b$yO&usS&`fI%G~Yj~YZ06$_aJKFbPE`8l9C^&l`ehWJ449!kmPM6KB%efGE=j2 zFb}cOeW5aNzDz)GSN2u_xlSNkhMBd-A)29}P?DlEJ1W;*vky(xG9WuRpgLz>gcK~* zbVgoY2p#Zp)=MUK-kpCIJ00K6a3}BX^iw|XQya29+UtDUq4sNRDpZq=Sz>6d+;i%Wr8W8dfZiKD|Q^zV)r7RD&l)lvMD?FnDp{ zwbx{m+`G?U#*G_vX=~F$V`>os{^mdYFX<5jChx!VL%RQ=&H@|`qy2s1V_CiSyoN17 z2|hly9na!i`5o05JRhr?!rH>EBy@&s0oN9$WHG}6M!=&4WPL_tDjYkIUJzD-$p*qg zewSxv!asy6p}iuYZf#2nXLp%KJ*L8u!iNVd*+{`HihHfZw?Z5%*?K0;-~%N?xY5$G ze2y}3_1D(rfPl9W`DAvNU2{PTedT)r2TKV+3ljpux`Usm z5SMAaN34CYJX+=kX~RI%c_SrzGy+AP)j>cu%|H?*EoBOoAwMr}fWtks43>pf@K{=2xrj^wtIzAe*Kt7fbDG2CL>Rdq*A+5lD zytbytt<7gXh|;kbBxsrDUtt#9XqQLr13$YK0YQFRV8LHj5aP35U4qF|!Hdt~TJ*h5 z9cKZ=)2uKvf@5r3@!A&3nx0k28py?iDW+aC?1KP9uwFf6skBTA(Y}Y5hmxmG$y4vb z?H>D96{Z%7U>3om;UTEA3=RTT2;W$t*;b~O)kZw)n(Q{J{&HVHxyevHXG-&q?8i<&2|=XJW#=A3D(V3sD+x`~%r({2BHc-?v69+& z4E~*pO)4)=tu8-NJo-=X;q#ZRvKan&{#O?cwS@AfcLiZ+u@R*0_;_3 zU#g=gDvq|^6=c*5L8g!=#hw%Ziz*&M!3D=wJ&6q=t1JB8HyMax%_i6Kn{0s!K8mOI zT&=nR9*dNbron51tpzjjQCCr)(Nhzc(H`e!?6rYs0-bhmoji_1xt}XULWU~ zQNrnZ2Iy@86ZS7!+nw<%b_OHg4;^62_x5g2bh@$mJv4w!ch2jwY=0Kd1Av-8X4H@T zTn-)Z#@j$0&rT0J?aCb8cg9XVf`2wg=JbEPDAtm`y5iQAZ$VkXI;hCDBd2j63id!a zNtA1Z1*nxZI{x&oTJaF7Qcc9`WMIfRuzrNXD0hcuPyj#!r4@*|WHsXF);2cj>%aC_ z=$L_oAN>1&M~`*h(e*D(Fb@LV<8wN?EK*CtyX|huHDuC5xY3PN}2uySQ<(Vhdmf z7d&I4xrI8%4XjjsKAaSs>Pzgsr}0$xOv{MCO8ddhkA*OJ`I2Tff`?IU!rg?+Mo1RE zFD&I4zSAsAQGg6`?-=wcCXBhAikAxN-5;0>_P{(`+Mo>Tjvf#$84xaSUXZp6xB)ll zfs*KgAm`Il;<+X=pY3~}C69kkKK@k=ba1se1GPZh3Y6A&7EBc=9Qh~El zz_&`gR>0w+smS|~IN6egG}=RL2kFLC!@A{}!p7>_CmF`zVKq|HOMq#Z2mLkWd=Xw8 zzN)=rv3MdY7_xu~X|ez(eQ8T!3PukA*K%J3lcQU=WWHk!0NClTuW4ont~Y=dvHk$~ zkuWbZK(m&RqX~mA!Q$`%aLSyNv09cC+vw*L9&^mGbp}`d`G5b<=!NI5(z}25C-m|6 z{zBZ`fBQfEJM@je`M2oJ*Duq%?>?e8zjU3x{FQ%1AH08$rsF_2Zd~FQp3tBC;ddFF zd5iAcx=k;=a)W`DJ}VAG7XGhO;dHB zM_&m@26sr$SP4E-DAiNT24~spLa>k_Rdk^cjmIPF7-WN4A}17; zj6Cr0gn%c`wpvc;HCZq`!~=>w$}K}KpclevBdMe%YF0D&2}y6+gx!>;7$W1*$TBP; zM5S-!{gPVQ&R$OuFLH~8FS}stToj3irqX{1aaHSNDc&ytnIz;DME;@A3g?M*Fw%Z6 zVgCncWwvxU0WI_SRwSOTB?@a6TUp6p;jw~{rXmwcn=H8@@lZOEE(uRa5U&q#-H1oz%1Xu`LY8eyIfcaY zrBd$zNn_3O#R#6V;J;zvU^1@6Yf3#bNO<7@u8om6f%~UFtpz|5Pt{%n48ZfJ4#tlo zU{#!>V3L6?olHZv#)FUv_Y#qB`aZ^F@lD`I2#L_x%czZyMLc6-LG!Gqxo~XM{3a8d z3STQQP}zc052r?P*Fvlu%Rbo<<<{vP3J@7T4udjd<1{MFqeH{Vw0_mpfeGc`g9l78 zr`~z}bFd9pS$GJt_RHKo(UnUf;nt7_vMiB>cpj@!PJmjTNALak$F$F~R44{CAKiN($=b&J;E{R5c-nZZg#pXahewCX=_K!Vt3OHTRDpF_ z>%NBhkGX+RY;?8sJw@U3D{Zf7tAvJ)QRBhU^Zqr2M7@%{?taq*fMu@PWf6Z zX8OKP%C&p@^pY->Zg)T;5QS5$Q!Ta8#;oyf=z<3JL^ot6g!C@I#Hg5|8eJJi(s)}K zq7|FKlUCij)ebZRJox!2&tOcQ5jflX{k`daY6CNQ-I8%MfpQIyBrp8t6rWGyWq zC&b+Q($<2HMUjO{Y1y;SCqT-+EOPlF>r?rz(EUfw&DdlRsuN8^NarWb?Q{LUbX_a> z{mnij=Wf-IpO>L*zb9t%BPxg$DQjQQIh|6-$HuqI!}q%2xhIlofjZQHEVAb6S$QkJ za!;f5Jk9QLU39Dk+H}i0<6ZMSTDo$4=#GH$SXiG(-I^ts8i&tIOHbc(D~zp)-~=@@W_Aby`;T>^z_ssaEa`)N-ATG;20E6vwnd3mZ=y3Ajz9`14uf9Ns zth@p!xbWKRw8RMg@%;xheE7gZT5MxwL1D1HC0-ZOIt$H0r%b^ubIkSSgMdtELFx!6 z3zoxzg%;reW+AGcXu4-S4_+IY##jj8&NaaRKnVmb086mS!81fs_X)Vcpv~i57G9JP zS2u`SfP`r7q2kfPg6766uc}uBz#YUD!%Knt7Jv;D{*|lGF}Ss-8HmvL0vwq|1O02n zdH_HQ_iCw?_|f@PBx4Yd$$&v0A^f#ibw~X*tu~hf7gu}$B3guC@w@u#+*Mq*v}<@w zW{%L%r_zK?2{r1aMI&X);fcZ(ToDf@*(Au)ghvaHt3kbJ3Z4>77XYWsOXY;e8ew8m z2W$Y~yBR6p4|x`mUXaXN)o`qBhvj!=S^BH8tQp|@sm;|Nbwj@i2haeSz1AgUY|2(& z$ueaEysU?bW{v_#QXU(~$Msyh@qz+mJf=MeBb!@1XBiaPJrYn-z$fue36koZEVa6Z zds)9%#^(g#jTHc-gI|B~B^s=6((XHNi^tRL?|hdYUD~EEy!Ivf%GZ8F1l<(|IzN5z zn7;r0AJE_VyMImi1OD9~f16H@CiF6|m*I3sKmOr|^bQM96-yMyypA`wFR(IjfsR3P zc|4{~xY_gkJmNn4F z-alt97i^o~Ti<5)(dT@5y|RNu+L4oF7VWS8qq))%u7CX$fSI4hHG818W@>i$)6-v3 z6^ozr0R-1S>w97%!^P!_s;9S%b;C`OTd$fBo?u`_OcrVY;G)#Jhn??3z5IU5$zZ>_82(%jF&=YR6Qk7Q#C0b$mZza4DuJ0AX?b0X--Zb;r zF>lz)wFJu`1uq={If#!(coFuSiH)fWH!7?GP%eUpTxh>Qu@%B{17(g5H9I88h(T0~ za~fe0AV8KB(g0Kt>I-l>Dxg#vpb;!f4g^tzbi!LivJsJiW~H7H%CTl4Q~-I(o{;@& ze7}NT<*<6A_HHbD5*jflk!lQ2UxB=buSmdb1xSCJR})37oL>|$w4`tvkt`M;j{BR zM|>?&t3KL^!Mt(QQ^wb{mJ1;}mhP2eItDRZ!=;Va8Q zUvG=7&#WEZx0C@%Y3@Y_H*^oFi%Nhf0Twz5n*7|hB_{t^+Sc#P>j@VE#^K>2;4rU; zBbFskAPFc1b{(5tmWcrFfgAv!k|nanzG6 zL=8zLY%ai4tS4cI69rrrjDarFd`{-a! z`rbbaGl0XHS6uuY>4F=l-;K!PX_Ebmo_Lp@%XpIv*CfW`LIt zP}l-%dfNEpqhW<8r48EjDE)`_K% zF4U`}4@DV*prj+78bV~qe6VmJ{vW&n;DvEAK9RDvFJGcB{>E<-W8bvQ0?Cg*y+dmk zw&@UFGMBH=(&mO(p7t4xnH(G$DekJ2GkW}p6=eo3BrO>DQ$}KKnjY2~0u$7dGp$bq z445Lk}DaQg;CZ26`Ywvpm4tLPK(m;?f zM~H1r*hUzQSRq%I1>C^h@J_;a@bsCS9I1OXfGF`+DmBE2G(-*c5rSd?T-4f!Fr6WT zYGP&MLwAbI3zmIJ=j~MD*lB29Gw@teWQc)`V8V*IfWvDD7C0PoQw5&{Y!UC9sVW!T zHX(M#7)Yx0P4U_RSBqz85bv0ArQSF2OcKy&Dpe}s{UOSOdS}Td$U-eVw8WBEC>gLU zIP|rFC0eeb%HVOBj*atLiKLx#NMo~EP&qs?LTM$DhTDH_9mda{2&H-G#dO&;&i z_kZxNc)d)y%Ex=Vw6VNKFTC&~gPd#hX!lT3O1}1sU#0DZ+`20^!@L> zO_#4;r|XE-Mpmb_fBi& z34f2YvPYIFErurBSehpg-<-c<&i>Zj^Um4?pGH1dWHX(Pl>l5hJv=m42~~y26M$l! zrKHV{M&x`e z8{usj?@O0g>F~jc04!rZn-0KjH>rfb10GSMF;a>j3XoI;C5o1eQqyTlsV>&%NCE`a zqI@f-k9h3JG}82{1;(Ttibrs1b7~|h(W{hkh|KDnz%c6%Pi2npmie4Vs&ZdnZqzA^ z`$goQS`#Svd~dnm2L%Mg3&hTv%D!)Aycv=3zoH@bOma8*IFfh<4GJ|pVE*Tx2;$8m zG62asm04-)UO=K+J#;OSK$9|{{gRQ(`@q&;rIvDl6+|HcR`S!@AzoF~*-K+=h4Qq> zOAO4Qv_Gj8HkcwlVp*Xt-dZ7LUV$MCKxEBzAF|OBR&%U>05BkL#u$!WyUmPsOi{3 zWLTS|$~7aKJIw&!K7QgQqD(&asvP8?8386_K#;#(9XJ}^5X0-_i>M`&C((3I6=RI*5Lj~q*0F@RUm`wMWS^0-iKedvjUs_3 zZcHs|fJOaT2oD)Nzhs1CE+u)}bqynh{gP#EEi%9u_u{>vL-6@nnC_K(H>S1 zxVOBY$j))`xTDmMT>wSocKtGqk2^vnPoHcIifo>`yrICkX9{e+pm%BYu?(Iz&oUUGKSLaM678z!b|usGQ~(O1i6JGITA zPLob2oHYclvj~addv`zjfIj63^Xi*lqF?{(-=K@@OZ5JGcWCZQ5)iv9O1@dQ zR50sVD9s>ETC}dTNvDgY6vDEqWI?ey(G=qF7;&JWws0YHr&jNqzD%rW!a*ejy`^R$ z!X(839xTPAdALY_nn#ZuB<{)^G9-VZq{Q->fD)SKn@k}<=v8H2B+*EVQ}!b~J5?ag zNq7r8(5L3Pqn4^dKp20oOoPh%(=+BYoHqc>z4c;xGI|JeTnt?iVYr0a?niqnmFfA#KR?G!S4FTVB#`o=f@D&76@NA$vLuQI?=(4CvN=%XL~h@S90kZca`-e-aO zg#Ow8`ybQ#<%{(9|K8uDwe@v+=Z8O_o1fmM<&6z`^A~89l1g0qF6o zP~>8z^PyLSgtLq467s#PFkxjzCTZ_*3tZ0t}wr^ zDSE^70tk@SUToi+EI)g4?C`%4fF2EZ94%{#j zo-=JSLt*TeU{o+gHW&e}a9vni^r)U%CX1c|wZ^yNZFEILd4OV4EO2Xpxzz~f zKJTj9Gy14ZSC+ko+a@-v#DOkcl0}62X^!QYiDFv24scRSK6T+ZTLHFt=sxZHgXtjV zF=Cv9qT_^gZhLrKVWA#MDC^2rG^1vnfLXLvKtZgLUK4s1YJ;sRQ@Hc9gR(uT6RPFe zHlqPEsXfvu-dfuvT$!d^p^1%0UC@v?c<8{h3}K4cW+n*Jwtn4b0}ImJgWMN$X!r3R zJ>k#R*DnAbkxY+$HbxF%(3C|~N(Ukf7f6EP2~!xKgl~#;BK_XBG81Q{em9g%T zsYiuAmje*3H^ru}f(cE*WZoF_y*wl(SdW4%Yh{@AT$nk(Lo>&{<^GSTA?mF=;p9ZQ zf*MuXCkuh}HAA5RBpggxL3VLG z^X64GQmcxQPHj&j-0i$C*o0~ET={`dM7hx1%#x-J9t!1i&^`U&;Rx?E(R&lPpq_8d z7&k;i`P9(yD_WvOyP3|B71N&OjcI|934m2urvc2e^0GP62Dxai5z6bAKCkN}@A*00 z+4YnDnSg)WV?(DbsjIEEx;yBxJ0BG!BRh|R>jJIzSf9AO5jrxH-QROxMwtuI1V=lZ zWm%&GZGymU*V9pI?7AU9sB~qixvavCcxwkkt!(9}@{|wp<3`?VB z_0X``Q7F~XP(oFd`_^%_Z9v&(lQtJ^kAOkO72|}s?nw~^z?dqR3%qC`U_aS4UKaH( z;uFxwc{LjpLaKtN-2|E`p+G^2b-|qyHB88*4Vko-Ax8!`#mQG`GN^~hh@7B}j8_L_ zz#>OfRoYD8`5~c2aIfCjq)FT};3OJP3R_YNCG`z#SwUu@H0feCMJ*&tW7Wq3e2~p4 zCl^+$M`fNdlO_aA1lUUY9l(itWoc-cd)g>5warzV=!JO;IUpnDz?*Ao**f}0;>_bW z;I@J7ANTgxH^tjWvIf9ghwF+I*O-R_^pR}_mYqTXt8ywCvEaocLi0qkgG3`PM&%(a zWBlONBZ3dO8J3J(+7_&2^y2Fh!zVc=I{bQt?Jfs6| z-h+dEIvQy@ZGb~!G3M{CedR5B>zBX8ipGH6edmX?v-40aNPCYS(>MR@&*+60o~IjE zuh7RIeM}D?JfIy0br1)B|Lz?IaW)aoQ2Z!|O?c21zxk@8`Zz(7*Nw$vF3u_kJ zt&(eHvGRS%(4n4Jhy_PR5?!{@B`!PbRM6m@u`noA?3B9-bv5Dl@8hJE?WlQ!d_3t0r~y z?9T=Wkad!PfjV>X)_0XAi+U>R6y}7vVEx!j{0oiX9kX)s_n&oX*EGrlxxz?f;Q_wB z3$gQIe)_&q6b<2T<-kz>uaOvSe=!jlNN7rmu}NfMfXuviWi8YH zhFPP4%Xwmn7MVjm-wI23F=F`#mh2UlJt|Pjz$nM*35NAbhEvvvEVcTmBV{sbz-MmK0YN*d)jwCd5RtN%{1B{-ycZDrv~1m~@G zqh8iFbX|0rDz@I$dgLjumWb9-R$KQ`v(D{mdiKo~F|6!skAl-k1H|I#m5x|K5x9eM;s_&@g2K7rbA@vBl=9 ztRHaF!F%5_@u^pig5s5gdG^!Gx_f>4y>?JBBV?xb83Rw8(y##!x0YShoCivax(L*a zfq(Ds_H!^9i0ljs**bPzFlK$10Qxy{T=2#aohdiP&T~(rdx+7%WrsZJLv+uZNQ%rrcwM{n0Mn9Q}}P z8M!O?V#?(;Q84AON4O3`O&BDAA}!>wP)0GZP>$<{lLN682vrhLgg`8|ucW(GWjdj* z3;{`mxYdA+y0rFcJLLd@_X_D`64${HEOS!rBc`4i1^_|f7tae@RN_ftV1ok`P-=(! zM-rbdDW~0=D8|N(OOVV}jhE%NBkYLcK!B*)ykvq2tFe2E;N9LI<`EN&+*sU3?T{4k z=j2!c6_j8W9}4b)qa?KwmQ-n+c45S9cwaP+8f1tYrW0{o1D$+wgoG9OolL4ZAbz==l7O$dIz-Ky5f{_s21^2p{ zG<~I7fsTV^;X-P63C}A+3bT^cFrFx<43>d-*Gv>FJDP~we6$cLPpdBSK(Dlo#Jq+? zX*H{QEE-EM(rEMC0BJCQp5?8Jbm7I9X=8JZ-hb~sdguG!qlb?k(qQ|tc;S?*%RCLh zyf_h8{5OB~SLyHlqyH6s@e4QTop1k;?%uvd>l+tnivgzZe(!tq&X3=vU;Qh;L0@?B zMY?|DIojA*6(MTE+>xNd=t4o_(N z;uh`i?$e;BWP6ioBajEPXhBF{LMUHKo86hKet-Jz^Sa`>Uqd056t+@7omp_H1b4;Q z;@2l5&*Y}hBx{$o=rhVde<`kH-KmLktD25~`=I`LyygNkq{@8$oqGu67XFY6O7?H2 zr6K(%{hi+vT;cH9?}|J2>{@~S9-m3BAWbJ@BQUK@NNh3|C8hc^UR@=69vGANQFC8& zPaB*%<6T)9xvt>KhYN@Z-^E@k;TP67E_~&R3cwWaJF;`s-JfG&d#}~A6uuk)#+G^; zU`@Z*vKlrPQFGIum%cO7 zq6Ujo-`^2eXS`<4xz6kFE)bLI8)t58*GV5p^TnUn1UrT-O8y&dpSum32#n-nx* z#k}|CV;)ZF|9SEOp6Vg&zsSyn+9M|#Ks!H&RPAm&`A&PE*DE9-F3g;9H0O+Ky~pl7 zZBF~J=jA@tWd-EtTPkBtKc{IHo4VnD?fi;lu9-eOc`>+bQP|#PdT@}8Q$bj$ftL}_<{k@T_=L!avDd3}_P?AZi>?QA@93TQ9f;8TxeU@8y1@VOU3lwl3!?YRq zdP!jM30c~~?TggkvT=_0uk-d;iO@uL zF02gzx9|?aoQ!ac>dRb&vOGUzCh9!Yjg$T-dnJXa>xv!0CP|A}sedL{XYS2@-9AJ^ zbOpU>FTy3gth1V#3m1uK*T4a+6NCu#j5Jq5M5B_|(p2BoW6)JHED#5 z{+#PnVYc&Gu1M#<&pa1gaG{oBy@();=L*VQ+m+6(j!j&7J*_NWyYYIEfEp9rBD^(g zCDyG|Tz;9=vFl0Hq)!$SVuVugci_81T4)75LgGqLLghNmm6XZJ`aDk`o-#RsRM>ek zY@EbP)CA_rG6RLo8YsL0@X!_K&5)EkP1&rx8liNBjmQl$h)YM9i3_s=WW~l6TL8XM zo7}kz$jk##q@UzmRwY`V&v+l2IbF}pm!8Q;jZ&KZZhQCCvMouPah#XZw?TkM`F=VT z;9CfLYd2mLNq+J2n>5y+QE)!<3Y2R?o~v< z`Uh%cTdf6=Ws35CcbnLt-L8G{zdhFF={4r4{Ng4e02Y<=N1e zxwiZGG41Z{>%PVH9_Hz^(PZ;?u85csD60YpFJuxWNudA?QUX-yoT~D-1 zG=#%8rZ&FFXqK{$QD}i$*(yr_h!AU28w|<89NbnfuvS{$Lo-#*`l{2Ekl)k2;%Q3u z;o+94QdutWhkDjMNp)bC6p5o#w1jD=Rk7 z6ls1p{au*1jC*D#@I5Q5%(A=Y=Zc>vZZLD**T0v~?0xB+@~#LfN7RKAp@+8aoV{;$ zUp{}X_InweLb+Fu8g`v4OV2j#LyI3#D1vnDYbk{y>O$@&F`+SWm0*JfAP_B+Loqc_ z!sDlE%On)))WF~juKtsM(R&*}$yOy@LsJFhMRud3VvL!`@&1gG+m06e#K!I1)bed4p z(26@$KA$mz2fh*Xk+Ku~J-h%>kIKdZ#E1gWk!8XXfK1~r)0n`*LzVH~^eo&?U!|7V zsk}=vE%lUV$i7t4YJ3lp+Ko*G=HLx892u~uWY_Sd8E_v+W{%|*;Zs0=OI*Hi-b{r@ zX2f8M0)0L4fB^s`YDw8-a}Y2?vQa4kUSabA*_Mv)-jVOYNrZP|J^;W(56Ha${>J?G zWJnKh-lR|JYg99Eb?1{iw8nFC6XR4a(bvBITlD&uzbf(mSaKcXM~=v@qu zkV;~WUb=Rj{_5ZT&*_i;hkrvCFJGpQZ+=8~@7kY&wniK`>#HY$H?)V7-t~{j3DX+Yn659cp7Wxb=-E{H=k7{Y+73__ZTWxRpv)rgOLke`E3L9!FNGQ9s!me3 z86+ABD+!6@w^&vcYCsFjcMl7Z`%6_=MCr^9X;H6mZcV51ug9P&!cuBeD8R|!bxq)f zd2Riqedd{9&gw@M!irA&ljNmBYzPal(;~Md73PtIqH67jffx&lmN4(U4`r{CdaNvK zNbFR&-ugml=;1HU2P0+1hE!JhqDoSuqMkN|39MpSgxBoU&Jt=uDJFKNRZ|NkGo=~| z=>YpP6x$JuM@p#b1hdLvQ_Ef`5h&)Ziq=jggHI(HoLsrb3l?PSuk>^02zo;PCue$;?M&o*yx#e~uYoLB=N)Q$#CtaPc5+Qt84WuJWy1RNZOZ00hxC+!#B$Q*0DnePxh^5}OXQa{TX@^>JHCj<%Vk z)WD$$U8GidX`t+=X#kh*ed3E-w-s`--V*iOLgr@xrxx(1&nSOYvnJ9r`5asj1nDlH zSrBGkISn{ZVRpWEpMP38AqVF2a@<=nbzhuYwFJ&Ziu2DY2V%NEQ?Z|2pgZeq>;gpj zSm%31%;tA4qX>3xk$ozoG|OB#!H6=0fX)%gqBlflUsH` z3n8?CmCBp~#M3RP?&ajgKGz#?BJ+@;Y>%}%wPdjla3T&9kbfL>37KKY%8S`|%|6AfENQ1#G|CI>HEm7W=Lnv2bZFe7CVc2^Sb~Z^%>Lw zkaTkIj)dUI0GKC;N?nzD&{*FKN(c{*jSZVf+Q)Uu3{*?_i?UZ+T4vl>;rXc?*W!sI zgty}ql0@cR(r0C}x4uSW_vV=>F|82en&l6CH~?w}48Uj~_YyE7VLCO41b1otWLHyJ zTTHnu9E?S!LZi~k_Ork)O!lg84P%Xh+rXlcdq4hetjDM!%bUGfZ0 zh@+MbA0Qo%AHY7$jVS{l(k~NDR}Mg}Fu+OY0e^Q`(Z)+JON{sNy}O#ZX?>lRw=ar! z4S=5Eg9oziUi#8kX>^h3_MiPJ?Y;jlU3%>`dh4(ME^YHX|Jtv-M8l(s?%n*5g{O+H zy?B|nuUw}0KYT3Kulqaqc>V|a?q7UBw{PE~Ee0+(w=N24Cs@>DB+O3_L zP!LVI#2ixBYV$&Xa!-0lPtBX6u9eVr?1Y(?!qz>}q|hm~;;qlSW|U8FT?h@xQg=dD z!tC>INRZDc&M2IVj(G#Js7J1Zly;ui&>XF2BZ!&!;{0|!q+({ve(fO=+UJ#~DpBI! zo@L+>gNBZSgAFG!rjR2EQ5A)@*8Nt}cx%XO+1I^Zh-n2ho1~a{oD=1=6vB3R9+cU- zkiFkPoZ382+@nY2o4TIq7rfIm(`X@`Fd!c9K?OyaF27wN9I|fWX76Z zk0i}_2-Ff_eeUE|>XfS4Wit$c@A-4aUpy!ZwW_MHIyD)y0kd7^Otd#~Hnhs?t-r>n z+IME|ZGj(cVLjyk^)=ujnk1K*90jz%SX_wzSlZB}BOpJ3so-Hq^=|QUG%4iewFtcZ$cExNB zq^8F%=-K`_-y<3@BUkV{&nJD8&aclo{B-T{X@g`ToBK2CurrU^b*CB7ErEp#I6O336eFOyO|appNF5=#Zii=coBymT=;;PE{XPq&^$pfu|u z&dkB)%=Y)U+LPK8Q#6YM{Mw)D0qgV9zYlZvJ1?s=58|#|MkZ59`0pw8%=@{H@yux! z@^YyScs=!%O?#a$(FP_^8+FR-?2tp~6Ya0UE^tM-N>Eb0?zIa(IHhb^=m<~SqQ20|~9aHN?xc(p6`_mZPvg}L@ zTl<_l#2hc;&G}xw_i`R;u3}Y@HL%FyAhVn1(2{6_hPx%JEeH)8f+0YH{l^XapMMI5 zA;W-e$Zkk(s11>An&M0rtH`RXIV&rtmoMKu$2{HfoUJwPz0bKfB5q_xW)-PERgo{^ z-gEZZ^Iq#)Ykdoau&GmL#DjxC6+CGA8yift%U}=jzF_?_1q*`LP(wXga`jZv&=^+M z+v3&3#I(w@!5$|&+gvWku`kRs;K5y^pb8yu1d0fm7e3SJ1OSLbVYqw*Q)Xv0v`1Lv z%_}A%yN<1B4lI@PFs2h@(4k-u1X`Mkngmb{i{izi>5c`M5}p|H&>)T%voe?zVay42@HkT_5heV~&$A9)Uc=PHtCNKVtfAkv&u1vw}Z@&$9Z{Fm-B`=&a zPh5a6efcZ!)?07FkH7aF_`)y!GJN4HUxk@=6W)2_$M9eOi~kZ{eEvE3>M#EaEX|!o z6jMX7oRElZtgXW~0-Iztox}3`9T8ldjSHB?Q8y?roArlzRmiu-eUEh{S8fVzC`-o# znp0?zC&6=dWeYYp9>ep`KMz|Qy-G^GY8iA1IPv%KlEXBIs+HQod$E3fSXZX|(g^Tk z$|mg*!y*wD9rLC|GRi_No`2-&p`I7?oQLQ^ z$X+m(?>jR9#R;XG_ebb&Ur}J|msyYbPOtn45JOt_d&b8zqNwAj5BkI;@HrvMUoL}$j>l;jyqty^(qsYNctbx^U;%cbO|9;Ep+mOh64H&He1qR#%1-z^joO;_>b}i2S=`{F2_ov|PS-zmA;h8qtF&sfnurAPEtC{meb&HI=JOX%of( zX!Wb2OgpFmKn@~}Lh5;ADW)r7cA)~QFe?b_>YJj1guELTTqw^?@HMBZ9KI; z1r*6^%;U=Tp9m5<)rlZezOq7$2A0u}=0?Lepo?q0%f@U;32*v6otZEO@UHJhrMcvU zZ(ZdX-dCLRX6czEp}&bASn_!=B$O%1d>#QAli48YOO@A{Fnt0}yV3SlZZIOVdQp8UZ_BshnfHoF&q6uWDGjfr=u&rDWgV6Dn7lUlxBrwjgd){2Y`YV zT$*5_<6gx=L18*( zjpS6zH0T_*RWg{t-Aog#(Fhrp7>L2oh&u!{REkM!@pH=JL%<4g*AU<{^Tc`foRP4o zzVMK6MxZSA%|N(s_#h?Asd}ZbC68Q7SrY8ZKyx-C7f03*IRan|edh_RWW*#WDga}d zb7)EuVJ~G7q959L`kNb)5vVEYs2P+ZO9h1#DIv30FpAncd-0OQp3}V)7Dk*v*vA9% zY$}QnzGPsP@yN&~l0|M99D5R^8`D^S0;Cl9qcNgvT|8D^gd7s^JT#4kIq>jsI1vIO zRA&p7($%8gJ5nZtX1Tbr5rH!I4}x&yMMQIh?jwLNZ?_l(q}1y)Z%R!iN$o0jcX7^0 zzco*sfY#y(p6bK}MD-z$FXjOvP!Ycw?sg>gw{z)A)G?C{iZWht=p1K;l1v7z#d&B^ zh~3Pba04KAEN2MY*RzIpdH3r+*&wdtxmudLsU;ZWh@gM#Hz|0J6z4JDl|M&j`_~>Up z3calkJbv(iJwQJF=}*Dam(RlbN(ZK~j|Q4{zKj2EZSBA&u7i`O2i&AVq1G*kLV|=6 zfE;wXZ{X#zg)Emv(pv&%Tq7t?76xNuLVNH4`(Ow6->e}S-<$$DJzTG(WO9fMk#l$)kuYj1$E!VVkm=u9U*x|wMS zo8F^Pb>jVLx40bQo+0_9k3bF0l_sJ|3on65T1CjA2@1)N8EOhJqB z^PDxFkvU)SrU@WIs0yS?jD@}&JlEph;m67~`zi2=r-_SRH?j{DBZ^)Ci+rN^+jqxt zrFz?8>uZu}?kBwOpdym}NP<0%SI~0RQ#*Yz7}@*>^-eE`Y4{Wlng0O<*M7(}tB)_E z7p9FF@puJ!yBG%A3zBmQ)Ms9=k?~E}N%~nTH=#fUR4IZh=^3M(nq%2?X%I13+o2J3U#ajb^YGSt@Bz zfk;BV+8k~{ZEeiX@%_w&!f7-M;XN6MhYNA#aHx(>S|K+s1yDe6fclMq5N-omCQ;$0 zdpI)_0uBxA>*n07q{qfFCJq$lp&>VJ1iW}2DKIjml!?lR6HsA|?PvFX_KX1m_NXt1 z3i>E8>@*`*uHGu8F6u}coQr1;f+Xx2B^pxzYS^oWKFS;Fr6OKC9I{1%{nQLUE19iO znC|p>!`OTHK*pZjUa?KN3TEW}#B+~+TH+Bi+}-85Qgnnsx=TU}y`MZ?sO%Pn!b~Y~ zHqO89fMxsX(`T@6H@Mtvstv7$MZUkcw$A-cU<`$b5drYESH1;}GiMMmT0&)G2Rd)O zh5}TM7T+G?ma{Ox`rKGsg{{|r47)hj8wj?bc7lpZpTnaFNE~8&?>~A7mtOiPWGj#H z`6(2*BwX#$+i$>=U;R~>zw$IJBiQz6We0wU@1(S>pZMfw;q>VXK-T-rXS(?`V3)X> zP>5UKSckv<>#xIWue}bx`J2Cm>udn0mQJDtn$prrXu!~yip4b;Ro>m%gEqyr>jq!l zD^u%AU8xzpw|Y+%9jPlcBby<_+xwiN9LF93-2%sbdTt7KJ6rJ9n{Oa6^DaDj`3fv! z|1T~qFxfFxghIF^yO)G0h+??EJLpla!@PU;zp8y?3PhHKSZc59!Rg0aibm>V2cu)x z*m2+0h0#j;O^=zNS=j^!;)u&?O=w~Zs-=?#JJ;=ij)E)`&>EN>!VVG@k1Nvh>jz!=!-)gTRBpf#TRQwMU`I z9Ds|0_z6%0CHc=i|hS0;b9kS)SMWesoO6 zeP(2&2ML9i)>OnX8G}4Yom+oyTsbLNWOKvjWvLu6)x9%%1*F%wP^|iUy^_G&J4c== zeFgYPYCcldxa%mwv)x~}VuOqIr#Y47X^^UoMYU}n4(sbtZ8QR&NnMhiE39=@*6mgz zn=ghQdSqlQl?>C?YA#7CD1%$6UeXO*bEWcJ(LVOz{(Y8z&RskQZ~f>E1Z4JjUs^{X zW(#FZ;!E2jPf?UPHc%#^^))cyNeyU(5oh{d&X}bs;HA&By@G#;7aNGDTWKElaT5-g zaWO=XqpWfkjhz=B#(*AHzW$!czGCZ0yc3MWB`L#K6;RoO;$F$0D?cRfiP`=kQ0e^0 zGb1@IYxQ&C-6=7uepppd(^t5vvX}l|CWP?rz&@(h(p6rt&zbAujn(p!_PA=DeDa(t zUGlfw%btUY7hH9X#7+o=uj4YCIZ)mbRqjg((+L1qQeR86?i4&v>$=}1;36=EM=+k7 z=SS(G&Z}p0EE+DV`%DPWOkQgl#%!!Sw>e{AelQRU0F%!w6fisk+D%HgpvO)iUZ>iz z_Xc_Q7ehTOl!V5~y9Y`&QN60`q4G^KR|C+&?PZAw=X^slirKxk?`xWD`oDR@7$0h; z^VarKlTSn2lfA+8=aGH4F5BzBxjFzu5NotClMrB=$64J|P2QyuI8H)<>wI|P?IoUr z!>oYnDpDcTMSj6XpA<})-O_QS_~#-Z+F+5=9IOMSI4zZ`>^fy|C#ySwBD7(V(m(X% zog$t$g}Q6Iyd~w*hTiQ3&jl!B`e;&|MTnLIoF^k~{u+Wr?QS;_%j!c4bQCo8aD!w)abJ1y$nfO(lnA%`%t9!Xg_qfLPI(DrLsO+p z`++x8<%}V363YC=N`=ltp0kvOoa)(BuO$MT5Evn@7n)0)ooY%z78+}E$tF)H19~#b z0M-x=8mfpN2xks^95FbDV?ob>^c{g;zE5uQLngu&cS=d^O28V2!Qnki2=+`ZE644FyVYYQX=@vS72?my zC_9sfO$1uHy&;@FwaBj2CR~YI@=&bXxmZSBh9KIYfGA1%uu-K}`tg>U^xzO-DQ?`l zX(or_VM4oXxDL*oJ;9+$O(GUY<$7zo11qZ=@bKY7xcb_U;K3KZ1n16Q;CVxYz?2E4 zEJ?Z4tSK!a9WBaO?xB{Z1FoYg8`VCj_EE6%Ca$A$u#`c7n7m?#3pEGTZ;~e`0i?zW zYE_l4sz}kVnX5>d>b@+(1C=KUaa;)RuvSGL(&n-lhC0CbOCc9eXCaNMb2xXvUzgQ_x)q zb(Qx;>n>mm&1({pRHy|Bp%hM6?N=BV)|Q3y-0Eryh)=S)ROeaj$MF3Gz{vQqC}G@o zkqV}f7&Yp~xk;3VKjyx4?MnZr z`-1`1Nk9gSo7FA>F~YR5_LoNLEe0KHOL`l%HG0B8d_xMdb4VeCIh zz>H)c8|#%4>fyrw;uKC_D!>MmzWS`5uQtx(LaX>JRxl+kJAjx87&LCfwD!~a968Yp26XR-yP^0xH3d!Ng$zZ^c29Fi58@7cl zsRqGiGa(qcnPp-TNp`6)+4v&YZ3M{3bAx~&0!l>T(onQavInsnTVqQ4pFkJ>yD1@I zG=NdHLVO5tFX-o23r0E_^fLc^rk;|9S=DtADfKC3I-R?7ZGVR*yNt^l9x zny+4K-gB5#K0CwSNICXtNqjyVYrM%$Avi{T-NT=57wdumNo#SLg(^xTF5X225CHq= z(Ie<}7hraA30iZDuy*$zf=a6hbB6)et3Uc7H1K`oX)_@5TO6O+`B|8m z5zm(P41#~y51V&4;p*#ez}s)V#i_zCKmQz@ID>#pYX-~3Il(f%h9Gz$xgL121`vu} zz%U9UmCYT-DgooZcl*f;N4^|;F_0VL^wb>mhn_h+noJJu*^)TBcmf_EKm*x17Jl2b z-_ZKvc`Ef2UXk})i4XqrX630KddGE5rc530JNdm(6)&PCybA7AggO1&(jG$sS}{4W z3XmqG6Om>KNvyL1D)tO{U2wWdwE{9&Kzkm8k3C$UJ+*MhcUu{J-YK9EtSn_YQr{~0 zaqx9eFPpFuQ%XxOngC)2M8Ts>gg*_pQUISbFAR&M&s`|X1V#Fnz)r6KPp$?Xvp~@r zBCG1qd*-g7E7ywAGefoZ(a4Y$vEXcSxe~%ED5F9r^YJ8mgty--<1SyA2gLqhMpe+P z3-uyo!vxm^>*AOg!aqnrcogHl5pO;3>RVc>Bcw*48)CxUdG(3n*jYn%U`ep@lLB^htIZNQRV>yv+>87B3fl zxojj^76B?qJ%{99+kc(bKC38WE+}!<+bQUkTAle{?<>#6%kS5La$ovRRhpc=o0X+x z9s8&hRo`i!$KTCH6l(>sYtoz3nws8{K4{-*Mw&F#P?S<1en0lhlwSw%zK(p`;}57~ z<%~+^jCDn-pr-ev&$BEAW#tUgf-0OfpoS69bJM^(`AReYxN4|j=xck1){)QQuqyxw zX?H;Nd@l7I$_{V`HeMBe-u~sX%ixG$ODoO^eVYO@St;oYL`SxMjq_3ZPLVai`8+W^_*!|B z)YGmqA@L93nBAvdOyXVYN6KdSz`2RSnCWVeR|Nwa3Jg>#Rj2|>im0(FXOc06EKJUe z)ru6zAu4^IRz@8Nd$P6`W!bJW0WHk?MA0D;va_smV1p4( zyYy)HwjuyDs}wOrT9zm-M>MI>4v-vd0{)nCWpR88u5s2U=DKNdc%6Cmm?sYvNA2aT z60~^|&xk4&M2-xFq{I}GWFs<^@PwSpY;k&dwo(ybMSxdgiDd7kvIs&AdFc?4GZ^j! z-kqF6k5plxED7zUB_7k=+c(s!rVriC4UX|%KK&w`xpV<;-n;|NnK=Y*I@}LglhT>z z3<{C=4VAfz^O8t07tWlAlP|o;F8-U>-vts5sGkV1Y|Je{b9xp!SWXK;#w$->hR^-% zXW*$TSD=aA*BO*774`zeV2#m2^c>5dv{fo=n>Rz^n1$^ z7XH?`#49wlmOuo*GsslHkS>%k5{Y%T)W!nPsduP?HJmjsqB63NfhiLXe4?~i-741+ z#%mHmDTHa%%k@cnwI3qcpK;*Gv+{4MvZx}Ixd6yeU5M+2!@azmLv)o!+DB)6L&B+s zN@AZE!dq7=D5Ec9ZzIQ{QR22=c!}ATzSO;h`c26`O>Z(FjjKoo50mo`5KJq5Xh+k? zcasRDhu<@)aQr{i>o`G>k%rVBu=p0y1ICH4MQ2`XvMy3 z+ag3Uj#qcOKAe>k3P>AWD>M1(fHAKCF^MuB6@5ME#wd+`pAipDPyg0B+UJ?RZ=7!D zT(XBJVACW(%Lf9+BxPIr@Z%`!peuMM)OE@f38>vWzMvW)14&=n-tDU33ixV0QZJLb zSC8HEzAgt9P$Ha}rouP}^YZUFa7#Dw~afG9ZpC zuAInngL^sgrZ}}K6~nlYjEjT9T-r0Dd7E&Pi{|=&Ba#E7?exH^nl~ z6ha7^F;9q)!VqAA4`S_~c?Tpt>6A_HdLf;RNlR)iea zQg7PpNW3OD$GD0q05x12EhXMJZZFe zY>k-A1ab1(k$Pkb4#hZ1D5DitT=+*9wuBow&BPVk9Oh!s1q3`Z4=9_P1Pq47oCztU zOB4n1rW%U3mKV^6Ks)vVA_8J;Bl8asp)_ac60aEBhnWg%hJJ@z2oStFOkwTq#&J&;0&K_*6ts&TxF@FPP8l%uG;;zYC z)7)p%7cRr*ZWm@|rs2Y+i*V}f65P0b6Sh{n@N=Jg83nuo-ne=P-ne#?U7n|xPQoq@ z&G)|dLwNVcWq8Nc_>(PSoqe^ z7#>>%BP=5lXIUc84F<{^qAZo-T~|5@!3h}v6e#wtHa}B=PWd8&*NJ802^Ew%TTXDu zj~(AsaL6Rad&HXLt9_S#FK+juq{*|wRTRLh%+=Zk;a>*22Vy1TOb5L8il+-(EAfXo zvUo3KKwU}X*&9ZH7YWxW#nPQyy%GVp!bxFDTKqkg$iujJAH7qpo9cT}DqMrB4#|hO zjy~vj`O3Qvx9lRQYl{9?MrFzAJzP5#>1bVN1|=C-QfpttqtiXtfGFE|Djib+hb!Hw?=T>w>Zu16 za72{ZG-R*(qM)o!KvZ7^Ui3fqZjjKk;05TTJ{0QZl;6Zx-(7E`f3I5eK6U23-$@sr*)g``@ba>-HUUOFrtCA_+#Q%=x74a%0|H9L(d`E1e7K?O)v>Pt;|rD?I*(oc2tqHMQ_ z=fx&^a7S{sQv-R0WDU&;>I)`yzs3#i74r$%uDFRfV~Z>YQquvf9!w0xC_jqR%uMWY(-Ke%lz29n44qmwb)xpx zR{1ju%VG`{FIk+3+_km51jWuSNX91uxCWffh%;dEhLj7a5Eh<-ed>~^t3(%@PToX8 z@*W}rszS4`D7?o1Q!mdiV|v);lTTiTHqPCL@4gH7?%ajFb5Fp9ix*+}{5-UA z4R*GA(B0ZWVQ@e>vt+*Jjs?r2Oq4l*$|jtGC-tkok%t*^z{b5FFq4+Kxk*+;$HdB= zy)In6b{oF^%J<;LyVqd*&K>x}-}`;|PyV<6JGk=nQ!q2t;Caj*6A%xSCeM|_ub-4M zlL|~9L_H=`ijH=;?sw%Pjmdi<3Z4M5T}1+3IPfFF1mA8M+s5UFlX8yx;~wJM*W|HLt}v^?KddonNnlinQx*Ljw0B;Tw;Vu9-GEYLvSm|u2G};@NOjYr)cBa2iB8*NnUXzpq z6I>I#tFDWvTyI@-Oe-`g`;hCn_8~W6+dr&#O>+5MLf}UGT~$7%6DTN)=#bWcXFetp z;d&GX-9f|1>@o~+K5vniHl6#kZCJzKA3k1zZIsK{JDkIr3jTgj#E_2$6ZT3ShA0cQ zIn!ei+9>UGk)xqTn$7ol0V+dkXll!tvtXQ(o_=0GzcZKZGhVKu*arTZ0~Ghlo(h$1 z)jolvTrT-f>J<~-sh_0vm0$fxdgXBY2P7B7v&3rj-d4dlnJZjcq;9p9b6|9{IsB@~ zXm*y?-cO$qzZoT{~$jtK6# zj7mt0t{(+t43v=o0F4098d$iYgB(Ty1ldLG%p1vK#J4DTVEr@Um6C4PUn}6o1csuT z9PV5SU?^zh%aQcd&L&l;OR|pbv+zNj;iZEBmQ+39;tGFU$@h6W81`?FHS%foXaBemfTxf)hIeaOJFLQse zrBD=iP(VT~f&^YT77DXGW- zDB0EblZT9g8wA*pCj@1x$utbfxG%^Xq`$odu9qB@$}Pj-1bK_7cLV_+tnlaEkP(PH zB&ZzvoxE2l6v)VW3r#g0GAf~h&-ZHDX>Jbb|VL@VM*LQ>R!t^D}5{1GTHx3am62}U;mds9#6wMBoF}okN^B z6i)eQoOrB=mym=M8TSta65mE7WKIrcnM-luvbb8Rx0V4pJcn%Z%XeHq@<`EgpcHQ? z;0#RaJ)=rmhuwSkVC~H} z;Nj9~SbX+5=&i0|e>))~CNK`$NMqVwUdH#XbG@_0Mb4(x-`Hf(rom}1bM>xi!r}`r zqLMj;4gxJJul^A3BG`8E<(J^f^UuTG+c)7q|1bV)_|N{+e+pArj>q~we)tGFXpJLq z^W4Wj2_O5^r{Jjz7vRqQE`vn2Ke7Y%nNG_RW1_%(5B0Gh3GX&hnjVSI(ajy#F zv){EJh?5?CfvMk*ddkq>%V*9&r_+P$SFggK{n?+w!__r7dFDKP=F7hT*AdA2+-E-z z7oU0#Rv$lvtB>w6r_AZoXJ7%>9P@EuITX576hFP*GV*T`)|_Qz`n!D91*1{HZGS;B zc+D}fb{T~PN#9W^!-D|?5-M4glKPnDGFhAlMXxgUJl}*)jmu?F#z2hBjaa`dzFNr2 zRcI;Q2zbbkPZ*;-dijxgKNkF?KTCOsI;JMih_G4sVWm#sMy+VlUNZVf2ry?Cw8HrO z*7HXVKuqonBIjfYi9VAhdnL=S$Lo)IZ(1)mM)(}P-;XG1;{^588e0GC{a$|;*Wrg* z=gBg}y|;DoLA7GC{)sBie)ki1OdI7sb0%(~+&jN~0#{iMJ7lQD^+en; zD{GtZczvBSAGYvZ>XN*o*(?S7_2MDJ0BgqCno1Z|Tr(FFM6d@SJx4N;aeMGy6?tVs z4j|_$YMS?BlwTJWS-A<6ZzTa! z_#73=)L`|P2TKC>7@HC+Yl?E3Nmr1P`?nuAP$L=2}mi1NdROLTuSlGakO}d zH99f0CV&E7!jjaxgayY^k1X}V;1tmcs7ShFoS(j7nR#+ zgmO4Lk8|OD1pIjAlK}-3I75?Vg;GUOIA#QxnmTowy&n3#zNC_#YQzzz_fja%u*>hH z@$*z~s=t%(!&u`*eM@EccXycZmBxp>I|#7pK3<3RiIbdq+;R4yfe6(E6qQnr02DHg zW?gkqBnmjFN0z$kl|J#biZ?m6Wb*?J%@PH2Kli<5`RN-0v?&{92&r?8Og*D=xu=wr zw6?Zf7Tw+lIL8_U*b!(pC4e1UZ2JRQjKrfv-YvZ@FTPyS@F9g6?NMs%9pwp{lJF@4 zf;5X0Da847OM%5q(q2=jTziJs2=@UIQRA9wPPcKcZo`?+evapTZ*7f+XV}Wlo`oF8jAPM3QFaC_TTHmzSw&zd+d|;44|7*8 zLw98rwywP+q|vi;FneklW|mKK%I@a;9Q^3&8}NLV2tzU&teB?!V>heXHZs9sbaE9DAO9i>e(pO1Y2|>O~rfc;OGytcr z%#IVbDk!{j)q8aC{r`U--ulDehi9LC z7B^1EDcTp8PQvN4r(p^K*uC8@TQbXG$?N^FYZ77oI0VSFtPq;wCVT(ih3hcDrIC$V z*Xn;aaeii$Jk2X8kO%~%sAQZyD2Fbt5h8--3`*FE1UdBb zcN)x*t*){vfT< zK~?Ejz$19aNk@*8tgWuN-%XDC1JDb3Q1|EJtRNzPujVbX=g(_$s^c z;bC@7s5Fi~HdF6|?t2 zf3j?VSzfZCL_(f?T!dijp}LPSXcatA^z%$SdWJ^`xz8*FyR0WXm~8S$J$&VymP~C@ z7JDNn`%J}Pl&;^zLw95)d!Z@k)Z1`KeY6~(JUh~67wb~@A~w)9R{$;mPJ%1}P2}M9 zGeI9Ugjb{$T%`o_0nJbY5N2K$({+L>uk2<;N+)?rP@F33rI}3B;31(dxg>bWwl1tfaI1~v#?{oOYK++qt!Y&p#PwAQm z0v0tmyrqQh+A9BUM89OY=P)i4@XUiF&vclLTt^g$s0z49d^y=YM??j&4Rl&TI1w|vR zM{9A3KaXIW=P)Jea{{WSPM?Oodw2DbhJb|lU7;RE{9$X)`>iC3d-tm;sn;Kfu9dKd(+Hfo3k+W zJ3USbY*v|ebDGnDS5+YwKv>;<>T0BXZ{%(+J_S$%XB?Qg6v~d+{CL5qkD%H#0%1S% zxu1pem#)CKzwIEIK^bY{XGd^ zY2*!kzs2K6ED=5+Ve36zCj3{l|NZ+Vd29l??L$=L4*XKSwG2VIa}_-x6(X8?W)U}o z5YWfdhXo=0uGMxh7~~AZ4Die#J_Z6~1`3FqXGe?qrX<{lQ@yHC#=-}k8w7~f4reCh z6U&1LV+8n{pkG61TzNe6Xv7kgzQa|$XUtnMxgiL8-p6p|5nEOQ`f$X9aV~iiZgq@Y z!ts@W^44z>@}%y;~ZZ+24gdRD@yJdxg0t*MJ#Wr@V-A&zaBOUb!r;kGH*2kFxW&P=*? zy;n{im)2~g{Z_uU&p??{4aWR$Q`>LtDl%S!oMn)hB{*%hPwFl2GBAnF+a!Ajur2kR z@nQW*T|)KsCxSe3m>v$wm|f%jPDcYbtS>@_Bv-H{#QS2vlUFk9NG2cl zyiqia02@22ER2T$3VJ8ijr$kN?yj#e07QH&)V_i}i^|}+;dC^)p9s+4Fd(l4$(n^? z&=Znb4#Da&&_b0UF9v!Sg$i}i%1`Z)zM0iF_9et-eqI2AFix65WGJbf2|#Pk%rjri zU~`*+8uF$f@QCZA;YmaoOZ`G2J@hYm2pFL)6Y?f$-HfM24t1Tlx$@TN05hi%rxDlC zrU1x@Rg{Gm5*V6oy}zhrjiP%AT$0c&NRVK2Z*?N{da*K1Lfq(*Afi%S` z0cI3tMBo#BPJPJW7)|xQhG*dmdYfAUI11d%<4K?pwUOD z8E>Mw?94Q`_>8dh?JXk(E;YS&F7vXKxyNa?5kTOEa>g+Pft~eUJu7%dUl!xMG|xxEdjwOP50F7OyVw@X(&#vdsC(^p5|sO z*(Su=&kan(iQX*^#vSuM zu`mUJOUn*Vx@yu%m$W;}vJjRfmKX>iN2Y)C-s(X;Q-l|&(IjiJ+{YxCLm}*?@}{P9 z-kJvelEeFYees$Jj*kl7fPx4qajcx5QeQTJfDfA#lZ1Qmo}oEU;kIm)NCf!GPcqJj zUQQlzI+iKPp%s?r?3nUuT|=vy-kI0*_>3i#Nd*UNUni95Jo$FZ)p(F?(^ z2+*MEcGZAVD?a``ZVtNeueMBol5yhsNyib&NlUTxMB~U6U%JE`VEy{TNww zv>5B!3iEO@>*r+m9RB0gn`|VUG92bk=c`~^Voo(phJ~Xq4vPwIH+jkzo z-3Jdjt#u#!tWQQvl)1XNe{bVCO+N%27b>4pG7THwOcgTO53PmBBm#{?Jv+~ey z@(d}9jod{LB-u-J69!ZE3YDib{hR*e@Cg|)PE{8jfs1S?R}YA-z#3c$yzbvwWVWD4Mt&(B>PC7=aqRI%W&*X z;Wev@t?SAh*Z2B;7ZxNxiDwSP{z&hy9W!A(17DZbFrbpPQh8mM{^I@8~&EqzLqqB0nBiTb2IUOsC! zT5S9qkRt^3OIDp*$!W%OsPHzfPWV-L++AE7v?hx(jD?XC*Ar-@$p@-)KfYf+&%o9G z7ske$ETM8lQc9@58e+sYpR8Xe#xm&-{Vp^9)A+ebu=IVCA|pWNo>bXsXrJ2>)umKvD6^I#WoD2LS1R#*Ii%T&Q1@l1WA;hKOnyN51qh}6>=`>WB%)%fr zd9Q{-^w-xkPrYaNOY#5_t3X4*25+E?oPw)s<&p}Ar25G#%;>M>p1i#*D#$z4lM4V0tW19A!)_=9eE~7wWV$5 zOjs=j5-2kd4>D!yK!uz@gC=>mpfcQBc_aq{fj&cV6(G;mKmXPCY&McfkAC+HKKc1X#%i=subjz z%Y?#uNXYSEgpE!%MI)KEEG7!Zc`;z zIU$+6X1RO{jkAni1XOh%KN3)Cz9kzPXR4A6QPj8OMMR!O!wzLVYUx}fpswI>GR|5> zJQSU-R6xNN7MPT$i2xEB2bvR22G?+`u|53j1ps|7NcP zT#Nmp&la;h7dr~cekV^aK&M-(BJVkS7HxnnY6H$U_N?QS#!9$r+fxvVbrZyUaKmH4 zxES_>5J1W#b8_ zMI!WtdPSk8GB5aipB(UGg*h|9 zs$`EMmxM0>`0)Z;Z7$ZmPhu@2*`ll0)sG`+^vPhxI;3}ucF?F8RITgyI*(oxb^Pcx z!Lm6@wj-Y^!^wA(fF$8wJ&WreLPsiVqIMmA6UlHHWFup*+jnJ6%S+2jCF-Ed`@JTa z2T{q+l0DTW`hHx;q=@C2f{P%sZN4x3g9W?fx9> z^!l)|+X13Eq_Foc-b>(ci|7MLp>v|tlnR{MxyM!UqKq|k+_SI-q{^l4QS`Y1wFcHe z&<`Nd7`4hhb@U`#s-E~4)?Fg5E76m6mk$o*yZXun*F0^Q5%L+hG(odCk+q(_; zKIBS$F7&V(*~-$j?_r-kAl>Ij_TZ#=Q&LM{Stjglc5XW}l+cGF?=kRTbtQc+b8(!s z4;Vc0*5457%NNb{!mC0b=NK8iylBT^oa|!5kA{~;<=K>N7s`+NpnPlcXubU|*-!0E z=g&<>6@obhY-GLD-Z#K|$!IuKnvO!{6B`S|h@?Ch+V2(klZ5pU=dN>Va!6Hv?SE@W z8P`hyZo{0@Z>Sr z0vD-dxs>@xvR4ExX{Rk!=ghRPcP*VLchU2ajAFixt+E=qAL@p{J;o=ZEKU%(r zYIzMK)eG_2rEW-M>C1G%Xk&OFbhC7!WJQHFEXI{Wq-&fr0R&-~Q$uY`aZbBB6YrGF zyl>*` z!=CSNa5=tgn53b7ue>m&ww+?=QHl2r;oM<`!$NUra+Z=JnnGDD&X6wVco`PTuQFsS z3VFy7Xv1UK5TZCoK-6FuX9g`|@|ME>WDsq3HUJ__@=SGV$T((}u8qew*A$DIfl9;0 zcu`QekcF%O#0^j1XNNas;o@?V1#I971A|VFY-h@W0CX0bzyJkjn<~R0RXI@Xb1ytW zt|#QxrSaf26ev-iBj%nVq?-DJJZ9q7B|JT92_Qg(fE8~f&Fb|;ZEnny zjv?yDp^`6C7A4}PA&_mDX8|1K`A1wogy0W)To!pi@y0^^+-e7)OH#-eJYGYzkeL8r zppD$G9%9rFNb2L#MqD4Hei9doSG6I zr)y`p*JVx>a--f{S%dj=XW@;vufp!yI_zA20-iW?8s--lIi+s5(}U@32n+L5C|H*G zcVB==4i}TdatZ-0vh?-3TQD;#p^an(ByJjV%ihCwH?hA!GfB8`xY}xnN(Z@xnsG$N3IUZJChC3kcpdJoZ=o4;8afodM_|k9W4L+q7Hn)h2d{qr2XOoL9XN67 zG=fHFxDHFFPT;I;!gK?zmrBqqc&=E2yvFmAa4zI-1uOjoVseT^RXS+B8FT;e*a?IE zn9r=IeDc@m{c@n?wK6=6Qw%4$s!F_$g^%C4L|}DEJh=(5PTldt{qhT>)ms`mS^=^%FSK zl}Oa7(pXU-C#=VDTrtgjx_09l4*Wu)ezpdV7mPW|cjRMAqUFpQv! z{phqHpX|%_xy*HYml_SgcrwZ=S@1rWPey9o{y94DYx6Pv#@64sb?1{d)t{~FnUJ(6 zk$yUpM0pEtW#T8 zw8pd!rO1dGc}na1bCV0f2V)UM=8BSEsvKgnhzo1G4952ASo`oF-75g9o?0d+Sa<68 z=0%F31v$Y^{A9T$UL*`vi1d8b<9Q2G=!6c{$H{uga_*}&%T7bz?#iKe(204JS+wU zQfMMkSdF4YoK;9uQIkSV${nYeR-{UNu0*ls%8++U;f0?A5@eZSu#zXVSs*R#vH(8~ z0Y510iIm||Kp3fSDVdR&To@QEAl+sLzpJZuKoj)4G3#4S@~0NJR1{VW9 zP#lp1Gwve}a9&gH(ucXGbLaXD3EbI+?&^*ZMJoX`Bgw=K)Rxe_VZO(0ZOl$HkYwI7 z%yEOjN=lMVnZ7vOiNHkyn%KQlvWO9&Mc~nEufGl#FJFcZ0(d0~k3?ilpdWGZ3=!Di z^zOYOynFR347N96<5+id-)3d%+G$7Xsl4++=iw3CE@Y_3F~V&GolTG?%n_` z1_Gq4Ki=ic6Jo>jOj1Z8KP1@p_Ifabpw|%kwk*K1KvWcP{f<1K+EZ-~Ut;e#0;#ZF zeQd*xM~@NkDd6Rge+pLCH{g%{7RD3;Y4RJORRCJ?4S>1WAJagR(DRadQ{ z3omq)=PV5~1A>LjJ&Erw`5fHY-ey8P8b=eDAgP1uLSqHqdfl^xqs^2yBeJgwMKz&c z6+M@>^?<9cka@!J~#S|vo>Ge6&63GEA26V;1SE}Whyqf(OupzN~kL*Pzi?{?# z2^nE1VX4~MN62<3*?(Mm>ew!?&mQo2*z+p?1eH($9^D~Bd@xL0pE|JYCz$_rfZ`}? z?BFXwp(ZWo1KNW317Yg(0sV^RVw}m*lB-E1UXqLga>IB1$o&Sk~KLS$J zfPwn=Zp>Uw%hMOeIjevpgfazOqOk8$;-zC9!PKFE6oglm8de=L4Kiq}03=u_k?jBE zY0eTumL(agM)!jKhAssP(mgC7NY2&TJR(u?Cs}2^kL$C8=T5zT2k-Uuzg+^>#ClcA zgR1B^>1Ez8p*kkV)#OsEg8?$tc~$M_{jP?k0R=F!9f;g2wuus-hI|!MRI0LTs3KXg zo0`cdD?}O3RT(GuaZ>PlYpdEAvG|9ul2Ss6IGm@I93E7L_d)ozFezGy#Q8zbG&E#~ zluFKSM2hE>aD;HYo_a4xk7PlpC98$KGh~~hdeS=x%ovacN11UNqQG&Q;(>w%GQ8Ag z@?;=ovedN8d6_3dwT1!_7*dE*D?)}~ENrRI8zC%)Jbk#G)cu@&iN;03Vt_nas2lQ_ z9g4xFp%5jrheamDzyt&|=NCg56y4jWP!!4*)ZG)M9@HyF!5-HC8@X~$NSII`4}Y)x zDYg+>dS>B&5vFkVmY}kl3ch$BVo;52nCohjIuQa4Oc`Lk0!m9jn8o*IB2G{&Bm;uP zuR@_`ilQ5UBXhMB!K6s~2$K1%3xc_i=y&EX0Ui5NFe6LtJ(Tp`<^kk1wl{3@6thkJ zu(`o~%tXxEPR^F#x9=v$Yt%4&B>cT7sE#Pe|BWcNhBDHuC(U`IPfo%6Ojo zVN(DbiseQCf&e$VECqRif*JuTjpbzlZdkc%uxFN2?;-ZQ;5FIQP&#QhuS2>=!Atg3 zVF0x+-e07wa%dKU33Kz@P6`)%Kv^D8qTGJ;0D4=S%-uw5yp=65vGew=n=p6r0_@(q z#hzkonGj!}Sz6{kT6?$yJ@S+x00ZmM>kqk)3AY&F?*$QnXC*v(w8{N_?)*6vUi%CV zO;H+9ym4=@3oUHRfPg{g0wV5p(~OA*1Ua9=y7#buh3|vj(_=7<=F#T*I^4YeE-Wpd z#-)Z&VE^?9sCoUzI3_(f{me`7!WX{+FMsS~@ang}4VRvK7JlvvpNEfp^mzt_`n?ji z_Yfc(_F#QufFRB+wg=x^cm|o+9aZs_9LITYcaN9I6t368!u`|&#A}6svhujSWDdTf zr9^ryT*=`g7NEN7Q4?a0#;;lx2o4fry&lp!u;g-_SE^|+2FPBer8b+wL1f<+QT`E* z1&#j}D~CMAd@`kYWl^>yMD3UZX~-n9;ug&3i>?tqgvlD7*RA=Z7iS<#ENNbaINldD z)KvUj%drB4DX4yeq>ptFEB!aMUQK$9Q{aOa%@GBi{jTE%1m4TLf0A{Wtf|A2^}{N4S;NH+oDqP!PV!GJG8%S@{hUSXT1OH?G_Ba^WLH$ zFNvdwy}%|KX~+OUp4%2G+tzxt192*Eix=&{1BzevbGVRB5R~dbEUm7dJgc~NdRN# zV&A9lVtq44OL74SV9P%O3{1pIJQ147 z$eDW^afTEF4oAsn=44JQc`gAfOq}Ybw4E+w+Yqp+416PW^_k;Ecx~95Bh#=M4QVR! zrge-i0BMO=aLcPJI*|c07~yrMl)}4X*)}Zfh4D_~gQ4~^cregS*F$@GG4yZAAxfe! z`(`P;A1cLL)+-yclEYhenJC!hkqp%}qKAxd^|V*AF8A^bs>ZOb-p zP_G>h<>~i>_e&7|dc6S1FxY`0QTx;>;of0lRoy@@j`DX}hRAk)6fnhhn=Zt~_Wq{)<3s?VNQ!u#SF z2%$_|yohI}p*c6piaoW1lzd9(O?)!k7t|gC0dYO_cXnhxH`?q4MgSMy5W>wU)T)7H z^@uZPCwdm*miDDDIf#k<;&&9NKi^6oqRQ@XlNBz!MiQVHp_; zsT~w>5p+b*gtASPz7Nm5a2X!m-$r1BIB&|ZuVjWILu6N{Y*f=TZ3bKDnx2_LD`tb! zV0Svx@Z^=JVSec}Ja~AYvsTdf&R@L3!gRKH0fds8T5vOxWVZmOtswH+F(oP96mQ34uYF00kJ}$ zS}@q;vIZQ-W#UfyS2!A68UIxm@YL!fKf1Sa6}<(T>VtR3Q92%)D6=NAU;?c zDgwbiCv4@A!!^a}UG>0B_XVE_nuRxh7{_6$GzWUPJ}KqwP(d>iVo0dWw2sz`M*5b+ zc!4*z5g2d<_Kq^*PZxv-&Xz~sQ%Ww+z)aF$17!Gm9}4r41?vOKkn_MZ*!W>x#|fGo zq&ywxd)`Z3#@>@98b(=tHhgzDUKgI>qEc{%{w^mEN1Le56NHxNofYLK1&0kvAK7@VwvK?ZL*z8a#Y-pR@ffwsP3r8o=YnYp}Ml z!9WY0+Z0tv(l*NwAlw9f+#`sXoX%j{D}`{rk)*tJ>b)2Hi_^q9SK)p!dEf5kGyw|m z1Z7Xh!=7PNnV$d@wlv?SOpXD4_5*&Z1?fAXI_8jo#FLD_hnmu=$D1kG6@`DFIVIm` z73FR}@5ph_jy0L{p3b9098PHP<;BtFn}DW$eCTvecNmLDgH>>LX$P)jP*DOx8GSW>xSb zfT|Nr@ATYJNi_h3R@#tdeYqMs-nPe;ngy($xMSQ{Gf{o1Gz(lX{H~JyDJ290VkQC# zTghh}D~AJASm}L!1{J(1sXueO^g5M{N9@@^izIl`RMBA0fI``HXt7cKtP|<~g>iOB z*otLVvG6WS$-zSQ+*}9^iTasKz$ih`%7G9RgKa8VmGPVv2MyaQd#ET-8gKPtpt?4O zk{W#K)M+_vmG6b!*%+{yM@4&z(=QXBNv7kRk~H&zS3+a?3=;5{H@GrYQ7`K*UB*$biYprt!BH zR!Ahk)Je=4Lw&+T*Rc<%7sz|eV?DcTYcOn2BQP{AMA=Lx+~JU`T(hc`n*N>VE`mzr zDMNkM+g#^%OrJT!fDI{O%`;~ibnC9HGM@~uQws6eBX61Ou>8@F!b=}{8Gh;4e;z*Z z+-1lRfLVLA4G-_$h3|jw6*ztF3}-r8T%2Z4l5S_fpv=@v1BKNNy#D%Y44SmsAA`BM zMVMb~A`o&9-hTT{1XMD3`D0JRG-Y5?#n9GHy4jga<<`bJoIZOJ_7Irr5@!+$v^(8h zcgzx^9Ps{id<8(7~CEFtjLqP`@+h38+X0z$@z@7n4LbIY8woS9o-Z^$4EW>q1`+L8+Q_E`j*lKsiTDpO_0 zMbIUtny$CMtc=w`SE}@+ift@wykJnjjMK-;`5>?3D*wGI6XSkAj_bWBPUFiNZ{e+c z50i~)yz~sUaqv)|~$C2!Hj=f5t{e3(dyU zVu*YGCK}4N@Mmpp70zCI8s*Fk&&S7b@9rJgLW57C_pji2!CMzdm^CLOpb+ESvxhpE zV(AmBu!AI&0rx%^WiR7j@e$FGzr83xMI~(3Rg{UN0J@d^25Mna3CUbb@|hoR;1^2XE2_e7)2P}g*+lnwTNNn#^^GcctQ4F-1P#+9m0 z0i`!@jj}crkx%Ea@!qd5d6kU&-uf%7_0ebJnzF8UW7nA(-mK57b<=;rhYVl#4Dej3 z$z1yY$KyPqCc1Q7s(=hs&dmz&YygsrT&E+ANy?y~27wip%N%QI#b_EB&Hm`F&GA*gFO-k;x%Jr zo`goSzzq@>M4=iy`Iu{CMl$1&f@WY2Es(;zaxx(XCIVXRYgWEfpoo>ug1sX+D-yj^ z5mr%X@(`{?%AB>0Nr|JF7;p0p%@5U4TK@UY6nP6Pnn5FvszJReHVfD#Thor7GKT4*ZDOj0g?&LCP- zr>}+wke3uGSNdM|D4{tyon+fmFDUjFYRUX46jWj$jLO4uh-7+ZX^DX?0=OtXh0~Lh zhX_8$00_+;1aA5ptKf0oQwNe~SBby?)rnGLQ~1)A9yb!xz8!GTgfM7VKk~DTYfhi}jzHYQy~e6!vEu&YpV$+6YvgJAVNImv`Vl`H%k@^l>en zK7SETU_YO^cnSKw0la(d9k~DS0X+D|UqX&x+VYuG@WQjtfyeLuZ~y22E8M$%13vx9 z&%kf|_P-7N&MvMI8Am2RR}hvCR2tXS)iti?Q}{fSEthdWr8(6i0Bvs%j_ax?LGmzq zaDq#e3zeHKbBKYd-qoKRThdW$R{>;9S>*87a`fP;yswd0!37_^PC`0K0$B=4O+Hj2 zdwN4w%9%#LlVz)qdwLJo$WR5NlIOi-h6BRJa?22*q;FhvO(mI)f+YJL_$GMqJ!zUr z{k&kVqcUx@=?uxl3rSCXQi9cE;AoNF;t4uscDCFHdZVbo)moD!J%-APffBjR$XJ73Hu=bSu z-=l3Ah7!k>XLDYoAVNK4FR6es&Z|L9`&=aGu;+M|<%&rD4iJDGX%D+P=v)2x`Kx;e z)TWb%S|b3$9+-^A# z5jkNp^~h`(kY5UV?v%M6|B_U;T2C}JBZ z6}FFunt>&JKckqE)rUYLV03pFfD|j2yO|NtW@s}D=-Mv6hFYe2N^mF*0WNC6gvnlXyPQ!-A0J!E283axR}S5s30fU)P! zo`5;(#lu_}*6@HhXCV}d{v|~p?C{Za%{HFaKAvM`1fqD;$+JKR&EP|?AM2bRj>)1S zl3DYFVvZgSrJ}JYb^f);E63UZu`c|X9=5yp?y^@%Yw?7Dfg}u3`spe0=-ERMq=kJ= z-e2@gAGR3C;ndaCW)h-sOlB`!6z~n7nVw&ebl2Voz8L~I2qa??T}mfDC_#WyaWiht zOmmin?X`6V?lMYeO<_d5TbIH=)1J~zAE1r(VbW=O$54Pwh6>3Ot3QD0Q>UPZz|fG> zXiCcV264rdlHIE8b|l=4*YJQze@XakFD@|=b4gOp zl6T80vfFkFBGJH{iGC9XZs@9(UY;~Z3@JM z^F}YTSjtDKz^dhWSr?MIAc84{&J?qBGbe+m^s+tXjwy8?;@zw%UV)~N6ehev(pQ;- zNwF#Ryi0@!b8Y5wY2OcR@Blt(mbTHu^tJv*t4N2&Q-Er8K6w>&GYx>`6Y_7{8s%tQOqFqAaRwnzOE+oF-J*~ZRfbI zcpf>Zrpd0}Gu8vU_TG50K`^4jANn=jq@+jzqyU_ zSGXl~k8=s9OIn(T2s8LV6 z$)kaIMKskg^%D!p#Dg+WZyFG*Iuk2{SUeddq4lSSFDNKRZEjNAiHiUg$XwGogSz|? zC`7;tZ$5*80?Bfyhb%rEqS9qx4IqY3ae8O!t6o2ZDcK<{d?kab*NR$^&AW#bb|WPY zzzq`=4|HxdB1jc>X&)4l5Zmr8qmpi(+LumA0KI}-ka)aQ0GtHGu`s7hJ%gx@G}eY_ zQ>cy+GxPhIKzUldMx+f*6r`q6$>(|9)qXRej&B)qIFoC(!-8Z_Bc6L5tBL?6%gao_ zJml2j>J_G7BO$I7>eS!bma$`xApy+<%*!OZ7zs#22{R&3CrXb^9yr7!#Qmby0L!E$ zfTE;zmwC|_4;#v^#6-vt`W+Oo;(OH7jE?~2XQFy_?%m@$KJoku@aa!|8h-TJ>#(-5 z23LRlDjyaD?4xI&x(w&fpM^Jm^cGxw^BQyz@R^yPhRaW$!!{sT))cRSmDM%a+FFBW zUbqB1yFJ+1+~Rv*f8%v{yt>NXX9Rk5@x3p7pP7W z%DK4~?Co|Lj4@!&6l~J^i9ngWA%+ElYlO=+r{T>v-+;H?eoI1^C}a@Zxr6<(cI_=# zeClcVC;!3ka-Y2Nt-poUM~~ohpZgj3)qn6+SYA2-ot+-c&a_eZ-sZ6v;DEAhbUAFP zhii#aZ&O>hwsufpZ=)r38o`(r&wcXBq34JrfI`H~byru0f}56Rdjd(+iI-g)+fO_M zxq`)fs38zBe`1aWp*@@{v-7k3t^uWe<~b&Ukynp4CaDZ*7QOBjc4kzCcsVTPGp?_$ z%`~(y6~b*z*gJxsFRANG+e^-xHP1 ziub_C`wy>Ay>G_-?0dfn+D8EPf?=cnfXQJKb)m1+C6wruL|?6$)hqGFnV`*+&aY5< zssK!Q?@`~8KA)MK08zNMcQ;HfGkMh3aT&=Zhr>Sel5OLDK0T8|Z_tBB2=>!?Ja=LW zX6G8PxzT0P-rb!J@1L}D57EUQZMxn;l`q;GIdyK-B-P^)DwuE5G2#iGtogcSJX5}p)I-qDf%r@b z4r(5DLDZAqLyF?$ISaW8%CCCLJBS{M^%TD2&caO39J`nMVxN1`^DAaYw7F&Nf;dlX z4%nFnQGt(VqYLd!>m2G1@m(YH*S2cEKj3N#BEQ$wKOems%Ax2q?8DWbNyqu1^~8X| z7$C|nZlBhh!)vlQmmmQQNFK9igOP$fL6UyTR99gykfC_8cDo(+CS}7fCC3;H6A&WK zYnBHz?R1`H0c>)~yf7ez?#r`eEL1)W-XXfDmStHzN0T<&_jCnt!p6teU|DD#gmcpR zhwhXV){*yyMyYgu>mssIL`;+|wct_J;H)?HvQobnImh1Cy(403pmj z0~N+P%Z{4^&KWuo^fvF~DP(isypQU0M8J!5ztxo9zSMBEYM4)5)~J`~64|qUWQ4zc z@_vvr)4XR=5Xtsamw-Ix-9+!mHB>Bwp!zuPnSO-i#6;iBbT5-JmLHMdtq+sBhVFGl z^y|V+ly!)`Hv-3qe3xs=PAC&VLKR;#thn4VQApvrYXrU(dl@O0RC%x5Bq=WqFJe-X z&5B4xr3$qw(X0f_wlhmKTR7A9;BPff~c@6@RTX>7mOYmab>^@FJiI1;|D=6$A?g zim0vx#E_EPZb{goYjQ{-uSxSb<1o7>&!rv;nXUObp35x+F_mD9Fvj||iyv_Z(wYdpvxF+Wj$U1xRBG>Qwjr&;E_uw<1{1jYVJcDyy z(u2~0O&jXYR-dyR5n-zxwgd*Y$pcLJk2W^D@EH4elQ?8H*0BvghMTu;vbWjgXP$#a z9HVIjT_uqiQ)~rg9&INaIgl0j z4tdXyUV9CmxNs3>aQQ4Q%^)DM1#6uFEZ}?Q=TMlRY2u;Vio$>wQdl8|1qM|rO8r3> zxwhv52VFQyCiwTI}xZ!Q$cx#sZi_sPGIDPbB?2|+J-SC&D5-OW9^jU_#9C+7ttz)=0$x`H_4Mp?#0c7gW9Q86j20jaF<=MVkCI%*2_k2HP+%)ip zL}1)kckp~(Sz7~Wp2Txx8y-Adg=O0Nr`mA;{u-W%JDl>G(pC3(Z{^@123_{LA|I6q zv}|KJ?G|}wH`tS}P~C)flVMOEL_re*egkBDkm0NiwlAfMgQ+BDT{cBN*uJ$d9G4%t z%u=P9uGBj*&WZSUTz7uo`4|j$R98)`k$R4#bz)f*_E*l*&+GHo-eCsJ6i};^Zr01Q z_os6|lvyTZz;s_GN*RM>Wqj6v2$#7-_t3Pz;=9N2*NoY}%cR})v!nW6Ym1GS+qXXT zE7oW98K0b4HvZ`tjFVG}BwLt)1feXA6o`pKd@zm({|s?Dxe&HC+K!~ozPhK_u5U`Z z0UlxhfzfC53wfT#k}@!6WsuM8U8EygyVCv4YnWqbWAct7fENj9;1eT`<4P)s1R)fQ z`lE%q-W1BH6n<~dWMoWBj4>=Hl_^5u!f)OHlyPgpj{=yZxA@BV+hai=hIIYd*a!d> z_6VEzI#y|4*WZ<15io_3cR{=o8+}d==l8>qXHUSIaX53C^YhfaoLpm}&a$vJ4h`03QYWK=hi~ z&LM+EUIbZNh*q037v9^(z3!q-W;@X(WBHKUB{j-4DJ}{Lz!w4&n2EDN~UM97svHxNEeJgWusHDL%AG2xU zJd%(oosaDGB;y@GMf|I?vLc=~UbAk|m^O&hN9LnflI2WENjWVzxp-0*hN3S7!^6HR zvL$;)nKuB1%kh?1O4yx4u)sUvJSuyI5M8rZ&M@>L&p+~pX*P7dYu(xNOA|eTG*x2d9xzkJV^vln}ySLV1 z=guD7f4l|fP9n-*k_8dlL|{yB2oF{^UaP8_fXrdU~nv&3;9%s7BV0x+rojtTZ?(D*uvvUY?bYyI>!b9?o!*(<@T(En+TLVcz}S>GCXnaJX}N&<;uVPJMj5m_yqozY8#($4N4G$@k?mxBlTG?9Mi@bK0>xc=@t@TISORje$O z)q~==+by22L*6HxgnbRwGf)pfsfWGA?SGDptJBEIYYH@hDAB^e)n`GcnD31Z+&E*j;@iTyd&-V>fi768Vkt4WNr784(z0LsC^bi z!Z^=9Xh7yTuSx0`JY*8V-4u8OQ-=dJpybig&qhUnuvgGov9q-U8~8(k!bIA;Nk&1+ z4*I~s{W~{Vp*)HIr9G8+t7xyG{iug~6`ebSLO>Qe8z>thvDXnGQ|dl1PVl10@!P$M z_`Ll|TPF@A8j+tMoG&RTa?tfbgRhnOZ3>OeNr>|O$XVlHqWT{Mj*M$t^;HHkK=hDN zd64B{Uj>xv@2l+7uKJk)IQ8{CNq--04;cl1-tTqTJL_$x%d#svXP%a_9(lfNm`{er z!6tjhHdK}#hD=~A6R}*JRRI-}n`D{rzheOws2z{K3L;v)M(QsyM>5w+Sv)*`s+dy- z(4sVuLCeYFyfj&a+2AgEW0`^z0O~;_?IC$ZJT1f%xKNHIHV`KUNa31;5N>Ut zqV-JxUXLOmBz=_jT^-z*w7j6^RhGE|RSCd#*it_1Z9ct6b?I@>un|u|ZrM_+Ye~3$ z%F5dH0Ymc9bKHBC%|&lZE0WF!tB0s-F)%aJv!@Z1R~2kQAV}Txb)hJ?iXeoEqG~Q+ zxhSwuj_GaYKq(}hUweutm&*sdVmR9nmCXo~7k&~W{I!j(6pjrh%hb>jMk7g4U|tYa z7+JWM=_Vcn!`KFz_ZjR7E-|yUgOEg!YhE3O%C)w# zo)8@V#E8H3r;ylM#v=B5V8mOF*f5dvEV#To^^B2_BBvoI3MhdLI1~1=;@#lPJfNtu zT!PedND&cAb(Pnr*APw^tyjjOU(EnC1%ODyTC7YVWY$AyfC_#>O35K*+YpTfy&k_O}m(E{gPm2|_Brcvj z2@lq~utHfUwzlC%Z(N7L(@j+VyRfyr4O`tl%$!()A@(N$8B_BM2p~*ztZlPB1M>)y zkagken{U8_x88<5RGR<2-~C;fo=4yXfu??c$Ol?c`UooGMV=qcc9ZK^c6xfaiMUH^ z_|&;m&}dG>6IU+4i8D*k-P(ZbH*PTZPLET2&%iJJ`ftKZFFeV8v3uqm0xtwyl$;5T zdZ>x(iZV%ccO^8kC>?v7?C$kod%Mf7>aCesSXe#@-~OAg!xI;ugolrwgRAdc$K^B) zPd)Pt3+sDZyBq@LN*9Gb4Ji;XMt^rMgcTlmDG4%p3pF{T7pPz(R@fUiZ@{O}Qrp1& zDA$y&1I|V!Yn8dUEUw!{tClF0vKWt|tW^)VL=Xa9EZ`GYQrU0HU=S!nKO~D*1UfGq z3*rfcpbI|3N)VqPV*Tbb%&F%l^hMCoROGT9=s99*R8^j$=pDIj_0Qka71}u2d-Tid zIs749KaI+I1R1Kr_EG2RB%gg)*Cg+rw0_PV{@HP~^`~uaG+SbiWN@WOLQxW+MnVnb zd@PG-;SBqO_Yziw`@;_I|J#E#Ari-PbQi&v&D}?^wz&!OvvaVvy2?O)t2M>@JMqd4 zs0`eQyFJ=>ao^%Sii`&8jic}K3Os}IlGS_CRpg)j*L+ZXz{DpXWUKvvzSIK#L0uK) z7sdlahpyS66i4N!UY48SjH7J?dAdODgf&QWZluW%QLgPnpnG*I~UH!81kWAM+3%3?sz_g*;Mn z4~h_=&ne{G_Np+?f&yY~h7i7J<8hQLt>4b@$20@H(o1W>Pj}|^g$uy;RDO^92!pbxF!hn_5gPtSL81kN=@`-?%l`R)ZvuIjL+UFvqV;115 z2pc4YU9l2mDZsTagao%>LQW=JqkGBgqV$@9sVV883ACWFs!Y5T?A;l`bp$X}NaI{O z^L48O0ZZbnRJ&Xm15RM67F@e_4NlB0!Ko9cV0CSi=ijC0UV!_L9>5R&>Mx;x z_Z~d;xi7%^3s+F^-GjZU0;ZY*ko9_!acl+wt-+w+3>ef8OrnhKA(Gy_h1SiTE^KaX zAs|!2+Jk#|Uk)cu&A}&s{^w!g($lcEvI4LF@CUHHxemYl%fA8(^9|S`FQDlbOkw+m zgANSbfal`?_nilKSK-XrCtzp0!vIyA)*of3BTgIar;VLGtp5tE-MtU%8=LTWbqn6U z_AboL%)=)>`6-y4o#MTAYPJoX?HsQuuf!q27lh!hYu7)42S7xeil)q;HNk9zp4-^=&zU z7uCpEIH)Q5lL@)U?@46kMWa!CSGMoFk5cF3x{j;u4bD7R1`lpX0OAxZ=DiO89i~=& z-YfVI*hO%kJUb~X?IyCRhcb;$>kzAr){UJEnWVex56nf+Z<%r>_}NAX85`{a`$j zktlp4?{+Z0Khkoo0{gu`y)6N!-!C9@(0eN5jqNY6fML z_mIwNmPdtN+bdtphzG;C%6gl>29%6;;9;Jo@;sp`S?K?&(k-D&91@)v-m_Bw*8i2> ztGAE!goYC8-&W@=81a>R#&}CK`hq?yIF0s@L$ArBxsS3r$#~`oLm@RS+>a!)lkn7~ z`vuFD*|-@z{_<&G`08`-ZAw)=S;gxJR7Zhhx~c_L_B8Ngd7a8+|DzGeAwBENGX?@? z!kM?SDo0(|leI0T%cr2I&0o;_1(cbc<&NP8&;nj)<_Vu>{s9OvQV!e`8y~*AO8djvCCk$|S?L_>yzqT$JbDXr5y@PB55g0V317YDXiiB1m zJdQU-!5q&nEXvgECY(;znulbCjyQ^j&?wk}GFo0p>iyJ03mAigKE`x&3R+q_J;{hgeZ-4+ zsN+kEP`Q!pXYRrU=x^@`!7we#DFWPtPlVI4I|y@}_+;4AgEnj`lTy7SKt$jS12(0m z{?j^I*pus|Qn zx4s4ITifu;H^0fQjL(1Uqwvw6`5e#7y9f;3{?QL%>FjBE{OBP(czgCxP#>S`D#`-FP zD>LjRv$fgbu_T~k6YKi`>wf0kIRw4dV7I%6pwj|O<5;ztLMkU=aspyxd7V7f*Z$Q7 ze8}apG|o9GEdgd|&t$-tvoV0~ahj<}!4w0idHdz_hyVbYKxV&w;4mu-XYx+T(sj2m zvQ2sw^XcL*&6G$voM{4T3a9vJAInOVGIjNX303KyWCt!BMWGxMw;z8WrzpFM!gds) z`=<@K`5@|3E%Utqh)MqkPqpNXDvuyRx>3b&-0%C><%q!Efn|+*Usb3ackfZ_{9#^` z0H3r6a0sh~=4V+XQ&)MTp`2Q@rwlc`(YR&!yeHyae1*Tq5#>hrYXIaBFd7`eZG zRTVO!Zz$A4p7u|@+*)Jfcd3q$KI^T?K6dCqOU#X)Pwy3Ud2hxQcj#xMSd^0tM2T{0 z#!KeTB;AEMMh5~$6cVz-XMVu91h6qc#Kv4ksX7J$xUs&iWUP|{N5)^@kpeo*E64Xk z09lw{2Fd`KxP}Xf5!g_hguaZ-OVg9}&oVEA7Yjv=uuWBUMXqC+kl_M(e>b_WjNm(Z z3Pr`A^<<^l2#Ev?1OV%oL(+_cuJOtq@O}ZAcvaSnd!L0>t^};BRnpLfl-S!mSV|uO zX!^HNA-7JAp}qpZjlMepU@BnHm^Sh9BVCU{+;dQ8< z6fw(&({LbGYVn|wRLof*S2atYdFZ%iw*SVUWpbKdPUkBKsxM<&W(#-9vZi<`P^Xuo zg!-~A3O51~Ex!O=vSFSM>8-B?V1+O1pP}-^PZHNa6DYXR3DBlZrp_ajXH>G5MV&$K`iX>x{Q!5QH5FlO+#N`n-7B3tmg=SQ0 zpd}{LY)ex9kUe9DJK|NtM6#sYtGge829!RW0F|8hE|e$7`m|uhQ2-Yp^5fKt%0MM2 zr-pz)O(BeO3XUjQF>h)^@dRQoCC!W_#bgy%x@x($1oVJ{*lztrkyQsNdFIG9a_IX2 zIAlut>=f)P6sY0NkLIm{Ql*X;^;x^U%+Gb#Rs@6rVCxurljJQ83z9VBjp->_C*)nC zG3p%tM&2;3CddLuuw<$&^MZuMon1t{xA^ns{5;H{!ps>LGKn)CQdyJ{OUt8BA@U|5 zkg?EI^weDxE|n=q3~fB3SPw!doe`O4BzQK3pNPS+sc8YxN(pbu6aY03FskV0)i+`4 zx66i2&fny*se^)?57fyEop2t<fJ%0gCl7f$QYGe5i5ZJhN|1K;% z^DF|jt1xr^3E1imP*~lAYz9FUyuZJ<0|T6YtGDmMpS^PvX6F~-?3E|jnt126*WuRd zKZ462`vko7kx#${1aF>sW*+7ma=2}74G{<_8H{N(GiIo7G-Ts#wWq}^4)3LGPrG{q z1X>=$4_va^!*Wlc_v+(m@`6_(+)1QMkUi|@l{jdKD{^C#nJNTtv`*m1YTtL8+2Fbx5 zzU%tCkKpTn`RDMp|Ihy$`|k|9oZfrbfwlDx>};$d$a4=aUbz4lpE?O`cM7h)eiw$> zprZWQ=FJuooCEEtX*le9;=&~+O>R#$@m=eLtHJclG;H43fWP?jKZRKY%b$B*go+c` z)+aArhPlOa(4vfPl*tPB4j~t=9$)|#jv3!|Sk{|ySFpl@`7Vg{fy0mnYNgIxV87=( z)SHJ0dtKR3B}ZJ?CEJK&0KJI-D_fM%LftPUvz3MD9$jXaPH%xh=jfGL5V-k zEAEBkUF)lsUjF1KqA35gDd%*>KH~qvet^RyW$^EoDX9j^94^wv=l3n!Ma$^>y(Vd2 zMY-NbkvvS{3d+tg)aS#zD04}vUZl*)KxaiGW6(nY8zBO2wFHy_=CcCLz#(lZ(MU75 zFb!{A+hEdOz;nHW`%!my2WXy=XC_TK0{fRwEaE=ZMsR!sw$T7X@*RQ2lx<1ymZ%_= z!ZaS{igd5j6x0?rqYY76CU6sY2n4>a_HVr0$cJHvaR7Bcl+?1Dd;U7gmZf1Ff&toxgMYgE8qfzO8QLdzQ()c^-_ef$$F7Z{Uzi@2LV_G2~~Q&7%sW zWw76v#6FCPcak>P!8OBmkgLdEUL1 z$H$5kZyKny)xwB?pHzL)RgJu|PU75PV8xewe|_$GOMA_-*O)nDhMclY|KRk@C)wC=Qi%ag8o2uf2vp$b1PBlqK#FLtUK8xiqU5elmGhjk z+JI#E;J7&F!uRY|K`B{@UxU+QXYs(%id*BDSk+|#m_OhaR4S^+lk=8%j*lD&$5 zC*B<_r@OksUQ)!b!rmY$IH8-WvkXy2bezTXWHyNd+MLb>=aLETAUWaF9V38t2HZ(z zBPC~Jj-X8XfOsaDpm)F^qP#Z~4>DXQ1jbM}R&!y2Q%{4sHD^giE`C<|I4u3QFO88s z3g*-gG%j0LuL|k46FwkGP2T5zn8LAIICG8<8d^)DB=-@p5b{+5WLk5xFm?L0cyxJ7 z`={1i^<<)+u(@sXtqjU;9>NfF28-ItJtH6#gFelMq>e8H041=9u0F02%1}mGi269T z{jCjFbkDu?BCJ2U2c4A%aQ5^m*jjlEr+ zkKqgg2QPi{GcdEf439UrU~1_kG-l^v@9sT#;>t5{?Z$29uX^T_pM+;W`+1y)ZTRNb zzX4Y+T!f{?6R@>Cgde~94!rZ$Rp{>ZU~YB}W@Z{}(VU)cv(P;|Prz%2z)gqAgh?>& zbce9By$uT|Ps9J{cYYWC>3{aWfm2UEkATYt0wtSRhdEe4;OP8?3-IDgFT<^C@50^t zcX%vMojN7y2yqTwe(Ey((l37&e&>JskKo)B&ms`AhychIJbJVSckbMW2M=)_;JhGk zhj;MBx<`1t-~c;#=t3*Y|M_u!eQpJid(!tKmTk_wiSfFL~t zxOy~3g96$J#1fJ2qx+9w)>}Jw70$uj@c2SAiV{3Be1n8yrkjrkDc(c^9mT72Y zpY~-9i*0bmG9iL55|>z88^9?iK{Jl1@Rqd2EKQkaAgl@<(Q*<}8bc&~3>+1<2N`&L z&^1QTFe~|f3iCmNPzZNB;AfI+G7pZ)%KEU%8NV(@+dfJE#65Kslo7t8;?Qyq0z9Jk z%i)6Nxb)=j<;SOUQe_nrDAUYg``3B0{yVPmG{12<3#)E=I$=6Z};K$-Mi3b#HIlQ@~-A=n`rpMbCW=GO4&O*GmB?;i$VAv zhZsn>Qok&jhbB`43aI`h`~qTdVtyGX$|}z{7eNY>MJ+5Md|qkm=--yTDRY*^Nxkfx zrKFa74+CUuZ%P%cRQb)^m^J9?V~~Iz5EV`XG&1GWF=aW-fm*S4E~N9gJ~ztR*?H9Y z64nQ}eZY}8P8OOlZf+U?bC{Q_s{uag_y*v>nVf7tV9jLcQ{OH12spqx|Vs-)J=D&;}CCK6AXm`zgNR6?~M0{w(DBUDjI8BO&d zuERp93K+CeP>TBz_alcDlz(wd5QKoQ}zvDP^jsO`@xM-Cya>ENw^9 zclFKABlRl84%BR~uh@Djk0Yj_k1?%LQWZU0vCq>P^1{=yfO6I%1T@*44O2}&9#&;kA_%~>0RUj;gmGiQXsQ; z3<4N_AStRLcnE=nBr!LPaOE%nLJD#z0Eca0-rh$_yTgUJ*JXYXPIF8`1s?jYH6?-t zc_dN4E-lH_qD857VK-g;E~jWUQl?R`5HLbhA}3);#HGT0UMl}csURAK`w*ByAr;J3 zBdLZhWj871;(1kYs1R?u%rj%|{hH>k<~Anhdj{#@0(B3W8XyC@37aC7dh*D>wRl~7 z#zL}`*c8PtuA_y|v6oM2q{}jv1k@EYm#~fv1vILtuhX`QcNlMw1mrZD>iuNGuVb=Y zNk!cQ3L&KL35=n+M)%Wr()jlfoOt}k>(HE&6x@y31kNyQ$Gta zwz}gH2^fwyzsu2l8!(dV=wIIaV<;d2F+*B=R2N!5tdz>;P6tHBA#xkM_8T)(G9U07 z?rsY(IX?$GJ6o`M?J7L^@lP;M35A9c?b2U;^ZT&2u?DMa8?b)!I%ffzI&}v7wg+## z`8vFfZQZ_in*pgyKmQeYbmKY#U?<>{U;Hw>`s%C9$8!7aZy<>C5SE{N4z_l7;Q#(# z{9oXA|H=Ox`nV?$ICNrR9!{K`hsBdq%)a022kSwXawtf1CNcsavla^69)9*KUx8;|d>&RG+=K7D^0)Bg zZ+-)I?%aXTeEO64p35k#7jXLAENtx#VSafY+6%LA?Q7TIYhU|1lR~oB5suY=^uPZ< z!W{&6zWrx^29Mu)n~nuo|HLQZvtRx)urHgJj7QC;a2FN9yG-`f2Jdq@RE+Dg7@&R) zag8n`$g;7q4fAsje(;0W;a~mB|CWh=zxoe<6Ro}1;f+^bfh(W*IK2FkoZm}fKqV8V zqs5p=#pxU<`pL44R)=^%rtglzy2(P}7;>6*fJ6vyImzP1b1fsc{vHA^JqBl*P4R%t z8!go=av0EFTKZsJ;RD^t9%E-&ANQbA4@FkK6tJWdjY0}JwPY^bFLlr)9LmQSGIEq_ zQb9T1FUsR2Le@|3b+k55RH8Gb8s69CLgq1N+ASRKb^L8V__BGT#vP|?nO$mK%8&UT zijHUSL2o}wi_@Y;N*yUE8z)8pHEMbm4KD*PnUB=Fmqghf0`fxtHx#|k%M9);#h3x-KFR0%!&WL%OkT06;X$f62o=;8^BI&Xnd;Y{MOg;g8B)B`uNbh&u z9Cf}PdL7e39(zW_uIJ0bii%oa7ywQ`oLHq+SPBl6Wo`BNnwLy^4)G#!VHG;P&p_OK z`6HkI=gw<*41LHTfdB&h5TTO|P30R99uZ(o$!6lj;SegdW+>EVl#$L#hy{T#{Mn!< zArh!`G8ZQP> zjAWNGUA3nIcqV)^O$nLtkXXAl^a_-i*D^nm!eS}215W27!k3FRg*{?8y|{QnIWHg` zXD3=;hr#9sd&fw)lA_GH^3bp#;xz`iEdn2kh5fMS2)$6rl6WqJwAMb3FS$DQ z1*{4XI$iv|fGgAoAxz8(V8P_kLnSj-7j*(6KvU)hu#YTU3ZBq=^7af&pE-wRPA8;YjS6LqHdYBjp0<(Hb!?wU7y-P<_D3_~CQi^);T; zC3!WN7l3mC95atBo(~GvNZ)HnN}fg6dUe+nP_r#VDPhMhA zi%oonq?-1bv#`6h12^A!2QFW_0#9AK2v1(T03ZM4XW$E8{YAL+>}6P6?c+PT@Z(p1 z1P>mr!dq`&h3%aV%wyZmo_hjLAV4*Z^`{IRFMj-!@QKg70N3x_ht|R}y!4sR!Hb{# z6r8|5>v#9yAO8ARIW_kl@eLt(KrX$`NeVxjA7llg^wlcTa2+LAkmJl>PL=}>tyt11 z?2VqEpPz!|(~EH8%o$WBa(MgQoABBTl*9{~Bb335ybD;Rh#wO@+78Q1 zMc6E>$pL1;N>v=y9pGZ0UXyr&9HlPxF-t$2s2t7mWfngZm;uaKB75?r^%?hf z-Fp9i+n=b`;m0Sx%b98413*wZe8|2@>0O1?GLQ2rt)m~ACCUFXA=A`{vN6+&!P883 zEC`mzEC|BL;qLuaxcA^8 ztW)Z1szN6FAn%762TgGQyaiR4O8F(GN471T~rc#}BZav9xHxB>i=XQ&?HrYDRo|=oJ)NhLZ6)>*D^=cy zRaT}7wbRvSinw(H%~zLI!edF(DSSlXSoshA7bk>0p+4-AQI+SN-r~Vlp~?oHLvzyb zndrFPZvBM zjH^i!z%+Q@@(Pw}@HPaT&Si0#bjF(38z=j5@m>ob<2Lj9(f2#s6f@1VHk3->>PVY*njZJa7x4u7xX z$X-IkVU$a#gM23`tI3Ok0Vy2oVbRraJn?jLLrvS;5YWvTh~&l1mcT=rqn6c)d62w> zQqh{?a3}K2qIzQ)1Uxb{svbT5ZgzGAZN_NIRd4Gw{a)aA<&bt5@m(jYFVS&LVic#a`@gBf+mArp8*KE z3OXc6QAR+sF*U>e)|yAlA&2D+*;~ssH1it%bWka07jEo_Td)2Ax{p`jG1UkAx3{~4 zz|T4ix3^&m!G#OYzrf|wa}OUqhTFHVbJnD3v`l{SOJ79rqJRf?Zgcv;ix*F$0FEFg z{!m6E3YmPo`>U{u^?dx=_fat4g5j&*gTD90Mtrt~?D}yB+xctFJ=0 zcoqQ&4>PCFLQYw!uus~v^C(c{@aWMdT)Maj%ctg`vpZk_hAg4Nc#cZ{VIk15;=; zAi$T57bFDdZB*RKCWF2kn;m$xvW~z>4{jqUwt7q9 zNmTTb1b~EnJ4ud^6;Ag+<%ogW{03jCV>N6~ zJ5xbsn?KTwvh z)=~kwAxNNQzL3y}mWCQO3@E-S1~&`IXX(X2;2sW@eJQ%N2Ns+2ca zm@uMa25NL8HohB1k`b6-CEAqhyv@pb!wCT(g+7^Q1W#NGk)jQyp`I8X0vIKoCGM~& zV(9O(`BW^kGE*TLY3ZsgX0q}IaOpUdO8#rEa6AzP!g<1zNV#kZQ~LRU5uqZ}Oj@9x zF5JzefTNPl+#~I_lKFN62*zGR=>pT(V7>|;z)y<74(;}3Sd<3dIcM>wWoVlyA08l! z78CYRv9#q377lnkIV?>TKlbcmFD3~+3w$sj?a!N(R-F2SR$`&kJ|0Rr0b_w&)k~Ue z;>uAD7W(lTuEk@OX=W(}CrL4-w3uwCXRnZ*;61}#(CS z;a$qvlZ*O-=a;9jq*FY{atck z^u;-{y|F30NW@_^-GZfOp22_H@Uy@C%dmdu4s7mh!|hwwUn-Lcm^pJAdf3iK@4N-;PhNoMUV0H%J}L}TIqdBqXoW%r z{Z7NfTLB_?gxa%Zg~rk+8-DGOq18`wy4ms^uGHz4u!11c_VovF?dEO7poKiWyR{87 zI7gOGo`RWKoKv)R1||1hQ`2#?U5^zY7xrbbC~2B?v)EJ!!Lwj76;eO)HXA^PQ#dL> zta11fBA@`YxBmcpJdyH9UN(s6FlUUUsg;AQP|vT_T3HpO55A618TN22*Cgc}SDpV3 zUhb!??MJOo_5R~;i%%5%bT6pgG&+ZT?f1+D@!8dsIr}ZsqU=>ZXh@*mGFB5+#@yK2 z=>6gL;hb3jM)kFgX*8Rc#2k`jO3iG;q)>{PNLB14_BruvQ0Wf54WbnZ5v&9`g zuXf(Bt0b>^R2Hd{^m(R}tQ9JX?7|lZlzSajyyHID)OwLNGKNzLZ!L=W#X1LLu9N< z_*F_;H}TRa0)HyS47f79mjNA3c^mkVoPZqMXt19WAn z;amtN>}>M*bROMj>AE?)AmLuJ*U8xB!Z|fWA({G{JbkF2+KVS(_T;j7qp;@_f*l0r zlGjV44JR7QFgHI1QwZXmJ$HuP*%#*9aQ9Y^4^?_*Yj*(OfAwv6CuAF0@XZ z05^w91cFGNNB3Z7{V`m)atRhrorGS$gCGjRGr4$-@K(*sL_#`=n9{js5Wd1T2@&w5 z&$sbC1Ue6~@8?b|!ybY>>)jP5F~0bzPs6)^^;gUV_2}^<*xB8tY0R#=d!0VNV|K2^ z<&=F{J0`c9>#l(<%uA(&i!?`zGFlzXT0sXDZM8*`NuW?~HcR0`?gOaigE(5Pp>vs$Xah0>^z^X!eUR4#`=s{HVLJAQdp$>4!yW;#jP&s!F zTy4!cICxHtJ98%m(Ik_Qc(f3qHfNJ$GJnURP5r)j(NbweVVRBO18KW@!lZ_24-tko z15Kh1$Pav5VBkWD(Ip#gIXX|0UoF*>|Wi5LVDDp zq?Q(ixh2YP76k(aW}3~&RYINtN&*b3?3n8n0}j?2>F_`IO#^nh$NvO z@(v@#x1r!31rV9VscUI7dCl4vVe zjCh(*m`VNc6f?*O zS$LOiVC;>gfL#*>ujbqw&m+pF(BIt={tM37(gbsBv-a2`6Oc!|$V%luDwV^A`H<*2 zCHrM?gtLjYz^q3ui}Ttzd^l?v^ATlR(gkQE4--!wDnuGQ zJsrG`C}y6%H-0FZUsJ?avZZ9eS;u25$ndQ^W z-PGAyhaJj*gn&#N0h&Mk<3EN^yz~;h@YEG}>dN!5yNcG)y&gRC?9(zXXeE8+o8N%W z-e=&-Gv|RKe(tQSz_-8iT_zcBW4Y@;ehtoj`RCxw6HnsLGR)3&VSavr$D7vi^r}aZ$ZCT!1UBCy!FmwxOL+(Y~$FSzjO}np>pu% zyYHYCwg)?#+YE}$Ubw^|evOuZU`!H;<8$i#SvY&<4D4=f0qkY?`#e0j`w;Hkx(kc= z{S!}KKpZhg>um>4o;d}(n?i67;jk>Di>}V#N7&XG1itRvxx-}26jFBX$}_NZ<|4Lf zi}$=IpMC~r7v}l?J}N%b_>MO2rKF_5pu?b!b8U-E7lOS~j-Md|&bU|Mydm(4_Q(Ne z85#0nW&1T%j})po1kYq^(w)}Qy}B~26Bcq6s4;iY(tvGEp=nu>yjl0goW38X;yu=N zxpp0zf$85|e{Zk4hfH0OJ+3Q&BVz>A>ig>7IWT6>(c1WtGDg0YLlR<$Qmjv=mE!GP zOc!9*My0Z;)-Ng7KFBB}2|;Qm_|BUu3bftY%)wArc2^3_DOG_wN9G`PB zd?pXs3@tnrf=rs}zXj~iX(hF(>1!~)b8Q^LbD42JCgWez$qoYN4!X=^tfAS@KtV0> z6lsKVg29kIW{MEH1gbBXGMgoJFz;RJ7M48~SvF9n;(1}sO62YmqAr{QJke-Ara|`M zBnW^i^l4pKcg=-EhJY6Ws7xo1x;cqlVvMTq#v{ANnEH&a;d-57-A0-h{sTHrx=tZ_ zUm167rAGVg8=)`jzr%PByn6e>+98=T@p{>J{#B9Y(fW+JxNVt)+?!`8tgwDiF+n%cncLgT5$dCE$FVVi>C?^y;7zf1*x2Y5g;z461q}^gPizDh{U%w zJ;gjU+@3<*cF7Zglz8?yDDvchaZ-PpK-5ooucb7m_mbyJL1~szL1cgl-``qX;Ln)s zRr}epOVRxn?jz|y1;pV{ltREH$wt+dO~f*1RTf1S#*q56=`46YK*ne|5HjYeGv}eV@)!nt+gt|*DKiPR;uPL{d(b>_5?=bs zSD~}pfq5)zH*PUlyM+Sy%-IY0 zo)ZjMzW%Lm!T%H6c>+P1Gs}x`<*6$u(08%?ci`UL`#`LZA9?vBaP!V}xP9*i?Baa+ z=*K?6LWYY+AZLY)I$r*V0<&VKfUw95yAFRXa zi_7pAfBCoYoo{@dL&HAzb3X^?E}VhW%ebH5`X74n7L?dmTVkT{FzFiup&2~&+zXtF z`;9;UGx(c7{ZrV+v2i%}r%#;1Jxa)~|HuD}|0P^FeG1N&G8gF3A)Xf!n1}>1FFo@oP})~gbP5CB65*X)lWi}xeE@{O z4vcKuxSmi5$r2^gT$oMS;pdd3Jyj0Uv*)nu*npDaa8Tx_?V3!8o&6T-e+o~OHq#W37>pIJWfsxK|vai-kYiCMp?^D<`bd3`i@#Si{9cO zdb|bB1G~dleMBgQ^d5!IA|Nx>6oV2Ohxp8N5-v`h7o5tv-GGy)5VXd$u;q zuCAhhe1@|qHk%n67;@a}8to>N)YDnLhvyFMUvxqeG4I}92LYKTw8gq70JOd5pe`DUIT(zRmyNxpg2pFP;VYyNu3g) zDt-4P7nf}FjQKqCNa(EIBILP7MxCN4lMtpd=zxPk4EwPCt_W$TCCq6^I+K$%SW)a{ z%L`y#7JwK1&Lt!6A?Tt3Qvg4z*T5+FH||Pz!m=nK^^~I5kVl<))zLS3E!}$vWy)e2 z=1S$pT;qVKaJguB9_I|f+fj&Ch~6KzhZ%4bh`#whF7$CM%2n2>ubo9^RJ4eQa373c z3t>+*9VR(f_4qjO8u6MMbFs$~>1zr&S5Gw0`HTz%6wfCgfJ~dm1jrEZ$iPb`S@kUI zQUD)`a}2+4kRlpVPgp8vR_44SQ5m~;rr=8uev{3^#hEG%wQ)5R8h^+;gVIq$8M6kl zT+SXDO;vImm1jl-2m0?|5O^^_iIw6erf!ynp^WNPz!rLWhu_`Rj>{Bu5+%XBQP?Ac zdr8AP$oqp7fK~(2G~x1j&I%WEe2~J+h^>Y{(Ew;z5&;?<5~Sp@95+cyG+N*}MKvm~ z!|wgKDH~g*i(W3)FOuflv65Ww?6HRg)uFw75@ybvW2Kuzi2{*p3F#?8 zI_;Sl)6X3qppFy0Qn2kt!<*t&I09e@+CgsRx$K=2Ym2 ztkmI05lAS80hG#;@fB~9uxdhmoRVW1svXM9^Kf6L_2-Z!%D_OGv(TDGfraK3A@2%sWt`1Qy-O7Ip~aOu@rq*5%lgcaZ_O?xRy55J!@!kfsG_ms zEM-In%ynDfvdyc-4|48z2^EseUz`%1L&b)43JHKl>xvZEewW|H-YXj$k}XM7xN|!+ z+ZPjV&(32XZ0NddK~CHv2*R<44v2tMYIu@_t2qWSIi!%%f9s(_fM;jr5rZo-p5hHe z@1T0kW|FaO@7^8G)J4D)C>f*>O`9i0#$Gy4TzG=L)HYUDV4K2z9zMkRzQF5b^X<1e z8{6K)`>=`kEn=O2=I1^KpM2>lXySV}H+SJX-~1-L`Sx4zi&vh37eDz)*u_37=a*2x z_i+73KZfqg8qAzK2V2*!!C(G2{|W{OV9cIJFa`mk#b=&_ndMVFP89BQ?bTOd^PM-b zrb9UU+;fo4OfzBa!om_fbNLz0{`L=l>)(Ml-+UE*_~wt{+kgJ2&>?VXW`X&I7N33& zp7`=F!zo;^ci()2m57rkm*L50o`IznaUSf!fBP?g57r(%fIb2vZ{xdu;fp^HzxCVy z0F{i>u<~dFZd|_yCzhAt;e-3IeCj-yZNsu6`DDj5GPv)2`@3-a_Fed;-}zm(`u^a1 z-$T%(fM5CTe+T~Mzx=P@U;MxRAMo$}?*9y)f9gfJ{?;}4qu>7n`1Uuy!KBE)`H%ix z`1H@d4AFS}cU?T=_wbCN)3r0`!N%q$EYO+CoM{NW z@AP43k38=Xgz5GXl<7l{&N2k=Sx&?AjY)cO4;Q&JW8*__&=D>ym5U9#s$&5`nS zkf~B*a*|F+TP0+4N zk*?C0(aR&zSrio<4X<#aw0hm+@5i%lv&0)bDBC^>wFiK4-VNy-tB+5pq46<#o1gw5 zojt*2Dusu6?bYyB8C$E*bIYYBvrl}yQZpj8uxp8zf&&7 z)br0kHJ%%^q2|VA>PITUEm9!%u)5@V4)v^%cIA1LLw%xS2N}+rQM(js6o`9}oR3mp z1M?ap@a7?80FR!yF(@f35!Z6rMG2M7NXQM8Po?HQ$Agtcr@fXGz>{H_Y4qp>7&(|NmpCKZNVW)=IY)aO8R5+C?HgIScDEV zGFz_G?5qGD>|xW8bZFXM(0Unfix=&J`-ekY`jL>9zH6U2p`Iu`@y6loJ8hm6L#!_W zAijvHpn3CS&?u%Tl7AW;nnPYJ1j?}I2i3dX5-t$D2ngc(HyeRmmPMyb()m$2{jCjD zoOig+oKhSF9BZP|NzZm3KTuvMH>dr4Ly0{sZM z2xPSuisj9ihcZJ^Rw)Dsrq7;dPagujh(m_@oxw{=%Z%XRAN`B} z5>7nz9M^FVLE@S7=eX_E*10F2!e@36Kv{%)2%_MnAzesJRf+`WE{tt>PS%LrIb z<2&v=TtUEa0hZ5SgeP{o@OXnfdQiweeF_$ze;!tU@EryhHm+X7KEKM|ESv%y%V1Ee z*Ma4iKLO9Y_$<8m+%s@uaY0fuVtw!2ybIs^!S|uRw*l?x7JT;OpMk~YGjQYXJ=k1b z=P?@W(EhXuH*VeLa>)zl;KbTaT+&ZV;$>(mS98glPwrvX&h(RA^0aEWz}=Nw_O zrE;68aKcB2_rWDp&Y?09v|S~W(}xZeOd_04P^S+Q1ewh1oI$m3HG!o?QtAo#txiy(d<_ZvJvi9d!cmFcfQ-|O zhBJ89b`gXoV^ps2gkD~jDXfub~12g z+)V!-2XqJ7-2nHj8g5=!bjQ^L5({|>cvM8daIPJ4rEPbKCJRsjn@sr$b1r#48Z;s> zla5JvE`48Z?H&ba7a)44SXdGk@~NSA>e z?9mkTkul&59POgi&*X8{N1Y{C{!h?U*rbED$(x-sFp5VB^--SGos&+m*LMqQpEw2cX60jStKcz6Of|k#alAc|4{-9fid*c~aFSq{wi98UsZ}L2^fGzeeo=;A)W7%h%^g`!apA7Xw$@rJ4 zLqQ;EcF{wL`IJmyu^8Dg-g*i22*kuH;=&}xLXD94bA3L z@dmN7O6_nzij;Ztw$a`u|s$Z4mNoakcR?iq`|7PR}5#X5$+jw`KQb% zs8sKv1<0~EaoY1*AAYmY&p%2oB zfxZZk073IF2m%HJ2@oIw1C5pugqEhKySk^Vx{GA7NEWvulbOj}W6Rh)e0P7_y(ase z#mw$~&)r`{MzX6Kb;(F~fA21K&5j*A=V#~q4uA!ul&m~=miq$lI0}w39AQak8gN8F zYlp)7Xk9S~u(HbUf@lpm)?B`s`B;LXbnYAjG4*grhheu0AcmyK09Zh$ztx)JWCWj? zay2kcpJj+=TxeXGlz#>aDb$(Cp>p|H6v%YUW5l;Y)KBPlL{&)XYjyq_Aw>p}Y=!wi z8ac)NJW-v(~GMdpxJ24jAi5zD9X#_%FkWIHiBS<&Wk zaJ~VY2}mfig$N!#tuI_e)yi@#tIkBr;qP7rU}MaH8)OdUqXD2`JYbLj0GI?Yia`&S zX^DjLs@$4j^a5;Y_V<_rra`5r&~8L;kP;iSp)d}8QjG-|sWs=B!78M;0Sw({zzHA* zN>?vIhPg^v!|8hr*af2(sZMAsR~j1&5QJ(<T9%r?=~HT z-$f2c`KY9V5Bg{S_8z_TOTWa%`-3~T2~zdSXFp4S>u>)${TKho{|61$&eG=2F0Fwd zpjrxZcS1*x9>wvWBUB> z|M%(ZzxErn)(i04;Z86h4q4e=y?TvadHEH(_78uDmbv;BQRprDmEo_^KmBL_ioW@; zzZ2f&GL0TS4j}A4j~xJ~y$>JK5AWZlw^6<6%rag5?5k|Z-+A{fqB^hyK0)=|7?$e&=pX#Y{~=wua*htBj&8hi zo$i15fS3TfwiF_bG*mrZC`exFJdMDrt^tpngCc=G;npSqm-gb02Eq%T4z0 zUN1nLBbs?Q_B0Hj%TZXrmd~7J8|olz4jl#kw;lBEa#-(n z9|wRutbtdSuF_#xXAoHfgL=v#dKK$U*c_v&*Z{q-e)h^fuQw=bU1Db*5#*ZA%l4)1 zYDXJce|X!;Z5#h_x3qauSN8bBFW?r>i+rKn0m|N?du|S-)EX&SYNbp2KE0Da_4(Xp z-?j1aw}B$baXIZU@M!LLq)zR8FP7#X)`r>Vh#h#6v%c7@YNgrQWnLl>EV4AFiP6bA zBSzoxEnIXS-Ry}cyz~4cI=yqoq8m;0BuAli16B~jIBjaBJYZn2mgwxd5xb)mk&vzT zMYPY|Or&XEO$;Zo!%S_!E&_m=9?Jn17lDdXjs=F^T;}en7V%LVNTMcR5^5tyiT z!W;cHu!l`vRAxDb#7fCEkzr`0GaBO{y={=*Xs zgW50EftP_!%7DZHG}PQA+MH@lXQLtmefJ~3U90qa}yg_6DbMzp;8Bsv$1f$&?si6)wDSr$cRMrQ< z@hZx&TQfc4Qo&MUxi4)-T1{}g(NCp#Faj2oy|D9thEt#>`@4KEkoXG8syOrj-?*|8 z{x_^Sm4*doD3y~W(!ufHFhV$TMZtq8M9eWH03MUedMRg)>p+;xm886o>7oq{109Hv zSmNjhq&4_vND?YtB&b&bA4^k`ZYkL)iVHxKBCBjdP^Ltz+EX)w0^vCb=oF5SF$j}CtHBU%cwy0p6= zc3g+_;m^W7A8m5K@I1k;YG~V^{_uTzbn^}!KD^JIHDNNcPCEO!SLuc4pQokp*%w~9 zOsh**c-$Ej9Zl)IcW={AzyBUxIe#(SKg^9F7w^9JA-(ytw?qFQYSp)8mWf^fq!4`u zFmN2+aq{4hhWn7C%k;S~{t~@#;|5Ja-#&PFKrdZC%X4Oks#iTn>+37Dxe305sV){I z&O>k%rePNudDzRrQNixT%Gu?B8y?bIZ~v4Y-G30|e4W1Z8(*cb{?3b!}^zpS9o~OSXzFR`NR*)s=4;bW# z!a}qhoE4OpB?V1l`jMx!+o+3r+`Y?;0rIJOg+&3-Ni0&ub!bU4E9*8=!|KU!o|csN2~oTK^X6C* zb2k?Z$gigikeNxp(RMWC=fW&qP>7?a)$VPwO=08psFlMnZ>Y18nSvPBv2pCZ5DVvrl)QE{ z1F||g0mOCbhxZX=ia@FTv$uB%`13`rmwVOo;%BF{bDc+}aFrG@a#`DNeafGEsd`Hh zWo-3F*HDWtp!)8@4^-0ZtGD~3&H*~to%hrN)F{`z)M}EcJQLsxqU4Ao&}Do{RjCz-up3TwAr*q4bUZ1E zt)i9+j4*+2_GVEqOL4M9ITmp&Bnm;CFD4gN?v_R;oB<@HAPtwL=1NKSLPgXh=BzRh zQkWyIicsR-i3#eOCi0pX_+uTzMo_`Ll7;qj<)KniVc_r+4W$e4j7marIV#6eiHaf$ zM~te#I7}t-!1{w1Vx$=$KN=}ZO;&A7`?|4IE;B;V59aWA7i-lsL31${oS~@5SlXM3 z099TWE~^s63K#$rJKB=pDRR(oL<#@}pJu1@O=)DmDLnzzqnwSYEyP)wb|KB8_UyB= z&zWeNo}?W?b^s(8!*&yQ%tUs0KJg+^O9gID z(-49ughxwxZ6P$~zQVlH#Z)5Hsu-mPFko`9M^>i3W?AfMx>Vv%Lgfes0;kjTof zj(%x^fzPGjL)#F20EbKDPa{_(%0!`EJ;i%Y*o z8)y2#8QEn;-4E^9-`NU(kLZ!#r60fbHtmFY_80Lp+T=8K2N{)D{s)z&V;`A?QhYS-gucFJlLZTe)e;Izn4Gr0$sj(IXF%$ zVZ5eXwsjpu#M#0m6%9~6cFF;LAKmf1O-G$Islm!Pk zGeHF~=x|3f#$nr-%bbN4e}Mrmbc{2cMGg97=y#9Y$X>)5{)GYo&!|18Ic(4NSfoA0 z0_V6V`g_s)JniwUz?5eR${gD#ZvJlI>>*A|6@X)?&XO5$#c;LoYe(kT5JwUlhe&VG z8}3(DkJv%Gbol~pe*7^#+S&>0Y{APu*4u`p%I36@6zg7i<|sUGG#Lhc zHVt~R<}_ShZ(t_z#s}WX$Sc*!ak4R0+dd(+r*jKr<}u62Tx~3U8;syhA|@)QG|rTP zD(+<2Nb(@u5WI2dQsjyqjiwy5A`Kd;T$iWK&@s^=Ip~o`#*hLz2E3<#O$(ICJ0&&C z)4WPgGv_w*+oZoNrY~_yaq?Qx{X06}3+SnN5kUNt(hx?_#JLEh=-FvgoZ4eF`wSQ5 z$b7KErHu;bx||?t!>Us&k9A}l@Ohi^zBE4|j(b5JP=i{}nx~r_WuT7tak8Ktg%$JA z!W)9ANNP;p_x8T7(+>igSz#LazRub&{B#oCBCcZw7MhPr$Bm_qiZ?)}Y0cZ%ui3R; zZJrtVp)^13yQB|NG?R~g<}}?i^;J%QuER8^%?6sK&vIBK{r9LIu%DEu+xKk6v1YvVkPLBV+DE z4o$?hlOm0I=tJhrVN_5-5faqa#c(|Vh~i|nW-2H`Ryx_vZCop-Fuj(Jt3D%6LZs{{ zL7%0;u`w3Q_}$CXo+Ypi>}-&h{7>++4xo%)Zy_f zcpN#(r>f!{G$rD6A&qjR@4-<>EW2YiUSsMX+M`h?T)D|>NFl~uQFneOcwItU>v2*9 ztX>))D@u8df}&U^T@)G?ImqI0^O4R`+1+R~QiOAb)F{OBaUSLk?gb7N23ne%(;1ohw#voA!*s;FGJW<@zO3J_EdG&N8+ZSA_nTd%QOxh2I{6`-I5Td_C zx6YoW_uhG%e*V*+GJvqRz0JhB!*IXh;gI=k)?T_2+B{(L>+$XuN9GJ4ZxW*X`T-2#>BePx>!l%}uHS z{#K4t51UF*c|?`~)Z<7t=$5L_?><4;eK_yo!)mK#PnD+W`CJLUGs1(xciJmzM4$OWS*Fk9G{-X!<{7au<66rhl zAJUJ%|2=AgE5pGzd;YS$`zJmA zZF`@mIZkr^a&YG4Ly8UXZX9o7$ovzsLRn|AvZF!~l+IYW)Rvcfw6xq~o|FCk2}cOx z@57@BZ3mD8dTX$}ME$;S435UTbg*|w8yC*AGlcCUj?M}C041gm5E&Ts^!}lQejfzA zvW2xHoO|iY1?nTZ5hSRv98D1 z0f#<8TGGRyuMyb-8|u9eZqfGcelQEPI;PpTyh$PUCcqhhNzmK1?vjfA;MnoRPG?m_ zqmYEmmtyH|Ul?(!Z}I3P7c99$5m<4_aq_->O&5?kc4U1U9BDbj&c*SKn{>G|tM(>y zD8$s31pe@u+H8q~&zwSgrYGa$msd)@R<;0 zJ8q6nkLJt!%jKWt?{@4(*+(4*G(Sh$;Iw&t#H_A_eD&sWZq= z=F-XF$>U&U@;Q{8fk?`?BT*h!*~TmdY74Em-jvB7fhQSQ9aA5p zPnfp{LRm;ORKxr-WxO_Qf3aW+Z;XrMBvZH%=xi`|W&+BofwANiXAtBjeIB z(o-g!j*(@F0NHl047p>#u1Fj=65`jy@KXjUkdDNFMJa$6#)T#dp7f+Ad=t~G(jrVM z2WqhM_G-mxNTijxc=>Z0rWyKZY2zZlAHWij26O3a*B4;O$fx^K3LJff=Sm6kRescX zx8XS>`lDb_0`kEG#SB39I28tqDL{lqd6dAH!zp)55^V(b5Bh*2^+vw9}%dY`2&@Nj|D4H0$WasAL{ zEG94@#-lO+-E?x`b702i`>5BenNry;5x z1zk7@8yM^BeL6a9SdERtcRPCrw7nDB5;g)hw;t00_*@VPi?vP}h!M>KP64DMp?!nZ zRodCzW6*^G|DsT8LdUvW;HrlIp4Ogq887u>Bt$2z@yWK!0ScFmfr}0@5oL~D+*rwg z7W)_N>S)(cG~yRM=05VC!dTP-W(ebosjHH)!?U0wq9F7^uQagxZ32<$c ze4jh?l$_e*02Aqo)8F0a&pGD&nJ5i6FRJYH?SOpKAO{`d^=|&gbXP~_PHd;4^RGO{ z>F-8ErE{NLzeQ);Wf3l>87k#{OJ-|ppG?~q42NaLwJe9l~1I3tPrL6p3ElkZIwN9eWo)_pV~c=pY181wRxnK%^ld%RbvjPI*hIAH?>sW$zLW; zNRvoOxGzT&NjNJd{9GkyI*n;fETdVpm?Qa&OH@0F665mI7?X*FA!BSY-sPZ5?ZKELEr?&Y zklbqp8_Yn)#axCQ(G|?UR7#{1s%kDumaiknxaf!K;5JdtaTm~$__kz@-(Uest z(tZG9Al+_U{04J%$a^A)#gyf8oRUrVE_sNkU01H zmpBy*&!3JCIVun7MR?z%hXLFfEYtawH982Q_ufYz()%C28vu%N0DE?*AG)$1`t9J( zUHXUri~p2{^$tz8_sEBSV2}q>Wh(7qvhj_x;r$94hknEuSIYw)o4tE?87#T+%fCW5 z&YzCJC^i(dTv z8?=7oIePcazo2*Dev9_M_BE;kDD+Fe^h+F#1A=qxoPz~_KR8~KAn$#yDCgR9ulqMS zQfjJaZSu@LexU#d{o9qtT$esl$6~WlUKG_lz&)_k*J;1K782ei*=!Lwfnu*J%CH8G5|4$3O>LOJS}r zt*y~=SR=>5$q(=_?H-OeO76jS{%ssPycEI4Z59)as+OoZS$RH7-8HZsVK6w0?^$s=|fHO_Qf569rG)-&@ z4TElfgfiC5a|N`iPl)lYd1H~(#&eu<)x#!CBWMhhjeCkVWVGAFBcY_FT>MpHs7;=U ze8$7l9xKP|uGqJF529HBflinc-X85wJda_gEOp7aViFi6{Cb?C?^3jmwT<6{lH(Nt z37U<9XjLrfe3!S)T((@(ci-Ln(^r99Z06Zdr#w^mdrB!KowY6A!JC6T)AUb# zabDf)VFfEFO^M|_NMd9jm4*#Hy$T9C<3b%9Vo7q7J+fO%GATJL4J8dzqFFeOx;ri@OO0?b0GL2{e!tI^Sn9)r;2cUy z2=8vg$uq=~obHfInP}q~NI;F3G?7};d;~Pyhte{P6>6aBe-)k9Vq7- z;ja~(DwMZ_34AqL2t=zcmW1kt`-w)|gX} zTDt+Jpi(8HvRWnNZ41z>POl=|v0@6Y1z=XmKNC_br|hO>0x&8mAt_;Q5+dfNO=R&W zGLD!clLZxvAg}c_ z<+V1NrWRAs8sS>$g)!%}7A41Rm|%Cz5l@AZpN5x?3oZka$}-=$DM@H$9pzDg88My< zjU=;j;2=3HFr=0;r_oxCrWuj~oRHBNy~dTFgeaN`8N)e~-TgEcf?!Bw3&s>tBjF!X zc;tSPZpFK+jS*VU{Q}1$+>Z&Q55i9C#VbOfO^pIfQof$cadQOB zm2kg%bp83y(WQ$Qg3*6KcW>Qf{sB(C8xLs|01uRSM}$rd76Qlt6ERb)+y(&Yzx%)Z zpScA0Ab={XH?Gps*$p}$0FURxj`2&^uhID6h`#={zd=8L_ZGeV<2PwD$W(nWX22FC zzg#Xo$O%BLYH7e=769K8sR1Yp9`p%PlHmOO^qsfq=+S-pZ#EwWP-;wHe(iJgcmDR* z>Eh)z+6{fTw7SOWQhktk>y9_ltwTB-lsqL#&_t$M-OTF#tZb_?|hd5zKb_r z3OnBGwE50E^w!M}=-TVAhaKw?{XhT9|BBxHqkqlw6OK+D`h4}`McTam5&c*H`)|`t^1ZCV`wGJdY z5s*pzaL?2v`-L2z3UJeL2=krjQx8OwkVF-O9J8!s!wO{Nn2<|LeL6S{Kt}-Jd%dNg z^Lm`dw0m?&TLB~i-%1_Uj-CAg)NF6jcCg*BM%J+Rz~>S`^`p@d?FHSo6@dPJnDe7x zBY;DT%iSYI)5#jY6@YDkGRr}KqU^(DGNi{_+v11>JqQ4OJf70tzDD~6+vspF+&h3a zC`G*-0Av>yKLF_cQpoE8*2r@t!ny+YO#qls!LkP%65xv$jydj*LgHjlJOOD=eN>0! zsAkzpDwGqC?KW3Lr=?IA)hl2Td)~9ki#x(Dmd??QDb;UgzZM-ZpgV*oMIPAm<{nX< z$}gN2Vg`QEuJqw8HKmY^7N3Dgj4$5r0nrJi1?72e6WWeY zk!==6;Gx~*g|xHF$2sel{1Z#_Nzo>Ljx+CCYh3r)oqh9GJL5GhLjnQjX;>Ld_zPc0 zPt$c0Nl(#_Fc7Wq?OqiwB`w0zcm)SUerwHwaAd%ZkN=Aix4KRkfI~T;;3!5ZlxjzF zMI%?l^F{tGvRz1e+dZ2d-ai#sb6i*1MrQ;#b0EgV;sk&$fiZsWc~9Eb*v>f(j%iTV zHubUci%o~jJv!&k;7Bf?aV`Nmr^vMi;>706oZp?ebbRw#s&*D{N&q%d1Xd#c1se>bT}1 zaU9{XoRlz}FsbxXF>xs`Tu6aX2a@?@B9W;?0WiTRryKcHRv8aOL`T(RXrsIjDZ#Hf zyrxLmDYY;?mlhw3+F^$m=^IVc8Z`!b1_L6U>_Qk^GY^TSOd-kw?}2Aeg5wrRhYP9d z;s%wbOGw&;L_$bPNzGA2r2Rh;2OI6sbQF%B8Ber&PI#ZbRI*|MU9OHp?1ZLhCl}MD z5Lr+t0cWGU5B6@URAaVCszJjF41MB|Ggt8h&G#0K#oxdhlLHY%1?Z+);Rj`?5e>n8 zD^W#LKa?`dkdGpp71?2=&O8PTz?4~gHDovAM)Dn{A#L%DH(`CVC@MJF002nA5Uxlu z5l$kj%oPET#zz_AxiS_|tVTtn$nm4Oh!7XF5$_%V2(KlZlTjkr7nja1odOL~)|{0Q z%hZHRZHtof3|uf!I8a`usYIP|nQd(|2yn^J??ztMX_}OQae^GmIJibi4Km3!WMmrT zsOd|T+vrHr(3}~WiXzuies1)5lMVR>d@8{xNAwW@JVbyn0VJ2R9>`qQ=$J_`_9utK zXrPXFr7}~sa)$q&9-&P1SonRkR6U-J{yqYj6Yg0B(4xnjS9qTh^Uy3^yu@=2x&xKI zTu(q^+~X*K1pU>}Ki54S-hV)MLdT;j$as82`vIr`xC!o`qF>W!CpaH(|CGs#kM7;$ z@q&JY)3A5*Bklvd!}8@z;qQa+-3ncP{sp@J+zq;Z`7*u!nHT7dm)3(%!IB?9yBF#0 z+h3vYfBz@+C;&hJ@cIFq#(fU%-=(Ds7ch_B&Ba7^#L|1KSbv3l;MS7hxENa z`!W5W{)_*dzWV!rpQDxbzW3*$ZybI8%fAtTm@jbZz(;@l&*}D$e@O5AE4YinnjuO~Mg zjy2$(ks-N=LI0^Z%*P#1VYof@v!2nh*t4EZKhKW@nGeo<(qoY*n8oh%3-)^Cp>qM5 z?(fGP6?CLfrSbj-))|m+Z*2t-Cai7!)jmCV_=q+G*t?{uiM*)-@MQfQ6XC80@cO~y z1A5FUL__ANISOmTFl@N(BZ@GrYmWl3ycFjBo&q$#IX!r^Ju+_h>ohyiGIMaT>yN}Q#GClPI{EVZ<) z6sw(OQ86-3MFz&W?(nw8@`+_k8x$Q>O`j@=PIc0qdGhn7^ql$G1p_^`=kam7#PL}j zK*k#H+{`17KcZK3JnWquauXz?k!-g|rDcB&zKKTW`#8%MTTiaAjb3FL@KBjvig{nPGQ@cc{9 zHM`XM%%WI~sMoGFAk!+PvVW9;Q7KwVBcF79nM|8fRWPsRn_+)SWhRaCa7{d)C;>+C zemW);W%}tB^qDyr`={MscucJ36+udxJ2x~oMlaX*ZW`)>qduVpvo=@`7^rV7=M)*( zpmoYRGTSCFZ@*v!3%yJ5nF(9_M4EfV`^iS|(*m_8-rLWQ+RlMKYlBr{;?ndE8;^AY zPUh&t*sopRmD-x$@DZ1_!Dr*dkusk7KPrk0#L9cZCsi6vVxF!`H?oOFI$>=`-z(2b zVUDWqngh7NKjC6&;*P#oVqA0!c8}o%A(e!xsiudd)F=jb0OAA#A%9DxBax;+QKpy; zkg)1WJ{x!(;HHQnt4dC4nt^YDFj%BWSm%Z3#4uNn3OnG>7_#%r-@`fXOZYx>Z-6fZ z1B=uaCI4k2*v2X~5l1OVI@L%@5#tEjyjsVPSm&4N7isR4LlM{sf!<%W5IAm2zOVj{&bp(m0eh)5F#mo%Ep>oX^a zm_RifL>R<$H;p_~Sw6UPoA1q4w<<}e!!Bd3DN{_sc;TY-U9Hhj3b-*}lt$Pf6~|Jg zY>DFRSY(D?wi zOhR9P7h(Is!>k!Qs#%Djc@(rC$xHYjehMv`~zwZcj=V?(){@Q-=#M` z_Zofux4umG9&FM#zx5+JANuvTzV;RR-}{(01Gv6&=76JN0Dz!c z8%lcuNO}A1cNugArwi;j*b?BX0)Nbk2ch^fEe9~>@%DDu6zkD$0K2yt@SZUE!bFwD zlsRpxV9QJo4w+b&c-I;!Ooz;6H2{BDPoiInqX6RU*7Rs|j}EY*!Id2==BPo>Am$lm zx*;J;0RI`38S$F2)L)WyOw-DlKPEhj_i@lE;hAMPpVL?IXERk(ut*M%Cv_;(Mua(w z+^V%UzePV@KzuHSLBHliGHvgE@ru;@0`_nz`ct|H5h5024 zE^vf-`?bsAY$yTL~6YXpqU!QO#yQf=(G4eoRCDidJdl*NQQr~wnOeos z&b=+YV%}iQ)7k8+8Gj2=0s^A5uDzx-2`)Opx`|jzHQgSkwAVZz*?)5F)Fm{q;$jmT zWnCD@j8FWXI-ZSYLP>y)xXUs^$u&=}p5_cuntyp&^(Nk>{kQoVSqEuTwXcaHP;5G9 z25=)c*QLov+xozF=Q*{ZB-UqhKm%vv#Io52yJmES0%bODEz2WsgZPjs{SCKl=wzXv zk*0jkJcFZ!M|FYm_=S%?zdFgBS|*T(WPG4vIL58W{8QKIBWxCwt{nwvCB<sL;f8=?0y`2z0Un~F&jod=(I`cjJid-jT`cKK7BV_D zElt$j!BVnO9@wy;Pq}i;Va$VOU;zLPcEbDpRPxteJ_Cr%apupJoR#u==2^OuDGBWC z8%uwof`>?+f&m%FU<-IAn54K)XfN~2Al-$Xy5KA#N~JuK$N+HHAg!raaT!_cPJ1PT z_2v*O3%*pE(kKZuilYZscp(D_12Rw;GUdt=b8b*9(dacDD!djP_HZv;hl)T*>4?>C z;4y+{17vtp0j~hcM1k~1kClt6Dd41t4O!(1RAmvrvQ)IFd;thhBG?7c#!htj*C?^F z&e#avO%L|?SzLzlgrl?e%4bbdB=P9NlX52iQJp!%{f6ih2K9pMqmm3hZ&s%)uNE=G zrQFApsJsQJno9L8sW-~0FI<0~38DLv4igN@a&=w$!8b$XKvK1<~r`$3mWKsfgU4BYfJKTop20v{CzS6pVG;3)~}IK@5t0QZnd; z-u%Nk_Y;7_k;Hp3=KP~XU;M>#i8=(0?cUzI+4mY+25k|>(}Y>jT?01>UCOO zTc@qyQ2gnieVg36fKZQrdYAS;dY|?_sOesK*25oOqMNUMo{DiDcAxLlTQ@(Xokx$j zJoxzFfafHlufV+nVD{kdZRy`Io=fM>bBS!;y*)&^apf*5Bq|I*+?#KHKtK4?@6nmi zKQ9GfYcwwC$3J|Z&IN!6B))^y6}okMJ2)&Ox^#YxUj8iFy+N=4%2(*ue)sq25C8aI z(vSb-n{@E-F{h0U&Yg=D<;vA%T3H^@4}S6&G{MexSUTSMU@JIp%d~#(0)24nL%MM8 zEWP=YAJDhH@h9}&H~yIZC;#dHl9tb`1P2c33L`qVahCSB_L#7m2N~LIF28SO8B(!x66|sNMv?VmcYpq(vJEYc-v+t>0Rl}PtkessId8KHhxYo!O@!I6rCGWU1)Y0PWxSQ z|Br)VJazikrFXWzNlr9nK%@Qw8?bJJ1DW|xwn4Z^N9K`4tu`tkWByoeTqT7|FQD^8 zkUz(?1=In%a)6<#s`hg!Im{M00^S)0WSSOZPJAsoZG@gic=Bg-#!S)+vq&zVJ!gUW z@JWt5Dx+|DL6P)*Y)~dtUQtK^n@M$L8jI|zIS-{M&RvkY8+r0+9jA$|QyuTU{k2$o zVt*1*7sSr>M-JA=GGPFe@T*!sRt&~i30y`t8+LqpoL;lUB$_DQDkQZ+P#aZ|NM)X~-_x|JX?zz%^uTfDw3u-2WN)7U{vmqE2=pZF$;taQEzNI|E|Xr# zbiv_KXvuJiY|)9Vky%^~0O?=~pzyo*g;$5Uh$fN>2HBbH?n;Ucs`!wEqZZ4;7lLyp zqaE%i09*hW047b*_Y7`SET_GVb)C45BP@)+g^wlT#SQJid*djV`toXMKmG>qjHXEW zX%nMcNJ*JZ0kS!W_ALpR$war4I=*|H13cGCt}-MX}v+b|1 z@;n+ox+kCsr!6(g+hV*#jie(1^r{7{!TmtIJK5c1Fk$J^C6?{c);6sM00r;MQ5rmd zG;#|OW1(-30{AlsjtI*ToPhl!N$G?9?jNy^8waOi_39<+uU(*FklA;C^ke$@H@_8} zfiUI)SlkV}%EFT~qT$vSj~`^@Gp~P){9 z`otyd=rPaZ*ckz=ssD6Ef& zuEFatc;nk)_3R*F(}LN(g{6ff514Scq{9Fjz5V|CH0B6s&wYawB+n7t;rpwO6CwGfEV3v8FYOTyx`H?4*nYNl zczGXw07SeIzA>@E5|;(;#SDF=$ggmZBHDTo+u)-Gop#3YV`@bWsE7_4Q3BwZrT`n1 z89}S<9J8&_G&4HGciy@EUB{WTpXztSlotaJ#7k;{069X`jRdf@WvUyUrP}IFc`&P9 zPk{}I&cN@G!GfB|jVW>@{ZSY-0Z$0^L1I5q2HGUBBqwLKcV-!hSw3m~%Oj3_wl>9B z7?l++l|y979p}Pz| z7V_<9S_TFxg?7OU%I~7OgWKpb-ICAcY)!TEEEuCvUxuTwI?<_eixf$O-zqIsWFTb8 zk!cORBpzlZCaj%sU26oUb?~h?~S5HcC87 z5;bAVfbd*M*eY{>aQa4uWz|g@XpX#5J`9T)j00;q#Njy;;nHxG*H_7^Na^5P`E3SZ z_}pNMXxV4n13NhkhIk!(O-X@~P%brENvC2k2~jl?9V5U{Q@FS*#!8l*nTeFZHY0&6 zJ5{;}H{w9o;<(GiDjyjBhb~9 zD>a0euotX88!8{q6V2!Up&vy94HfQ*XUR3BBX&`Phw!Zr@*f5@R3 zH{Pp36_tWU7C3eIO08tY?;}x2kQ*k6KI=4{NB1>&hs|>;5CbGIIKplnI;vb*WA2af zeovx37}P4+F-KYmlLosU#qxeO@wmd#RFy-GtxHKeQ?Q8_K76kvyDaxQKfKK=HC|%6 z8)*foOraU7%d1LcP@UD0*kmmwCR^BO2FH+tB0qjUhk|SguJHM+d+(t<~L!_A+YC+fZ z*Us{}uIvZkWS@pdLymA;KX;Zku3ito%o;s>=Vt+^Jwq$yHCnlHjRCo{0sMI3h3oW% z&)(olac{kIlP+IM4MFkS)9m@@@f)A+o1jT46xI@~xRTm&XHg<(az& z0M^CJ7is0}Mf%|O0~!bC>ba}eIKAr1wd=HY?mR7rXH5c-GYBBjK>&De-MLTi-@FsV zZbC1A>80?#4PE=vFLTu1uquMH7Ivw3b^>U)OFJlU8=S9UaNNq^td*g!kHWZ(cD8Bl z%9Q{*FVX!s-(~W>D;KZQmw)qb(aP#F>%M7tm+i*^s188g#@Z@v1c&mFOM|Q7pvH?i z3ylKOi_nIgv~%JzgX6SgcDHjLC}ZDr3>=~i`|w1^H>q=O``P*5r`+N%<csnL+&z)@hZvGuzW;AB<`)D0p@Tq2BdKY5N2y9fH2^>L)vsutGhe9v>o*30d%AH zT*+t~8*LnE3De2(T48IwrN~S5PZH$Ls01`NH0B_iM1}NpE%83x!PzF}m z`bSySqJpDuMhr?HL}xf2y8ii`biYu*pR^C-5b1MC^rtveVq2xLa1zPjHPJxrko3KM zEY81WKjdPNJ6miE6kXkt|L%3I$}aR4$&v19r{>M*{s3)2lE0DfZYO}j+CkCjZ_SH5*lXe7#Q|JOhJ;i~U8}eD#)|pS8be5f8i8 zclmJ=FcbU2-npaO+ki!DR>wY^NzYJl!JJjLjnoN?AiIJMZ2NjG{@{sXrPz2*dbXHm zg#rR8{mI@x-f$=Z{{6m~)zSW=KNm#u6L*{Lz5u~E6m z+AEt7ZTW8Lv+S_>C{1bWy+-G6#YHBxuZk?a4l1nWo~>yWA(5 zic=_f!s#5|Ct<_`IEhc5)%YSh9`X4c6#!yk$3TK8b0g=KGTP{D;b)nO(}nWbYejsP z2w;&aMB(X%W|^aGolO+UTB$7O>wG5($i^|kyd(JzyzX?#j!nfWEA`mUu;E0mX|;r<~>dnp7QvB@IjumX4p(XuKSReXh(WtIse&MoVDBTqJj5FyN{Ruh1f zgS)plMb1h`do9~7{h;?%o{`u$3NZPiPK!sAB1mk<-4u%eA+>^wBKX3kB8v+53rTe) zF4erZ%fAcRbYGnMeJK@gm8CeMVQEz&v%t zwNxmI<>S%jx`}!*RLW$AgO+f2Ibg_$a~T0OGp2Y<&<<1|0+698adAPw?wgQP!HvW}`AvIKMtTQef2N!ON7e#k|lIuka7iR!*H9 zBS$XAh<@rZnK{zOhL0YGpM%f_FYSX}CIB%vKi;Nc0F02LHR<;mOqv8|NeCGW2Dl{k>PY5KQN-M7iE^4S@CDu- zw0ZC2yY#L9_7B4~6Ix$8LshXvufOpI{qEoUecB6cxc5?y)z zMY?tCBl^L&za8XiNLzIPQ7&JlOINSZ!~1t>_t6773jY8;0{x%t?PwYI5%v4$xZ=|C z*$p1Q(dJ_s2geR&!Y2W!djG=@sove958qy+)d0RN_gCoh#s-}U044)^#UvSh;;W@4 zU&EAj7Sl;b%c%DLsT}ip_c{$YX?>Uf`~=TG?Kywhk7w2L8IX$H-0w~suaf|~Ptu-w z-?h()u14##NPi!#-Hz;#5O&50S<~I5&L2k-J>it2Mr#Q{FV%=#C8rgH)Ch)?t~vit*}+D8Y6THyi*C)1ab{i4 z8?n}p)LCk{5l)aa?;U#_g2J--n+DoWRkQ}9C?%vpHr4}+R@dkX%j@-a@a;CPGOF#fqd@>@^0fkG-)PRw+Y{)=*H3*2r2eeZp z889Mna8&pj1sf6=M6qHHsvPl@5a286_aasDi7Kc_L@sv zx;ZLP9G%mX)FRs%Vv=Ew@|g%punK7c#$8nUqz<^Gd)2XYb2K*XncmVAD89Rpd5YnM z@3_j5bFqq7qX1W&)OaR%gLF)jvP?T}Yz%5Samom?9yV6qA!MUa|gRB=C-r5f)El#@QAGys_~WwL9e#YofPg_=vEYlIpz9`uZFe+&}8@iF71YQ1Nm*C+&rW^C;(g02TW{SX@7!bdV+|;o`9z)@yfu= zh)b_;J$y*pcSrQ%D=*QDufIwgmoLzn^(A`k%U_`X`~U0z6Lj>5?%lsfhdVoT`PvP- zbmKYNK008ohJW#g|6OSNMOwZ79QD^$xmwcXAQ7)y<+o}{o(=Nhm2>A2Np^xwA+a${eZaGr88! zBwVK;$Hmp5<9Jbeb`s>jq1YY_((l2hl$LdHFV7vqUWaRj}+zkf)F;GhbB zudIeOD_ruu0YRVfu0nNz`2igun%$kI{Fad(Q&B%W9=wjg;856Aaa zT%&5X3&g1J_+*rJ{3$wN`k2^bxk3M|KsLMk;^&>l7UId(2H`qRI7FSEzy=*i4Hwwon8gF2tPc7#c?)BOB%kL&B~8C|C%GdE}2Fe?Y` zzC7u$opN`AUTHa|Gfzov@3v_cn4xGJvF($eFBi#pW#{DWXh%Vud~|oxwP(dwYi7Z? z$<&%zg zvq1Es$4tL@O3zfe%mHbUGoShHS~bbnd9ype*sYU}bBzH)8Nfp>kr#L0CyqzE%`vJ+ zqiVY6MzA=$X9Q)~i7U0b4IJ6pN-j&zEgU)~%`AK3z}n6UhvG^JZ5+(2K@z4%ji$R; z2kJmEpyQI`?=pTG-kD(@iBcSK%o)vX^pO$V#a(sEU#v(f$_YrAE znnG-6ks;eSGzSd#FG0H7tC-sXp}HJtqTDsp;P?R1B;s)t6r0HQ+^{AGz+x&n=d1N9{vH?;Qg-C))NkEQDauRtmE156{T8_tA zzh!-AK!=hUix8XK(B|72AMj(g0hJh)^O(Xew z+;#?Z3bINqEbvyLDQ~Y1Dp*q(lwp~ac1wDYrd2U8AZcIVx#1`o0Aw81RBH53O|?xX zIL#>Sj53{j`?k7Xn#1S zx88l9_J;e+sZxdiz5mY7=x}RGK)I;^tK5FuE$0ZjfkYIMDfWU%lc8^!M0q;penge1 z^RK@~U-_M{(XW5;^)RNPjgte~Iyj;~{pL65JKyfnSAOf?q2K;HzsqT5@4o$haL~5s zYrprq^k;weeR}-n+e~=O&nbjQ2?X5u**|wd$6iX218~{?-~-ybcaO&ma&-Q+&(rni zo~IAK@vms}=6eC4T&Cw<`vP6MevPUi7i07_^aIj03(@6Goa^m_d9D^PB$1NPc0yFc zbqw6akK?a>R^^ks_nr6mUmrwWhirZyoitv5x%xCUM|amKk0-GxU5W67UD2x)h*fU4 zvI;tKf664=E2{%`w#H$OJLR1l2Eb-Gn$Q5edPoTl2+P*)9zA+^pXc70vm10~ZJi$P z?a*eJziS(pv1l?OE=S^GePo-Cc>S3+S~5EGV7b+7D_Mv?HYLO<==FrVq{zZquwFBt zjRFSd(8YI+917VkzZ$f%G#hZcI4G0O%Z%oykcG7SdHi#7z@ue!XOAn2r`H>~A3xO{&4Ohdcu7k$UrPuYFB zPmA`mQkzb2ZadD8jU`v{Ic8OHD)-*EBM+=i=IlAw0j#WT*^M|Z4zvcHK5A{sk&J2U zJ}v=F`CK^d$U(ir3WHE`5*zR7^w=%3k-SE$}qYq=Ojg>&I+d-2dG;0vWSG( zEzOS$-&K|Rl1i6>R7T_8uqsex7D0BJo;YcfXKF=Obk2)7w8wa%V+M4Y1!n9E=d$x> zWOnY&)dV+SwpPBL*|{LSxCo@zK61IC?B_yyY>rOo-lx_=LEg9L^CHnPrya44MGk`c zI0uTXg4CR5&mCu{X-19t>@GzQdApZxKA8MC^?`XxsLzUfTjYyXYO^#a%4}VW@@Y=c zuN4Sp;S@lbBa|Kv2pYnrX3Jn0aK)UOU)XDy8AmK|Do!1ZdC%nqy#fH-bNq|UNtv8* zhy^531yxW2R21#P4swi&@d+qkyrWD&PMX|BmaizGYX%faZ$&YTnzfxTt5GD;``1MT zJQzr60FTLJ!oU=#>J&nJ%jBi%9F{0uO{5V7eM!-AVX#n*N6Rh?|AGn-+E+*(YN5{n zXU6E!!-yW)pvFck$dk&_&70Mpgo{OXUbsDIr;|aEbfnNfymMc+7dlH9a(Rw&+NI-R zihMa5Dmj&R_EvH^2NvK=D#r-;MUdv@G)l&R1@uL2<-Xyps-W}V{G*NwKNGiVsAEx- znZY6sri&>@qqu;u6hgL{OQtW5FiKD#?2Bwd;Ukp08A&;3C8I@D5Cyp}D~Zg&+s1dU zCGrGOI7VhzD9Nw0Ha96GaJ0R}*Md`puhWW47;{V6;?F7pDaaXb(^S&0h;-Zpd@;jW z&_i-FVO-u3bRHhuK7A9C8!(Y=SX zbnyzEd*e$SVRiWN$4nFsK#Thq0NseBG&ca*pkJhvykmlO$OC{aRFy(CDYO}m910E| z1W@t8{ayO#o%d;bZ<`M8eoUYF&3}hp{^D!2Kl1eRH-AD~L6^Mr+2`qn7thn5e(QV8 zi-hOzzW;MhlVp-&<_ZieMUeTNT@XyxiPmfNF;4>?6^<=S=f!6_UBIseta`}_2h z?|+vbz4I2m`J*3G^ZoD9S(J1CTfak}d*xNCn0OMH7ZYcxk8A7 z3*^%|MNi}4Kdti@e>WnXhW^SOPip)fcevts!0M#2?2gx>PW)-dtS!2Tbe?dIi)N4> zX~&m2s=}9uo-0csr)?uZ=B2_ zfnukrEFxhspRembb}3sVjh#N~PNl`iGj|9&w|#>7=`v@r`|R${CAs!!cXvdOZRtr4 zq|2jH6vl(>G$&u9ccvtRKKo1nn`r+yvvGaqP*4OP(tTrt)w2g`At0b$bl3e0ZX4csspaf1$gp%dEbg` z|HOy+PtWRpty^axg35}*GLa*rvCZ<%`8MXUPs~rr$AKtxZ= zPG762(>IwiJE@PK`bauNTz76Cdl%ncQ-m`n0sm4Is7Y0eC?~j<>zdrq%5BJ~ zd!e2-Zr$PSaHr0TM};0VsuE&a zoWRi=+8}lsG-V??j7TjQ^o4_la}rzx10)?Pr3QtI6Ut=&l;fc#C<+J&nI|UeL_nZg zIii(+K{PvdZ%VxnX>>^)^R{CLG(KB&q>c5FlxQRcVMxn(vqK9$6gcF;nLhmZ4(}f0 zdalUhl#CR+$Z)t(@>=`I-X|x-jYPYg`>F3$ND2u`Z5Q=aQ-zu=H`Ahdl%GbD&)SQt zfnFwsiuSP{%m`Y|P%=Va24u=&Mj&#<$%`Zd1wsZJ5mk-w$fuQoEWG>8GN9<7B8<|X zeXibRDMTzkkfW*eO|`TVfjDubsijO@1}sIg02dNhtMXAU*l-2UMi}4Ts+2Mw@9%NdCh)r;lEETRB-*B@ePOYV_If@B}IHC-8w-r3`&Bc-`*5?4s&$x^$F+bC7@lJvTQ0S~EKA<9SO z&E@0l)J1NLAdOM6)>u*&a>sqIB*o|#q3qEy$NcXFz+~+#RjX?Zx=r`?0s!!cQ>ai5 zyC1G)z$TnG-UdI(4p-e;3E%)n-1H38gdP(99L7qXA`3(0X z%Bdq-r!1GG;+D>Li4K#o0q}+B7q97t_=nvSaJ?W!2@NO%$a8RXj}AV*ORLwe(CUrn z`1|3*2Q)dF@VFn{f0tIST&F6ueeL-*TEBWFyyFpVee@p7GRT5gZoE##uPo8-d+#wA z1HFl=Wq8kWS<1sthIzEr3lT9J8+^a<&Nc%xoI-`j zn4R4)erMv?{nik(l6YN>k2F91vcq%@rn(_){&;WDH8X|6lz=o%C9%acFr zFWcdYXVv~W{X_1={+Tyki}dHS>hp!}12I(}*+qE6{>jm(AqV|d^()qa9F>YJ%H@)E z)rG68wE1vCqX77xJwKrSQb~`thjjPeJ-+_J^Dof;{t?~1|BxPUZ?m%m5O*Aa`Qg6s zL#?c@(+HJuatPE}46PXaLfFaMVA4u+}BodU%6RHw9?%sDYDC$!y>S4#!{^9RtkhDbW$iBz5MQ^LCEg=ggPi zHZVgiCn@J6nCJYbOInr~NhF8>Vir%)bR2+g1WvczZ1*?E?dEr%pFdueJh`-)M#%x1 z_k3(<)s`l0_onu_d|v1IbNf64D!SlSbi|!&+d@P$EGU$7k9_Q7kqxq5rbXQH>U89n&H2)}*3-ucd=Vo+{ZOYqw zH5sRjGd-j8-=cZufic~KK^Z@pMkQvXuk5&3>&dC}Jk1{HB8ZVd7MGkj?wFb+9Y>TG zJC;5vxg3e*J8IawJVVJ~yjbL6kDaU%4OdOE>N)7FN~``T(7}%5w2F=;cZz{HXrHE& zP?M^jcy50?N(AR2)dlGh*qLX?*?3(@fE$jU0cq#N+9r-S94y{tM+xHLklz&!7^T!}_WW3ltkB&cw*EEkULmqdExJBp3pPXQ-!s0G+zFb&cfd2WPEm}R&~Re((B zW;R5iSCMW7@B;m-0!9WnnZRZ3vF|Lw9M@IBA%r82G#YkS-+1Ed;V&IDNQ``?5x2Ohf@F;MAbH&Pe!b80d@r zUT_K@6XW)#T;iK68|A!85p~xk+2lZZV)%Cu>Y{B(ow2rQq>z=46YbnYAd-R1MoPT{ zP!RxCfk7_Cu0~S0{!DNV#=$8-xp0)E24KZeLE$?%`T%G!797=txmrnd7D&Sp#bS$1 zq3ruCTIe4Ic>(tDoC*C8;6?yir+pjxwI8k-4+FR%z$oSw`Wn}A6chRu{0og&9wXsr ziA2@ljp2Tou)~0;5dcR^7jG!JZpG0|%U7<^>T}OCFw;yVH1pujZH~}E6bX25mM&eO zjn93KhL1Ps@ZK$!kG1PBatZRm+4KDOC;(9aG7!;&KI4+qwQ?SX_Mj4z8TbI2z+b}= zRpEVh0r-TrFP*zUhYugKL-e^{{VKio>Z`Q7x6J^`y`Q~Fz2!AJ^W1ZE@yowVhntV- z;P!{KfAc1-KL0#{Bpe(-6z+l4BQ9Z%UG+)LQAp_D!TE~;oI%9iqX0@>r86&nhTj!B z?c%RKPa7}4N{<3C(_cSFH~#j&M^~<2r@cEj>4Wcli~i`p{J+xU0A~HcKlq2VzO*Lk zahaar`9?wnho6l*-54rJ95-13I!9b!pAsnP9M2LoY2C}sI%D+gGNpcD$J4tMryYv{ zGN0B_obY0);?yYv=9*|b$iD>0Q!YvAIb9&fZV9JMs@$}lNblS4lV6j+Yx@mm9iDWqOHSN8hgH9qly7|=&4Md# zjw5KFAJ@<3%+B_s_KE#H11w}wMy(rWzvw*}WNeaco~olz7~_E{IW#a8#I&ojUwed+XmHPH-E zl_D({-B^p8Kv|y|u-_;leI5ywS9Yrvu)@JnFwsX%?_qdD;fe^DfOm~Q_x7DjGVAnj zpCWU}X}XfOFDF(j6jLDmzE%*2iI9no)lIl(dFHv-|1&rt3?RVy!|psl1ynXc^^Zd- z1MK61UkYDIwnNXxhklmt$}{LOtu+l`EIZP!h0ipBxQ^=BFhnXI;|Lp@^S1aS2PisAmLqcT7`;-x{0LA{4V%e z^eB~*KrxO+Ap^VW42)I8cPgo90916fiIF`9=3x$w9y|;{ z!uqeXvSi?LG?J9bsmW-;QBz2JLZ1V$!TjL% z1X;j6pqtS5h`1SVZAlasbO(d74NbxvK*|rQwRues1Av2w7?Fh`_q&z*U{EIjq5x%% z9^U7l48GjHMU#U)o=1oTY_z;LzQ6J}zD_HbFEghU091SiXK4S!cUhwMZ{A_<8T9Ws zfL2HM?}auU@_VoxhW~MDq;VS|&5?O`4y0{ZZbMrS@86~M7eC99Hr)4NSA1#X9P`2K zhdHwp^vY(~A;*1p-+Py%i>`g7t8Gk`MdFMp1szEHUese~J^f1W|1W+XbR zx3(twxE2m5=-{J!AJg8=51BUyb#O7JXI^-bzVx-0OCLV~g$L=x7Ae zT^9h=19}iZ)~)SbIvP&t&Vzfjy>&<*y#G-+XG~!!3*T?j{Rj8is4IF)w2dlgu#q@r zc0iLbk#Oz=I=ht3reOemR>OKxF<_Ey9*|)6NR{gKgwKY787?A_0D?kg7FNtO=mjpl zt&uPm6(H{?-lOfEo#=7F}~ z^jCa0YlHU@i^%UE=eYthkzul;f?>yIypT>oJP;P^g;yem7Fz#E?%oH zAsWW{wy_mEM*4!Cy3!(WBx1m+11E@+@XxR_f;{NpY_QV`KnDQPMADvwkW=qNQcM?H74v>lL& z5N7qBJE(3+~uVh0VAlSfeA$%J4`+%Q?69DniO4P(IP2I zL?S{YMQw=@UJ#+8O^D2Z^A87kdNdT`*(ELCte^|PCUA5_Jy9!w#Bw5KOp&HS8i~cS zsHuIC6F{lUlWpGBdwN* z99`Zu50w<%=8)OGr1${vVS>v5>@=!(NV%L)3LB9#!v_zTgcyA>+I~!<%?C8v+6?X6 zQ{5lHqp$;xNHw$r&jevKKq&N2FI+3ty@+{mz~{pK1@0=O_Nkl;iSZ%7NAK)e9uK4? zaleJd?+}F5q2FG3^;O!sdzVJx8Ib)^0BJTq_<$aN^bz^+_xfjE4*k4GWRbb2Y6%OuxfcYYGU$gK}Pq|JBU*0$|a72f62YoDhg zocs0<{+wP3ZF%jr=jiA#?EX*cw7@xW1_!-?RM!gQf!y)hs-S`3xUAy*E_9J?FJft3 zJl?TrANj7a9rLbP2$V7YvlIR$rhSS(lLIDUw=>mPC|i4ffyW|!n0B_GJiNz@z^*ZD z{Xx;tbSK{9q`%{HiXt-rWgTg)#aKhI239H6fXAz4I2LVL(Y6nkil{r%PNrvlF8dw; zFs3vKVDEH{lJWpO5)o*BrBA3$;QA%)>>lz@=+nnrd-U;xN39r+PY0`XTxQ{LQCc|XNY$ViK5YI-$%zRvmLv0)poJXAuV&ePS3ChpC(JO zL3&O%iXX zssB>iK>OV(>RG!sIsDmNqTFfh9y!?PTeok?2kUZ)E^WOF&%;XlMJj{EO;g)s>&ii9 zZ|3hxoxi=ll>M}ZIZIJ+)QUQZXK0`L^uYFe#qWJg;VUw|lLMdT2ViXzvR}35mG7}K zyLUQ?fMx5QvbkmNJPTOnWY0NIM{0*lH{~`M39HRxOM^)cY$*V&&Ph%$va-yvA6%>N zd_FH)awv9?^+&AeYO+fbZPaw$%K!vFFI|>R<9rQP8B@nR|7U&YodJLfMtIZTO}uHr z+(u<9+9GREJWu*iX*+aty)3H?4A7p4vg%@=bmyq09pPh(dTES=+AiuYxlzZacNS9a z*jSo(G-|(=3eubGc(eIC^QJW~^trr#BE!VXd^P=4Dpd)^_n<7DFX=AcV1~^&ohB|8 zO7Cp_Uh4T}hqOE0OF$Idi*;gFHoUuj;IpX~En<#UYU|Skc4ICI2#Af0N(s7a%IA0=BXZ=v#OGCPoVCk56O*GBu|FBO83-W4 zV1u3;7r;UkH=LfrX@w%);V1HOF^)vTNWH*oXmuujW8H0cl|+9C*N0T0kyNxosy=xk z7iO@7K`x2%5O&Ul`ZGvoB7re;3M4@uY9V!&5HnA?Q(*#YyfTeO&Y+dztPkSiYvrWH zhEPU(()1_;CU`ebBCedhw>M>x00rX^F@TR9YeZqxS|&RKabPD1_~lZhk8!VHl4=QQ zlMAj|h15Nyp+Ur%Pw1efwBq8U5mvDpl(X5DQm|Oy6*;vkUX&?Dkr|)b%;l0tSxB5N zfJSg;Ivije#=2ClCje>#DJzY#_B>7+m4lMi`I2fxc3$VF%~O_Hjga!Ciy`a`L@Gea z&*@9F3a9Edjs88+>RgSyv*{59)eyx4nUGhuw7YQxdxapmN0HoH%gj%edj)d5eDNYJ zUAQDN>?zJselCDrji@S=i-yP6seCiy;Nlo?v`qyAYQkmG2ZIaIAYw;4yw3#uKLJSD z|L6mnLcT^r0aWSOIarajAw=B45IxwZ!G&|2)@KU|fGK{* zT2pqydjbTiwSpOVe~=btkxOTw)66;1%cqlb?;^$Oq_ zK&_ns*dS_VvUez{UO^uXLLUNj;>u)rCn7DE-LPSeh^67CIE^OM0CNxlw;#ak<#QYK z+LymXU;35L@>~ZO23M2`?=u|>&{OD+d#$A40=^_pv9z$Zo#PaO>Y^bL<<>xu%pRGy z+kD!w2xrPd_c`XAmIKzZc;;U}YlJ`DG0(9{ALu#7>F3btuRiCQZq{*nk{d1b3{w5= zX1>cmvt2Q#>Jy2uu1RCjGUn`BwcDFoOSI}bS6CqfzLyxt%PY`R4U_m*91&A+Wg>*} z_n|{ePmdmLQ5}@?#+g9?T^t>RbN7!%bQI=b5x%co&?~Gndo+gAhR9KwI0~Li$p3gM zhNx9R;rXIvU#ZbNdT-GYqT3Uurt3?K#=}S4Apuh6sAXaQl;-K&e$G5WPZq&y>uXNB zNNsuYdVWV%B4{Fiw4X)l^r=B`^4y%24Sx)&l{u^}P{3;xi@sAAJ??nCGStUaG2z$=lS$`c2ivzT&saLu0Cr= z*Kx9+slPnsx+8ZWefAFd&-`999pkcbCqHvf%DT zy1wyrE;KF49j_M!JV}uU=@otF*~!^!%^Nb`$396QD0P5>WX7kct(=dD*KB9>1dq~<$69HZW7VVO{$=^#s#Q4^2osd#S@(03(Y8J4$*^2T5$=jAPQxK4bQ|_AgJ9)F_Z_ z?#$Eg0$wz+awuO}h>sZC8jh+gThlKGndjOTGhHNOQf54+JSLbVMfyJ9tP?qGWDU$J zFj=OB-~ma_tiN1m4T|83a}g-B!^p^`1v<7xkwC3%j^uqvF3oJ_7*&8QAD8@E_5+wJ zLLDOEcF01^P$9*;Im+MLYqw;FEKD*p%F+T{%l$|rS{ilAb$|s(byDtHk$Q_@alTe# zs30pb%noQ2T6Ng)r|!IRx>e~D(2y-|q!Bg<+o!OD?AdYe2`MNXOLi)IoN^>P*JHEP zBEc#&ItK+HX2Koih#@NNJw7?0U06!2%t$6-ZWB0b)oIc}1h8 z50$KXX4gvFq|f1q6q|dhfPFTXVpN#QdhFj?omKqTN{VZn%<+vAIJ9vkIQbyF1;>ei z6;eK1`ZPrrIX&NH{b@VLGXDk~mBqxzmOh0@kHbU0o@*c>^d0;L03iXSXnG%~=Y_wK z8U|jL>HfZeF$Rb#$R-u2j7VGgatfz&vgYU+T#tErc=t9{>t`fdrw~xisgrMI=#2ch z<%kt!j9e2?NWdxv9Jn;Kq!n>>q|s3TE%q4DC^fxHqS6GEMI}1`c95ZJ3F(MK0oE#! zamWjzc&5WcN!5gYE7H8dIhE=TnKP0G$Pq;7Q$(_@o?$03d>9$k*ubLfzU$NbAKaz0>ua=xd5xWn(B-}Gu2sKeK$Lg+ z!LMbzEV-kEsDlpBVy1*@P0>a6cgJ~{U3^bA*eKTx&-!pDf1ZQcpWb0T*Y210SBspp z;L}yVsI88LT6w{4?C-n zbpR~ki(9wu(wTD?s9Ia%64yKXL)s5>ZxjI2USCpur;TpB%)F%7E!bS)9d?WMBOmE} zNgXNX(Xv$S?0w8?6Qi7xBWM*DTis%_&76p~BjoeRx!{<#zz(~epCfZbEoaPt5c_-H zI+~m;Kl9Y?J!5NHFC7il6V}jIFD=V_KLC z6>a~nn9lmmIwx>;w?R5KF4sH0Gek0RWaE*tB}o79S)V>Dg89Zb$LJ23_c z3yp@dYJ8HWl-eXwIt9&(YDxW~vg%T_nRJoYh@Wn>p^K52w*Ijm)(Dzd1(2u}QDcP1 z@+wK@(;AujlQ$2YYx$9d%fRc**35NBSC{8R*WLHcHvlR)Whkjj*l2E`4aCXgAylcP$sPnhe6Cxeq+d?v&75qu&gfs-8$ zFAkMWc4v;20Sd~YgUM5A6(#JfRhkQ{z<}P6`BO;yk|Q)KpTMSUaz+6zinfx@7YhBI z#~*Kp=odsbX=Dk5OzhxR!I+(JG!CaY;nJyBpkzt!V}dDG$LiB47n^P zHgk?8B5j)Fhe5L*dn7EQjgo5>!iB=6&vm>d;-ZcQ001@tVH)mdsem-$ND$+)DU95X zBS{9@HbSLy(CEMK`K<)uf$QG;kPfFRt5WiRWyjQGo?g@OS}fGQe2 z$SE|aT!bAS$jVSdkRdCptD>(o<;ZJ)U=E8;sZ+|J1F83zqjc&@fV#o?a}4yjoTOa! z3-`4b@DOCmtJiOcI5YynI-ceYZ9mwg@7}pXJMX;}y4=&!g^SX!!2|5At}&j1{A-(2sPP_*|NXYdOICBn!*QqKvQc?7#0AyUwJ+yb}(pA=X9J$yNKzVs}h0b0$ zPs8bme(;T-((_lZ(n|QO?<69DR|;LMczrOM^pZ^YJd-d-#wp zlmnU;Jvt2YZEI(rMo2-@luag`*EJzpP-cIzfD1*hIC3%v3QAF$IC%fme2NHE=p3U& zN;qqa`{+<~ckSoOCp}?5lbb&_E`1-J-g(cS5zkLHw_Bi3=0Ivo(>bbqe5P;2*lxd* zcD34>(b}bFc`PE^&q{9`e}A*Qsb%|}e9b3s)7*JK=ev`l6Zm&Z_F4SSxsE)z86xLY|C{; zlx6enGS5veqn0Xc{o?cWxN}avrp%87=|080wKNWX-W;C;wk>iP03vNk&-Dw;(R`lA zbXRLjoCPIaAe*kC6N&KNi>*eM(GOIvj&8FW)}o})E* zXBSr!Qtu(l9IZW$9qPEo0wsJEC1xe5KwPOy|% zcFOI;3rF3=iN~BPkP`!;k{GKar;|k|FMuT>)GZ^2iA)p$ofzB!sC3lmd!_U-uf{Q| zErD}qye$zKTq#P+7BlxxEm0cvXp-hmT;wS!5vN=xDocfdGM3Y9`GyuT7D2ouqdcKG z@=2p{_Z3Q7$D$k^$I+{y>CFVd1@aHuK!{b$msZ(f=Ho z!_hLL{!o2HDneBZ=m3;~2VZJsvqp)4vGdHJitWf~+FcwU=6o_zty=e9Pqlm!Lkl zdyCJqT;pP_i;qrw` ztalC+hyf8XfDo&K!nzKeIlW5C(Z`55C5bEqgl2ujdRroS$^cj+`UdZC^xz)t-~51% z0w7Za(COw+e@btC|GV_R`rrKT=*;?Z*!{1RkgjI_nCV3H%K*GXsHz2B-dJi=BK74I zjj<4nW*VEE<(`N)8s$FUMK=RlMM&q-0tVcI4#sJRbH=~c{w#OsiaBK?Kh49rR4t@co?j{ zcdLUbb;=VSE?XmQ-sXpKKXeUY^4af19jDvP_+~kH(tUpSXL4RU?WFcDu9~>{Nz?|J zvbjR}$v$fn%^dz1$EpqfJef@UMF+>{sXMa{J$1$>0^XF~Wf7H`+MG?OrxT!=d(OyE zuDg!uE3T>%<|vnyR?)XHkDJcUX(VQQ9FqL{)+^*uDo&%MEhVIBnwIm}WVRdZ^qEML z&MVKC<=JzaP6>1Chg`;?Ta3evcmE5D93yosPo3U1%6)!gwozOQl$zgmxo^CTJmu2q z@^&6~z3<$=`@3@s%ezGuT05*2Jnrh(D%+4DdTKloJ6+R#sX#4lH2opzWywVcBM3vdn-LHqMWTeSvG?;v90rR zUFYNX?EkBO!qt(A?tH^LB$>4|BknD4@09py7{F1Ws8(L5qEK$A!T^&Z+XVDcm)N`F zUXAZWG*XfkuP@ldzOnE0o|IuA`S{rV;&a11WfENzOc=c=?N~K&_ng5EI2X(-;)SKZ zkbE{WP7&n_AaguScoe0wy7owQh*g`2)F@D7ZJG#T`6adL5<8%!qyUxpy{}}h#`0X( zDT=_0;4$c-z>#aLoiwA(z)ewP;rJ}7h=8d>yK8wj@HFu5v30&V(3$-1;goa?eTIraq@V$(I+fB+-&mxS6Obkg%a|frrqBH1swq-E6cQW=`yXq_#!>tKj8N+1EA4cUg0Pi zq&AJWiQl!iw!$1yQtrNF2d!KZ!ei3BT;`nsIcVr_0Kr0-ydn`YyTa|VeEk~t7gw~x z*adHpD^LZ1rho2yXwOC3eeW&m1+d7hsPXm|?Y#G1c>W>JsgJ4@^5R%mVgOqg2@9qx^30+2h1;Zo@1UO%+;0K{(<^KdZ#Pg+)5M|-zZ zb#dn8r5&5hFn9tm;YpnM)9;mmM{|z6Du-V2se?17L+16g*V@GnhyXy>3_;cqzuCM9xX#Q(Eui!6z9=>WPl&(ylRo(qX`m>o~gnI0MRQHcF@a zXYSUep-ztH+~>~uecs=(UF!6xmqEuKYV1>Ve7is6X(t|SXT^1#zSKtxfig{V>NzL% zNpj@p^bNJItEr}^Ii5hJw4OJ=9r=xCWif$llyr!blJF+>@!m@2Jp)QpE*F&6o$d>{ z6d@!0ly!EB*-Ty?Z2dfg32eQx^7JxSr3E&3=jm*3ck)Sg^8S)^5`V1j&HJp@vcu`S zIWye1BVStIDp+7w$Md!A0v@Rjh_)9+-Qe@TeFBy|&6!i`V=Qts`9_I7pW6M@250Br z#}ye^6JIZZ9gE6#1OQC}=3MBs545oq0U7;L)(MlD*_X%x66?df|I#I$w3-(WLx=TYy1YxAY!NhF`Lsu-Hu|t08rPy!Rx&vdP8)f^bTXxurYa0z(zMb}VJe$X z7A@8=W})kj>H>a_7?_f>q+{yU7Rc1J=mA|Kyk5)T57}BqWXq=kE=Wo$GS%*VYMT^_ z3BIwB$C`%9l?T6k(`boj5_*kF%OiSS(7jJ7GA>O*d8qLP$a%tDk|{x)h7O-h6OTtF zyZYE!_tPqMDDT<|&w`cE^NN%KcqwuuF*DeB-sX!Xmzg$$-m&8ZXOYY9GJiyH;KJ@Z zoFwL)0Y?QmBNR{qK*i2yxW2d6XgfSRf)@F}{4oj^F-U*~3>+kQq7uj2j;gnk#abCC z@mpvIRm!`d2%r&o`h0e&&` zPsS&l%K#G-@)i9TKSst$b zbIEvgF}lLEh8h@NKuTXDEi5Q8l)4YHI1cXwrysJ9NG9fJLi07kMb?Qrf=7i$6UpM= zXr$0cQjmHB;Y{gO3|gU&F?S~SK4#hOEiZ-p3y30|EC<5fgHo=C2hx^t09~gIgEPh% zg^F8vlIfHXS)8cpY_xm5a)`#Po#8mLL>z~BA# zv*F)H07^zuvOByVo)4e{sf=jQ`)~f&tX(nJ2InsFIRGb+I)tbbu2i%KKqde;O91~Q zZH)EHbj-TK9ZD1$z?zs!$Z8AmIyDCk0t8~tBa{gbU=5;U(3Yb|n>5~f9NP0Z^p&Ht zufE2_!#nT1LxT&KnGCo;^$g?|EMKUw6hNgVB>)fo+Jnr8F#rHL4(|osF$f?}t#b$I zgVT{j0;0S)n`iqam&smx=_NXPc#ri-b!L^v{2%}^h!i@1@gn{3d*7vAkjJZ6uF$Km zzed-eyTk3!fBIaGw~XL~1u4KWWunyHTC2RN>AM+6E?eB}mmE+?Yrs=@0dtN| z%GZ#$zr9oMGe9JTmOqQ5)nDwq||Lp#L+I9NJ-22RnGFar^GtbI7 z0-TG+lzd6N1`ZK17vvTZG5o(0L1s1W?;X*j2M@Ty!~M<2Gz>P;5F9Z9>|74|@%;WJ zTHiQNV-Wfd#~fudRG^wGNNB3DD+So^l`{UhR_cnb?H+O^slvd&)E}|3g=-U$CWp>( zYBtBM^4D$tCU4NlJSTxN2jNK%mz*H8)3UGlvze-7bH}}z`98@)7G>Izg(sCkz458v zC!53{d)Yj>J^9w|n8%&2$C~E!b6R2h(az|$KL;h|%&!Ie@T9)Zo$Y6Nbl)dGFn1cB zHc8h>W2oH{@%pphPd;+z5SxEC4~3SoiM#qm2Hdc|Q9Ci86A@7L9eLNb_)gmmm}vnr zEu;&l;D1PtlPU>?A=uKI^ai8PoxW zeK#VBvfur}A~^Sgq>Cu_Nh}&;XSDRE_{BMpV@|mB!6I`nZ;!g#?IV)`%G&3%Hm46< zM}GY=kMgZ?lBf`sH{YrL)on|s4`RfTPXMMpLu|6s?S!sA%mF@o1*_5|)yvxFnjBA? zIs!%F1Gb}m7&zu&3mvzt4UOUeeBUOsd&nYxDB5IvZs9WNo$09r-emYmHf!WNved}@ z+HBOkJgbuEgC@=t@0*xDBMyI&I?VtMQ`+9Q20S|TL@~`lTbv>Th$4}tMA%f~JR>A` z3DGX$^J*X{Ri%6&-b?5`6Vpm%8b+p!PelPGdk%AH%scW9Q)jy2l%=4knO~)fd?}J5 z(C2iI7}gJ`oSmbAJgyd?V|qA}ds&K&&jhcLic^gWnP4bF$ZL^EG?9BDdWD@^CxpiW zE;KQv$H+lhcxn+guW3=ZF~9~P^W2wyDJp(9M0jwj6;g#t0R-?KC`H{cnQA2w7#sy8 z6A$1NJHmyP1J!CmJ&DRe$_lrSgfoPE7VgzF8355^Py-GzPpI*b!4@f7En#CE0R#tl zGKoN-Ei^H@q}NZoK(?)^j(VDcgPvisT2sC93FBz&=+_%oN^f8 zs5FBV6HWutustcYe3q{pu?%I-q5*1kwwGrL)_7isVj5A5Ou&7#?TODPf0srHw9`D2 zXe}ka%>Wt(F--1^ucpv)*=z(5g9C$$m$)o5xIq|*Dm0qPkpP4`kG&HA@_T6t6pOSI z;KV>L25$iJIq56mAks(-CtOH$R4~5@qCBh|-Ei}ffB@k@+W|Tt;)J6)f_!pRiIe#} z9ZPv?aJldTI+bw*(eGg6Z0L?LN1Pz~P0DwB0f-tGBY+t6%Ob&SK{7zJ2(O2G9NxPx zKoxj{kis||^XY?)4Sp9yj&RqEr?kIym!rJ^>Y@r1qFts3J2cvU#Hl_UWwU&SId0G& z6Obbh4}%=7aC&Bc{Q{E;Tk0GDGt33Z1>_IWTryvmI9+bMzsoX@NG>in8Vo4N>SS++ zD>e1ct_2`)#L-Ry7M9dUg{n&z18}sCZq@>jmbpv=QR|2B;tKjMDDI6e3BXX)?%ga3$r{a0V4jnMyZzx9a6>B8jz z6bF5AxQDdCh6YG!nly2tgUpqcq#Ygv@aQ1OWG{^Wa*&6~IO*|uPF6#ny1PNPkjivv z=3aa3+VBjHydAlN*m4T>Lq zQZ?(vV45|IT>=YQ4yGBo^MHaU7~<}(bbk4~6pq%MiH-_!Xbwa)`c!PpD2HF1ix_4c)BMZC| zveL;MPc!eSHnBOFIjF;&kxuWXex3O&1`;*u3l>&wHFI{obQtA;Odf&J0*QR?ybF&< ziUL>Xnv(CBkEi^UUuvHsNxDa)^DYpU>s52={Q~Qa9koyQ zn9+TdB8EJ5KrE8>H7cH^OIHbyMXmc87!V`0;`>`Udd-H>ERJIj=VJ9B198d-nk1To zNh5NWM@1Rv@%wLOSP~HrF5#~NgppK;(u_CZE9hY@7KWmb99~8Lp>Nt7tTN9Cm z*GeFh0u@?YJUQ*IwZ=r@#65$f#{f$q)l+;ulpJqPBUlwsU@W{gIIqyszql8ic}q{g zD@+cLB9OyXdo&V8xMzmc3l5#UN5fTTq;JJp=Cp<2=;3|<1kj%8(J*q=aC#L4C>VmA zD#gIlsKwplEeZ)-8vu3+NgF~tCU|F!*Z_-=)94-Un5m>`z}n-o!KLs?G)vRqq&;AV zOa!Wl{l=O=iD{WYHFGSS?)U5RD&XQ%$$W< zQ_C>0N<+5Y&f_(i2$u-@trSvPUK+Gy^Kf%Boad0F!WSGv4Pi(9FjIunSx(3NW%9vhp5D8qnGrJ32>Um$_PA<#r;v zgCpb=EJgGP1BStgK^bX`Nwu^}gR|!t!~np9If=*=M2|G%qX0H+OUjfkl+YzojZA*&E|xOT|VEL@73`&#rF zfTL!z9I%!Y(>w%F2jiTMd22J8MBlAi`yE;Ua@q;Y0?0 z5Y2)<19&ug^fABA;Nm$3voXGVAH2^pJ2-oRs;g@>eDr|zHv>1|-f>dOTJ$P@m&Fv{ zLoUYKJCbt85qUx0!<<0WAm)6doKuJQJ`Mm+a5B%Fr3;^ZnV$R1%k<*)YXP)cr+@y3 z-=*(-<6qOGyZ7mHuY8t%>C0cD=WaYtYXK}iyS_rJD@AZ-gS=p_Hlin8DdeRG;ko-k z7B_+nu7@^`$H%$`X=%$1@)_sHb4>MPUoNGB#JstMu3n1J*L;q ze$k6pRsl{HK|Uw67vvs%M?=W!K>%>U&lNU5hINqRppzz0T|ph^v6QyJq>6v@0xrE__TY@i^}V^>scQDQyi~___T^16;6|d&#Q!UcBFcHIa+>OHS-WwaYsq#5Ui9{jjzMYuBt6|>V{hrsc?Cdw zt}2-mr>_A-6`3;7v=b)F)d&#bA<+_6q|R-fIAc5)L}?gRmCh`3pxPJgmI1+(`$j@sIIQN&+DkWML7|xMFnJ8yl1&4&Y zd?M9dV(I5n)4RN+ZLD0r!VWQvO<1%tzY!`M}4R`@*{?SJ9^nFt`G-~!5f zGEl`xg{EZH)2P_^nUEE{yX7g!%n^sIDC0O`haOI^q0jPM?Ak9$DvD}!XJv$y6GUd1 zHS0VI1A9Q2C&3DF;8RHA~6p?{bYMgSQGwHPFwveVDM z*9}L2SlXYICJ${1AO_OIST0Z+dLq@A3MP4;M!mwafanu1;6=5%&Y%#^uRwZhq|jCh z9#K??AS;CrhsO}5$orClI04ug+J*EYj3>YykX8fytDBKTT~!VpM7s?mumv8S zGF-zhmSeEthaWSojCv>ZakIp*F`VfE6hP)=SVXQy0y1D;Ac$trwklI#xQP! z3l}&Y%!eKN{<#f0^TLZPPa}+V7~7@u=a`roDOGF)aT?f=<=%+3Il6{w0Yx=B3h%~! zp!vE0(f~qLD{BlkjYltaBGuSl#XH z9MWKAK#CDE3qFS7An2rrj~~;1=$ET6zC;f<_Ynj{eI|$lODEE0^@{(*#7|8bw-Y6d`~%Yj)MLh2heV1`3!$gy312IE4K);x;k;F zbWCDQxy%PqLF{7*m<`p@HX=ogeSj1z~0Y0+;(gEhoax zX_V00xVoZiVfI4!*&l>CG^!=KL{q9|EE)zZdSUZnd{pyp7aMPt65t}@rIDSmvR_i4 zN$|s-#c;&W9W3|5zbeReLx%_8i7Uc)6WZFH(8l={E<|t;<_U;;H+Qyq4;Z_LQ=qZ)jEN&9&rqqZ=7zRmMJvJ|nAGGdd-*2VhQZ>CIl&ydqCjx4t(y z_Q~|&2s0iMO-Cj(9Bp{?*-dibxxHwpq+9^fOvh>A=m7zot}6KA^JOXLS^9i%E1 z#e{jKcr(zeA5sVaKZ&Us@-ND_KBMt<0&7f0ql(X|8KmtMs>IgTU!KXvjf~i2Pc(Ls z=70WPM3G0P>Xk`{+i=>_B@gXLs;w6-QQ%0BrbE=l{DOL~DffHX1_k0!Wox+I!JR(O zQafhnQXYLd?@s82(r7yJ&z%AEt^@zb%mPT=F09-2v?`I)2sghJEmkm z6~zBA%GD@fC)PL@BA}s)kR4Qs^k6W=00mZb$vI>s_v#;-q9XcHx-|#CG>pa(pa} ztjeI02%W;I(qW#7Xh8s?x&#E9%9J%DHm`tfdvPoZ}VU~yX75p#ubRMeo)U`G#8A#9{*bt=dR(#%w~ThtBY zfx)M#M7uFx4Rb6Fv|^cK9wY7}w6_tkL->ija3Ar#`jR5U@+p;^ASctR)bildSn{3A zkb|owfR%;v^6=QeG1n-xdL-aUNdRl7(U|1QSH>?B&MlXv(h*k`s#D4)sk6dz%8q%- zz$KRmFAD~b7-(bwkyu9Akl~V+S~eT+k9T4j7xHgBLrPM6<;Mw&+E60wAeR7?CcAq| zge>RdzM}Vf{Ji}Db|9(=;|czkQlAA59R|sKFvzwZON7!?QyNk2=x|ReW;Ij3X8Gzh zDjsjr(Y+z3LB*6qj!u+P?})^)Iby`k0?gHs=ZU$1rT~QwxFQtpb?BhGwix6AP=oR8 zpFKyHpMQy7c;!VpcljIxiX7G%fDN>fd8xwx&Ykbm?T;VQhacUcciwrMZr!{|yP;pc z_SLV`^~)=Ccqq|KwSuc9c!LV!N;ojC2fZG3kM`~&(d>>_avrjiNNU`9<_i<&uYsSf z3w%NQVXS&#oG|9&>6qtiZxF^VINBp_qXI=<$yJ?1-=ybzUZ)T};fys7ARZg5MVxB` z<~OStEU*%iAgX2{0jYq6a)K1OuF&vYby~P=x;pH-f|0qt7J6%DY64}FKGz7*)GuSb^XkV_4`j z3Uf@=5o2BnkY=;&2g9;oax@$&AZ=~#(J;t$-N?qt;lU9{ag|}L_YQ`%ALR2O=$j)= z^{bU2lq~n$`PMEW+i1K=Q>T8UWRzP+K#pd-g1pj6{x1jj)lp8$Eblv?8TR>GNy$a5Df%k|AozU;1xy&`D>er`#d$IzfxHqt&9kW3$H1ri7>g zO?lgGPMr=&&3QC+Te^@xx4`Qem|{cgGEl}&h+|6g`jFb7luP4o-^sP}qJ;dM_RNns z%0JI#E8VAaoxPB#wAnFInUoPxI6T@)w!X^?nkH;~0;wWUr8WTB^{SJi(;NHOXVK9z zzmp^Dq77}Of#b6Q&Z-_LDF^>-Q-L~tQpEnwL6oM+$3@yE=@F^_OsEo6=U$R&faZG6BT~BIF7C4~{pN*iLjs+sx5ElH<=%wCRmCv&F^JvUj&kUy06Q` zD%YJpU8DyTRJOU^k+VA521!>p>a$?XD|YnFNwt#|MK&i?I0h=2)P78|J6vd*P7@dQ z9Q0^OkjX=5MV6P!ctV_zUy?ck%qgS0*lbwAkO#*?lUammWhaWxdBYVw43TP|XAL4D z&DFM+8hOFCZY6}Uo*lUr7QC9P2ZjH^fl|^~duJv|<%pX^?#l``7;fwUVW)qorwf^j zi$Da96aWL^D|XT(DyGlT84TboNjee~^fc^rdpHDxzC;W)0`{PkF&sPL2$2X5SN5g4 z5j)4FI7D7{^_=z-Te5hQI&uD3+pzP_T?c10MvK&JsFrZ*!!wbJWzi=I7)fKz)xE6Z zmRP6ai!iZs8HsqAq!`ZcctYc5UlyY(+z)A7Y!EBQN0wqoM%GjcASlnxqGzNWk=#o; zUkZ~4lu*`j<9lh^7W3tBe>v{U*1IvkO~X~hkUkP8KR`s3D@Ixhz=XWomZcuijQF(` zu`O8EPu5NYM{_VITgT)!PTOB-YFZH$klee7PPV+0mV8&zXyz?J3JFK7OgJUSO%;^V z>Rlj=#ktewKq7l^T_Heeq4Tr`-xH_RO}UX)9y&QzMI?V_MWhwoqz@bEKN>3VB`*oE z0KYOn4d!*-=ae}%eCi1UGDzE!s2~L!%&^obuv&9bV|6Ppedf&oP|hC)aq!Yp;c`Ns z;vJy-n2a2R-a+00K1k#iaYZ7IjL~!jL@j}X2I+`ctc+JjWDRMF0*F>;);I!Ahf}y* z(65?~hdu-d3I-LCbR5J$a=CG-A+pD{T zxn?Wodfv_U9a~y1`_hc^YVHZ?)}d+L2ux@8MEos0%v%RXj4^y6t#p&Wg+4cjkNQ$jKZ*Y4uU3zoItI?@h@u zKe_F51SP*Q-_j@hCOgO0uj4%9NQCVZ2vU^7=Q7dvEn*~*0^IR-KCTh7CY?0QXKj|U zzD*0T@ha53<~p@o)r@pmbeL1X!m0CaE6Q;_=ekCv9(fc(Lv7QuvqJJGF>=WJ%&&EZ zg~{CP5ZdNCj#wXhDrcVZbn|JE`Tfl1syfJg&jbsk@5pC*Dr=il$kuF(Cn5ZuX~OZk zC+~_DKtz7#yCkbg$L0P;z81teqeshj=>RHeEmL40QKD*dz&=?TEC;M+DggqTEnB@P1km+b^gS|s(c58MW+iKZ!qHp>s9ktPT=zpRuZL<^qX>xuk z*IN7R^NM#@tpu?~m_$d)NJfjE@I#bE1-D>p7!Q1ZcXZ3X1g!qE8K_H*%`FtFJP3Jz7FVeK4M!S5}* zVO+^aonbghaBw&+0-wU!QO6IvaqRp;@!LXRDMuESB68s*NwAS-1aYol38pE*Cy3~d+X)j(6*;j}2L z2=KY2q@od<&n;8-Hg{?%?d}weXbujU{FoTr7;#%Tr3>!?5XWWnyON!Ki72vC^ixTr z;^+<04;+QZ@0Tsih#>N!u<<-Zp%~yB%V6`g5uOD^tKfbO35L$ zuPl;Wp-qmoujL&${nGl#+59YGBoKqE%5lP7uW6MWBI)J6v3$9v%eko%UORRAAQwm} z3UdM=W5Z;@60rsF3(+V@&BXJ@EZ3!01uI&iKZPptMbEXX3!5@c}@Y`Xe>Gz4_(ZdEE&-};Uh%C zKraEHnjZO}pVnyU;(1OZ!ro-^}<@I%X?)qg0WX9q8Ug(=qcoxFANBf?J z>EiTF@bJ3!0<(7@jnLo^*b-{c4*bp5_8G zlnh%s;TfL@km=lGo-=eJkh@^NKg(k==hGj5t*2BTecqg3bRLtfovwQW{Vx4?&V^(E zVWD)G?W#BJd&Otb@y==sm^noziWtS8aS0Y>BH2~F(P}Ra^Fe&ON@nZ4fWygwG{yBO`_j$g0az|8UAcjvfm;v9G6;}4t8()$|C0KtI@M{X)}Y9-i6R#lKG zBFH6B#)1&$wr8bOk=-!KcfJ}$`9L9R~M`N~g_L;TMe%QB-mYx@v z%#qLdZz>qQqz)gWq_xYGo19c=S!2$5ERWR5Z2ZX z|K*4Xb!vTdE){{AN@@gBS@;DMI1rLx9Vjh#?Ttv-6m0xaMBqWf^NZ+E`(`4X4qBd@ z$xqdh&uiaXPYY%#}=9UurZ z$Wf8L(U<5Plp9{TdX2em#wd|{{~nEkA&F~o-&!j?xJvJVXoe!W3Mh{oqoJmC1Qslf zCOWK^9>YMFy_Y!4UP+yVs8ga-EaEC(9If({l>uibv2v8ECYAg=07+aLnxlg%9q&fc zt{5R{BVOo@LQ-~lX#jUFhiN4Ve+brZbae@ z1k-y)z_ch*+Mv#(Mu8tMgQDe_`;ovJKmp{Lt8(pab7~w%TX9Kt<-5UaA+-)%M6Mz$ z>CXH`HiulAY>k3}qCKqye8V1}DMpOHp|(yY7n6w#o~b11_4;Bnvr~{$nt* z-;a@0wQ<@o5w(`r4stZ*N?WOYF@j1XYB>6h)1Jy$A#2K@;4qO|_bCz*bDKgxPXXR) zYMtc)qZ*O{Wz26gQSx9^S3z424*0q%?7nlfjS{ADS2-6`D50AxCQv>jQ93~edmHCy zuzr?Pp+=jJI4Wm)1SxEITx|YIYMDew$+&xox^o!-tqTF3Z&jZREatg16`maQ2Xfar zRc&dB!C%ZxJi8hmaz&}(gNH#6ZPT3x_i5|l0~&!w=Mf5ZTSerXEhd@}>f%3U_9;~aB&S=F&7ihpK|JKu_yF+j#XD!ios_)ed7 z`}MQ~_vP+&S-iY!0%WWyoY?8*-HIaZq*dUf z0?GN&g!aRjJ=of2z-2ke@+hqNsGtN{C=ZW#Y{1um+<6e~gL{Va?@Olu=Tv`{H}u-|6XA1^Y@u? zH1jr*IUxO_MZM3&ybu$>bT=sfkM)qxn630tG0eaGaz~Q?*;T> z{utlcr09O1uF2D<<^wO?uM)6q-|O7TbpvH{>=>KLsjrLlq&j~IXXV``{nj?-r;YlP zMY`T9J>|O9d*1?4DEqwo4&>X?W%JPZ_VRl+*#>r=?zGrS^>jx}OQLK&&GaF@VNi?x zG1JeYN6Ip#Kvv9;pa>QK3oeVSjx`fL>TbBDblSflt|8MkvB%{Ix+s0zC@=~y)=QG7}jVfNJ-iB z0e#9)cJMhhhL$8nMR{MG7cLS+9Udu*pznFj!S1 zCTN`qc*yBwDEVAV1Ozw{>^&oyG?N3%`J9f^6V4;Zaj9ucxDNa>rIued5@k5d0?78I zLX^&7fKmwM2RSeZYmsIHc@UsUh>e8{W+ePEJp%zrokP#S2dC(9d2|7IERuz%F-W$Q zh!^DF{OpOQJpnv`EL0SMC8s&9Ov;QXH!a;0qtc4RXCy?-Z7zTas%em}@TiRV9T|+{ zG>J;NXoP4RmCQuP=&pf+7i9!PhI+36CZQDe5lDE?@tm249e1hn7C^q$b%|C&iqK>% zfJaXvm{93x5I`7|{^k^!;5aUw-(Udc@Z&qm>m*g$xFQ$ZekH#*z-!!Ryt_mF;N+tU z8mD-1-#8v~(ZL0e6ZgCEU`?mdK}k+r!Qc>d&cW?l3@V*@;e~MRdD?pOr*w4h4xM@a z1sa6*ZNL39DlT52wX?5LFSKKOFM#>wDxEpo<5ZokaNpav@6qKO=L0w~rcuyueehug zJ@B)i{Dgl0fA|mR;smIQ^&BbF{N_L@Pn}*}O?+u`SMK z6z5K?pX*#A^{!$7((!_cISfZ1bEUUDpfei-`jbETW7^$6r0Xw#h6XF^yxW2Fnf3KB zo?#B$zx|NTUAQ1*n`&Gql)y(FIvtHUMagRv7q_|;PN_!^x9JDp{SN)^@BO{d7d<*U zIHE}yk3L6}c^;ptkE#cQs7I0`Ab6~en;8i5WprQ22p`F3sR@})AJ2Dmsui<{0opph z=(Ne&=PPTUfP_r7qHy^-t;z-z$>UZXULFAf};8)ZEHE1>(ArJqS zSDp=tKgqzi-}BO->0a&M^2o+{_cSLj2Ohcxc^ao=6wjMGiyV&TfIiVu&K%m@iEwRT z%XQvC&YNRvE-I6q_sRPp0@octD!=oybw5A7!)2Q@MO^lr0(PBY&%lY9ew^d*x4;wE zmL~zpYie!E=JVML(0j7X%TL}sYc<8|<`-$?ye{ub67E$u(c0`!1LJCphNKi})Qq z*}eWU9$i5F7+3X^Kgau-HDWd@ru&^w*NT%vT`*?exV9p;T(+)~a?E(0Pby1M2D4+R zK?=716i#{DG&Koe=2#=3>$=fs5b+mr4K}f+)A^CjL`hb8p0s3&5=iP(daM1<-nF|X z$P#kOz`189uLcr{9xUSAHhn55*FL>7%4xomCFRfpp;p2xgZg7Y}-WtFTCLdMs%s6!LJA(`)yQ$QxGzA8RxR4>U z^<9=4MO8>;9*k?a-|Cq)1>r=tay})p9p$4TDa=b&ji??8uZC4Liq(A3uL?XR!$U!! zr6n?;(o*AWd@ap~K?6$t9jAs*hJZPk$=Pz!zCufRYq@y_v0?;B$t1_}Mw)UL{=vb= zLy-E0h!XCb01$u|=jhP`1_8_<;Pjs0te`p&kk-=nRg~LF8GGpBm-JrvmsD2Do8% z29RJ9z`I7vdxH;(+W;j$o{*L9OKL*p zAQb1Cdzs_QS1!}Rox38pNIk418VGY7CAIrO20`r2oIG&QmCzUwCk@DjHBt+J)9CRg zw~GmXOCk0}nQX}2%9ShpcM)`tMZ2-6)IO$DLdT3AZ}Im_VQkSy#*4$zRa2?<)I*iH z-CYJ-u)r_@ZC@)L@%a-PO}Ul~jd!*=S^!`vK)PNS%Six?aPEEpY|g&&3jOA9{ucfA z*WRG#FQ4UpuDPE)?QKt~x3o$>`o=e@`M#qo0mymoi(jUX9^9w5zWpuQIDe5Y2EF$7 z&u-C`D_7~}`yX$|Cg%T}y3`9!v$7ys{Tq|6Pr0Fi;Ov((f0-2adDJ#R6 z^dxGkzcQeu0e+sLyP++Qwsz^tHE_rvHI3+SU*`0g_4N}BTtx;**1=_zSswQoMB|E1 zwWMWzbn8R<OouK;#G#Ld@aBH7#hmDL6?>^*l2LLzrQ(9gUa%&iuqo5Cq zFz*p5GvPf3ajC5E5gf(ZHZ?LoF1EF0Kx?XL_8DacTI`2nwhwa$4o4T1nYTM#mPPj_ zGX`jG$Xef~d(zDLl&$me9f%fk!&woTy=aDk0?`UQYL|OJJlF;6tiR}w% z8-JzI*$Z=y{gyY#+AH&Ge0%Gyi8FsS0=AVSUoo-R(QXRy>QN@e2_Be%dq9 z#bK8UJ4C1I-zPfqd34Mix49DS6&v@Wj5bZ)t~B@3BTT0AYI*jV`6rakm2R7?YM4c$ zbH|vG)_(i3$!8 z!uO|A(ZpAt9S1IvYYwHMGM)L!JNuboD1DR`kNCM7Fy=5zscUh3qT?K$Ul$`%q;#Jc zOQkELkLhM%ZBIkGS{F@&E7N*!4SW%|NF(QHrDm~LVPC^%z|q`DFuw{dVLBuzn5 zRbshja_q2TXTP_$8ikH1DZUs@!w%mtk!V`G$!RJ{C7?^c;JzMffA>EAI5!WoN2eK?G5Oy$DE zpVLCYCr7=on=L6RqFB5FZ4s#PUb#;C3=DC4-_-NGz&WToBdJGL9=#^5w-zI#$okp0 zQ+49s`VMjTt*hjHd(pI1x_B>5cSCtlM?}@|(IXx+Tq9{m z0(=0dS-NzQqe80XfqdQ*P74Duq;zeVP?@?wBX>x))H4*e; z8EGW?i@>b{E*J)p8c83+JQzt8HjwL9D?KKh=I1MsEdV5&KaB!HESn0_kP`L}oSG+u=1wb8fx~6=_%ZF?dY3`0 z)f+dcx^jv3Z`};zc8U81rMlS=M8so|%jwaGQvk&+ceMWU%K%fJbUhIx)= zyi7b4Wf8fC3MIbgG#QfWUBk_w?}7sheX)P@BeD|pOXn{zu!{DrY+RtDAhX~4lOHlz zwiG~==bpPkuYKV)x^`(m|Loh}<@6?$!CpPwqe}r?x_16NJ$Q7V{{BDupV7vp%XI7K zZ`0+gmuWNH^ZK>t!ta*?7~^O(o^l~FChctR(9hp~msW#rIv3{601-A}wq3n?j&^n@rc#p;uj`Vv z=@8}TK`aURM)Va<3-hHPcp;6E$fA*)}qLuZ3mj6*-@0e!{L1HfdtF>lBQg6iX7`h{$Ek7dGvhyg z?lLcoX7vjZ(Q(lSe<=@_k1J_3w~VgzX1o9Ay>I(|sc(D>)@cJk{7D|6N))d#$4rsHC|i#-CD};?79Z+!G%c_ozt1VhDPX`!<7y5*&iVh7_g^vAE!mkM zwqoyN(`WwP-QQhr%d?86=$oe4Y%4n&NH2O2AVGitJ?O0;1`r@UNCE~JK!ec$qfvKH z8#Ou28Inyl$uca%TXk=l>&@?NdY{Mb9a=Ub_C6>7%v*Jvf}mZMH}gMd@7Q5htcdl+ zTHng`u-~g~Rh_RXxE$>blQ%I#6eQ3+o~!9Yd!g4lWx592{G#@cIP+w|{CLewxK?wE zKybSM4}DXeBLIi2Ej68xu0<~SkY!PINm}p8^Ec7&)E2ebKCLSN(GU-lY%40juaD%% zsQzX}rYMMiyA z2p>&u6?0*;nJOYOSSZ{;J}WB#ieoos2?b~`E`^Pp*Q_MuKFxrDy%r5L?k|2mCDQde zK}A5=6R8mmP8bzogUAG|WsCcvLA(xRxaC4R%Zr5?;Ka?+n!(fgtjXVT1{j(!cw*0< z18B?;A*a|Trh%M#Jo%8dNH#1P8w@;|jjx46UWELayb_91_*2**&Mb46dX7-@h*M)= z93RRB;)OqmI4%ePA-;@!suPSr?!%^dq6{}TZ6~SKmCZ5t87-=#KBxZW6aVQ2&M3vF z-Nc{4TsATW;@QyRP_O`HK$^e7_BOYL`U6rv02|-D5wkr}y@^v}W{zc%Q$aJg$`pH> zQ2!F>WCXAbR%&PxgPs6UVW_hAdE`l`t+MHEBK(B(=B!kUWMV~L5F1Ae`^(6CrO=eY zxqx5fxlc*00LREXr(LazvP z>B~loz+omA9%-g9FJXKf_UC=gP=X-;Uh6{l47WC6xW6l7XBpNsWi-v0Wxhqm3Ql4Wtl^XS__MTn~1Whkxa3d5V?S&QAuRI z-P30o*rNN%!=;VDMHA-<5&RxJegMt+g^&@czp=^v-kh0}&xn7AbRf%)@Kh17)LU5* z?;Dhb76K`p?i)LVvOMv^8&Z5XgYM(`KAl5*evaq=!O9AM*COu_(m~ii(+Cn>`Ndy^ zz0Gx4dF#jU_Vxx`La=3bV~xF!2!41GK^eN9f9YkoaqAZJvFx3l9eDQTXQ1=DzXJdC z&RzJykA4IQOXpszukjAj?s6%|2pgWU<$|Ui(mK*Tzu{-ws`={ zkJh0*HCx$0zyxDrerb_IY>KUdH#I}%!jeo{O-f&m^7V~xejT2B=@oeD(nSHi@cw2; zGOIE8jPoID=b_NVmWI@XNnLq;x^ebt=!P0G+DFIPQ~pesJL+sR)s>U)Byf&tpGxJ~ z0`aryqs(t^?lNig?BXnEO={o-?LrfpEvHL{haSq#9)hCXg;UTkMe+REK%OcsdAx!+dfL2}>FkV_-+!piNKdt!=4C#@Ibce^uMwsBSuI8_*+9 z3nyH*VLkdrH}<|y`>J?p9CfdA$2Lrldj1oEO#eS{rAES0_Z_dmabpeKPxq{NbWQ+2 zKEW8sqh|da@BTE5Bkc9Pc)>;E+J8a|`;hn1-jpmB<@d5JTLtv_6htoV!us?yV|vmR z?49~&ht#WLFFct-r13M?==r4ug^@oe#8h>_8*+#;Yr z0iTo)oSrJnLPW-L7z%F$ww8ukP;uuK!6Jj2Z9&P_!$viE8kFMILFsGh9^zmi!d-eb zk%l&M0bVR+v!(D2;Z+JCFfc$T;oc`zN|ZkRKk+0m6qP{^OIb_xA%l-NfEW}4HVkp9 zu-llWA10%a!4eJ)5)K+RviL+_$Zp94fzxOA_Cxw+$8PcJEzp-#;7oQ)U=Zh{C!mDJ zMm#~7Y;wrQ$}x-pbYjqEmHI=84Veg<+Cm{L#=j9VeQB(1;L>RFxN(>m8bBisMadZW zBj842>@@RIuJL=E*(zs_7rHnM%uWTo5aC)sGuH==7a70?XwY~Y@S!qgh^mkSH<*fm zjeSSp))aq69za5NEXs&Ir#Nl4dOlHov&hrJWz)tVl@@ubP#s4I5OEr6>TBZxFvCmd zCV?OLpva5C)J{RX#50FNe!OL+YPS`{5=BLe8>c}gqa6)t>hBSs*yk)CLrv*T8H1!T zG6x0eb>h*%a?_E}6-$Fn-Xjz;G!VILv^so3L|ijW*v*-n#QThaQ+}X z6Jar6!wTC#pa{+P=FB{F&z^;ipS%s7(`Pi@Hw3;S^J*JzQ_AQA^^6klC`z47^&l^s zawvqvSUCxeQ*vuC11OhqXAYUY1C8Zy>^;SOOQDH4A2KBv?{99g_Y1H$nhZ+dw*t=u zyd5&Ur)Icp(iP+dm$Apog2*@Vip4<1^MjLI6C2pv}g^d#qQUzVZ@vE>eDm9{!_MQ!(4C!w^B13j#kpBH_tX{mfBv8U6PUkv39eoz z9+xTM7}WKpewuRFHSX0xpCxM@P`vaYq(UW<-_A4{+I{%Zn{U9^zwveEfoYS+AO8Nc z|LXq%CoVk&zxO}*2XN`BGqAP33v)C_i!SRzCgW8QP)-xgeO2DKy}gSf)fMkYI^jhS zxrK)attp%z4;rw(z5&1an}3JP*+SWF5|2}}%jYH(=G4de!=$mJENlpA;bNyRXJInJ zjx;@!!`kW=w5L&j_D6hJ(do3H*CP<3#IkdCDQ@61OG_;{*dM~y<{oblI`jUv;8}DUY6tF|COxN3b-yOb5oqW|d&Xc}3kf`oXZR^#O0Hn(O zP_wyy3ScINf>h^Y-1uwCRfw+Mc7Iw&Ik17T=hOEbryqlXS^LZ#qYa0Bo_<@Yca}Y| zzm7Bh!KMF*s~U1-&&tNXQdXtxGJvyz2p3Z08{*+n&1g@Fd)4$%qpj)*7yHOt=Zm4{ z;>o%2F&Kfac(XEqVF!iu`VxYH!@-1{6;(JL!{L-&Ngvon_vS{p?Zvx*vgp~KitU`b zZiDf1>&CjPeQtP>)3rdtPJIMqg1$5$D3K%mK9=pk5@K*4_}IJ5)xrF4nGHw<=wLhx;287zgaavbU{z{0%%5~W`ucGvx^kl)t(hPp6 z)g|SN6P_{`zB7=)#5KsLPazGfx`#=?i&Vu|usJ5pFB2K}vH5&YsK+PMjkU&waN*1u ze+%gR$eFIeK=+2)0P=6K%b8DtY2K#Nz=Z9Kz|s%5fUf8xjswf~8jG3DcCc(*+sJG$u;EOysC4U@CiB zFHJKo96`F+ska6b9jm~n;Y5-xOg+KMWYLq{$6=$wpiCYYu>i7VSw)GI38zw!&Dy3n zOy*27Rs}AhRzifU3WM5VN(Tb?7*n$oQ7uR4X?Cm777&nuySnu1+HbOvF<%UOTB+xX z*9Ie= zQPopGg$Zk?p>^UUlLWKfnro;B4FK?Dl2-auW)Y1$hRXm*;-%(%P=+#+y?^bvWwu?Nx~0f1Yq-KNf8fB^w} zWZ=@fTV3JaB5yz^AyERxWelto2Qo)3^Ox04(xbODjeP7QFXT}=4;;?b9U;K(XxN!9 z%;YJxd+#3HT3d$In;*le=U#wkUU(M!HG{i%R$v~1rIQH8%uFL7us?!x=VsyNoq{tA zEiR$4JeXx(@QW{J@Y$dH4D7D&!yo_ae+jpiSKtfRo?-7S8rvp?Z(?8V@9x9=;tYa4 z#rXW8!eE~J2jnYQWAP9&y<jS7CQ+2fEmYiSEl_v$xs^y1FPW=7Q%6uu^--5zbXb%wa)eTO)OH& zebRWP8|TV%Ppa3Gu5=C@@y^4(^J7K&iT{3Le}ORxnJePvyQz{p4ae$XE$a zsN*ES^SGDoAEK8`G;ZQeX(gipETZhgK26$EGjVh;YV%Y6);jb4CCPo{4yk+i%q4XW z+ss%;y;s6C6tK%=e>PSe0XXHPbn@f=;ZqYlm}X|Y zr(n~Qu1v$hWt&ocsnsElr`mG*BIoqInj|2C67jvI(sKy8d<0!Xs}xl7A!}ir-`*;b z=xq9yfeA>*FOd&j%W}=s>az*@RBF#&&gpZNwkA5a0^X}$OXp6O=+!#VpMo>#=P&`_ zsW?c~?}6Bk6!5FmSxc9UZ1G+LWYRXIKQ8Fb2pZB@HR$BbY8>1N33T(40g1drhC3Q| z1QJ%l#%3vGupC-6QlwgPQwGnLwBb$-4t^D#RMW}7p6UrnZRAyv(?$tP3Z2CUa-qrt z0#*RvD}5;klU~ALOxRp9SY=!^m~SB%t+}GI5R`+3a*Qb33zL50#;zfr1&ooXn}1H3 zYzRcajULsXy=_J#Rlw>2FcgDNh*_I~n3d~MNO*%0(#k2c4~;UiTJxOYuqH435Ak#D z>r6Zt3`igVjj~B_$O~_J1w?_wP&cDX+N}LtYPggtJTY{D$GBqr*vS<~nh5eAl~%6Y zC+h7(^-;ENOJ_{kW}q+LJd%M&CO@ab#?yN`nI>Z!y z9Sl%N6mga(&o~Zg^9Ck0H0`yMwpqKZuh^5qO7lY4oMo2IdlXZj2LnS-4G7f9^B@aB zfR*1wNVl_)(JCOq8cM_>Y9Vk=!um=gzSQhV0Ys@S*1`#c#@)smdufo@7lm>$IDq}s z>`cM_#<~Cj_s*+;8sN|nzMxJA z4a9u`dKf$`82F*n`^HF!pvkj?!f`mva;PcTjVy~pl$^}XHpQ}Lp)UhiWuO{`*lcVE zzLt3M8MvOhI|l8I4v9-5z*u3U!CfAPx1TAdbb;+%Txt#^Q^jbDA`^RTnk z=d4B4Zcntg_*IqW(P z&~~hH;L|CmQs&Rl=F}S^Z1|lU1FXDRU4AlAYHCcl2?joVO|F~D& zYaiX`PW3}Y9@FnrgZZ#BAOag{l_zT7V8p>#ox{3aDHF60(>|pylY>f#Z9Z041<<70 zwu$4D)~{aQLoN^FhGeB$Y79H@$Ch0)1kJ#+eY$}H25O~s_7M9pl|kpKV2T;K<2sA~ z`yWK79D1oyS2xB56cVny2ug87VC*m^1!F)wfF^m{9QOL-T;V-V{t9vkao!*2CGL=W zD<36#Vp3TIxRHDmWmy4dOfHI|NN)EN-sKK``6RhdK?Q3=3e-S4P2sR=r(j^^vC4Z~ zO(%exFlXyJHz`A321i}N_J!))sMO8-5O$S;^C31Dy(zp~W69hS))}a9A2yxbYCX|Dg5n|1H14WrAF};-d7xW}qlsqWuC#V4` z{5kxb@>?*uDY^cWQKf01sXsUy4|@!WM~_$H9!Nk4vTzI;m1D@bVDtaT6R4A(tR!mH zMNo#_&FFpXSwqBxO+i}=;Td5!C=jL3t}N#Hp@gm`;&flBMn7}DP>2N?Ii+Mnk`%oI z<}%>WCms(c8{x8u3#kbhXK2zf_1cf7uo~?^s2aR>8ZLxtvCAkp4TF%(S0QYz(9Bgq zjzGMy=-(NBpOf@OV8y&-SYZ`1CKb>{Cm84?6rfO5h@#+3;%s4YrFhbSy7vXeOY*>c zD6u^AO!5lIIVFv(AiPG<%U)d~@0MkYjbEoHsaYO9afHMQ7C}fG<5eY!ddLc!!q+FM96b20ts2Qo}50481IMgNzJt8oq(e22Tr%<6* zM_eZdGFJ-*&^)JaW?-Z*p@fv3j8kjlXT#lnE{oDZJ0|1>4wYb!GzQa}9I8PfYgwxc zmK6&WaEhEWAV4O8RkQ#*CF%lh+Gn zlG5->a{m&}QXLZz5XY;2p?e8@7IN;6J|g7Bxn_6kt*%2$;&DXk)RQgn%#bYLvotqp zeiR6rakeWQ8}goMaL9~j0_5h@EPKjO*b@a9-0(y3FNrR#%t--DaCZ}Yv= z2&&94b`ew|^3)-G_~BjdgYBJdc>nFUxL>E{7GP&{2ma#U{xNgtJpJlx@G^liSFZ3W z=OFp5UR|+1!I1+uy}DQ<`iF`)MM`H!LJ{($`LZ(rb3U3y&VGLU(qC$Dep< zMjJ!8@$oJA@sEEDGt(zvePsoHDJb^VPkU>dZa^8Hbc{3CZy$*>iK51 zO~*-$?F^m-#8ldy0tknjq2b=2s{Oim42Oc?$CSm9V-@5phJ2>$Wcc1sF6#+u?x(u= zeF?~9*F;a5C(L)}B*bUZAxzq?NnS#F6MWKoKWV+SK0K=KzT)lWDu0G?$&MGEU2v-D z=rNquv)~N5lgo+ANo`F!GP_F=9e8^VsbR!C^xz5=e z$1>{V;wj>NZgia6-1b?URU{4fvD`S#aBZ}3HJfvu( zDN3qS)(jy*)^}{Cl2M?Bt9hny|BZw%C9{lB2{ER5FENR-dg)Mz2ECBND#%lYQd*ON z%wtw$vPm{lXnOass7z{ei!;!T7k3KPaYX=RX#AM@T0^nO_+gUPc0*E&cf^QguOpeM zLEfxg0s?`A@wn)!Y2ZabiTjdyibah)zp(64iXP{tz)A(wEM&-BO#veNJOsll@W(I+ zCV&oyXpzU1dLGaTw=Zgw+`ttUCMDEmQr4ar!a66!`^kw{g8?mcdQBlk>><>MF87&b zAB*oWcSW0f=4s^c7jfZG*%VU5?!1&y4duGGvm={S2J1@p&Y<^ls1r;{SW$1ENq?J{ zFA2v2S5Np|N?q^?EF{o?!L?$fhQFjVXAUMxjiWm=2pT1d>(fqIVCqnXppMI##m66E7G&c^{bvl5%A6!j*@y73GipPm@nW z85>=%U~I;pN5<09 z0-Sql3BLE&KY@eCkKy5+o3Q%$dFbR_p&!a9jiG}k0&&GLcCJ)Dg$a!c@xB}2+#jN_ z4hE88?ZQr~;`U1(88wT25D24}GWKQ~4Lodb_u%fm2MpFt&o-EAXA5=G+QvF;qx@0&>UOswhQwe511z6D z-^I2Qk@JAodM}wI$pcB~DnutMCZwQD#`_0B(=1#SLft_(Qu4{oR`q8LiLhqU>qdp*loDdipl#?W z7tr|oQ(z+Oqbp;WRgB(G<8m&ktE++0lYp1RSe1vM3b^T5jlakMj)c;pf>w>sC8+=H zT$G2S8+MFa4hMm}{-;cAkZRw=d+S-r{1~_w>n((_8bYHTW#D7<6bjl5tTQWsT&)d| z++F`H>o6Hj{sBiFt~pT(aA^5@c$*zdXF{d_CxLs$?PIn%On?C; z4S0NJ638RrWWLfi+v~{Z6uzXHgxGyuy*fC3E`{arW)1&7c^VC|ZO#T#j$&GCuU;qy z0z~pv$D=}m=QRDXgb_5@(BO(UY=M&hh_OE6Q+W?b`dmemWRs*u7rnozEtvdcp;$hI z4|ye(6^kI zU1{kG^rLYU1DkyblmNdTY5XJ=R*SD*JIE^u$qC53?VIG5l2o`xfQ1}D^Ar@*fqD)$udJnKXs0RpV&LKlngDnUY;$5Y3 zxR}(IO0KJ?Hq;j88&M)%2nt0#i4sp12GE%6M>33X)*Cchn7G;6XP^uNM8rel`ShP< zh{lRCQ#Hld1um!0^`$I9+^ci)6we#}Z7u>-MM~J)IND0_)Y=M?I^urjkF?qRhNWI=QuP zc{&-lg^}78!dt=KSk0WnmgsLvWyb&zXUrOithAci4gwMrkg(7++mu1g6R5H)q_9l^ z7=5n*&&z`MSb59FDH_Ypq|g;4cYR~WqFP_;q`WeK!ta36v8A=Yb7 zQlxt#6)u#!sL_@U9SumQEBr_e3G48gf(@w>)dkB}6sK;!X}*(;bQ%Ka*n*=Wo8mPm zh9keD&WyD_r+}E51iimkj^VV}r%uU`7Z3I>r;Gqyb_O>g)>l_f# z$W^~|xgQD*pA%RV zd5I(p(g>YxT_DdqB6z3JPnJup;}8vE%CtopmT0n2z385qlPBSo&wLJ^fAKO5v78U? zZov7oH0}-f+!vpR|N5W)TeyG!K3shM1(-Q=9&Wtz4(vXB#2z!R{^s9-9_pd3&2?CR z`~Yr#^Z|VKwO8S(%TM8Eg@BBatW9GZiu&gGcpFWUqXDH}$9suWg-Y2!7^1iq2#TOS z!9KW)K-1o%M{xhnZCH7{3a3w;hHgu^shUIrO|oCwX4H$W4E1o~^ymP~B~KI*4f5)^ zclSQrx^;^|F&;Y{r*D4i>#()81;6;^ufT8qonMBT*$(Wi@8iKe{5 zoY!-6)6j0`&_BR=h!b$CI|KWudz+R;?q|GOt(-}It)`5vA0X1}ifYllLE9voQJUW?T)9U`BX9w)vX`pwNE6ue~=l6pqusm1pJQV2~bqFAF^GDatBW0)ICND5+gpW(J)m?2uEkdSfbO zSeK^ttpG=gUZh?uJVxbY11=cz$LypOY%-EqCQvoQ>$tr=0g!p3Q9q$;j(epf;?4jB zHozsZ3hS_BxXOAx^vhrnDtP9!Y{{CV{o>OKCteAMfQLucebN&u1gYU|<6e7M#;EW? z=LVq1e{zkI8p)NZT-WbMl@nyRBIuR+Mc_gHRe7%g8j#2$B=QecS@QaCOR7^U;J~|6 zFCL_&FXOy%H`pcXVj=EAkFZDZQ4X)KI)#Pky zDhQV9eHT$wsgrUSR>vd~FB6|(L+}$HvNmMu<-uW1xn%31kdlzihW?YO!EGTO$`KM$ zMmu$pQvyvU2G)NE5>{0%W=OK(NR`8lIH#T@E)dPwA{m2*VF47BSi__MDqbMczZCYc zoAw--k^x;r==W$F!H1b?#d8uy_CoknD0>cj60zrvfEogvD0l-tg!yn5D^L)FIdU58 zJ;N!e(RiQ~wxCKe46ZF|+IK_{YzCwN2O4ITJVGbsW;ih)0Ru@22#|40gu^3A*URLg z03j?)JPnMrGpn4Mv!@40SW|9k$+eBCA;+ib#?-A~gdy#Q!plo}WcYJR%T1YT@N}k%{kQgIkb!_Ml z16gjyDNjMe^fW|>!HhmHLN6OZxNq_0`hm6uYi)oFVb6iEMafl z&Hv<-$CtdjXkNG4Jom^uguRMr5ty47 zJ{}5(A)sj>V3g=rALa^$zUAbBxF@NvS*KW?7?h-2n+*1}<`-FVyn@8k0hGFXuu(9d zkC8Ex?2v~JwUI(jDGLg*Zz9_(+d!P-Y3!PgOV`R-pYFlfAhVCirD&hNrA&t69mrVYRTJHHJj z>V*4`S73W>m38*grKjMFzx6d(T3Uqv{D1qug4ruqu^oFbgTUp5r_R9Qsd-r2=)vq< z2f>XJ(!(S>J&OPK$KGqvv?7m{CXQ>XoiP|dpk+hD5r6XfO?dk!KL$WB@jQYVXU}6@ zPRuaaHR_2s#~$jg>6v*1Gt{79{pZ1;8S);bI`#JVpw*dS^))@)qN#{&T4NyLg_mA| zFMj?@@Rxu3-^0w(0&k@I*v?_cvnLO=cR2JR;~ho++No6CJf!j|rFW}rGl0c8IuNLs zo}YsO%KH1?{5qWc+!x@*&pg95JlK&G-Ti?Vk1m`C6k6omPh(0FtR5yoiLOGuVkeF2F&vMUkHqoD;T1S*qHC|FH{}Z3`*8l^%41jUQ5s(5i zNj>Phx&a(KZM1xsKIc>N*YS6T6K6;a1ue%8CXZ}Vnti8c=#AYQEkXfd{P=eP^qVlo zW-o-f11{_tt=8su%5>mHD^462889q0>t z1%Qgt_9Q^2VwCX*q~ppcTZi=PQCB){0yNuUQ&LtUJ1)^}Wtkf9E^u6BHAB=-c&Gm) zb#+NU)%BWv=Bt3rB+rOEk9JuFjMM)~Giu>xzWTkNXiSGgJ*q<) z!NMe3#A@z^SXw;9Tv*G)vudD2^252t$}E&A9$zkqe3o)vCUTm3$)rm}>fMrt(b#8I zxv#d#^iv8z7!cC1jJqKFk4aYwpiIgPrGJcn235Tj^rWlm0|UK|4X|1}f;^7b*Y+zO z#^on~Y%YRq5o?I|S)YOOQkG=|bPSN;WD}fWhc?{`mN4G|lMA*&sEZgD12G)IMh;JYH99IS@?~fkH&??_*udl6z8bqmT*>t;#p|Thg~Y;E z>~z;F@B)c~uT2=PCG)hXQJ%ZNQ+V}fO12uis40^7-Vb` z2ZzQigL=NSmrj74tdNHV86fn-slSzvr@@(QbTFB)S5NX2RA#udsVS}-A?(W18fTX3 zjtpS}k;rH?4<&ARp+6u5riHkKQu`=-3SC^TlT#4(ns91}YP_3pp)??bq$Pqaqn`z^ z4qP6dXHFhUdrhbA3<$_3+|uoKPMp$|h+f0hG(0UcZlh^5_68xtm%LAZSaeh#2ne7) zA@2$uV-9_xzjg8D`Y>-uBLazeLuD&dfMbwwv6Lai&XgtdEaAIHOxoI%Y(?OM#~6VO zrKK-dB2QV21u(Hxj%+NU91Ib73cNoGG6k8YaUpO5d?-hhd9MACC~@VEkupS{ne??G z9v++$9P7@6vDmMLda!WTAe{UCO%U%c@&KSY?*+u-@zbn9O$0LYmZYPmEJ}@O0v_Ak zpXE%!_YhAJgBzrH3o+`cd<*LtZEm70Z%K-1B%K{O_;ZwdxADRgqQyU(5(3|f^c zKMGKlL;|g$e}(E40}=wbqvIm7A#;uAZ%aG@$s43_I95YZtfJq%dWxyX7|Jrqsz-y6 zQ}{X;2&)+gC9njCfPF2X#@<2%$`D}0JXL)Ox9mvTZEDMi(~}Rx zLx#iETKpUt_&FOV}IwI&bf+k(zc>1N+;M;%l$8hKEx8Us$KZL#Y zHMsC=zYSk{yHmp6_9$8O;^xQ}!Q)=UPtzt3 zAe8rhAID`xX{wu?wwgRfsP7N+t2`8|>-g)Z-*gGiTcmLkshtGWR zGw^@=PySEvYbf<~(QD) z`hdN;8XV3{oLHXLAlCD;t}##yz++08264B;8)VB+!kcC8P#U)^ghGb2FudG29aBqx zet1V58`N;_iO;%9@vgE#_O*MxKPImV9DN;&*PuLxHT+W;pHI5RjL_P5M?POOGRKS( z81J7+<5BM)+gCa@{;4j7FRTE28B8+zUF|)tx}!hdnAU*+fQjHt>UqHibZPsD>i2fS zTQQ>bo}4+{BKfK>l|n#G#k4Ldr~&o1Cu2Fu0OK-z^bV*GjIB|}nriG-px&Ta7Qxn9 zSx=PKBi>_e;4DvW!dL`@_IT?Puf4VVBj8{KJN3jlWKK8;2X&x_dGR~jM?YC_u!MYq zHFdlW<1#P(4K?5*%1#Q(@GtsLqHiSpEs;Sj&+ab+^?-pi9wv6tG33WtdCuxvDIo5b zAnwV1Xj`N};A0vFB(iGg-guQ5d|?1aS|k6}{aESZ!A3}B@1xfY(?XCfQxr$5-&7YK zb&qpn9+aihpBzV|8_X*g$J^KbuD;Tb*Uj3T=M{j+?hheU$61#E!oj4kfjPFfrLvnE z(pY*QJe44+Gku<`Q%JS`@sGniWeg;D#}1W z3hKE+#ursFCo({r>_M?Z;3^5c4T`-8IFO_f<^|02`z@^=hd=o;F)s6fE(fyUWU&al zar|N9k3Jfzfp0>SOppcvEz`o4AwM7nEP1$KJ(`7ts1Vo^7hxwvxXfwb7%Z4R--00; zYn;huC?O>b43t8AN^Ki%Z;1y-v!!iz3|bfvU_2m#q~(DWlD&f1dqdhtAs@sg!6~Bq zeMuo6NKG>)eUfrAO$A*Bt6G<;6 zAz$7Pc-+9JizO-2I3dIX0}bu{15SCIGa%4Wgjk1;`WOK&GL$*n5_?eeloP}&x){V* zop79hX{^}v`&>AJ3N(5OPKn(V1H2)gOOk$gDD9_mTIuA-f@K#bXi)~Q7XB_15@!k@ zAy9%1UF9kf4}((V)W$QUX)oiVmu|K|40*3)%v7gB!+hd>YD|!K4t-ALXy^=oT}oCa z3YTFSCl7`!QD)3d($p+e1%s~CXWR$s*+YFc>Iuin%u`pe4hNF@neXq&f<*E&>}l2` ztPi${vuEuc;P8x?XQdeQq<{6)iRK|aPwCbRG_cD4NW87E{_Ukx>}gPr`jYi0FXASb zKta?^L?T-Z3gMqo`OF9C?GD7J@fa|Hd=|0CNir$`07;W>)}k@_eIAGz5lGntI-wjyPjddufS5Gx8h~fM+B! zu|Qzzta9Xt#?NrPi-Cr^c{LguLJBS6l%n%UugEmd;sQ%@SE$Dw@!(JhS*fWkOCf&d zFf~e%-RN>CQwQrdq>NHn|GoS7VE_Id88007P3)(GwPkqa>J|9?-}`%TnfAbq~?(A83@rBC>Mv+H~gokyfItWr#vt0d5mk*{D12R44d~pb>l(4zE z0}mcPfF%TFdI*s2tw+1|xDaX@7B-cq~*f>JZsB_8_45P_b80T@aAC@#xWsCOtt zP)^3Z7>eXc$p(%>h*{OO*$k#Jqc1G}dKZIWZsLK@CkAAaeyJ8S4gef>i3#xk2bbA9 zdc}6@U$yUl>eti^gRtj(!ZT(Z*!`ITGyGZIHmEDB|3FvW2%d0*)};!JOe$w$83yRs zdz=sDO)TdL@0fI@;G*$n31F&rgdVoop+Ln@3@A&r%pvOQOzYw_+<=T@G3F$EKdXeB zPX-b`$=r_j%09UQj`^eKuN@)>!gxW3!BQQYN9b{S_Rx1ZGu!JF3>c0X;@W~qK50!iSI~~(>Z!=88AP?zw;cA6Ymc7R(k2sjz z&(?P5qL-Kb)b+)2=V*L)wf}tWFpc-kb<9EEC0;_2b|QeL3eE+9$fsGdQr)2KAzN+X zna}vg)Rq9A(lUvt5t*i7 zHbY8IZk?Wl=X@e;ZuyeU2Ed3f`NX-ehFsQ=P=dUn+>u{StaXr_L?S zz@(>Plu3q-P+6E|1R1I9mEiKIq>S%{PE_}?fAf}x*0rKX7aDKuA=DzTiW%YAaXQ9q{EPPukDc}x zh0L(g&fzj%IBW=<&@eIv@|ZX_3Gq^IA0ZkRj|1}VX-rEN9LpMJyfbXdWBIL_*%&6G z00EG<2G)z@&%)cRTyN=$jl%;>;THn z+Y{m*A&7{~GF3G4f8Q@wEx<^15BP^D=%vr<8!>bgJI#BS0ylOo0 z5s`ODAz5)4jH7TA0u>4YJb3Q2YA84)hsNBg?vni`^>4{PUU`zl>&!6-k!iN2tRdk{ z5++m#g5QiGQe3AHk|iJqhjY<}VJMzO1nzS7q@nP}$Yx%~LwKY-d&uPMy(T2s45X2V z6-Z_)%ECmRN1RH0eNEbCcYPHQ-eHszy&v9 zGfvI5pMDH-pnDJa-Cbzo*c3j8ovkf+bn7PEfA|p3R|c@XvCd&-Ys-(|{@wcw2Ay1* zfdic5Q`0S`BqGk8CVAUsvVkBDm<$1>9_|H*OKmuydz%Pq?Qsh2CV`45za0d=S64To zi~72WeX+i}4%=J%ut^>;YpV#z^kHUk2G-WM;l_=R5tKQ{U|DYPPv zu&o3Pj%e+{jx#_;5)hb&LN10EkB7SEs|aK|xA{ONgb%9`ooB%#G9YRY-I8TLB)y!; zvdi8Axo$6XG{U`UJX73++9y7O2;s*CJK5=c%hU!9?{>A#Dol{+@VwJ(Vp#wQ!gIbJ z4gd+5=#tQsqYWAc9+jIT&+T1V*t_~e;!0dZEyWu;Y*cO29nV~Z#623Qn(vOsIn(>i zU~6XT%3sEVkevHMjk>Z3=}TS347K}#!_lNJj@uNCEg$d6vtSUrV8hmBMeAq1toDw8 zg)uD0C8J;=&+bfs8d>WxamQ;Dm|aP2f@+eOP4HT z$-7u~GV#)OhD5j+Vq#lrr+kBu&R0mnpS*ZzF!{P>lH>Q%-ldVpwwn$~#@>M$V-}W{ zB!A#S!mvv_DQQI32>UqRf9PJ{#*X(Myd{s)?4wZ17#e`3!|V*;3Ic402lBU^-phAB z>_c6UgH*@x@9?>=DU>*}U@{1a9r6El$MzeY_u(&r!@|uY4}P0xD!iI;;z`PvqX)nDUs3r+x`885dbaig19S z^5$eeQrP>nzVuskZtOeJ!@|`W(y52J4`FQOUeQBdWuXjx6JjdgabH*4oDD8IJr)lS3e7kW&zVs}#5*V>@jT(|H8cjA!H4Qf0w8H| zix5)d+Rcz|IP{%)n`k(YDQr?w;F~uE02_|NxOg@KB@BW{WPJb=B-|q`wb^T5(QhU4mG7|pri6eH zNv?Q%n3og;`J%DptW7j&2o++du1sU41${2@MAi-a(ie?p2qThAH{v}YI%^mdR6|i+ za?K4M0;F`5cPBR<5UMkI(Xb~*5jM8;oA^d3M2SyvNnSM$n*j*Uj#Y|0Y3PV(1ljN~ zAW(>Ri#Q|Mtaf}4aSD~m;wzikJhfF%q6BtQVEXU|2B>eaB&d`v@H2XU&;;9VZ_Mj!O-#3_zXN zlQq&2e2*BFoWaaepffi_DMYrqA!O+%(3Hai4Tx#5HSL+WSQnm=csg-7P@CkUWUn2T zn~>pv$xB#mj~Hmg`^qMdJ9(#ZMywPVWj#i3)Q~hUpsmbrS**#Mh~~`z4ei0^ri4Hd z$4xHVgAu3n7SBV%SBV>^I2gfjUjXGyQ)lyXWV=QSflE9UOAb8|P?br<37Bu{>PKK7 zg?Zw`JGX8jV7bWsMzTP_97B5r2I zInqa9Fs_Z2%_7L{u#bH|z0ib>jZH3Z3W3%Jg3SzeQr0L0o?d?SGq8<-0%^KCcOF0o z_3<3FZKlKIzzkCF58>h6yRdj-3Fc4CvOE$PGdCx|_SS)ixy3eY@AMcfX|{4$URj6R zw{LNVpxOCFxP$fH!|_|1??Ue&L-3{#JpxC`E76tQ&c;+*^eot7FXLugP8N6ko&Xd2 zeuy$dAzCNToZ+xDIxl|r?YH5>AN~-&_V@n*j830{?|%0?u=eONeD*Uh!3>s9S&pdO z4FpS;7UpsMa}7HxnCB%gGxp>npk`(c=LgE>`o=zd^uY&k?&3K(efAt~oKXMK1{3G* z>goz_7|CgC6TueZfg#SDrN&9vI~c+`WfsHvu(q)QbNI{w&g}!7;{*0SG~*#-Qv6|W z5RJ)94i?157hu-e$y91o#XY--L%I=6Eo-~qTbb3%&SK+!$^j%Nglpd8>!25nlV!AM%{_Lj?1W;R0^$FhkGU=(VqO4%XkA8VIr( zt^%kTR8M4mT852FZC+>LPaSVBPlXM;&J6=rtPq!Mo(%-DOl$^^?R>nUIxZ>?RzKaWCshJ>*gzlis>?u-;FJjIQ1aAZlE(7rKkD&qd?aFn@=g(o zcvpBb{cmE;r~&O|PswX^5(4GLz-gdf7~$TE#v!-+*^7css2lvwQCTErLgj4&(s~!| z4Un+}kW=i2fz4So(jd&uUrdM-s&e_;%R7+gjFVMUuqzlEvENs&I~Z{r83G^PNE-uSyuXy$I#2(AuH=7 zrciyakL0XnMQ0}Of(gH&YUEbHn=+=vP7P}ZiN|~TOlU{!Z?Sz`rQdA{fTW)w811g| zoyl?L;^AdfReb8tf9Lv%NowiidL*i*th6`NLtg0%XZ{ibY^1%XeP?#IwN+AL=gFA3 z(68zGAZP6?M6s`2ZC!FH04DNgo=gJnl~o-v0g$or3gsr9=n|!u-k*BHR9jJ#6P5FH zUAONj@kQ>k@a{q>Ipkfs*2>G0^%nv*Q6_+<_tkpadRh9~+?}MrQvk}jq%0rS&xSJ| z674MW0w|UIlu{QHIFo7S9`P;!Hfp(X!;w}*!vi1=2D<`!2)rIdS}B7W?{Nv5X2wsZ zv7Y>C=3>SrEtA0jsz*~eSJG4H018=HkSQQD;**6@$b_3<*^byiXA;*ThntX*Hr&~k z)V}1I;nX`}FbHn_MiL9!xw2qqN_;vBp-~k!`?A6^5QL7r39`xnmTU-R23!#8H!@dp zRZjMot1Y~?xl->Bsb3kwJ%rfUB+SCM%CM0EMc;+UQ$lhw15`W+w~JRYQ!*xrn?i|m zy?Wv>s5IS`(2KAbOWF1=9y{g}X$u%eArbT$J!AYV1h}A)MDoMq#atYEqEF3i2#^*- zjKUNHbNAyuFAD8H>06;KlD2b~X{Z-Z3{K766%P%sY0HbE(zm77LF%oZH0lLmeP5uV z%-NslG^J%E&{^mMbB7bJtXAj)p+@q`ci<%4M8kq)gO|lnIz@1W@LJ=TRnASpIt79( zO*?<9{mh8J8%ZdVf*s_!VctpvtTBHKWo^<7UG$s1*;E2K%n>&>?YTMj9^y5QL&Y>( znSxKeP!br(8MXG9>xM_m^pJ)`63Atw)8c7VXhyVwdJIXJSM=QSap%J_Af$TUWQ|mb zW*5qv61v0L<+{SpR4AEnROF?AYhF&_ndFPXA^}ppg_mVnATlNpmdiTu4ETg2FQEH&g53;Jiup~2&@ptP}$o9 z@s4c3+`27ZyW@qQ&)Tw!xnwz4?BKG8= zw9(r;n+Pyqf3G`ebsDTD3Cv$SH3vJ}l-|3583b}j4K2(zS+`S)>nm5z!}NRyR#x`l zhkv*YKYrtNc;%JL6eSERkCvGncnW3p)ag@j`rKIt4@-#Q^(Ck}H~E!4E`u8L3sbPQ zegNP5*0&M7?82F=*Tw4;f!3u9bMVov+pNo0me+ZGoW?oaou7fNtpgkv?Dw@*EMrbi zsoO%5o(<#XkYsPfKy(Ic>szqAyaFfBo`6m_0S~`w?Y3)RQRk*kQ0b7?v5Nkx0D73L6OfEPe;! zD;GCOb*tC8V7yPVh+X|(VKZ$1PVT8018Es`$ux8JN!M|BUid)h2=K-Bef)2Ke0T4O z<-vqLa+B||O>pe5Sf}x4lg}V}a6n?j#%Ho2u7$GQNB_xdu$N!?}Xcd z_8>)B1OtwAaoC*d`t0j<4g1zO2E^r*>HdceQ*ZJL!8@34v~kRIOfo)56TP4Mc(L5r zgsfz7;-|&4PEYpfeFn;m8H}Jn1RvZa9%%MiX?sq6)+OzP`Vg2Q)<}9*?Gsn+r7SbT zR{11&AyAvMqGGImk}I8W!Aoeucj;%rm`}p<%s^+J6yxBUP*w`CgiNi6)G0gzaSxxi za?H!-r_o)L6z~!ESAd~JeuH-i$>1nScO4c2@z}TQjJ$8r2om#ZiD52EG2u-=#>H&B zod!z8AE@tC(Kr#O_t}*qi4*peIq^~KIwuJRc zQG)R*rTxO=7S`~zd;|RccCUulY%}qaO-@La#v6Z4kxQquUQZ3wb%+g?LQ=v4B=Y=-#HEe=-Y1^aQJv`|I~OJHITTGn zJvC&R-$#xEB-4&B)WzJfrvs0l5;F64meQW)=7Ok7AZn@rys-xgg>Pjpa{uH$?!uge zw&l#N)CgQWVZ1^c2-I+rL5lf<1~GdL%W%nDL(E-7>5rYt)Nl|s`*zyEWW?kt!r6;T z4r^iMo+X<>mu@TsXyU%5e)4%(C?yM$*40ik6#UFO9gclu1K#>MoLI=*r|=e@Uvz>* zUN0p7;yW!cJTI!ig>r zAVdgy9f+>+l(DJX5nxQomkH3ZeT$IjW^n@zF3Js^OITPJ&o9(L!vo2rMj4eT)6U#1 z_eHV3rXZv@e|Ytr(yf3Kt|E4+bpi-+zmRv9fylCZWd0jhHiR#yl(0As)oOYUnGy~s znRoPVO83rV&GO|004G`LVO?iuLp>D2hCUN-^T2mgu*H4#~^OAp$j68 zS3ibBk{%#{ig;-V+~n+6S@bF^)iVYZfMOXdN(D-XOn%E=iX>9GrGA&x#hnvN&^~nn zw%&i2J)GK8Z3JX4!!y^e!f1CF)*d~CAAaxq@N2*QTWExjU~cgwOi!=C&5!Ot@BN#w zy153oKmLf@LLL@tyRb*Z=&aj4tRhgb@^A}IQ)tr^@qc;d4q=blhPdTY zs0?LN+TVS$p-WvkGu35%)Fke-OvYwybro*hxB(~6oQ0>Z{}OEN?ZEQKAHW9)I)3gK zzX}&FUqbNV6rByQl#pl6#^wgg#5RKYZaHTVt~=94pr;ED9&JGf_3HN40G6>IwpI$5 zotuZ*nK^j%mFEzscmNOYzX^O!jI#5mfAA-;zr6t+1hY;e5Hq`Q8M<@R2n5Xucb2XP zJjO0H4ILlSlQt#bjnZ#VPdDNAotyCJ;UhTv)GgRX;DbD?rca%MfB(mS0v9e`fEk?Y zXHO$ghJaqyZouqPmpxk6Ha1}}lC^Tc28-}eIo*U(%FmiO`Z)GOoG;{^ zv$x-aexJOYRuFhP1=|P`-p2O#iC+nI?A9I;^%k&!pbY80gWdqT{h=-=8PDTPJp(xt z++bKSIL#Q3Iv;}0OvgB$S=R+%@`g8TUyrkq4E0Gi>to*?QvN5rj<>PZPVfQ_w68pGpimmx40k zg`#&upXqv3sgAF0vdHi!&zVLp`#%1^ zdJLOSLLHQeAeRkqlx?bKZV5l=(>_e<*(y&^EiBN&We%5x^z#}tm9#JI7ww#+eDRcZ z8Xh0Ok+KAToQayg^$GHHlzvIU80*W5J~{09q>>Y>n>ITRdNiU#wi+Kx@b1X@ci7ZA zV#YnGM5u>krU1p{I%qvB;I6dG$czP)(WEa)I8q&G88@e5zofv&IB4OM-)>_4)Aa(N zy8bzUC$=xm29?(5r|aY6kI%$;1EBifSIesX+bg*1(z23e#k|x0Hm`;;J6jk@nd~Nn zXqU)$n<_9PIi1#wKTZiw4OHPU0SK)VL*I$Q6C^MV-EozlAV{Tz4w%9*(o|kN)OV}2 z({7%qni7{!)tlndO~$!$d`Jc(0a3(Lgx)XS3Czc!9yV4d7A{(7DAg<)D+O-Eg}bDy zUMCJL0}g>zl%}_hC#j70kf#fKR)`k{r~9RF4@xFK6sQW1aXnECZCvVKT!sTu9>8c~TaV29~`|oEZULLdlf4m&eS0 z49KABaf)&EuA;h?Wju*dZWNM7^70|h9R@S7KSuO&nn$#eA%MZ=PHv%6rG|eMDyqV( z!}ZFeM@i_?EDLgHURV_(YzX^I>91B>#*;aUbZ&vl4UkbQ1jZa*L@BIsK2Z2UNgfrs z%zFaB_$jKVaxqXb92zweVqi;4T^Jxkn;(*urh*dAGbfBQ?jA3INY2@nno&1!m*)~1 zMZiFznV6hY67r^I7Lt}~Yj}f5GUE00j`UH{+vChc1Tu-vYYBM4;bSAs6qg6Efy=Uf zEtF7M`Ky@Ui1<<(d8j{)*>HacS}2F?<>o|Z2&hvs7Z=x(LShyc`Ew>fE(KI(ZW;3E z!MgO&aL$#32`GGPs78fy26^3#v6mUmm0=$S1PCbzo>Oj_mVB2h*A)RpB>y?Shqzx@ z-#j?bG~xr{5h9)}A4Bc9pU7h&myjz7sdB7uSuYYWL}6FVF_SSk*`1$-Gv}_siPIjr%pS=ApkIkj0pM}*k=U{bx z9d^+`-`gF)#~*);#{K{n5cKI|{fL95i$FJp(-0^_{V^Cw8hfW%-{^1h)EGBZChQv# zSZH@MIEx^~u#gbX?X3+Cxw&!s7JTK`egV#2IL&-BcW&N*#dGK2^ywv-!oFX^wsx@H z`v|V>?oqmH1Z5~(5ns~AzuVI&?<1+KRoI1G((=*eY z32A+Ei#c$bd?+F7cOMT{hJDdpO_Z&6CxcE`*4<7=WQD>A9zNQDsrfA?L~bI8_wd0w zJb3UBinT42kuL0!8w}3DEtH!+0&Wz$O@zLb&92p?a4_sg0)ipqxk?*X^3)-6U?S@r z5C@sd!YOjdwrF~{jG-{mI14LcA`A5mry8iW?~l4{EZ_;xeUh!6ZH+4Bcz@jLggx2V zXIi+^JpeWDG0;0lIxkiaD{;VgBwIW2Lgz6n*>|M^a?nMb4x|HGM022RAC88huVj8kz<>jrQeaRkRX@!S z{RuIY&$vz;12RqM(&3UGfEKjJroAw&T~7DaPz~2{UOj4{sL6L0Y>iykRq;}geK}o` zmnqIEp$bs`K=rh7iR~n^o_dq$Z!?@hLmjw_UFZ{k$k<7de&Xk!me*J9ArW8sDo+^!`w5@rvj=#iv3+!Xjr3KSEvA(E&x-Cg&lEO`C1))hq5;h1SwYUK^aSgN* zbxe-oo%(5A4T|@t@TA+SGw`4+?p!WglIEqMi=%BO)LVo@0yJUA$XLzNsWCJig#eke;wiD&uJkPhoZYFA-gDG8^H z7-l5{CFN+q01)sAdz;hp(&mW_={}vFx4O1M3$ZSH3JEE&q;&SdWlg{=^1hJlTs*4# z9?TQVS$hHE?C=oAkxuOMZW-(7WZ`3PZUviihJk`MgO~>3F`=#YnT-(x5DY{}%60-g`kR~BZ&U195%8D1IR-JDQun0F#HfTZc$YYr< zBz%qKN@OKx@0C2Hg=hYzk>mcQdBvO0Ts;zrG?{sn3TP0CvFbV!@;=;p?>4MFcmS`y^aA|i zFFwy?wZ*8%-hk7p4|Eu({Dg zIc>t#r_RAgr_aOf*S`m=%RPAE)vIvsOFswe50>H4@?-en8$UwOz7Maw^ditGK7P22 zbF~4FmsenyJY|Ud7UiY0-)8TR)s<4)z{#+e)Bisxo4k&7LI=(LAvSoEN6bBt|xCknYuX&_2Ks>RBiY21k-eYatbI23<@)O@# z9)q7HcaeuA>{CLyavf)Do4I-otc~V5>EaR$Ubham;kCPucglIxhSdyM3r9K3|EBIm z5sia%vg*FA(l^nNOTj3Y{O12e#HcmgSAzr^^-=^!E3#V7IUDCFY(`VQnxJ0J_1Wz>bkZI!jMZ~)_e@7aIA>e{Y zmeg6+lGG@&av2aRf{7aT!l}Va7Xc=D*5co7+>=kE-O`~wEI!+#P-y(!ANC>iwy(*P zd3U=E#%7R)=w^vd5j(~}Bn5pT3Nw%T%5;M8bO|o2GKhni1$K zZBFI0)B|P9%v1VAHob@AXoX<&Sl=h#nNeDoF}v69;e8-^+9pYw9YjFJ>YBUg{gM8b za;ojK7gYcm17(WnrCx?Zb*R)l51ge|ROFPgzmL^7$GAj)O41OLTAxr+Fqb6|(Rc%n zD$de)j{_JGKCFT=exi&V=kmTPQ&k|x9RhHSU-cBzX@p4#1#)f-kV{KGE@647UH$&r zzpHhsXmS2up}Hj{-p#V;MOi3*!15Kf5TqkREvV*c{11CI%*e1zA^f{2B1Z;gQXwNj zy*08yBb-77Zx))&s3hq(Z~UpjBgqOwr>33>JcrVO258hEK3TxTh<2g}O`2q~LmBoM zfj5H;lw87B7(D5;82q7B$mO7?JPTqF@jx^MSdq*&G7!0@Yvy#j`0Nljl^JjJ(HO){ zVgpY$1r+J4$A~F6Qn=zxu!ASMozthdp2O`O4o7eX%3!rAwXmbmAmxP+Ai#yq3@bML z`v5okUJXDo{G?7s{7G){oDvyiVemy!RitW=y1W|lWaV++aafT4t=>+MOX}=GPan;z zfjo&A3_)XXE`BW3iVJDz6lL4aXNH5X7XbiNffYoyijP` zh_c3*fv)Z0Q;d$|@g7q4FCGusNEq)3^^etEJemNEO;P?`22d|-dV(ib78X$&Tk;5C zPq9o5(n3>F7n-^`5V01)+lM_0jMrr(982w!r=Yj8EF3K4oiIDY*@k+nt2`Ili;LoQ zVHvfk%A8q?z>2~kXrLv)JjXy|Aenz4bK#wlQ%2*BwV$o7ENf&q6KSx9S#ck$tQo%( zjV%GO8D~oxDIu+tPxlYD)+Mf6!86WiL<){FEbWWI-k2#Q4KHzz5O_c&&7GX*DFc~k z*cWJIawrqO6Xj+oV6Ia>74}@wjA6_n=7WK$hK2nAmio3E5i2lcv!7oyxHFBiD<-N&+}WD65%l+W5lV zu4Nn>Zf^l#ox&KDlKPvy&&UvM2Se~ufSDR}eEuR{}M;!D5ud3f=2FT?uUE`0pn$8h_j4`GYK!pJ*` z2H`mwTPyfZghez+e3)f!zJUsW}%h00vpG%w&rO!Tb`YiO_D(oVdmi6{Ir8CL$ z!61VVZ>+(a*e6@qzW??A=6?rQFLl`H$(kN+d~^$LKez`4-aE5+5}tkL88|?ldV1kH zf;Z2?wJYbL-H^@H?oJ=)(*az+dPYaI7pp zf0<-^;z@SQt6 zhA-myJ@f2yaOtU&cv6j^7s~Q*#Ek0v`{d~sK0gDq6sn1z9Uy4)@bNzO-6|}j4$LV_ z9|CEQab4ZIc>~T|dm84iTw^lz2lwy8#_F2HeKV=25H)iKIzLigrII&MG^i9>d7U zvaxq(iC2JaN`sN80D@FI0RfIt_0)I-f5-{AmGy)otCj+)jX8mL%f6`Tk1G2<`PmOpl25&g^E)AfFp4K$F zO5e*Kie`jWyTXOB^xowid{pMF$@nqKsC$m3pVL)0;4ANsil$PhT0w_CpU#tUoiU;Is_a|> zc6gIj_+XpiZwM9V{leIeFQunT^XZfpq=Um{<`7|y+w$|`}gIOuW>?H`*lX8`MiHe{s zOtznBLUmrHYp;bf{cT>2z5910Jco>DJF)hW{7yI=4#YU6%{Ol3i+(Q}zaSwd?WGfP zFKtNmWSHIhhgmT8Kr?xm>y@i1U-~Swum$y4usZ11^2@vu=!Cm1v7kiKO8gX@GS`Vh zWziPKFrW`9gN{?MhbDo5C%LAMwJ--I5z~~s97^O34;G#lNjXj455j9Q*xn53G})LR z3IO9YD+GBGf2QR9#QpXbV}A!K0e zwGbv)WU)5`ot~j~aTrM^Y0x=Ci-H3LzL1eR#8X`cObW@MWFb^M9{7$%N5HTK0dJ~U zB$TYlMqy)MVM{u^E-nbR`4r$R4?n`GqI^P{5}Hp-c|7vyAtJ~Y7t5*9$y}HMao!j~`aNRt#8>c1j15ob&q>oZu7UrjTtja6&}OmSqSa z$d|4AIa zJg5rc5rV|{z;U6p)C9UnU-Z@8eiU>I$A*_}5Oz|jxMy839(oFVl6MXD2Yb#@ma9^Ln0%%aIBuxyhc|D+GcUXZFaOG~!86y-!KF(l z;74!Xg8%ye^>3kvV{x#v3;*$d{QJjw0DL-_nxejc&JY4~UV#eV~T`Nw|*Ikxlf|1bWR@bXKqvhKg};rr}?GK=k{?%LT! zpyr_DaF=$wYIvusEa`_rPoY-U5K!5lf>WoLU~eD6c9g4A=N93&f9IFrNAEp^k8geq z{k!aikCqXT z*}?H_!TC#Vc)T_QQX8*)_GS3|mtKKKkJsVNAAJC~@7;&L`pZ9qcmC+Vg)jcye*hcn z1Gt+Xh|xoO1M4|8H4E>)y9%dH%t;%(9%ewYWH?EQef9cTSbn?>2g4F}H}+UZ&^&AO z_u&_Q{~y8c{QlSAJAd^p`25d(4*uys{{uMK-Gl32_ySzRpN~Jj0e2CUSwleT+V!X5 z{N<~#aAJYIh&WKSlucN78g&uM*I^oE?V0OqaFTe7$ioWTJt_xq z;o?Pjw7Cr(1fNcvIm>0-dFLH?{P9OHd-gnBe)T2hr2(vmpYkx>kt|rgA$q0FIy-~@ z;2;`}x&aIRfJ}lMy<}9YL*>$c7Et#}NI?b%$2BZnu-(@I^vhiSVDmBL0h|eaRu1^3o^pM(?5(OSW!+d=BcQ9&dR|<9=bsg5_pI|7) zfe8CN`7BQk?ZjS50jF4wVs@2(%QJFUpFBDBaFCuY3iXPo{Z23@eXPM@{WIxGWS)ni z5Lq42np^COhs=IUGVkGgbKMI~YCBz-4#S9ySrx;A+by~?C%!_j9{H4kmDcE?hJy1m zjz43@oH8D~L@z2xfEV$^qA*S}03~&L1n>A@$-tdl$cZDsQt6z~7p1OSu`cqCPiikZ zSDTLzWtR=sN%z+Dn1P-ZnbCiXdF87>K)_&XKy$5pfN?|HvRZNGEDE7^<>AVv($Lt3 z2r@XBjM;nweVW>=)_zNHlYEu}Uet2|yiiXcT8A5Iru=yiyf3^=M^^)`gR?I$TGXc#|P zR~jXS<-D?el7Uk;2A0}9&s@b$Esu6^{Zy|88D9aAVg00DGRE23 zl%&70&W$Cbn96K0w};crE$uNO9lvzL!JaR6vak1-RTomrZbRV*pnMn{7SNAg3#uhS zcs9&Iry9D{S~|%t)$EzUW#?$rjI<77m~e_(-tbDjK>1R*YQzz7&_hFIO49y%F>G^6 zSBj_nLo^adO%Yd2qbp$!WR!Avm4`s+Yeq8xTMX(L*|75FkP%4+84+dX)8dijf~zD* z=#_d`FnO*K1s9fCNDOoiksv^Uej^Y^#^~rk2u_)khc>{Jb%z#;o_HED&_?6mJJ2u? zsV~V)b7qzS3nH?mwi7s2Vn0wA7Kgmyy@Rc7sas{n=)@VKu8F!9O8t}@jv9bK|OhVK zF~r4jCLYPALvloOgTOB0@}RIL@|ZbTUWO39D4l zCh#wi0Vn0~%rQ_#vs$r?=_Z-~HynnAgJgr`aImv2;1q3g8Hf>npsd~H6Kx8AaT=;b zvPuNF)DNxMd6ZMUXRG88CZ{BN^gMZQjFgYY07VL$BM%}bonm7 z65=k)sDOCXzx_a_9OMH5keC})zy-;XTrzPk=?(HKA);IIW}^q$1B<+TEWuVL+&j6+ zoo?o-9BM;naS6-mAb2zivLsoP8d&Zk0&S02o~Zv?^Yh$i;&rscG9A3R5DX#DuORc9 z!OW>#6Zj+gwv;haFx(d{2B`wrM|x!>TrV{D2pBk6?&F-?;-3!bI;_`#Kpz_0tqt}> zBJUx}rnL5>kGW4w?=a}4UROTRzcil*dz;XjnS+evEf#@Y#DC;;7yo&_G$PHyyvyouE4_l41DXGZ@}_KpLuiI*smnj z3kwVI!ZR-bL1#C2-iN>X_kYIj>BLX+*`NOJ3j|gIA<5JZfn>V z#2fR@dpF@nfBtn?zIg*)Lty39sPKr6X(jx@?%(ATZ4W4yo<81 zg24ORKfVVYoMWd?&0rU0aBzTSB8WuZK;)9YdjB5$PyYA+2l&xDZ^Iw{(Z7LT`PJWq z&%OFAS`-6VU)zCm=g(q0GdTeYL^5$z<&A{?du?qOPT+f%SNGVn?xoLshUfFQ{{6p$ z_uu{r{K8j%8D{5Z;RoM)9j;!v3eP|H6az<(R(4_O%sHOhYdGd}(`zt;eL(AMzjqqu z7iMrQq(Aq21w3Bfga7nD{lBp8Ai)0Yg-bAl02w{IwYARR%<9Glf-7y*E4v)>xsLrZ zdiW65@7#i=(`VuN&wgIgk>h*F;BMl*O#-heq?W)~0szT4_Kwrw`UFX+?!;LB1z-HOR%`-R$$FU*2S=78K){q70Kfx73L+THw z29znqnsG^2IO%3SNh@>w9aR2+vyg&-#d`7#x^1a?rNJSUty)pmhm|>`-{+bKgpx%ySJkR!*{+2pPIX*GSt={pms!WEN zH9>LsL=Os|QFUydTs;@|Y@hZu?zxg!5Kr(D3C~K!`2IBGQUE;?FFzP-*Z6zW?`qR2 zf+L6Ngj(Iw-;+L1J$Pz29a5+2p~fcxzm9W_ftZsnI!I(-&kHbLimqZ0+05D`n8X;s z>W&8>ecD%pvlnrCYYEAq4wm%B!c`DvP9fnf9RA>aVmQ<9uJ9vpis_c7D5f;VP2S-1 z>9u9n;gr`VEOMpjUF0Bf0dV1O5^oApcA14Rd10&$1iES%=Iyz_ks|TkNAc{iE@dRR!A5FUHM)do^G{(L0hkRxzQ zy>jS1%nw3976S-F**awM0}4U}{umGdlDrALKhT9ryid3c&IB}IAb|RZ>Xe&Hcp=ZR zjMHX-noKF~}?^TK9w*fa?p4m?x)X(XejY%A-#uWqEwJiL$1ghXMkhN;YvCt zJeJI1A#;y_C7vT)@v;l4&DpysXRnX;+yct+Hp>4Vdz4TijcE#8@smk~%l>oLPpSwbKc0TssOMD-@m9O?@J zbsGGB`T;eVc$~3*UN?WB{6o}_Jm$U(U@@QG3JRy;sJed^qW06H;&H?09gJWK{Mg{*CE$^0Vl zg+a7=u2WfJ{aM#Ec#ce8ya<<`e+gFa+=kT;-i4{fMd%|4w0Zlc@QWeXvW@k4w7v$j zx4ZDKzW%S^t?&N`&R>5PmY#kFPG7hPYme?DNP#*N$93`KNqFYzXVK2jm`i}>$rb`i zufF;kES@+8?|tw9?%jI?H*VhK`al2tH3T*?*x4Gfnx>6or<)^?P(mMdLc81GvM36a zcu~4IZz##!KFZVE@BA1}VEr0XIrAe>#-W?HZo!}b#h=60y}Piofgmi-fp_2fF?{sl zd$5LWB>nYpV+-!DZo^0KzXz{>>s#=JFMf&1hzWGqMgWicX|6j14_4M-?bc1$?Tz5_ z}0X(>K2Y%;kUxP)g zClM3VCSz@7gXiSJ!Zd!?gdR4iw>N@EkCzc-xxn($BhD_=_1Ca}W=~AR*8Tykp_~$5 z&r7d8i+wkMzy8MGz#sm>AK_B(h_Hsiq;&*MXyttA*=JY|wh)M(MqqOeL7CwY!I+0@ z@bJ+C*y{~p4uQWu)@S4Xeb}5^4`!U2UObO5^%u*jHi!2tX{OKb?S*cUVp)ebn{!QzZsZNGvHKh>mf@t zE-Kzg<1MhaB|IWYztL+l7mOnS0~r9)tdevI*NLwcA%-XSYwn^)K+PbZST6@v1H~Ed zkr*yz5=s}mE;0xi8LMQ{4qRe9*q(XFA?Ve2I9D}@e2U(xEX1!>4k`Hq9msj{7Og%A zArvyR!~@=d1_fsFj6(!Q#xWU+@Rc^o8z+pT8y^cg;BC{P5cQjnR%l-HD2Uj5QbscQ zDu993dq4>oXb%nIRTX56_s^_NVmoOMq5Ej_5E@Yu6!m_w_B5DWUp!;@jNVDMx=cgC zXL77)=E@kR{og1wRge+{Ldu=k{%B4t@tvSL*{M3TCZw-UFZ z@L?WG3U!s&+Wq{Vpn&3fVCxN(z6#{&K3n=ErHhCF7PnCwU+S8Yf-@pp#+&0qXl>N5 z04aEoB_XN?7RhgAlk}5;hHwyGyVtz8d;+pqx^9xULPLnnE5`b|R9Rv&eg#Jh<$5gj zfI03Fu+bS+@}O*)f#*g~6R z&?}n;lL0A4FofW_3HDi>Q>nL@3%XV-3T`5BNmqku*T{H8;m_1FgB2ZaHe0je9zEnu zem?;=8Zk^mcP$*ELoWBk$H0V^L(LK*S8m3xEt+0VuI+u2u}*7Bm;ABjEj)bMFmGUDi+El3b7zbrJ!Qb>;2 z@E!4qYG$dasSid1DDk7YguV$ubmU?ou%a+-jFyCxaDA0Sgif7hL#z{PFw$&La!;vT zIh18an74EimyruZ$l7#XX~;z}h#V8_!fiY6Ou-ILnLUV}JkBYniU4vJsza&L`B9Bk z%#FyGKqWd+Mx)025zi$8E+`C#ylVPrRB}j4CLufA$0JkG(SQ&DYotI+>^s?vIwhtx zphgK`OUX>Zb><_&4Aj?}%gof^=HeCf;kFlL_?|ykeIOh|F}6B*(v{}nRj{mcd0Yp{ zu0$=_yL*R27leOExJ?>7&TXEre8!U{=^aUa2Kqkr#)~qqN|rMn3t=QMH$0QIYiG% z#;mL%GC3+l@7khLVEucKAH(gx`5tVqufpbyk7VW&K-KL)2j!o5zeu-!c;g1#e{dfj z-FpnDt~~?Ke*SY%paFj8{yp}(q;~uS_1dXl`BixFrK_+oHx2!Phn3YWm`9zwu(Sa8 zZry`#ed|Xo51R;n>?6STcy*m+VX8|ZE+w>yz<7k~Q-jE8Gj_Zy_+(TT>ivTPjsF$+ z7(t^)tIM2SX>(^Eft(J^%_4|#?IK+M_!@lo-aQ0zh6qy4z{;%~JO)hkjNt4~zWr_3 zTwiC9h8TF47Ed9VFa>)E#_cUH!`{ILG^b{;K0}_eAAIx?0!JRMJ$0Hl1^fF$tefNT zv5l=Q1dw{LiS_EEK3hTXYW-W^WPojRg~F@w@B_>GNB`*e;ehmhAqONa>{klKSzg^l zFy=9qvkN^0_Li1r5cF7tZ-4JQSk^XNx^`7a+vnz?*xrFZ_|N|{IRC;k?1l62F#;?P z9;1%x!raMId=LQ?@G zo7x_N^G(z-Wyz!>39pE)6%LH%Q9>2GaE2&YVme*6M`Zvl(hXzW%z^45h*xbBm4Y6! zG)AMQz7-q0^uAz79Rmb8&gq@Gwx`64)#v=7@2a-P!ErCSRSf)k6)iJly8Vu)%vED5 zl;xpvQd`-&PuR#C@KN!m3AY~s2DmD8C0;ir#LB3_2wwA0NS#N;C;}+1+IQ)D>&8gh z-sq(=eljcG2x2_e%T5hp`Kg6zhR@;9tKRQcXERY5q+m}|2w0o!svOSGCKIZ2N^G%g zBiCDId`$&>8doqx$rD}otYr}m$ch0Z4XVjtVg!PDQ`>z$taG;4wC)Jt9c?x9*hiTj z?8-K*)WonpfH+dLlh7nu|0z65Nzr8wu4B(_b7OU!)c(|14l-<>;aQk4WBuT2I>0$M z#-n5P4RWB9IK8Jb2P^iAy=<~PO=wIgPk23wBqS>7b0>Nu06b2{A%Nwj4FZFNrnPIV2h7iAejV#B;n)*E{bhx)ndi&MSneF7u^1VE%Va#XUxQ=}*b?AGfIpeWUTkSdbTYu$9I3xQcL`{h;2z^+A(@x!Ymk+H7}rvI zZzF362*8G#7vq>tJR6!al}=OIxFIK(cQ#skNoPA3vlW?VhBlf{dCMXgRE!cg1UaU( ztjrB!6*Oa$Ho8g>YmEd;aaRa=C-XdzVL|s~k;sj+rkIhZApk{rAgA5R1H&DxUL%~H zgj`&QgCIn_i6cOX!wEE8iJl=B$)R}rFt-U2k<#bXHa3`L0T53KZ!=1bXeU`!LMp~0 zX1;M6s=)0mIgDz+QS5Qf^nwLq44`@9j*{Be@`UoDXN0PNcJU?0pB=zkh3CYXiX=14y z86=|tkfP~GV-|>X6+jRsT?q?AdBA8|ViwmBxS6hr6%dB@;{z&>oqWIFyic`64#CHu6nPvHbD7)c(N}x++ zF_Ta~<`W{oKo@8u zzGbrMY{>5v;G`*59f1vm1CT*TATfhME)Xp<*vOWma^!#y{8a|Nuny$#zMg>5BjJFu zc_s5Y^7q8K6_vJUj~LMlB$KQ^{D8p*=DbiaEbq1{k0`ri7yaE(2huZMGk-D2m1Q9u z(W|EnZwM8<0VU%O>pX=~&2+gfy|s1NMSzUv4FSyz){h+f|EzwJ^}(eckXBiriDeK;eFx+dxh;U-{+(&>(^l6 z;zc;IbOzk)JRG3@<4io{xq@KEGS+c`5Y`aL_?vHh z9nL@f49p-{vA8e;9RjSeGN+c7;CFxLSK-q2^YE>|`WyI|KnIjd;_BgfO$9Ytu!8^y zd4ycL_!NgB5opw%n}Rj0=goU>L%F`mDWIDOZv6QBufzH#0v)rzffRyCPJ=u{P|o^;g42g@ zu5H3y9D|1sA0fDeV9Lig;QQZw9X9v-u#4@V!ZxlvdJJnHd;kv+^tq4V%$2Lx;N;n- zVCnQF1cPvH5b#NBHn!>X>9fpZaDaMq7xmQ!f;1#^l+~&`-Q*M7)922^%H|FX_FiY8 zeu$qPkQb__EKMU01MDK0l-tG%<*1AMj24}ylQ$uLKRwl9AZ88AU%7V&&R)6%3ybqO zM!PWRXKVzLLDph#Q~-!TcfXmtb}Bo*p^O_*@MeganvI)e%OC-+1`MPYU45QMZJPWu zZp@9#%ydH7oL3A(TOM6_DtXltFL#W)gaOMo#ECWS4OD>O`DqoZf*zG$N7re>W_sd% z;3~$(lkbIKG}qtrr0Y1K)v>Rdky-EiG!?Q-c` z@^Cqk3u9TRT&Bn1FzzU+L>Y|O@jG0#wMo(AMt69|9TBSG+{Akhd+tf|)b1zS(!43W zhLSkVDiuJJyi}W(Mtv3H_eOxC&B7T~%8S=mV-(8S9Y(`-(DX zbzN8!(g_!MiJVKo8CTg;*5|tcGx2`)mhmQI3Oi_<$|JZ?CIKJyKI6Lj7?yb0xYqT* zdDk2!8!4C+1Bjk*#f}MOJV{<{4QKD41f+`dE4K4V-k_DW2Ot2|_4kCo8NdQLaIbmF z#IAEsd`}|~$7(@rJQ9}zg(1-UMneucFff6^8}rsk3ZqOao{WNAQdE*c0wslIW1=T< zpWH=!NLB_=#$xgKRM!yeWHIw#z)Vrsl$yep23Czf2_RNakS4#!03WYerTFBYHnZI+ zIfbT0g+mn7pjU4J0tp5OJIph{o!#uPq2vq4WY@|l)~N#SSaO{3l|Z15>)6;>P%U@5<$g7*2? z|Jp|e90?I?F5_Uvxotjp*o3PmhEK(8HeSIo&~oVnxWE&52IM%VfUG5yr;(D@l3Y*- ziiU~M#l|`qDB>jCMZ<&mGd5C%^*`|Ej1)ZcrE=_e`J39=pug42A#*{IF+!gyFviCn z1IbuJuU5d!8~Lz;PZokk;V~J?5E;0#83M`VH4*~oT=`GPi;MsU0^Ar3(C|Q>C+dM_ zVO7NY5HcbdSU}2+NL~$0F_mI{qwac~5}WIq%>5cbW}X%@?_B_R$a5sfi~@U^a=}oF zcRN|KcacoXJd&_K?Mx1v$wJnyj&2a+T+fsMoPibYuOYXq99WjIOh|YOl_{smW@+4L zXqo$F7yujb^dKH9^1#v5l++fR|Lnmc;X>?o>p-(uoLfR*VgNU9 z-G&FZ@9?_xCW1sIaVcS4XO>Pe3FXG!`%G#~+-Iw+TL{Jvpo4890E*nRbCmm~#TgW@ z3$!A`&R!2bxOofKw|3#q+aEyl^cmPkS?(b~w1YoW)3fl(&wUA2cJ|?gFMJseHn-pa z`uimqFM;_-Jh6$%BH(Z+~0#IQLJP7`_s548g)S4 z{R9KAe$}&g$uBqd8JFjeuDy>pS59zk^M6!*j4$ZW@;$(low00Qlx8P_0ZuNwL;mKl zDkIbffDqnMh!-0gP;-JQE7{BWCq0TM>AcsxENnj5DuHOd`_&kFR zY$?i8BR#3BJy$Qg{?4Pvz;sLmKMcsVgcIIJkSdxAR_-`hn%-Bxd=-s?S}%vP>pGAA zl`AjexXuTi594x?-t)79>lGmVm=of#cSa!0Py8|k!2QH>%!}#hig0|1QxAgN0E$xh zV<=+>XImQdHDp6cCNmej5u`%o7LG>Jz$rihU@X&olEnn6d91NBuMr;=zlI})$&)2y zzXk$WCmV=EHd&q}|IU&Ln{l`R559sNmK}z?ZH5SbaQbdKt#38iVB75bp3@RAgpEk@V9`wi0YZ68Kp!{g3HJ_%ZS>{cYi zoWq!8kxxYc3Mo@U)jscM;KMk0T~qmDAVO?5ucO5iuRMj{u7>MYSJGB{DXGV*xQo+`X9sGCWrz zbFIz^A5t>L@&+pZF~v6v#qGO^aQ+A?;#-!hv1H2E z+{u_Qu-Xt(XyIGId)vA-3#kSNGFLzW6b5BvF0hWE`3jD?h)AZbu9DGBpVR&c-dd$> zkfOV$hVu{*LkN;G(Q{~2LxEWuODE;9E|Cf;h};rS7S;)UHjdftmNJTAIb_HZ#|!Hg z^5XH5os8!mc`OkSNc=wZS?@p>2ALDxv*(1*XjE_tdj?);{!TUU^A0o-JR}|~&Vc5G zOr1Sza&Z-B{s07I3I-h|EwQ*|%Q({C1o&jrGyHd}H{doAZwQ}aqD~=_;k-Q!)8{Ti ze|?!lV74AUf-M9iIDh;wbx$5@26yr(j06z5bMeKMn(KQAK)m$D zFT%B}*I<2h4IbTp1PA>&o(t16v#^F>6mjd2ewjLd7W$j3@V)PS2j2b36kNG*fwMF{ zTw8^gzWP;I+1Q33A}B+kR_7!FGOh_d1h0t0tc^OQvvd}2BY3lbK;*)77pA68LYHKf z#>wX}H+=>!UA+j`o_iJk*}wb)SR~FCnzN`&M?(*Lj~+tr@iIL3+rI<9{@cF+fBfJ6 zcW{96^f!O?7qCg-%h?M&ZT24A$9^~gt2aJ^lh0g(rx8G+aD^tyXrD4MZfsy*V_zUZ z_TwM@1V*H{iP##!G72RtmRC4UcxQGBRyQ^|tm*Wniy=e9Xi&g5f>ql)TUbV0Kv8VN z{MD8$z(2_$>{=}BSOAc4l}L)@Tw7dM5hw{_hJ zUNu1zMQuB_k#fnWVO<4Xm*SJIZeE3Y#nbfKSI4`KV?1RsU3j=^8}y3nyV{@Tg&M;W zK1s!*!8K-+rG4hB_d~^~O$$rzeUdfxALz>5IC?Q=G^O>b8FBFh-vwQKSPLvUfckr@ zY{)YPs*iC1O#t2UJmr}}eZpXwbKYg_xSeogWSuD{31av_%juRu#&{F1SQG}A~W5&5I&>XUqY2SgwzX>;v58fW3EUll@ zaF4KY*5t*BMD3l^EY&`2}JsbD5@k4oF)Kp0fOAQC1z9+*JlwXD}BZ{s75~Grh zBQh$jO>8ic*B0|`D2U^QBZHU9peR)700d*6jPA0?g;OM16q%@r%Aq=O1|KD4Bave; zPrMSC9|h~dS#AiF(#gey!*qI1_Ie>Cyi8`xULHjVp<^Bp0+`4srcg8@u5L<58guE` zdrI{fBL|@*oXmg$%|96CuDRmziFKnHWzEKv%H#EzVDs2KTO)1e>($vrpLrbk*4i1#S&q=>Qsk)=jbBqjg0wE~O zjlDrgr!Y~s@;Y%iAp$&kOFf-5oUtLP=nd?pU&TP=PIaTqFQ=P30*I(T2I4_uAP56@ zx^XhlDy(kQ231T>J?m_~P`Kg{Px8Hb)#QzihW+H?k;KH)>gA$}nz(T|Y|DEl1}3kR zoaJ9rREH2MVvfiD&m`r#gn*Sy;4MVU&1AzT-fdoGm4Tsw^e>Z8cMAqe+0_zt^ZtXo z9J1QLGKLHi4>_$gwWBdR2knIgTno_H_C4&nf<2m;6p_-!v!|QzRIR-62Auu!F9b5< zDFhZsF4xhx-@ktkHs5`h!I4`Z-@tZHBS>+9f#{xcEfFx)TVLbx-#Zw<{rk%Z%6tsn zb`zd^;c2-3^kuAH3G3T^1a=SrdHWGg*(tdA%yV$+;zd|ooaQvm2M7$cTR7h{37Z`e zu`vP@4fTu~;TY`h4iH3HX8yG0hmT=pehKd1J&6Dnz|uko&R-nz#+ zViUoW7R_q}+jp=%BLp1gPnP`?Zg`tY#% zP!5D}4t36*V?MWHxCM{b*Wm>Io5p8uagpaZWxN_72zKVw83tt>ShS+-Cn(E_@Eb+& zTKK|5?}hUp4`GAsbT0y~>a7t^NM&6}UAeUWs|0JUc=O}G88&{XGIapreWSt)ym0*>zIV_gZ@!*jW;8(?N| zL4Y`XRhan~8^tc(Q)#}7CGnQpw1=7;-a+EAqx&D1eCfgnhq=S|YyU9F;4-~k!I`AK zQCn3n`aIJ*l3`oeo=^XmF<3R;SCfou@RMcGYXcJmSTF!C1uH@rEY+R&XfCN^^yabk zCx=G;g*DK?AF6WF{w~U*Qr{Hdu=47>Gu4ra`l-IoRmN5KzF9(zQP<}waAUu%T9M*dSCkDmaXw612gdbtl$pA$xI`s87v~X}2Ujv{CV^Qt*6Gz? zw|5QgVIx;j9*>)IN|8$ZG7Q831dkIjO0iH)i%f>oh)%|o2c?0=?x^2p!@{!V(0eRA zMh3URC;g=>5<*E?h?u`3r`UfL&Qgpg%aCFo1)LFzK!{R60NJ03&=mW-;M*NFy2LAi zGXQDW54+jxX*iS2vQZ^W=j6^$1`HXZbb{ygRG3fLsZB#6@}zt6b`CAdgt0WwAqfTl zpwY6AoBo4d@Xnz!t^Xh_z6#7}S$3)~N+<#;th^NvAANW4|}@0Nt((ESur!X2Ci>65HRIfGqk=o1^nc^~C>K5F5Kx>KW;<%2Sdu-AguFbxHW z6fmSZl6=tpO*B}@aM`_en~fIpbn?kFX7Dq3VX{za_#01;EY1;?o9Jbxic){5Tqc{< z@EvJ#E*ZJh;1}832TNtop=DVTuA}5?K;cwI2CW+qr(80;5NK8gO5x5PA(;R=5*jy< zP)MA=(`V0%QALJUCiTgtrd41w<|1O?PQe`Ujw7>1=LgF?d64ajQO1P5c?f3%T}TO- z%_;Q8*}?_UbFLg|h+4@q!k%te9|qJ0gCI*5x>ni1nrp58@aBt*aVKu1AzY8%H`0(F zkdV0k#s+gNQMd{Nj#Mz&F1B zm+;Yh@4&M!z61{t7#JepaP8u0c;UG#@RK(`L;z(4e&LsYnK@f%oETfgWnsFLv&YQF z<}NHhe#9Yb>kl8n4gy52Db$T_2&-!c(4FhT(zy;y<1lv4z5pLSdWayzLwNf6mm$Zh zzWamk!@=4HeDzm;724Rp2m7*)Jbd^N_HnMyES-SfP%`VWR}QWNTOYp1A~b#B0?&yN z0vlIed;xy$7rufZ#}?c{(CXzcegU5Od;buY&R&EczWolYG1##U_uqL3=FXmi^H;CK z+=)3@n8{!c>x&o{u2mTf%K`NFMyxCD-P(kA5%}7mB^JSqE{^rV5Hou1s?u4*EmrlJ3Kw`v}PV z^*6r>*Is@F?yoGv!TJVs7|mR`2q#XT;ne1R1Q`ibJbURWn44RKDf}Er-mpVx-@tnc z9QB>uJy`zWZIp>6n0fwr=(M}6Q?{@k`zZTU2nbQet=+BlKz1IJ2{;Bj>;#*=F_Y9L z*(9Uixk@sE`lcy8(XBt5{+4@cMo#j53DwPOI9Zirk;-@3F(8HG016Vy8FiEMEac;k{O# zcsIM$V?sd~F2s$Y7j=^v#*9Sq@GO&P1z-9xV>sUL4+Ugg^3DJxCeKZ}g7KcTC#}2L zETIg2e+ah<)5L&r>AUdnO8Z^FY9e3}zSKQ)shC*oOJ9q{WI6S+Z)S3Mh(J)vCzAs5 z=EWnxq(Wxi1>IiPan^^?YscBPaBSY17hb(h@~02KLsM(`Nc_7lpEaPugA#~4I1Gdc z_delopS;-CjyebHPpsDyE|*Lk z17p|;ggB+h-f%GHDPy*g&9F(}JYD(J>FfUlH2yPFgO@h^WGE1sAsO%OrA0PQ26#f( zTV3IFzGAQl2tl46`w#AOYE>qKWRlI6ctTJLJNA|sYULs^noU+S7(pk8g|%qUsgdmi zn87E+ieQRC2%0K33!o2&CYiylJQ|W#wy8WFc?gpsqlXP6+;mbpY&s#Nzv=V#$wl=% z5#U1*Ffs5ggAtv0Qk@uFzCvDMF7(pQ@#=okc{w#+)Zs5|2}F-g=7 zu?xm@dG8F$k51W-#9DL>P&Oj)J&L#9O7ZS_(>!*XU?jA;bx==7U1 zmGn2(cw8j)vXEbsK}sAnrKM4(bi?>P{oY3dPWs4)>{{G6dJ-i7*Dy|G`w0spR6nEb zLJ3FE^*l6Yl-or6o8}0~5E|(hGA`b^-jP^JiSFV}IST5Cjra^sxdWh#20Yw^a#N(tS z*wh~KVkGdJ>dB#|nr585REW@;!Y>O33I!}|aClJ}!^D({o;(LhUojX(d>xsDjl6)AxR}=n;MWVB7IvhI79W`djDMslfr(aP|@DnGLu>}2s1awDYaWO zbGVKiKpzcx0-Ffn9jvV}z&88TRoHp>06zM`512Ie*MH-S@bW9y(3bDP{kxm&wRrMO z8{YfyKHR@^7p76??&AA4vFS zc?|avl-WjLueY@cD_Ga-FIA%Ll-G}qnufcP#yaI2$^%HpaJAVz!AAQI?D(%HZ=pbpBGz3+Kx~L}>HN7f@cOs^8cyJz;AILCL;bL~vkUW! zC*bNc&tQL@hYo_wef83uxpDE6!3J|!-ha9U@_?? zl$V!&?khkr4SDbMP;V~aJFi^23}?@rVXw(MH$KAp&2jqZhI-sONcCbCHiuc3MZj2p zGR@%TLdsG5JWGfpvkFKPK%6Xop8kXlxr-a}bVrr~x51DxqaZ2gu<|SK@<$t-Y=9?a zL2@7iP~D)$va_+iuppEt{Zx(Wno(8R;7|TObQx6puzIIlheR1nDD%lbaNIt0wR*=7 z_{tj!(uXmPd)PdWeR<@?Mtpcp$__2x`Y~PSt?#X$r3yZTQ^mOr0icn3*qCX3O`m8zLweyX z3mz|g9U_;KhT7V1x5|MN&(j1b$qwNadXnC-*_;9@uJ#=y`{np9H}PFTzocM+kM*b; zzrG^J@pCOpZ8`&1Qc#C3+rw1b<0|duaVe|mp6xyX=Y>wg#vyW3vYDX_U1Rrdt25}=}M z54%!Q{7HZu>%uId@>knAG_9g%4}A@n*RZ?T;OumHbHoNCk?>Kr7*ntyp(VtV0WhoH zDqb?k;6{_V2q?ug8J|To#yR|9AQ>|(L?fv+j8R1A#$^!^Wo-&Ca7IQ<7m-y~79Qo$ zV4-fd)I-2aD2KMuE;cAR>`JqQQ0M>|^k^6y>^&A<9jx=r#S2W(O2#1*nsQ94rM{Ad zV)pV=Y{U+>sINwnCYwMSB?%=XRXUvCET{R(#o|Fz=4NrGum?gB7uT?D6`UXt zgj`08h6rq{4dG>s?&j)sl8~}xHqo6JTzt%-F|z7CK*kxJ)CXY47A0vMoSe;8$u<}RZko?5Ow?|8&FMg)ApYEkA_?? zM$455It_{A@3U-df`Xkq&@+C(sdK>ysmn5k+}Va7$C!Z_1S?5C80c$tposK$ zLo}K}J-1r(i)`f4GkrA3$S@{Dn>@ehUTO!=vk`)Ry_PJ-EHA*}H_XG7xd5!u=Vd0T zZ73W`^v4JWc*0MdNd#a~c#IGN_a%g5I1;a+*%_WQ1a1x1*8z{zp|y01Pvj4lml>EP zuz;JXeL-?Kq&Ym0P#TfvT*Dsu zLaQBtGY5MEcyMR$%(6r{Dkqn)S5>?0#{a1e-Zr;8LZ~f_i4~@l>aQ2nYLKo-2 zqj%rIvB&yutRTp>2Ac@3{P26ND-`PEX9=`Yw|1Mm*a0>q9U;Gh#^k;tx%jB_x`rwrpUxq8#hqRHodHXi3 zZ|_29aS2W!K=mCg<067F1mv!7Y{4D^OFJ8z9A4Bwop%d?<;}rR; z)nx?W<{+ii4Z2S+^ESzy7(8Y8TGl)tRi$n}e3<`IRGk|J#{Yi8&MLF#Z37x#4fZE{ zzJik1rUnRndY4OUYz_8@pGw+&6$7l!WAe9nrI~_txA_0nYZ4$Ppo}Tb<4e=t zINV6CwpPkh0CnuyXgo8>0Y2g6brEPt`^sLSAXu1A2GG%5V$d({wQ~hz_yEp}hc=`M zA@s5-JyN}zh0M6_kaoh@ce1qj@!oJE73TDiY8oHP8Gr7$k}>Yt;V1r1%ddZz9xOy4 z6hc3b*An7$6Y5i4yCBS+^f~L}R7TkY%0;Hm;~aEYd52xbnNu);`B z|IVi`y!cP(G#p&?5MVEnc3V?HOB!R#?9rH-kqs4|bh2kjyDKjE^b8qcPB?+hV~0~ZHw3jNbd@rwba69WD#5R%fn`GrH=A@) zO(&0>Ma79B&w!9Kt_~j+fVv!qa4rLNIH*?#)=v4dB>gxkg=Ryu7fEVp<_XGd*QrEW z>a9Y?uVt_CdaCZ!P-S(g{1u?QC>GL0pN|Fu4b_QRXn1mKoj85>K(bqj7lqtca445} zh=|us7Qn#Z1yqPf29FVYC^SRJSD2KUj4_2>nHPwqS(gR46mZ16qOxQ&>eX|~reY~P z1e~6oIX+6!n#5m1nPwOOYBQ+E3u__wQG+F`j=H!qphcjOdKOSWkar0I59Gl?Z7O-z zO22{fEa^mK@Pkt})AJg}rru%1*FocU$%k zM24w<*?S4pJ4*OwB)m~PLz>Jf<0MNGgB2Z~pPXJ7Pvn_%h=7t-ClEsOx<~U8=OlRm z#LQhy%~WM`pM)lL+jbKANOOR~E%9CKiBk%=Nb{OAFj1=KT)h0K4>&xE-!0&;@J%&! zTuYG?tRsO9s-#z5T&feVsP0_-SMs*j)sajy_L z@o;OCz05YYci`URWe(#yapELQPtU=}H*dm+_aDN;M-N~R0nQx+N4vyjf^``6_u%@| zm+-`wQhqzwMv!2toipD<1M5r~nKrh2@XhbP4i6A$84xe??g8{x*EqWm^&7|TV?W$` z^cZgc&ELT8)-H346}FUM$<#h6_(!hC6p|!wPx-5O)ocALGw}ynt{G zAWtRZ$s(YJQe+d5HN-LKo>+pXKldf*pgth7;2~u_Yjj{hfECWoE`lTE(KPDq@wlzt zxB;iIk6wEIRd~F-0^j<}zl3+*{2|~-!OVqAFl^4kAOD*_gtbQx+53jZ{Ok)a!tBXY zaO16aVfDig;Q-&$I&m5Rt&UfJMJMY3if-3BdiMq(ml84Q%fM^6V zQwS5bWp?odtYE(%U|si6CU)1>HN01Vec~n>?Cmf=(mvK>`rLUYe{SLaf!0D=TWNmL z+RCBDI9Agr6O=xC>(&kE;=CrFpa#m=E|xPWgr#DhIF4wJ5b&isoQ%dM$vq|aBd;({ zFaXJq?s1$f0lWrhqN`+`0R2(V0!J!V)(+-padG}SgFLKo(u2kw;VknJ1YVcm)@>DV zRqvPv0og7~>hOdgt4}Uo0(oxUKZ&3dU8Bikk0 z-eS^r+r~tUqRKbnFC%C64vwtLL?hBw!8G$us0qi|kDbulPC7L(%=4rYnk1bX+jNM> zLfDTbSDr~W#&~dO2BGIUK@W%_;ezZ2(pV5zpT1M-sW#t2Nt4|HVXyo#E z(r?{sWcqLJF4|ksdgBB@YLRYplB%8#j|SwCT3F~0FgICIjCAh>Iv>P?NZRTqVg+@h z%4sqPuk$X-tBtFTkCA+9ySz`nm8&dbCdorDS9`ykaKaw8N2TKPRQZ7WN&qz1QckHR)WSmNu@?a?d;WY!6kDe;dPV!Bj0V3(D{#(XU?2jx7 zgCFTQ=4yMnWUkk{&guAr);A7l>=$Pw?0y`SFe8>OlD~#!&D4-#_>LaTA6xJmZg#SMqUuP5VfBi zW*HEhCmtx&o)JZ^SaJ(z#=NU`wEp%LkxTTK6WWW++Ecr)G}&@7MAy5>Efm}(OlPW$ z6+U{&r0+6L(xbqddf1b#k!IsrKiD|?w7GV#dWS)BPaP5xFEX(MWT-^mL>HMHnohAX zjPjZOK+sh(-^3)3Zxn`B17;xfW$YiZ8LGcsvc3o?NRKx73Pm9P8ci8%h72158Au3( zrc8EWWdTi%tsR!0d20%n%0{P zu)*e*oG?=;R@Mms1rG@iI!-V&B1URVQTPsp4UnP3JQq|hxulX2OB0hfkfX?X5kRVp z2|Iley-Gk4TO(b$T;v}ta9B8 z$fhHt<#w{TSO}7AxS}UiAf452w&%n6jtc45hAQHrq(06YEj9QCA$-YcwiotpQiaYN zLochk*U$}1YYrNcRca=kn2jq>l$j3;DT73mO1Ox`to)u_l`)k~#$~G+ctphOMde8O zU3|YEfJ#fF9yW1a!h0xug1{&OE!cS1g_Y-q0%62y#9%~23{*0337latk20Vg6x?>F z*})`RP!>EYOfkmnL}diZOy*gE$%cjGxP_u4;)P>)`tCt&x!WmIBEymRu4l7ibyT5_BiGTv5-Oy!bst5kAq z;eCi6X1t&fZ%Sd|LmKKw97(iEVFN%wHrpf!N~8;SCW@7}D4GF{IV7iU$x)TaaSK&dKZU{4M4L=(M8W58Tog^-dl;wWlbVkBbgP?o@NO360+e^!_P)6R|LA4oG{TfdAneLv=E3OT_>5j zT0FOyBTU3g+Qd9HQ_>e$-$M0{@IDoivb-b^OZBdXb8#8ueM6uU0oJIaI4cu{tZ--@ zh1E>4{L{Rqb)wmyfkM45=@k#|-sL*K@Z426b#4JRR`=l~0unP9F2JAt;m0r_qhNCl zHW7G$XET_dU4ZrV1Gs(j1}t5@1RY$bb`JV5gKg*%@RLzG>^7V}e+haBXmpy>(BIhN zvEN6z>&~{}`g7;t?B-e6LIC2e_ufY!^8^nfad8niL*S)wj18f{wQuFlE%?cY@57^8 zx1fvqzK!E?fS}{3EQ3t38b-ODxqOv37sK6M4n^%QEW*jBuEN~8vvBX$O?>yuaJM^y zAVUY&U<9!ctfeq9@~CXh%_4ZzhxW-c@H=1oRVKfE8$-0!84`txq<417!;R6JEPQ&J{+pzcG0ecIQe9}5dUR~sUC#3F8 z;gTY5o0S!otD$vQPu%!v~S#PwlodxOIyn#5yA03+%FT0bcJ zUBMu}f*S-t6Oh~(LNsmkC*>K?b-`5()9MwrXwId}TQH15*$&jDI*S`%D1))%Oh<>c z945TWUNFH*tzB92z+s^Z<%H)_KqlSjPP%;UnI~P7?y*x$uc<){EU~>x+TWr}U0AoO zH3&C_4fIjh7;&Vxa0{4dWFLOj?@>d{48RnSv6i^>wLb8Zq-BJ=D>jzybr@Lju`iOn zu($m?#Lc|d_IWizawoh7F)ePjz2+HUe@mO9(PxGcZRr}B5YsZLe5u@s6u#7;Fe}`r zykc-$rOU~&+QK<&q)HAtcp zb?=tSv7|bu9UkrNGO#q~ynn3sM3T&v(#1K}b zz)r|{p|*+vK~z?z_DWfnPzBbkJ}&eHB>F{2nw8D~l6eHO*R;7~S#U$2)_}qIjp{+r z@9J~2Qa3+wywc7L)5PX-`eEgb0LJp<04kshn?n%CG2D{?d2}&wr1w-phLSmI<2I@8 z_0Llem%46(+WS-B#p-4rW@)*8LVvM@I2Rlr%480io)giFqaP)rTBg^&3-$Eroe=(Q zau?=-^+BSu$F9)-QeJ~RJ=haOc{kYTBmjmuAMzHTRC87)+$a+uz!_;8y8;X}B(*L* z+g_NJ4T5E1Q36{s$TdxZ7{VjvV-Is!PEgnwE(%GDO3JQ?+z;HSET-ob&j_!)86zO{T^pxfxp; zTMmVB7DkaEnkoRCImhDZE%w}gSV$WzP()%J3|{YpcM=Z^lLYtqwBCRbE>8ii_PC!7&XkCi0W4Ggc3v?dEGaBzP7&WC*&LEQ zY9Ej{0sBW`+sMFW8=F&(3sTDcs;9C=aUki`+X7w+pqZ;OS6Q=7n~&aEBKXnAy<>O^h3bz92Aw>LMAxGUkmTqrd1o zPHaR*GkH5v*rD~8H(&wul&Bbm(@&OK`ze zOyNNylgdlOz?<}u02RZy!032{`K5Z|mgv{~Ss&|T}4(C4V7d$p( zw72IM*s}#}o-(l9MmCf~E(Xs}*2(27Ex zsDB7JqW9z)<|xGBIRh1BxD((*?T z9QMh>l~s82jqk(u)*AfQ`F{ipb5pRphu}#r^1Hje3oDNw!!!a|9n@jlTaR_l0X)8U z4?eze17!gLOe}x)#1f~5b_f=5ACd0I`8XiJp}@9uH2e+a1_`H$vIj+u7uht^@2V;$5Sp0DMA;^%~%~ zZEkF`7fc)bu7~459x6>eJaL8Sc0P=ubm%Crw4TO;4PY-XJA@f-Z84}Zq&0v%Pq9v0 z4%pacFBM>qM#Eh!kc~juD!AsGBUZQBD6HjUJbL zR@q9q2*}VS2?oqNMxHO@E>iC@&ta%M>yvkRs2U%KUbdFSEq<+)w!!qtBd%ibx|$(& z=&O#tB?))2Uvc9vWX9Dx1VgM|&JnFQGyKT<)YpFlWRBOnm2$$Kk@hGFC=k92hWg>< z_*!45V-XAzCHR*^$}Ape`FQdgQ||H;T1J%8EIVHN%#e)rm|!Fo@*)NtGo8->>~+)X z5XrY5j`$&S$c#p^hO^_g8O>_QSNq02xw9Y|n1>m8slf@ZDx)lWwBGtCE!DYN3n!as zBOOQRt6-Nqqz#8ZFE^$9KH;EQ4dwutn2a3up5tDL99GItJ~yr#HhyW}nI+sNAhrYV z%d`(tP{!IEGKE3Zt%|u+>YI8Rqzx0eC7G@M5Y1?E<`R7halCyn#9eK!$U97K1OzK9 zU_qs7$*V`2AVX1zN*zO=LfR~`GwguWtJQA&GgcR|hxtaRXUzMgm#_U!fekA+gz+SL zXxtl2$F%0zV&B_mm3r3dJjq)oeOFckrNaFxb1tbzsB>8!DfgeG=X{N%-`1E)oguH` zq4JOVI(y{1#^eLQS2Pr`*DMR9x#lt|N<^}B0*C@goEX{sJR2jUo}{XE2EH_m9J9$T z=_Q}Y4m8V%PcopS3z!Q$3?hMzfPk?VgAv_kW?1;j=7`1H;+*+e2`gbFbR~a!3i3A#GVc88PW^} zF%!HN!s{aMaKX!j!IXiVSi{JJAh892#kun$DJK=e(IP-cxGa2vPU_mtK!h7SL1d-W zMOHSm!L!1dca(1Qh-6NrN64>|@}*26;$<>XEWb4a%0}E7wf3+Km1Q6@)d5N-wU2*$07&9golo4bTgt;j;aK~U zVTZz@*oNj16eXuFG(1X;CIeZR2ZcNb%q3WN+p@8ezLD@QZL5MobW+U9#WI-j2|7)7 zX$t|M8D(l2X;|M#JXqLsM6+r6R3;#T0}wWBt`bHho(RI7Lf$S7O*u~UipN+Zfh$rWCf36`iVa!0oAIWHKcO+y@PuRGc)Ze>1FeDjd zPbVp#`;#*Nv<#pfMN&4JI|_#KNam3U+rURQ+KKN)$02N3!)_K7a0PXFR>L66_1`7e zf%@IX%XA7b@o|G?W(a)%%6{Z+PL>edb8W%0{?`T8GGB>HtA3_@R7G!x=U=1S)^_&U z!-(9#TX;&7A;>@+D+iArGC?dGb{yK-0m;~g^=CKOQp5TN*bfvUR46zt-aY31#Glbz zZ_4(F0mp&pRrY!!nQapA)ezLaCp#|!N?^`u=*eSdZ%=>#ET_FN#hJV|cL$I^+Gb#2W?>1o_IoVX zWE4==p6&>#4-_dhP@H&QHto5 z$DH|?w4Rv+^`ARV-}x(vII9*KPM z{3@8+2^9RIIW>&{)Qx)^aODclLF@wpvx(EKjbIf`;Ku1Q3~W(78H^i9IG}kG(!B4? z%`ndu9kR@xJr7GKPjVQ|9+5K>De>MmuU$g~XBMtM{r_R^&zdYrt~5dHsM%e7iG9n6 zT#-N~5(QuiJ=Im!dv$k_EkYrCC?th16bfJXKL4SgDSVh0l7E6CO&L;VA)7Vb?4^1` zp@6CakcnK7nGqTL=Hc62%#`|l=Nwfv^Xn0wsH~Z>gd^PVwM9*rqk2C5&Ua+@{6*D= zNzYj)00?yV-AflKT!>8_grI5Yvu1c}EL00DCWKEBOiaKY*jxnes1Fy})~grKxjBMt zjS~Rm=^Y+^{yE3yw?24J&Y#_nmD@H ze5UIV`_pV^og$aRH_8b|D}=Ba_{boHp3_vBR6NUD9`k-5Hy0umKw+oEcqZV$p!xD_ zshs;*mWVH1Fb-Cjrys8_O?6JLl=zCXj=8o{Y8Kcyb2Q%+V|? z0A`j9x$w0|x@uW>B=wwkDR&bkx%+3U5eQwH*cj|G5 zzP1S<$?s6vGcDuhy7k{rfD0S?-)YY~VQ(r>CVyA=r>aa6PX}wiiDMHW^H+U%{|OeS zJJCg;>QQ8e4uwJ*Yjd15%g@@hH_RD^!?=R8s$!GNy{Dve2aDtO!R^^laA46ETKn7^ z*{J|fK(D`!ojLHLjw}~;zGH5HM1=E7I$fvQBzRs_R!;9uD<+9_-_{&@F~&=oHDhMd z(7BuFB%|WOC9X{!+CHbB4xTm~DP%#tPYYQrYBh__4tF7S_kX49FcYSgUYSAMEwqrC z%!Xinn7c#prcp@~Xh!sHcIMTOQ3o4oZhK>rcp3c%JC+E2P^}b8HExq*VZzwJ>iZ(% z7jYi*d zZE71!OtflrSbvJXTcqJrG50B*@HNcK%V!Q}z5R(-sOkyY8d^^pI)UsW?B4)Rl7kEf z3gLPlcH{LJ%u#hfiq8l0gJtP+J@MV3aWK_PP1=qohzo}kMrG0Gy7v^<03VQwSJ_Ys zJbCzxWD_p6XIZFyLo zJ6H^L5e=b(Q`v8=)S&~IHc@eE?o2RMd~#IxRV3Cmn@}D&-2@@2TO@jIuUb8EYGpRv z2tNq8;ywn*g|HQ~WyGmFe8DLAz z00uC)0EafQ_%0=Y2m?f-r4(%pAk$84{Z@^P0v0w2M}TE36C0nNn*;7s<@Z23AbFL*@s7)g{;%K{7y2h8-AQsXS|d6bV2${OT)$4oo)Q zx>&gIp6nxy0<^Gy$nexq)Owny6)=HR(?~Ot5eUEp1Ff+wy`SqHHM5HZG4LJxW&$q& ztgs)#zM^gk9<*dv;5uX|>QZ01|KI_`Tp(&oeVOZ5Wha3Nho62(8~h?&cX0a)`SSh) z>aG0UfB1*#UI%jf$$`A{=8fdY2YK;iLCuoi`oRbC^e2BNFCIN){{Scl@ zpZ&#O$R|Jf69s?)RIR~Mxst$%_vPs6GdXpaD1wlX@EJxy)>i=Y2o=I7S3f6&VVWGmX=m&?EP1A=2G19ywoA8YRir#U z`&WPbuesR*#^a0BSB?+%*~gEcJ|-xGagMe@X093D@75c#mHNWb^F49BF!aNFw{NHS z3S0xsArzj@Sz2foL7>!j2w7{kT7vcHqZF!MuMDuB%l7MU%7qIT6{Jf&WdSB8=A~5k zcfWch+p{}l)j?GH{=F|L0)8(2ejehZ^NH?!;+`f*y6$!S_P$|Ig%okdr~wf_GO$~Q znQNM4G{yeOS|?)J8Mv^r1#HxC+WNAFEXo3$)c8fT4TZCS1tlCt?Z|jRY|-HM+ycyu zopCvXBX?$BZ^MahpX<;sU4S;5ortqM>`XwCgI_fW(hQw|GaU7~t`86@C(9kc{CgZ; zdxj_Eb6uaN4u{bD`zAs#C(a!r)5ze)X3=DD*?^ZGHRv<=*c@5RgQ9br^d-ay01ZSe zSKORTwlJ;RsBMzQ96}l~-WuqciH9BZ+UN0i(`V2zNEL7tDkpqHdE8++%b}-@Lkc$B zZ(JQ`aL7+Ss~W3gOvVhuZ{pU43h0o^S^XxC6AYYKGiQiS41s_cvnEZj7y5cYla%Mk z=Dv37wRS~WG3oErGjW?4%DWVxr*f)Czeo4~{9Ww7(3fz}mx9=$^`myYZ1N8JuGi@Z zWEgxWCG~xMojpdaOYT^XR=x*lM-G9^x2$8IG}WD;LtMMqhUFC zFDr}cSXgUeVZQPXn@6s=b1rozBTUTe&X_<2Wb^O*Z#qqAgX%t<%vivqws z9aj$1G-P#1$N+(LYOT|H zF_!^?MwQUK-R+)mkh_B;Ed#(Fl>r!8Co?`jO7Xm-N&m25?j8DZIm0c<3I+GIA60)A@Xq5))Z zco}lWMW6$AX!lNqM?3BF6vUpi*0v6|t}SDi(6Mi(&I+saS3<~rT8B)qb{A`ppsXbP zMo>n`5XeAPHpC&bagc=v_5h(dE&4zLIp)d9bVeTf&9h(pLgrVm$mHBPnaq@xMA2aa z9y??SkV%A;%eH6&P(YwK)iwGtm@O2jKG5uJlb|WZgV{%ALcGu{R0#W+b-AA_Td~h| z0cYRA6#z;cOJ*k>JfEG{RNlA)#gbjvs9*|<&ivq_-va0reP*~pL~))%j@#mJKsuUFUoz0 z(|&b_a~1@7j~_l(J(t5HvP6Vp)v3QEpl3S)A9%-q{YU>y1#w@yNhS+I1Q!TX+JC|E zI!|qm)Z6Hz)Q&os%j!VK{~V#9sV^Pf{VD-VUy|{HzI629F6#k+Raooh0T?NVY3%*# zKm0rSJe~Xcx4$h50CTC_hhN<#v-R9t?{MtR60ip#?c5u0lC8IZj**QQfaL(u(08AI z{1L||LW+=*-c!0G)Czi1`wt(<`h#B1U%f6DQ+*tzcY65Xp4_?px!k?;rA+5L$x)li zg=^QON%wg2@yD`CU{#ym6B;!H^N^7a??FwoHiNU!)VX-;rd&wZ-AW+jC+XVlRMzYN z$#2VE0*a8je3|O~^_#EB(*$_Upb2Cthnb?+(%p9nv{{=DQ4aTT=fdX%ap2@M=h+u{ zdU{hk+v1C`Fj!l))sz#>oAC9QElYH&uPYJ5!?eOY@F+!<$D zdfCpjm(H)rpq|wcfi;GSG`1uS8?PTbHD@_arrMRkJ#=%&*3G%!FqoR&D_DjuM5^H| z7V3h3+rmuHIlj&B5kuKbv5K)e2*W*#-|*nNFh&Eb+$r1ONRGzJS$6$TJZsbs$Gi7I z&ej$+uv0UAylnip|4UR#b;MIYAK8vDWP#B!ZwnJU1IQI9Q9H@}tUqHRVyxYQfhlpP zydFnGAgLZ(74Tyrtf!5-QTJ2Z7v3QJImqq5$fkv57i}mDDTjZ`=5O6V-px7 zr+l`l&vyiyiZ)EJe`^7EWQ+0 zpWzsWeHLb9dABl72feDE=j3ZN+NiF~P0i1l;N_Sxrd6kj4#h;%Inz;?X!Z^0wY1Bb zR@QoLY=E^A1dtgdE$sYZWQ&Y;XVkIn#jUS{6}nJ2(cH<@#4g+HxDc%9rp&zR+9k+x ztKPrM6Qed*4daL1G7cSqGbNfgq) z1zD#|WY^hGb$oJTe{1%iJ_8?oUjkm!YC#t*b$Dxz*s(FFlue-ZRWxfjkQ-It?!3%k z#Q?aW@Tu;WI|zZ@UR;NemS(zTV9qLMRq6$ya3RMRa>w4E(O8IK>PRh z;dz~xttEShI!eac!mjyxp-FiI;pJP~`4lcHzI`$SKS=o$G8#JEY=6*&-ivesNQs@hD%>uL3f0M(>%x<$O z!Kua^xz*uHLsRgq)k0j@*I7t(hE4m3Ag=YV=xOh4(siJ@v5*X}ch!ukc3pd2eR_O0 z+M4?UrftN~BxJhVy&y{$`t@vI)aW>(GrdU8DW18ToNc5^?iVU_3?PIHMsBAeF5_utnHQxLK}I-sLYTbs_CCD0FAXGnz(p<`qx1LI?nz>K~0-d`mf z__K81om+3n(ftQ<{_S_<#`nJ`2X{V~y-z=pb2na-?RUQ;|G$6tALZZw+kY?befw?s z!EgUg0u8q0@}-Hq@x~?j;@9`&U;VQ`mVfmx{<&rmOyEvu+0t$&aK`)4#qa%q^#Wa$ zOW*sR%r9S84IgF=R1k9K(gk_{5B>qmcK@e8VVfXjb$6Hmjszg>zWzG<-t*5smHpda z$fe){o>hE!yDHOhk{L<#`9#@p>F@fzx`vTYTr$B-NghJ9;J7Fo@@rdruW|a zK&GkhJ$$w&Pww7j9Wiqw#!#|t0B2|yXH&~UIA#5@FDFp#(c_2mG=Xo=_7VX1oas(y0g~crKt-_)(T$wQ;QgBLb;g|?<8e@ppYiwgB_1Z&+nT}q!=Q}(C2V|N zlyCyjX^N9qfP*NxAJ{hDORG_r-|e7{YCDims`~jRjY}ETL3N3L^tFzc0W$TN+hk|! za>VMprjkQ&{hMxdkJD`XtB&#W;}|77?YhzR4hU}iF2*y?C&pkMwBhKvVPqwPo)o`s zL&?Yv#qo3W!4oVXu>e%ZFg=L+4Jy>g*muy?SDI-?wHZ`jL1c>sW2i#fVO_p>Za~Q@ zJ2k%Z!9_i@(F7G!T|>iU&GdTO(;F(iV|R{PD~MG!RE`vO#GiMnL8AH+tvcb*Ea5>9d zt^h(f30!<26)Sf0#Xu7PiqK0zXxgj-^=zArbA)aBgPp;JH`)N*xS#8@#A2<%BmodG znP%}<4OOVwK4O{9(tY+;+~MvgstE%}PQ&Udpe{zK(}%My@mU57D#K|ZQ=W2M>vyMT^2N_M~sSm8vdt-MV%#!uN5zEprjAW*594zHJ^*gSny1FbYfHX1YcY-i# zKUd8YA1`Qkgi1g+C<8KB+%Y9}B?FJ_zqw{G>r5w0MTI9>6qwB&O1K)?KurC;BTIyCpf8a*qiq5f z1VfuRkRnrkli`GZF>6&jBdC^+GIP)ujEM&J3NqGAReK731|e>f^9rmS-haf*JJaOg zqu!ZGCzS~)mcgKyBrtcif2cY^>44@>Z@ONy-HXY7Cg5ZLkmW*A6*PyP*w)nA1Y;Yv zyV|Z`^=r1VSN0!5Co!HUTj%of2<=4hrjM54sU>?VPeS=w6H6IBp`Olu0*U6AE>f5n zS})8XwYB2AgY~l5dzQe8iv(xDe7pMS=F zaGXGjkU%N5%__u?J{~Q!5v-mrwHZJn^mm9gcSq^^&wefE-g;MF|DE5LPyVa_r<{B9 z4GQNzdvH(U-8-p2-DSOk#q;FPe`W&f6S8}@uD{0mMOyOJ-V1HBRL)1K?oih0`3tFD zuF1RaeoMZSfRW?l19_T&oL{A9{?-qEo8$2I|Kp#^lMjE%c?b+IfZPt!5|l~ruz2>^ z7;`$$;eDt3yV6{|EYH%M^6lUHEqRdIbMLVNU|68vO~Ba0^f!RyM+u;tr@nJO{eGOr z21I?aaGW8PeXBMQ>jk&jzUYo-$Ma5L<#6(h4eNafji1n}WCT80odI|X0k`fuX7XFbM_yG?cZV0IV3 zzkv*X4AP^@kmD2lzqp|dqh@W&Le;UUHoyu)LB`I_8SAnRMHu>%<=&m|_!tY@Q)8pI#n(CV zIEn^p#Np>>Ir{j`uwc%5s6Tm1h!@thmeM?L-HZ2a{Z}=FG#stzOP$xwy7q%2R=cS_ zGQe_5RmBrdb`H?=uPIS{-|~S)W0sksa{RxmduSB3fP?f4x@6+Z2f*tpE4@ zNnmd;n2AfWsQ#R?`jDemwdjHYGw7%-i zfKW1+`Te*7Zw$M-e*NFhbbY?5W86ni)}!d=d)&OaF=)J3KI>$)3~v=QdMc$5nE zF0>FAFVZoEOmz)AfVOSg;+Cd#-ln&re|V<+z1cZ|=6MgRv0z=8?%BXC{F z00tb>>BS3Nc;iGkaJs`cSM~uM!edR}>yEglRc<9`OET~R-vj(0+n}$q@=P@DT=g;f zoVGUD_xydLVL6C#haZcZZ85*r3R)(ysR39fTys3zf7LKoe^7%!c%V&I$`lgh$B*q-YygFO5kj;m=7 zDXn)>Ldgw&cV6_Xa*qh04cBA zrhtBy-3Nfd-1@$=!T|a@(7?7&?TT>`7mI8Yvd%!oyiy~kVQeyS5YqH#OemTmE)ax8 z)+GB3eOJR1x3$l&R38W#e-QQo4J1x|YXv<#-6O&fnf=Y`OPDDsLLO1aa2X}AF#rHmt<Gvlz{hR*@S~69?RUN{Klz=`mouJV-y=*KbhU1z~c`Y?az_mVghG=jhSHWRn)M zlfW40$4L4iV+LgclQ98D=-kkT0`msCIb8z9<_LF6@A3HgQ`ti(Rw~cEKmSvC`ZxcM z-23Iv<>{B7)1JXD96x->F}M5H+X*cCM7FM7*U-AfA?+Aazhi8;ZXE{CxwPK+^+zAd zak@Y3A?y-_g`cLsXUXP%_q*SfS*pLQ36#2m3|yFJU6@-|1Sj$Lq+-p9?QFZ=%J^uc zTDiNO^c1BA;ku!lMa^{8U*8y%$Tq}P?$15E5 z|1lgx$7l%5Yy?3<6-xbe>$^H%`*F+wp2Xt()r_B9s*%%jmSa=jsU6m?^Q?JQxUMk? zoE^Pp7ElX$uuZ1k>i{P-l|x&(GB4|od6@iW-Sw46Xg28?mBIXV*hWKk*vaqDdY}KH zjttPmp+ic4PEOYl(KRQq!UAUach#BlO&kuyi~;1YbN84{Y5_>btrZA5T)-nA2>_H*}l^(0EAD$@yql9`7^b@4wD54*lFz?^z>@AYgw2m^tmb z-{jZ?9LCxR{S^<57{N6qw5+Kt=&myEBlU|$_e45e~PT15II=z7vssjVSg8&DdyyY?r zoHAty2!_3RH5UvsB)6rl&J)ki#Q7CltnGo80$3f+!l znT8T|vtF7bh*bNj{(j!&>-DAWz@j0C7olkMr!eLFec zss8rA_*}EVg<#qGf`-0gog~`>0Ala<9r^0h+w#TrH{|ITcgXaDuQ2lC zV=S)@URb*87uKd2G|tgF1eZz$4iHHNyX>AJoVvpM5IN(md6tdP0J)CG3QaSAsnVtxAAx zq;}Sfa}I45LFXOn^`IXeJbx~Sk00^8b7>AaO!t3s{{>U;&Zmv+?(U?iH^_}-7cO7B zC@-Gv$>DzLgXy`m)DKpvzwf5^SYrNE7~KFFZarlgHJa;SJ8u?Kp9NtVzus^h^{E`^ zFI|-V=P$Uk%{0#dei#P0lsDddL-vwgSQ(>^A=i{A)36SNfdz}4&pVU0HbI7|-ganx zm;aSVUYN$bq*M2$hLNfx)GUUw8{AZ4lW}zKLTevAJ8b@=@lsT*)zFj>uHg>1II^MF zR%^7n%qQRXY=>$eh@24jt?J<{p<6i0&TyI!+hzccaIUH~`$mVerR^oM!T{6#8csLa?4+O8Z5R#1 zh&o1Au6w7>Dw7f*TPbX|$cbHOO=%l5BfvqZzIVqj*j}HPTkB5yOjYLK=QXyA-+4{T z31r9mxP}~iMTiu}jGP=cgVr0>(FTXm-)C^%;2N=1-7+Yb->-IfV>Ld;0A}ugrIAg- z!Rl`mGQ)W~#=?+_Uhmxohcj|L5-q95u&6PQ=2Th%;uquSl*7+I7+QcY$3^9#Il_cy(nrb==oP@_KVn=r{yW zP#0MrN``tn&Zfh-h3;9X9vTPLpicT};<{4ZZ(RWvVPxmEJR!N_D`q2fki(fM(}{-J z<9pZpIt>uY8fYQpbm-nLc}z!>$Efa8`b;_6%J!D=FN4q4rp@Z%Q}sJ}*zaVb*)+Z1 zkC`>0Dxcp=uU9Qdloi+aRh!1@|La0`hBGwQhP^}?vv}HC8%wJw`%>IQW@gB6;+@D8 zuIhY37L289hU37UD}n-3IqV2tiCW6*SZA9tmQxXxwMojrpJ*$)U;?jvP;c)Ehp?Yh{IFkFnnl*81z3xLRXyc<*mW*YIqA;fI^fz4acPcUr$Gj5v{|V}%Mz)z0k#^OD_9n$5L^>S z4P7*C9XFi(9{tZ2t8gj-$YAGvoE;#ib{7p-C_tFxMGhR_cCH~B5r7ais}$hS>}ls% zmjDPB3k|7)Q%=^>Tmc?3aFUY;@C@t}PYbUC<)N}!kv5~HD6bg68_FV!Wwy{NW_mIJ z34qUwXS5ZKrM*@#AT=X2Uy@zWctd3i)uPg1d1SB*py&47GHES2`2!#UyT{X8)2^E6 zssv-G86~t$PAwnWnDBd4+Y2BCPJEvnbAYAOnWrPKn05dWpFSbu2V;*QTBo**>>cdB zC8ID+PW9sXQ|-%GoUkFvMBPs36v0J^3+kNuW)l?#=DdQm;by!3?SK8>%A=>x2q1Nq zwFmEV=NG?}|M%x#%5efszyv!;fXBP~ zw0Vt-Qv+C`p#>cke1^UPAzn|}4PZ>O`DqO@h)0<-hhT320zR!R8O9FYb1QvpEwhy*kvJ+WJnK zqjq1rW!V^Cu-_o$4j}ewZ;yRi=Zjv$MlIdB*qjew^zgxh1hie1_x}Drl+SgiiQ_<{T_mB%0I;pyZQAK*&JV^Vz^X+83K3#< zF@a6%<*IUJLeV*hQW&vrM_zJx2u2+)qCX{kD*GkX`(|g(@8iz;$k7=b^=BariZ;Yh zLU#Vjb950KZIhzkbWb@65|r?Q;&_f1)-OBio#4FT7Q&gX9hbxB8`lJKC&C?|P0)_d zJ5}>aMgd3n&rY}$XPM8a!dm<)0^`{UAXUMtC=TygIhm)tSgu#u1RjWFkz;MwM%SD% zW~VjSoQ6L;7r56)=Q0yOl2h8P@@=)AV|f=}18AX2Kdv00QojXs8vr5sU8_H0Ea6LH zRgeLhVfzfiR_dDud8wnE%lC?Na@qXd?B4;C!OL7b?^PYtbs8(DIe6Pji^g8SN<#(ydP};kyn>fm*RQ1sTa3RBE{C#~8z_9*W0J<>f z|5+rsdgnpdr-+1lOiQt~#4tiz?p;bX=(qXZ>%Q(|tUAAp*?N5XMvSYF7}HT|+bS{! zd?&MuDkix;UNJN#czWzfYoN=V3pp(KmT95KFrIFui+gB$Hpvm1s8$FU+1#a1*JF{C z79p$tKtqAtxu-)WWhG%R?G-@X3o+wRXJTRSZOn^icgFH$h7bh&YHW`vOvI82;Jf$oijpcO%=?tKTqN_UDaB>AZ z!QVYQhHZ9)27@B1V~NW23`Fc~U4_V+)(7iP+G;|KS<^!&0tK43uFb_W6=|C1qY^GA z>Xe6RlkIDEI75_LnLLZ{Qe3oUcA?&>;Xw*ZC~EnG0SG!OEPj_7H(eP}>qshoLx3V= zL9^QUFiX%xca7K&I?bLHO%o|+1aqKfrHd-h^hB+Wpw4y>-_`0Y>_`D3jyXJQGRc}b z%={!SG%Gnw%LjWljg6LKG@Q`*0D;%knlCO*4P4wZ)NQDdl6MS~d}52TO<+h(a^ zr_%&HY$XQ|&Ly4A=GcJEj(wsAWHhu+j5)W~#dj*>QF3-$W12A}5WtANAK5)i16HkV zbtr3{h2Gu}0?5fR>wV1C_QGrgcIv!6v~C&+12kUi4monRGn@2S~>x}4BC z-clP6VcB%^$&ND1XeNm8OqgAW%q@V%+hB`WInZyRv$L()oP?>o4=4%?cFTIbui;OP z*=qEiMzh^1aBezWF_tW3J~q<%0HGlSj4`5Nj}x6|Y)pck_|c#IMA?|CCaG!Yp;?m3 zare<9dHdaW<=nY*av^~U7p`5B8*jZSTRSt^OY>cuHVWQ)|9kT6cqx02o@%(PI~}w? z+V*RPY98~8o!8FG(Zh!X-q=@Wvpla6K#~L;&K5ehCYlbMVPp&!RAwWXG`+ot8@=8_ z9RZXf6i?YHj|iLqFa&E7c0@NHG=mY&alNhf+yx7}++taJ3omWAX9-BTsEjc*DgZ8& z+0PZ#V~PkdguWTW5Ouem=Yzq6w!$1v;CaR}b*Y?338*@}drw^W8Y#+m&tH&&+S>%itq+fQZ-PB@4H4#MMw)8?{6Y`uwRhf?HO6du-!|R%=Id|Bt=DhJ z2mk30<@ML!lE)98%dMLih zf^^=J&x4(_9Y1bFpr1}DK#b3>UY*Kz0?KCTGhEgMbKGoNDYRi!N z{ZXoeX*0=liglX7qOqQLUUp=bM<{f2wawMywDNc=_th4Fc2&Iw!>1b-$Ke%>k}v{H z2*PY&z9>`a<;T#`3{nP2%=6}}Yo|mk`;R}j7FG=L)%WrD(R&v5fz$8XaF)`@ppH*J zCFaHd*ijifWOW@4>g=rL@pG$o%X4|{=w&B04xYZ8wjeQCSe zG0zT69PNZh88`Cq9YvJgBE}S|U&){2eVv>(@ttjbRy(+Fw2hP#-t(ZYBs*a04cStmqKt9!{qOH}(cY>P>%f)8TEL?YziF07qW(nP2y+bMp6E*s{*AK6k%{o4NM> zxv$4qA~WEfw(<=gF#~4f((5=H{++LKcSTONRq4~^nD9hPM~uM>P$4jc$r{lZ9N0l^ z4vzJ~L9_JG$ECi4=yZ=A-094WtQHcw6l8%=7$%nhKh^v?_rGTj!YO${1qA*tR#XFs_26d&_TA5(_p(Ui?xa^Jbb^8V4G7f0w$=V3H9bb~E;72veGu9n=&0t?oznxayfW6HJxyR4lzOzX~m z3IX2fQjP#7PE21XT1sUwCQww%sH6Qgn#PYB@SLs7L)vD9dq5uTY!g``97 zdjMRB*BLe2^?E$Z8{;7Gws0g(V5op_5KHAE)0i+!KkZJl0aDCfv{p8d_w8b%RA{^~Ky0zpn-Flc^yX%VG!vO> z>h#pZIa0P1^u5wG$h^alsO@Ol_+o(*S>AyXc^A&l$P|J(elcZ$ta% zfPKgHkJye3aobjbW$Jr$Ha?piN=YCufkx0!iE%BSJ+BoN#Ga-ff_nfFB<4^=Te*p| zZla|{$JlF3KP$I8(`su-pKDaHZp?|-aF12i6Kk58G8_;FwN_vr024xRkZEZrJ>#$c zgMTQuF6|^>W=9s#I9aUZlV9JFukPI81U^lm!G$;9mdBrbM&<^t_XPn>2j)J25i`}8 zBFluJlIptbT)$3d_Tb?I+Fj@;kv$3~5$1-awoztn4kf}nsoq_$^Y*ShS?2IL#3II!YxS#s;d9njJ7GQ_xvn<%%6I_}p z^9MlVN;Qd`Nk$#Hbnecr*Qs5!c=klavJ(*K8T3#mldWCZx_X0i7wQIpe$yzUF{b|7 zt&S9&q85^hr}s7v6lH6aNt4dUBJq=7eI!jP+r`UQWgS5KX2O=-?BOzCLdOyd)>Zlp;Y-^ISX;m7 z$(8}|arw%1OO4JjH-WT=NRtkYA!%-1@{j6zi{q5`0)1TEih|)AU1^D=p>TLOvqSQ%V^VE(`Kz3PZBDa+TokIz?r{Y&mM1`jvfY-l&) z*Xv(rKD__NGI@@lbBZ~TF?b#w;i=m`eK)}((&_ZrCC9>ynI5=v-!bcl7yyFBAF@#} z3k1%`F8VWFIAW)XLV|EqNmHJ3*AXn6&O|BUC^(bB9d2a>G@I+hR~t3o&g{xEmc)71`B7>t85qDRi=%xL;VKSLvk*uF>tVN&c>A4HV*II zk-7y6>)~c%#gNaBvXRZMB{Pe_O{l(%qAw292Q50gNe*in*vV8 z(UR>GqX9zcfcC-yA!o_)M8DYDeT`ZNtD_@^bl~0KBm&gw_Ea=C*Pn;Ppj)_xQcy@46n|hj@Ilx$JYW z3y^YrU&G%frnBShB|Ayew6k9>DbT%6fCfN>3@SuT`J8uyd|_!09~Y(6gWAtyKpbr7 z%lN{$>^wAbqS@mduxPeh08<$LlNL@4O8ikl_7zY)C5R6=-@mj z*Z=?>Hk*1#^DWgD**oM|nqR)mg*5xx)4kLV#|pYw#wqHG?d`FDYT9lU{3c5Sz$oUB z^s|+m^75fI+Q1%0%4UGaLbzcPT^7cDOK8T6m@ zj%4K=9>qhUqR9*W0(X3|kh zr&SPI0kxjLcb*QsF+HVpUw|~Kaijf?yFabYKVY4xwp**Ay9l#`E?lo;reXNk4$FIZ z?*+SC4lBW!MHqzW+>Co8Gz$PuZ@O3Y0-~3gvzbMPA-#~p=AO)sE|3MZ{n{;VT;TI| zwk?nE-jl<}Pb|#VLh9^(NCUog{g#T7Bdn`+mT0sv!fl3!9VTFMp5{uV!^ZbteD;}q z{NXR;e5&hnyF2pkTW`r>YV&jFb_rYpoLQ!EbBOs8p>3&;?;_;y3(^o`m%+Qtz2};!|H^)7`7xq7%Dq8yBnLgrhy)y?far zchfb4i#I%<42q_Ni3I~(?Mr#p5yrpUnkCj{I?H`VS~6$7?&N(!F2}%;u}z1uGxe7_ zT5L9%K;JmPg6PcmxGs*{uNTi;yjXQ*aUKF7|>b&=<_SeVJ;^OCddG>l*q zpp=0U^OYH*9E`#4z)Y+mgke7nqq6$>Y>$F3SUuU=RE8|8!YC1mr)EGpy$^-HJJDf7 z{cyc{^KHjo=r?eL3Y5){sX^K*L_A*;PWE56t*zpAQ- zR~#pRzFgKIX9aa|G^X{rsjqoC*32$E)WdRp9S5FbJUPzlziZ~r`2O{|wJ7hVbNsV0 zATxemQ;)R`b5XFrYdx~e+G?6JwZU(46y{dxFF`_Wq;r?k6KnfCoPXVS^SRi^(F9IE zH9xo`I5mG;2QcWFaD=c!id{tL!f@wyt~<2>JK+(jQfJ(arH)E80XaH>l95{KP%Kw@ zP%0==(oZw&0~Nc3^V=|dL3gCr8Q_SPX{VVS*npA}uH@U%O%YJ%Nj0WZuE9BNl;hni#cXb)Q?-2TS#8jisOtR-T+`s8{C@AQ>s^ z&RQ|;1n*+LP}Z=sCQrV7&cGCgsofYc;$T+++QcR@EZ)W2s#l@m4mAJH9F}%cCikWo zeQl!J$VJT@#Q+Q0x92D&sUjg zL8qu&TfGFXI=KKfp=dH|8r$XSi}MpG%TdJCqEANNZkDo|;D9sJI&)%KUn-!?-z}R@ z)p^TJt-rEg1!esZXvODg2YYJb(JCs7_n6SJq^`qU1!q@>3O-I!-RvZX4q*Wl_TJKr zL%1(8&OqEW`p&=T4sY2}?4{n_LzqLGo()G!Sx$lJl{K_tr5Z4K@(-%I8EumAMG))= z99B_VBpx#6VL{VW-}7}230y;*RhIfa7$neV!SewuJb$7rCSN5zaROe2aA*|ntG2@o13nT!L#6rb<(P;hFz%x4cK+7Tr|6aj@(F&g`Z&}7E62gYXXEPK?1{Q&jIP&zV43{0ak}gSi^26&0NB)qb&VP{$(1_DlAxHDD9ru>cK&kikLl zaUEGNFA`AjD1G+hk3W=KzyCMo`Ildik@ow4_>bhhAN{AvnZ7JP`3dL*$l1y9rDH>*&!hf1!30O5RhIxe54GdT@~hrX3RAG%e35! z702^&0%J5&;UP0TAv7A`A;8eAhvgu9-)3f-l#dl)(2?ap75^Or8m{m(yTc#$&K zR%F1OOY_zjckaj!KKO0|vbSUhV%6!IRcgaW_wUI%)&Dl?weN?EzwEHsTAD~+Aw)OHoZ;O33xaC&{{U%i-gO_SVC^*W$hc)t`_ zkxdKcljplsZC;d1Jk^=Xpn>1V?YNv?h7;upVF(t4!X7!Rv$6@089NteDbGtDP<}l_ zkwUe6affyM^jK{^#r(IP=&#LsB|W8Km}lL`2k-kEz0%OJbrwuax0W zh~2r|;8=;>D^~X@l@MQ5$ie+WzU;K?0_RN}E=28Oz+!+}u?>>{wkvI^TlFES9Q%RO zUVVDv^p?)WS@3t-d(AH)$svFI^8+7BVSFIWcaQt2a z_J#H3VBhtwNopIFF>Ee#W`u2W-o?9vjfv2RZ?DHw>cHjJ+njQh_0pN}XgyK;A~eHsWgs!m6x8(Ps-%>bX4t9P zF5g4LIZEnj4L|F$7^x%3J)MZ26mD&6tIBSj*#gR*QYH$Ug$$aNMAs3~xPcQLxU=k4 z4E2f8c9Pd7nA#>Mb|;5LIE9`_eWQYSjR8O|Z0$&Go>Y5fL4>95+#5n^?_r=r-#ckS z87&5)5KxdqyVHcMfe;8ZNxxH+}l$jV|;K|dZJl;dJ8dN=usCeb3mZTayB>s zQ;nGdA>Lr+VpJahsGxm|DYqF4qU^49Y^m1)=P>qL7OtRSI(uonFBABJ%tZ6#904Q% z!vYy)q5*U|RyE8dtd>#~|JC8cPSP~(7-J_H&Mcj9vfN&%BT3<2urYL;_Y6m~s%Juy~KW)#Gj0c?h{LEpm|dakokChW!-0{VmB5h4Z$8)Fcx2V~1Z zD&{E#P!qHShYq00In^dXs1V9YvD?%qz&ud4kFrT1XiPhvK$l=P5db#;b+TE|j*Ddu zO`50nnI`ZAF9>nxgF9a_1VzV~WftpH6j+SCGP`)5&p;|=I@`elX`euifpuv-%&%O|shejPugHbB z-e#GeeE9PO20f)<^#>n(Aiqj&ck{+;^1a{vei{pxhvf5AmAHWL%?Cu?T^2O(A^Wv)f&;J+y8SgzYjff`?AIJ-Y|EBA&q`Cpv z@~Q)4W0m?P1bbnh2^4o42HinBDuHO{ubh+r_(wlZ?=&YX_|HH5P+olRf&Bg-{Gn{6 zHrn38uG*9gJdPj;^j#hLU?CC*C(W}3X< zf7McQ;{sW~$bWCz@r*C|zW!{?sHvYj{%{Nk&?#wru_{Uh3TFcg;)e44COe)@<9cZ9~kd)E*K>(;85=KGfNR`-m>0X(fuYDX2n)%8{1BcB`m-wlpw zRR?2mV{l%K11Bu+uD`^o{YH+k0jSDj)9i+orPfHQk0uO3g_C9UKBw)XasqJxdMYS0 zzA8%DoYel^HYJHjJO#>dF;{nR-DbK^O#9i`=Dw}BrC>=JSaR@%RdND+)^s z9k{9Q_nX)i?}nLa^EIxm!41c#>M`exm@$LJ0lMLag$&-K2HE1s=ASy3SX*wIqlSIN zPA=aL&K+b58=d9lTf3g4-c%C~kOWdQg1$LXnesX(-=B=7xXyMXw_{)Wtn16ZwBE6P zVn~R^@9SNBRS+$U(2-@Cfuosjy66~I#qnl+@c z@DVqxqS-)9D}v!Pv$>_k4Jvk;#WG{oD9PZ?WRfRg9JGKKN&RvK?T1;*op_4HCg+hLS^6D% z2-~ULNSOx*90zv5X#i0N$A>By>}k{|ZSIeF*5c_CIywL>I@lRFWXTz0xCsTr*J=0t zk{Z&QT5Eu#haNI@Gxb|mdC?Y4m&fVxU`S*(!c;+1%|NtZpI9C2(XnD%QLuEP{SW|v zWef|=mdvkSQK4;wZb1+?l?x0Mga$FxFxkE1r%$ZC%+~ZiQ8es#EGr$~s9|<^9`Kwj z9IRn{%e|+TwtGzgVC&jzvUTMu-y3}tVMl6X8iu+lAiSeu&I|?9aI|SNOXDknGz-l_ z1OZsG@)Br(bjq^?tP$)>brVxvER(a2_eO}6G8h+fbpJjDot15-qQGsKv3x5qYQUyS zZAZpl5Q?k9DQ>%IvKR^)HwgVmz|iu=z6zc%J2F|=M=%@_?$pc(9s~oH^EB6Ks36-I zmZCLLZ-m7H=yg_nu!RP|;M6~#fAn+S56j@KYd0CTg2<{Tjh5%u-}qb1xb%8@hpShw z%a4EZk$m~_C-OKs*Vt@0|DEq~e1g@X;bhO!%juX0FoQ7%kO<>&!OT*ZDP)X3g>kE! z4vp%4QOsBE9>5@q4wH%2vAqaHLo`42C2F)8(+-vn%&R$oItZaBhiIC9Kiof5{heq! zSLq%A=+K^*zW4oP6Ev+g!XI$}073}XgkyPSOuZFDkdaQC0@2*6SA8p#58w*Qvp#r{ zL2~vh^kK9AEp>W!<>2<01iJb+-{Rr{AO*mc#p8$Reb130qf9|zUy9Gu_&-X(=HifT z0icE5PU-{a(->GDd6<}ir%f|h{G%T&Q{AkVon~x`!2DE~ zXOXVmd-Pl$r#bnJx8IR}`hWQ^72K)c zy>`g*tiX*orH;AN^Y1D3C`@T{D8MbH6;3=l#SU`!U^BrMz z?g=Q0CQ@)g{%9LcHBeM1L+6OdH-}brc7utAumZ!Q* zV?bfk5eH#aR%55twc$u(FviErU&S%LcV;o6ZmeQZ$3-MOpIC})n@Ju9RXgtX6zggy z!vn`4l?E7(ZGrYDim_%8#6?;MXKA}{aLNaV+bDm2kZkWWY7@0zPMR=m-ykvupPTli zO(<NY%xFvN6|?OCxA9@Yj5LCfQzoBu`h4|%c3u(UeaU;pxDmLJQ9s*s{3gKI*Ez<3QmFcpgGM;I6XBbF#^`=Be7}k7 zC}7b-;J`Eouse>Ozy*K;h(E#!HJuI6$s5<1NELi^?=JOHvepK|KrZZP>^joSrX631 zej?k2F1F3-LMc1VR1|cjpNiMjZ=Q{D7LEjRZy6i-dyLt+7G^+N@R<~{#Vwi&5w_9q z`Q~$$3H+~Bs=9(Doe6}lnH4AlKp_~_z9q9qi_mL5&{N|aV4vUV1O-(sU4%J zE@T8w$a*Buq0T3cLP@vEWmPsMUA6&2n!xU(Iflb07L(eVa5BI{8~_!t^Q|E~0pdA@Rm8N`ldNq-_78xS zpk)Aaq_r#~tJE&cY$9&pgbQh=4+bEC5C??SSeOuYodZKXoXxUU_E4{><~=%S5fMvrWl@Y*|=WI(c=eXgmsHGg?hIx z-y&GC1j7hzkN~?`0tQfj0CI5M&dpn7cpQBBg)CD42fzWxmii;e`bPWS$?W_EUPo3- zYIiu)=##MB02=03ZxB>jy#VOGR1x8(DWQGPXnAmtWxybXhRD{%D}2@}J%`~&=m*ec zIXKjC)*waT8$T-z_o5IZ?BiTnP?;HHfIh~7>w9$u2#WOyvctAiVEDp!J|KgO_O(@j zyK+9Y^@qRyT<-kj$MV&iZ>Rc6U_lzIm(ur3q|%=6Xvodsz5yqi zm5fw<1Bg%#0;QI%2msx2>PtrtAE*vfD$Cv{A7jL7xE#Xvl6|F}h#C$D_7V<^FBFpL z!qfYJ71bI8>*#2q^@0#5XaViLQ2n1B2+6Nmrxcq`*YQ3H^lLFD+hF=PnyHF*Vs*^> zpL_dTrd6by49sM&A`j z4WYd;|IX8Wv8DiMhcW`t!R89Ut;Lf)+C4IGW|j`#7?0H5N%eQkao)<)&px$2vPFj1 z!K24yLxCX)CdwN>_$|3}_bd76v(M!9o3G1nzw_+`%*^B{z2m{*A^|mxrH8e-sUJBl z={T3#YLe=Ey6VMdk^oY{(nxMJbWa-{PRCcU=aGu zksLgGA^*#N{EvD6gH$J1uD?b`@t$RJ+ezc<^>@CN0Jej?1QDG|@*bF#$o_GM;-rJ% z@P;}q+ktS1rT8xubRzzUjj^ zIKl>p5>&REXkKeBw{AJ%o+3=~DlW*f<;0gN}C?QT`uwk&n ze~NQ>7Bx2k|G5jiai)9WzCv)hDMx$t9#m|MRA z%O(V=@H82Bcn4VGhG#ptV`#>y^>&s%yXl(vm#~audo;MW*>eZMGOKZP9wQ6-vq9(I zjJoRj`oGscwE(Y=B(Q4Exc zS*&=O7N6L;UndYCSXLH>N=-C1b~HH{IxC%K+)?q=3hgAAG|7OHYmh{v&nqAkyib#% zvvu{FvPMKdQwBt@Aq^IP=c;Juf+v^*?+7o)ZtiZN>?}%&3sy7 zTBT&z$wF)f$a$J&JePv4=nt)?jm2&;86{arwk@F}sgK3QN;PLtIp*|vnr0fuPQgAQ zo@1HBy3Ry@*EtMJg{C`mE@nFXve>iT&sj*E>5XaR6TV2+(g2%-b?5@VXcuHG>#g!d z9X0G0!#M=_!>lMv)iMdjDqzN+nPnad+LtvHN5kg$+zHYiZ&~)0C4m9{(5aiVKH*rQ zUXa0N1x82Oi6^@SS|yVy%fK|fbYMHJKi|Cz3J7sWZ8kG@*qRIzf(-;adlNL){S;<} zf)mcPeEON0Gs|?dG`kSAZ)utowyleB_XcKam-iXefK<~9QC5_SIx7n;s-UW|)##+A zN?K*@}ZD$;jbO~E}eLG8|1C)D*} zSk|FB+tD(6EtXs@1BgujN4q^ecTrhgwDrBRoLKLZEJ{n8VA?cWm#@e)0aj>pj6GUpm*=YvD)W6Au0ifx6XKSPMN8Mc~@GA;db?KSV!-3u3 zzI;i}Cy?biHZfit$o%p(g4j$Ko#p`oIcDFP0>0BW(TPLnD+e|xrk(&t{7&b6WuR@C zD(lMha+o0vn<5j<0mPKturu3RSx*VTp#$F&19{`ZHfT)D9AF=SB0O(~esOL`ZBX7! z(U3sSJw_=;D*A@N=ZxSc`qYe}oT&^5$xHSD%$(!Yj_g~hyt50JIgY;dt?y93=%Y_R zm0$nqPh^pRxy!HLl-J+9C5H)+*?;j|ws+4Z&{;Q0@)|9uKs4GJz~r2DMLA=cZO!-{ zn1OIOE&^~&?f3+J+a|)J1PmRevh3ctCEt4Q1G$toQ(k}Lx~!HO;?^<~*<4nsU7tUF zOxEpN-}$bb-@QN}T{A^(vrMaQ$$E!9_TRT>b6pQawStq>SEuN&z1qZW6Ldx!I{e{I z4%s*ESO!*U9#8IrTF{_Q51}v~GA0x%9g!+Lre0I(Gc*HcV>c!vRg{UPi)mXwnGK$p zNV_vv@)0Zgy_YqV^J<23eveoDG?@_<%Y8%v1GPm>sTa35_20h!BuHuVhgVU(t1L0k zEqUJZ^;SjR_H~tNIW*;-b)Cwn92K<198yiC)ni4_Y0yMF?d_YYj=1JEutaJtJKN|4 z5CjHr<2pcO8T1yi-%7Pymbw$TBiK%6d>^LPHSI{2%Ql;!9~b$3Za}p~4$wr;W)Ge(KvTHn$10BL)Ih7kwbbaUo_x06`*u3UCE zBJN9gnJUyEJN9ANr~T+-;j{IzTBqbb;G4)5$PvZX)3%27`$Tt4+tSHGlh-)PO3-kQ z4jW+@gZ8ApFZY&QjwWZsa+cI4HW^477~d>-x3CQmlT+^4+H<&Ac$y%2_D zgUk!7kKX$P`*@LVD7M1gz5?)Nrb|-*Bk#YNvBU2bWWxN^vhU<8b01whb7%x=IXFNc z+UB;VYC|%}92l|x`V3xa_OgCdCI^3F^_)$B5!$wqCTE&!a$Pjprqm%^tatdc*cb^~ z-eBuh@iGTrfrnC8qJ7ZYB17+?3ez{+sX$4S`(!d8Bm+y{*9xP>eFn+%gMZvqW2&B`d}D;|V9_CYe2R~kCeJA+ zLQL!X*+-L{%>=V}Yuzxa^T@$7nPsOBv7hav*Ih}h13`~ZPOiqo2JYrblXiF!jmJLD1D1n@Ih7vCo<+wFjt%e4MP8Gs@S)1qloI!m6%#A2!&Ex%-Xr^T7N(IaD~Ex-+( z=VJmHsx=d-B|rc~l!^x63n3-UIuvcPW5OPFp49)3%F1Ze*m)VV!Hi}qOcTag8tmk( z7flTugVhNZn~k!H)Ii&=M&Fn*v(99|mVV#apiS++ZVgCkt)ECX5>ihHv4C;PiW>Gu zI(sh;$kw1kE@pB8F4*9qPRA}7B|T6@sYan>1L;|@_}($om{}z32&1;aGMcGls(pA$ zHpg0yv|nRzrSHMo38n$m*#fv}H7rVeQdnu*L^BMWZy44#F&09bg=JYcmgUKvCWa7# zS&&2JS_4t43_y5NO+!Q*thyXx!{=e4MG$L8GfRPOL`sP|OWpCptdCCo6H8@Ht*5qt zo*Z|nysQ03WK=LC5Ew!XsWG8pf+U(+SAiRYEa>5642P$)@)l~Bc%5MpurH2 zgCmBXaM!-okd}bH@y!RQ(r5qPsMc&Kmt<`7zb=g0_h;mOd!d!?J&Hm)70E-3)}-N zsUrp5bV1Ol{tL7Iv>EN!exZO6Cc*A_Wxyx;g=W!#E{}p9tvMr>Z6~PsEr5ueozDBM zGug!IbEQCNy19h~a)f6d6XTj$%QL&@w?yUJ09M< zm+Jko0fxvZ1psMJQ(nh4fkCy$8p_H=nlXUH>^8?eKud;%nk|PeNh<#O$suj4vOg4* zX^a);8w48Cv`}CwYGyt3!-FS}Wd-dY02Q5TXK7ehnbW#t*WzIU2XoqYO^Hq0x;9%F zI|cW_9JTN&l%*jL z-x$-S)hv5>KJ|#!wotWn_ffNkd3n0@%(w^!>_9_GGuT0F9DoVRzJiD`K-BZ+sBxu< z2ae?zKmDoPcBj2c+JUX_Tkpc3g%J{}dEcGD?0ot& zV%&UP^`dzfR*Hi<29>BK(DYnCo4;THRmj)+b^eT8tFbt}9%@kDJ(l_jr9MLKJ_H5A z{2qN@)-wY%BgR~R^}7bI4}V8Hhd_K=&W-w_#nEubC_5lRP)6(>v|P4MHgu}uWa~

tYX!viBP-^{etk730qUK&Zh4Z?4F45Ki}Zip8mPz|!Acm;A*6)c)$ue1)imQm8O; zMXJ9B$B8~_r}WiW^5t)Ne#mP;2UhbkxdLxgP_!>=XxlIyIGPz)Dc!)KNfi~>a~+WI z4ezE7@v)!a9WcL~NP6oBLF;Aa#v+ThkYb_1N-n%h>69&FmYb06p$U`T6R%DF^O5lZHfmrGll|^*?sFa^nTEUnqd<2m?$8iKR|(p0iUPp-?3_ItxMNUsS95E z#mUh!JgRP;0U6qlK^=x%32LwG&s=YocNZOIQb6uns>CNkw*vzZMoQgzp}IlAhX5ek zSfZ_S+?GfNkZMq^)(*=V^y*qck>SL0_p|rZ%4Vn=SH=!1G}^XVFNLg(5KJIb9e?b& zYIxN!zyicU6}b+^Hn5j*BNViu$h47YnjIY%bD>r7 z%HA9dU4RvlV79Vlckv4EO-NTea%24_&_R>j$d(l+z3a+F%tDzo3A(H;O}0<2mg*DY zrMwdWm!o4_>}m*0P7^z^&?eK&X)JAYy$gv@3kn1y9Kc)7oZrSLudXkjHx?%42FtA( z`-_1p9(sgVX&XyN8@SNtPHbaSHJweNQ>@P6)M((Ektl?j8Q9*2QZ#X+X!Vlrh0r$a zK)}JbtRyZnoU_|BrCl<+#21%klvtgKcvdM2Bg4TC8mkCOxw0nKI@ehC7_t%2R!mo{ zf|3j|L)b}MiAqI9h1yC`_}2#!sCkcVc~Yibb4@oeqO zvFlE_Sev5>2qY=Hj*fSfoXyD3mC(inri0S?Y;yZ*x;$+dUimHhrA9z%t!#Kiv(QZoxZq#M;84`-gxI- znWZ(%(f%j$cjc}3K9K!ntM4FF)%qF%t)uk!{YMYv=G80m`4?ZwcIu0J zsl9IBy-j=a{P{C^^5CJIyKs){lc#$R<@Fn{r*`UOKiPo!OohX{)sZX@moiTP@Oq(r ze|vX};LvLAj#0Ewfmn(1yCXC(hoyZ&wW!TYc(uP}_p~@OQmrfe*9@EwocX~TTQ8B~ zNIHu~YDZw?qgLPKg>k5y@Dq#U+Tr^;$N0gU3i7hc&DN;TA1i0C{6pXd(^Tub_PSG? zYcv+o-XVZhoT*sdZvX~3a3ZCSrIe_;NSC!9s*%45qxP0kW?#p~e16Pj^70QhePVf9 zZ};wEVYIsYTiU#GTuLb=R?gxHhvX$kZ+exg!Bw1gT@H9BG$+yg7OkmJy~BypaeA{@4c$m)wU(p^&8`` zABCYk&CDFB#$=4eMu=p68YXh^2aL;Rwx+&^pIi3{;s$33l^Vkgnh0}OW&rCKvn&s@}Di^D~MJK)g_yDegUz-8?e z37JX53R!4)6km#BnyST7cy1yxnD}Du7+zVyzKpTN6c)8_sf=@PfxS)cfGX;m7I8qB zDL!mv_DLCzj_sN%-B-*B@^Bb999RtEbJa&7u+@0 zvbN;zuU((pyKM@ZIUal=kO|<=$k}*syQTFxT)Nb76oP@R>RS-#izblk>>#NIBin7b zLl6xh#P>*74yFV%<$xh2nz2m7FchHVj=!<3f_JJAa#?c-)l~H(&|lVzV{2E{S8#Fb zTnDHcgs99kOwq#@P0X>8`|l*MDilVG3DbjeuwHy>!P)he@Y*n6xEsQtv5sHga;J*SKk?cB6OIW9c2{I=CM9he0$AMou#Ffo*GL@Q!s04=7vt4 zh8mdwG8R{;ch4HOQYI0>ZwNAj9q{4>LmiRc8vSJjCqI406w4PbQjC>MjYdI6i2kC3 zc}6()Q?FC&e}wkdmR&5EbInX!=gH{fy8z%M6tkn_E!q7kGQ>e37}=`;TCOZqicYtb zR;(Nl4^fiQgiT-X73oi$)`BT-)dQgMEo&%tCD=WqDeGHtyrtbjSea%mTx%7`DQ& z%Sm3uFzg7RX97E!@vt|5-+))$h0%;;0Ky2QPF3$GfT~9@vd>@$!i8NtnQffpAWwjq1W7WQb#in=z`NMz$!5WZ{Yq(%`-jj@gog0q!@4{ptnkW>Tv>WK2Nse-Y;A;zc=k{sQY4dO4F+Ef9J}AHcI9^4u9UeVYD;05R57 zL%Zky7t31a)Fb3MDO8JmpU=bC>#46i#o?*P@POqKDvH0HTo}LXK3asBoyM~|?SB== zz(E!n0bHdY^OL^MPGVgbx=!o|PQqE7$Lb5SkKshSY${Pa!@G<{jt6xd!U znq71HGf$R#e14EK^bhN^C2NqmXgRc9POSCq<{}%NxL6uBp8iZZOW%D}(dFfBqmPOb zDo3&QkLsf6=HT!;-N=l?teg@p+iCH!#$%~4PAWEmysRyynz~EqP%I~Db)NF9P);lF zSl0pl2AxM8u&X!W;_!wt3~4$2IE?{u8UUO@A$j#-riyhx1}0x#CSFvY`5PW*8awr2 zMJ&uDeRf}gDZ_Gx6W~>R*{x3jWCrKOSHEwLkg3kEeRnI|OYc=SCG0+KL!(I#gmChn zQcOb4{5s2_OtiSMf}+i{Er}@Al5vB5njoWwX2xKm%9SH8c9&*8iOcBgVgvB)$ z3Ro0wDG)=glty=qWo;TQeX9ctyNYf^Th)x=3wH|ocpA z7zz`0aSUg;gzl`fP-oYanKFl|*e*TOTw~YOGxTr=0HGgi6CMt9m?!6Un5Ba(gkGum z+UE@1iqWz$%?#x0-2)RB7-bsgbRL{rWE0WU#Txs_P!9lD^ELxY%8t=6IZm+T)4EWq z>g%v>dv(&4Ev4mdWUe$i04LF|ZH!_|phW?hKBy=*pBF7&lYo;t=+arLcsh;7x=@dY zV`8~y8GR7)gAf#}M}|z`@6IwPq&hxC7~-+AVi=|bHUStCsSV)#FX8kVP|J5f-Lx^I z(Fj9Wn?+)X6TlxVQ1NbSa}en4sJ@7fId_P)|6;@dgz`z)`~Aq;^i$Uwz@3(zawjO>`q?uyJxr2^3E zczWD=Cc{S$y-8y|?WnsgM46{}HiT}`hS-^3ta1nu9B-6?tcNOQ7a=@s2NOER584^F zV*+t?W76PVH6zfrhB~F&u26r_`jBeU3zoU6tC%^dZ$RL8@#ujvlXeuuMcZ((2tAgy zYD~4jdsjEnJFhn>ivkUko0%i8g4R;D9qe;mptEl#V65vb!yN$v z6*E@`(@Gxy^e6IwBFX2~77(;PvQWW_Wo2c_I%vk=|pmI0ddJb&0C#=$f7b<6f|p8*U7?-0Kfrw25Sg7Il^wXR7jZ1 z-(GDiKwj4I)P%iz)9oT#54)zF30m7c*DNi}SjCA6KqFHb1fX%7a~Igp(U;~|E-5&? zUguCfhM2~(gRQ1tnV<~8nW$(kn2T!*byC4!(^7i_pObd<*F7Bi3m zj5*eRhg96j&K(>a$pJ*sw|C@cfBIvIsXsow^CiD$>iX0siv+IhKY1j3pL`-8{Po|F zTi<$1R)4gTU;ON6WK{ut+e^UDfB0wrt^BS3?0+SXo;{XFckjyXRE6I)UFlTj)1LNr zYqlke)b4x7dvfpIUAFtq&N zafpNt#qxKar>pb*z^vZ6_cFe(EslNnc0k3i{&h#~tj9M2=#1Za@O)d`kDnP%Da&{V zwxD90&yfn)8rR8&2jt_#J6Gi#fM&k=6i)&&!#)s);DG;Y_R*a$*#ztaW!-qlOzjMx zcI1sAdzu3oI1JJdcy{l3-jX960lXW50LFAR3@ zsjXK|jrgXs6z9#^m$`gpIyBvwN{drOb*X$)%jO=kv;DmcgmK5v0h-vKbjnLz44e;L z_x1g-S6XG8nv`rh26g8zng5I#G>}bBaoBvXll|VuV@81FrAO3u$O$4&Ie14;zim&Z z?%WNET3*M`eK73Scptqn&t4yAxGYtPmzI=^VBpx)p6SG@*1 zd0ShDdznXLy#}ezGIm~iPAq-^vk6P7y8?dKzZ-xkQUQ5I|Ep&1giu=!*=V!;dS}Y` z+?4^nD0yt<&+|Q+kx30F-g^Qu-}UivIl&i?*d_BFQ|t%}X*GHl9ERkuLSFzoc3512 zRxB0{0=*G}14fBca75|*Sk#CuPT@fNbDagywp(7KhL*KVrK)Lgbmt!nEG%YZYmzHL zg=BluzOl16*_sze&QPlCI2qd}gF9Vu0;2&kz3+@uvqr?CRjpjgtmti*w70A54=1X_Zs0H=9L7L^NYKjLO*L>O5yEq*uVi`_UDV7n=>Ls5Rt$#%I|7V?q5hyV0jHK>O32`o%8K!h&?X5MdIL6x2_q9^GB5|b z_1J+&SOGN{VrLoGraCO-%2u$NW$cGq7T(9&COg1l!H->_lxkxrct75~Aikl)GHPaSz@q)TF&tLf18NnVC}QLas2ttDr(h?>atPW#L`B0^&-c_GPUp%3g!U9t#{+_0orH?2`Z~l*G0{lI(fWypAK(hqQR+F6g&}S2LY5> zK2va-A#M!2(y%8mhHy`SJrIS~%sMUga$vWkg(^DhubpaI`>ZKb{Z24=XInP`Y?Z;j z)p&^0x-3!|a+E*?)RT3H=vxt(Cz=`iUAv|I0YHNev1lQjYnflZs=~b{HV4+C3c0&T zojp^GO_|2U+8A;Kp2$K|n?JpHf%V%P6Ap|(vSBO)2?tVIA3uI*VZ$A52JX!;;k9PZ z0qChZLR$n6HLF-u9hljS_8A&Td>5oArwFr(#X|4MEWa_KbhARsXc}2)9~&p!$%oT# z;`Yuq!q|*!1?XTmdb2$o16w+_01!H(uyKKD6L%oj%H|R>(9q_h02J(Lu@Ay}$9v&@ zQOOXBjz+zwST%(9)4yPTp}n7f`jNJas7@BHeeiTo{^*bXSe~bGh5ERC`?h@WgZE`R zYh-z>^@^P=FsAU@=h7UpL{`9w&QDWh$x82Vkbo2bG5|Bb^WJ*|+P+L+%J#JzHuv_j z*n7fuK6mY^eDL@FfxPqncjU`2p2+O=H|336Z^+T3hw|`~k7);=-nlLR_MiWe%(lF66@i z#wa`AI^T{Kerh(ehDkmL_Q2+qY<@*f1tvn+aQ_Mf@bB^(tS`)D^P0+eu`JW_nx(#% zEp(f+IKv_2MR^S}G77+-%$7Ca*f`r302sV zfk4G)Kgse?TO9@!O}k_u5&aW!DFrJZC&QqC!pPYl|9hgZocf`d6IOT>^-*V*>GR3z zJE(xEr?D<|H+)t!p;BGnd6+%_wg1M&3YCqJs!n4p{WzcNYX$wo9;x^3W6{YBm8}@J za}6q<03_>nHUkiYJtNlr!rCcT@9y==uIimnPL#hY_Qvr$@R3fbtHxN+S*$#F8#9_B zITY+HNA0iKgYWan0@pT&x31GFCZgLb zYkrgMAJ(H}8+j`58qNk^y$le~W3w(ptj4gPCueJmv5k%!zCX*+cV&aoyJEC?%UgA2 zkpr9TppTCU7CXLs$lbKHY6{?Bj5rori)D`O4jvvMVhb<}#aXH-Ai`lF(u-Z)FdD?` zn05OdQb#CwDX9V8QwH3`hp-WYJA5K;cMX!9JhoFe?`uB}2i4U1J6Ma8Tgd1qdM)ynZU4$;Snji<1>4XKu1ZL~zECgd$Rm0XWmtynKC%ex`q0H`KB0 z3LBG#ixP??TPkUs+jADvGBibOneEW^MOVc_wphRDFRQ4I0CW;Mbw)y4+9Xs!Ot3a4 z5Rx2DPuEVs3t=A?UZDtfO9QEl2#8`Di({>fEG+nE7cR-->0=!b0HVYOPv7TkR1{r> zhKn%>$O_w5wwPudTINu*tQ)dk7o%+qEwt%0?ch3_3FV0hL+TX>V5(+@UUYO+JaZ4y z61O`V0zqdBJIxSBMRRw3)>}}zYCBwzS>170$uj?Nk%WFUnUeLUAy_&ddTSRlGaA*q zphM)LK+x<+o&owL(zZ8Yl66U_t3#%UWq9c=j@d#Z;*Nz_dH&blSR+#nonf6Hb)yL? z>N^-n#ED_OGSJW7(?Oh2uF1@>IOBoY9nPis zj)!e!PD92nz~KmED@<<5wV3b3+HY5!XTYqY*X4bm78h|l$WVc1P?;c3*n zVcP8PkVSEr9BZ&JIL0TM?FyhHz$;}0b+ifEt$MbL3Ic07XS}=C*(!s>wBMd`K7n@J zlvp;j6A0hpvy6QRyX14Cy>^sp|i4DhNXBs*R&@p6_3?Ct*5%x%ISC@UpSaa&=*}Oy@ zo)tmE)q$p#W;%0(a8U=VCD3*B{J9)Hd&=is|LeaeKlwNRN`CKe{|%X3N}xx2mx~u> za$$E%o;)~^!(`*mUAZ8ORL`^R)E6e_5?HgA2lwvD&wue3@~cliqt4LVZ@(iK6KMDO zrytWkBNg~EwGqmE_5Jtdy$`-8Z@&JPeEO>|<)8nT|5Vy**W|bV_TQ1C1mG+HIwyM% z9ivA-`)S&^dL~zX_(R$Ghks9YFYUna}7e&|>5WhIr!Mf91yrT;ad6;oWP{K}O|_aU&=atM9X8J8&Yb#zqeD z$(`rH-A=3pLUpZQSJU!0fi#15j!}Bq45T8EmP846qGq_f1i zJ@|Uw&Tqm1m>IsG0UEvc(GxE#o8JG_&*HEzzv>u3F;<_x)`?>W+})+nW?S4zaA%?c4W&qW-UVuIsd{zUxO$cQ_-@+bgKpc^NaK^X!~Z z&x3N(?&0)F-VKO`^cY<{S}2gFV4dqC)fSg@%CRU_pOuS#?ud$0nkDO|;NXIe0K`Oc zmY&Xph3WKLCJ7E^b=sNUv!CRh@jT#jd0m^uSOblQ3xu@5>L;28*pXnZhFUDx=zJ7E zv>44`07O#*9BM4uyfC-eeALfuRvO;C%vvxJCJIyqv>DtMV zNxSxw-SZlXf-F793z?ov&zb^^((pTVs-x}h?`T+F*Ja^qhUN9gnsyt`Ey8@3$L7rT zCK4XAX2*C^4H>AZCi>iFkt`mqw>I}z7d;j?cE}twpXadw2j1Bm(C{FLwtGn&WCSS6 zj5Nuy2NMOm@^FL?@874!4*|3|&tYh+uhc&QVA0N4xFgtE!GKK{zs2vG(t1wkdup~| ze)$ps9h7hN;&nMr01^98x)*dk(0&Nva7`34mXdRdP!8C<*@g4clF{;14)5J1zypSh zhG5Pa4urPtdKF?17Q)B$-w1VrHW)J`tyotRgoQw`5t zr#8KH<(fQ8&i8S%P%yPQX1`f6ch>Qz4aomd4A@&6^Bu0dRG2=PSz+G}Vk(=g-RoAvz3al-!?s6X;b<69stH zX4)-NXUz~d=MR83554600Pr>6W}D#o+{l@#@UH^5Gns;EW>k8D zcz8!_#CZ0`wT8&iCZ^8-zIezd#x3kkv<(a}zW|h8_|6BiP9P!}DYyoqX=qcXoln5a z#q{sz0D(Y$zt8vN%dZ~GS9c!}*hZ$L@W!ol&Xyde@%9%#|E0YDy$@vnU`1yJ!n?bv zuYCL4@5yVgy&>yVACD3M^Jl;Og&ZXi6VKnedMyEbw{&bL+x?3VKa?N;^Z!o1|NDPe z-u=D5DIfove<}a$zxY4P?wfBh-TKkJ`||wbk7WD$4Y~Pu{yq~T?5`&YB#JUWp8)cO zX5Pa4f?+pL_NNV+<`&thR%k2O)`^C&Jxk-dwXBrE7olQH5wn`X{J^Gm=tC&1Z`a%l zAv+g!41cK3-E<6`t@^Ngp1M;y5LX;uI&{Fb$YJ0NOE{Y&To?dDmWkf#Bw+QD8+qYm zBaq~$WdKQReK}m%mojZGYqWYhao5Tzc1N{li_{MPOLwQM=i~a$vZARYR@OfbXmHcc zHrVox3 z*)`MZGzYS-%Z-kz$VvSaU{RSebm7H5|ghuX&#_rj})7I*wP??gFKhZ$(8`V+vGE_C+Y$WgVv;UQ~$ zhdMgI%A6TNrbTmN6j@&!fOVt8>#De!)_0@T7kxu~+LU#EZj++LM^;nc3~cFXM;Z6} zJc%d4woTwg0g4(K0BjrHDc=X>4llQOGei(rn{^iAT-zTC_*VdZkkMFunZ2t3nGnt< z^ef@yd&JR~#kLpw!Zl3=%naVT>hE@erO__-H;l%akI}K+kJY^Erzs-8N!;V1E)YiVfkS3TWgPW-aIr)mUb9-Fd@~Db!XHG=Z-B-H*E$k(qo%D zNNYRWY!rqVEGXDWc1*R{X2{muDEfVIWYuyG2OPsaCaOo!c;_|e*q1BLreUtxUNsmx zEXr}cs4fox8nJW1)R|fvuP6H|_zG$~bPOgIV%GcO#efUTDui;7nob>yD695RB6i&= zSgD^KKe(qEK*ZV^b=Jq6!GzxF$i>7T37R`xY?LD`h z_iYOi3*4n&uU(XMndq2Vxi!9f{-8-^)_FThW zb`=OYPJkB27#I*_S_K1Iz#>^>hhQrK69`A-voZd9wTc)61Xhr`9brFp@#9B)*HjYj%u{0o08JVj(7%`^VC6VDuTncW z(d=FY0y5otr@#Uj4Rh%0TuOcJyzAQ>Yxo<5hZm}eJD20FwO{iS6DrlQWDPX8;x(IQl!1jyr*w}8Szm?v3 ze&w>9d*>Z$1Hm>d$&}I!fZj5up$hhIf0>;9i|M+Bfpja?@0d<(Otczid32aVJ-Kir zkhQIS9dnN@Mm?LIUaLAq8g{rgmdxw2c>0ViCD;bcHvm`wcDYvD!una5T~I!q5-2g{#)|@=vZH`M7+ak2(|y4@+QJ-#d4uejiG~{?G!FMk_JrfDhZA9&AnE++ z`~m?%^oQm1=d?Q=K`zVS#AE_9&iMdkz~ni&eTV%5EGK5+OYgb=<*1p0}UCuD|sMzb_ZAUXq{w zH~)=1zxP#YcCoWXq#S^!BH7H=;%BI(@fti=x=Vb@mD#pAamCNct z%W2N5$jD)dGWPYtiC@equ08luj_{JcH;%swBi zxx}Z>GuC&MGoBaEu2C~?|NM*~8Ca>08jz^ly7nd&Na+n^tIjz?xpVm?7R1Tt!5|y^ zYLxQ1f*%#wxamO~iV|(Zwg4Ny*|BLnX}M$oYK_6rnt@b+<9O=*PCGJKb;fgt7G_-D zR}L{d_vG~$LztJ><~xYl;MRO22W9;FuVbIbPdm%_i7)*wj&FGSxu=Y+3Wp(>!g5w1 zil0+}lOaH+VBN?b+M3!y!Z9v|V{Js0@jIxE)MvC8-}`I-MAMTRgT+n;Ltx4s@?Cxh zX95fC#FIwPuf3{bEM&;TX`=1KTSg*B7y&d$>w=j+Su4tyjb)oE2JAs*w=9<#>=ume>x3(;6PB8t3dC7((rf;zBGE;~k#bS}~ z9jy~JE<$NeK~G>}%}hjmFEO!O=%qMA#vBfYP?0I4x&UO&h?Je&1Z*%3s)ZS_Te)+W z88eO=n`Viz5(rp?68eSrTv1fIR|ZTi?CCofRs6D#CFrE_r?x6%1`ZuEoCS0-O@9*u3wXNa%Q}bXlUTn zQk$!YG0G386dEM}L?;$TNGHv-B3#n~p$>53QBMRu0eqoe({2pXLQj(;uHjS)h~)lg z_=;ATPt0rZdxq*kPL!oMkxOjP*6h3=x%udnkGd=2-99X$N%j<&NcKoneS$r=C? zK|{Z~ER@b2k1AZVHO&@`Aq93dhz`y;+GPq*D?Ja47%^a?H9eAOEEYJS0Fv;Go!8&c zeiJn$gy9}E0=npSO%WHeC7^ArwJw2bOtGHE_x$n|V|rN_3~Q$+IDvLVo3ZcUdg=@5 z*vDr}gq5WCdhOb^J`EX)y} z@rY~^09vrYi(|DBXk%uaOMU$EW$IWhpFLx^C-q;b?=#8vkSre;*-w)h*d?6DT?E(w zPmV35woiS8p~JMfQwyKl&vO{S7}yChkcFU-*?xxk0ytyFww5-AnHodLyRZx+L#8$Z zDIKV9O}CD7yoJ5te(3X)tz8v;Uz_dN(v;c_^`R2*dG#7Ijy?J0SF&E}#>jE1x19^; zt$Hvt}<{OZF5%3Qi4&l7lZ^Yu&e=;1^8>h@io|B{`$`|y$6Ou)(W1eoon`+=1M zw%2|-?@Rb{3Bw5%k%=e@~8| zJ(c5h?ajBY%gvjY((_*=AalwrP|&zRn?8H;SSG0q(3P1(a2}g79K&l_rm+eT2O*j( z*aCoDTrX%yIqtPg^@z+*2xH*p4%$6Avggk4$lmi8vI|hy)(g|=v~r|$9$zIpFm-S* zv)DA7BsW7C0^0H(tuYeo#rk-cx7H6GFOtWL{7vT!j`1SAI=8+T`?vkw7@(hbDy#K{ z+hh+jc3{}G6}F)!(6%Rr|8Yc-I{VLx0*P>x209nGsb3DR!-|H%poPS$zg?dfO!R zGUWR4Hn#I5jF=n-GW&Sck9-S1ZfyUlB?1Xv1{s!@!o22q`&ex)!Gg1lYT#fK05T|J zsOnW>87HEkSMUt0_4PrSD{a%1up;sLv3DEwpVrv34uko7xuy@k_s}e{epXW1>peIg zydDSr%+FEgm0nlIInGdl-#!cdQa7erOR3mzb8>8)Vr!$lY_=sE?4aKxGoS2!dCYnr zZpiJCVIzggr?ho#UvzF*Kb8G#+~(W0#rD{kt-!pxZkr5x)#Z+~9pgF9>tN6iJlaNv z^%m{lY$Jm|*~dtET6^)^Kl&$Lt#saunjKA$QNvhP8LZH(9OP1HCAp}pEfh(eHhmgL z66v_vgJX?KHSVX$g3s4|NqV*0yDUEe*`*DnTh91XYMpsN2zP zy)RZ8t*6GGL(L5{t_93#lyMNtb;0YcEwP1-0V2_yAL_kW-C48d-F^q&JS{T~jfHL@ zqn2uNh-s+=rJbW4;bg)IvCmzP#M{qbP}3l5xXFsFiIstjJ^K*^YI(2av9i42@QNDv zqOYN0GjQ_Y$Y94=g`;Bz!BGFqdLtTULtqvm9&~tSX|bQ2&8dbtP)FqWK6%6vaFkHO^XysxJpeQqh7o-c*sGZ8 zTD7WF6X+<12s(SsGw*~PTIoP=naEva8IB`_Y!zgTnRS4k*)*q6 zhQUS|jvqcC2+-$oY&NPh@Rv+51rLH7_O8z$gc^6(4N`Ee$v}r#8dk|d&n^y}GsxvJ zAvV5RhQ0yl;X6!}RfX_4Rx`oaj&%$64f+Xe+1kKV^z8}QG)r~nFt)KP&|6k1wyoJX zf-<)F%M+SAMY)}0PS?#Hn>!vKHNbGJFW21X41) zZK54?U9w^~Iftz@)QT(}fHdh`1!jW@u6OK@08YA<>0eDWM0ic@q7~nhA!(^xU_U7s zq?cmTKAFxTyBUorf1f)c^6p2KLPMIni4*c7 z1g<^!@;1wcz7D{svqj&HH{X%>fAB+=^ZDKjx%26-<>}{NaC|p54>Ma@`hlj?i#xX& zR*0-kZ+-WB^7i}Rm1(O$9Gs7PU)^RB0NCw2x9`Xi+91{2f?;VZQp~55RvdJ70Y-*a z)8=(tNbe+DNUh~G9`~L?@&FS^I1&BE5SPl+bllgt}LS1Cwl#QS7pXD`7y*L(g0;)AeZ+dF2Wys3+ zibEy>>%H%@Q&)o{MasZXO8o_Y0b$?yKD;s3;ao5ncRt!5@xby6N|GO9Lbd^gH9tBh9EU4Bj#9V zXIp^}cOF#ewBv3aX#RmIT(p|JBBL=!JS#+SO_in?Yj^B3BWBfEct?{RMy3dcQ!ahh zVqqnkqn>p@nxc8*YS1)VU0;nv1ytyq$38pG*lEL#Xk#(;WGi@>NAG$$s^~{29)>rH z;bx(qat&Tl&$p(`Mgw;2~()UYt)Xz7DBrlhC-CSwDPh2&Y2#K8yONk{v4 zHsShQ*1Il@I;*Y4-VEWinC6Pj3V# zmT;H!VQo&@+WM4)%h*Bz$}1g^X6{CodrPmXO4vrv#m z?+GWTv5+l}| zudaY2^?Xb`6;9P;d!=Co=m)0lK}JWqA2d4F$iTFEiSoByX*bF_PajP0S8ktGmMIZ3&QMj1~1X?qMT@qO7T}0eDc*5sa~pEGXJIe9yGyYaLfpokN*f>2RNHI0hEly-=5H zvKA8yF=LcL)l3{ z(YdSFiZsSnJzW}LI8(=_Ifj@hm=e3mK~ zAPR;ULfx>~2Y`v8~R`j|<{j|mTj>Tmuj@rw;lwkEqSe*6IWI#bHvB`62{fzv+{yq}R`q%0T|MGr$ zQ~Ydo9B z-#J-P4jR9`{~sCRCS+=5Xa^xty{5Z;sVpo$^Z?Y z-YXDttfGUu3#mJ;r1RJhv?`|9d1i)(^rGLo*3-+lc-*0EJ8578lOsa zV#w^2-WK{iRe=iyaImn5)omE8qXU}ZOg)AAY_^txwYME_W|FYbq+IrlV0PJg&!B}( z;>;T1PKP1S-2Er$qh*Zd&=G_Hg9dsi9wy@<8a|lXChKIBl*rba*&u}hIHBc<%|aqoh^tV3hFFqLrInkL9(2*@-}9gTSuxFaX?Xf-I9k+@pR188a-6=b%`cLnAJH|lB6RB$kIaso=Y+;Bz!ZX*(^1`#|cw!;6 z)C^eS&Y;miV_av1l>c>=!|b4lX9|l2lu;d-*3x9Rvf4}cgO&_-i@};$uM5?bfLK@9 zJYa()AO!7Cc0$y#g|=BfeN5dEh6N}NRmx?KRAU0EjfFD+4547KrE^C-BN<%DDS=ok zcE_1U8V-3H(*Xabscz<`!?DDI+*3Fc2-B=l6mu5s*XYX-F=hKrRF{c~%fmvmtwm#y zd4DGWsO{wlIv0q>mXI)-j;$>LCVBXtGu9lO^6WVXg;+0^8tQ;@PG+UwM$HtY?Y+`; z>rDY9H4{zDU@S7mF!YOUaiHNrx`IvpsAKra_Kh3d(T{6$*wgdz9@OAT_dz<~<@&j} zNN_WSQ#qHs3r@SUCP+Z`QQr;1`gAf;Koj5&^-a)o_+CxP_y$V_p>1>S=)A8>+GAz} zLbjeJ78V6rURDk=GE}#yF#%(WB3q^~rYlBPo}h96=Td(@PUSgHpafYMn5eob>$Nx0 zQhji%c!b#vpVZk`GMh)Tozs8Hyo9WH%A}ZCsF8Mj2gLLdO&-f+My(yBG+iVE-8{^d zPFn_A@j#SuLSUfr5YTRD>!}%p^8rdAN^Lti!AJW=5Z=0KW&(-=UOm`2cm(IunQBtO z*)?|1)|D%Cm@)UZ0OO}xA8YG_Xh(#%F_T=U;b43Yb-8T5N}Z#(FfNXNj6t&AG{Yfm z0T^?9kCh2f<5^pC1p||vTOF)S^uJZd5rF?{ZJ@NWx!5Us&1lsh9%a3(ER1e|8W~`g z2~X>KotNaAVQ|aFLYj9QW02vTEfo?5P#5A-#m;+W%yKTrIQPtf#?BJXPYGyw@=#vf zzLVNyL5-#T7yGjM^%wjeti#!Bw+MdT|LTFxYb_UOqY*-v21SD$@CvF%xU zXQrJ`2;){72kTU}hv~adKmU|tU@HMR(9eRc1;BUV=Ib&`z|7OzUnW3iUk>lzlQ}{; zQ~h4}_IKod0*dZ`^|{=7^G&&Y{ygXZ>#x5qFVeYv1Z{u9d0{KP`#jn8Erc^Bz~x|X zUuIyXrS@EQ7EaXY{4z(^x)c0K4$wugA? z+Fo}jds}~zsXS?Au*2_*WYO4owj1VUTD5kXijxNPLxM)#@|Y)la5==6@&M1=O+JY;8&Eqi84HbRDSJm zd<+~n2`3ym-;s{KE|$@+|1Z26oT;B#zXR9Ur+_V+ z-gi9C{NK3Y+A%;V@i*&GA%wrQz1VnP39o+cMnFa~AamB|Z0@@!&z*3moICSDgSXI6j9WCN73!kTCn2Vhrana(*m;ujkON#{F~edS99+2Ddj@laneo}v>G{sC zokOA6St~g$w^+w_Dj1cy)e(Z@4@cLXMvBtfVg~gckFM_dIY_aYcz9@`hC9}sFD8Rt4|V~bjm4;CeWLhq6=oGp`$%_-8guMy|IO-D`?mpy2K2C8>q66W zU}}2dVis_9M^rP7h*980!$v~LtP{OgmorE~6ca3uG;q>=jo1)D)6YuG&{gD(HWnabQrd!p&ZO! z1yHEhuuf(_Y7}UVOJlVl^lvs*CX;1X0(b_YRUZqzg^7B2XtXe&?Q7SS9Yk@`^h^rB z+B?EQ77JrC5IdR<5Y3@h1nX5r(iaMz&P-r^Vj4@_I`Ex#-nW9qv#r>EuCjl}y z6Bza7S9dM#y4tqR!(pgvp()7e@R`$2FuExrYy`1p5I@(fZSEYXiHJG0lR8o7&MDAD z){ct<2eq*np@#}~Gs{`99bDoF(L&MyXzdcX=)Esm8GHjmod^isX@;zXD!I$n?|hV}y>LuOAZ<7A?&l*U5uqJ_AG;Ceuk zK~&A!rZ&dGtu8xTI<^!HHr5|Cdyrx5vSudOLb& zfWcv^;Y-y1fS^6~Pqd7fQy}R5_~(Caz#v#mI|PDf>Gun7zbngB&rg2#Q~9mG{rBYI zlSBFZ_E+-o=`&fUXY8fA`Sq_qktd)3S{9EV8M9Kw&i9}1$x#A#q0gmSMBB3a_B(R> zvtOkq-)0{>|L(Ws?H~P)G^yV9o+Qxh*)!R?d_A3i%sFF)P^XVSl5*qIt=)!xYKieLAMw?d$({aIL=f75#7HyT9ZbyuqYuBY8>RtHI1MOCZ-l{y@q*jPCQ7 zIWo{VzE8;iSIR36O!_I|MCPl;H|U41WWK4|HU}|AbrZs*0Tv5 zU}Dn(>LOsGUD>WtZ5UB=Z@Ji9r@+glwPBP+I7MI;_%3%>#9<8#Trf>)Ptp1qI-{BQe7C${Y1G+N7R{6_43-;$qsW-GJXR+g z*=WvPplIygCm$O)V3TIFGCAnhD8L~e^3^*ny<{s=A-Skw6ODxx81R)HHz^A&F@P$s zl6p%8h}3|f?gw?6f=&3ffZuS@7GyjLU*o% z+wWmhO_;E+Q7ANh1_4m^+pXkar}D3lHA4^q0?T4ThmOGJOy(CaCm^PgZ2&Hy)hGLK z3?|L?Tm>~RU1r;Zg`y6dGRROKgb;8NgoCiqwq%w!6Nh#&RxZp8IKkNO<675nT_x=6 z3!t=gGG)*pEyHX|x##oHGj@%}q zkjN^fn+}bpf1XTpA5~k>k#$2285=8E-^|M0S@;m<#o3l_bPy==kh)&&5kze@B-ONb z@ZF-bur^`8IZnFRdL3Mcdj{d&Tc8C5G!j_iFQSVHT2CS|L zGf(R}v6?KH0KIw1adOEgKyH6>;a=*kQ@`HA@YLQfE^v%y(sL zqh8r1UdNp43mNyBDi?dH~U>UZZ`Mu3aG97Mn>E&1}(|Sp8Asu|9qW0A2nOp?-hn1kKU`7G1XrGZEV^f&+E3P3FX|EflX0PzW)gT$&SWs zUZ^$~GfOyZb{fa`@cX-C-J5+ayS;G$a&5X_cEr5i?BAMwGj_P#_2e2b76%P$`o8o2 zQSRpqcQ0Ri7Eq>g;%ktuF8APcDSfbjKt(&lnKDf*;;DX5*Cnah2=2&5+py`Ya@ANu zu8U2t5X1n5ujgK#Wn5@Di+xc?6^O$E@g(>#Du&imQ@zW06c5Yr8y%qnNOPZvr&dX= zU!#|Y;tyN9GR!{9hK@lOF%V?~Q=tMg!WrMG2DSY9(FvJ#;$d$!&=s2s#Hf6?5QjiW zUib7x*GZzcp%nI3^?s*~>)H+tUw;VFoE1EIDL`oBYH+6*&wTxfXZiVNQ~Y*c2k1G$ zSQ`I5c%Ze9KdX9v249Ak+q^KIa`FhxWqw&3)z`I`KKR{#;voPOjYNon?e1cchxD*? za?A;BUEFXoRNT+nE$-O#ecmOMDji-%Ngd74<6b8v#$B&04KF|d?l7*ahK&}o&{{Z# zg^SoOzf<~EtZ|*gebjg7rylH24HQ#>^XGG&l)L;*)*FSRaJw?eK}8*57gzy_ZC*oL0xc8QEV258psc3nb=@TEBbEl;`zk??ilL_U zYzvVpdmB>bs%;3BFttu#1f`I&8X~1@?5uC)Oh`HwB@58%ZockD(QrXB7^2r(-ydaM0G zzvn0e^hW>~td+?@J)(3SoLtxTm?6_k>OU_YK9CEkA5xcxPNim1VoG_0rc7q6LjVog z)>Y$P42;F+$^@wGopLJMWxHs(; zgta9AeCOsZ-b1y8gy*7NnT<muJ8JRPO%dPvpTbKjfIW@a}iy;P!1fPCyXf zA=Ss55C~59c=7zHT)%voDY=)a4xk0I26&$8?ajB}lv@e-+1c8ad3v`=s`vX}-DmwD z9UjZ)zy38-&|gTv`1$k>YXDzh)Fdzu+A)_BVD#+iQ@OjhCzo!$E|)G{l_w9MQ&f01 z(J?*sj5VQ%SrRx*{rLV@ci2C+OykT`qUIF#71Jh<(QtCdHu${gKO$xBuE+NV=W~4Y zecX8M;CW3m1bdri2sT6u<&={SLS6paMurp5G5v%JpxIatA-oj0QJ2(0xN8S74)2r0 zq~zqY>LW8z>^%qN2nr~S%QN0k;(AA_WCI3RbiNjj@ubsb>!RR)i!by2+_H|7SlBW> z1(hpZBH8R9yF;|efu(r@TvM^DSVL_8&=fGvomx9;4WE<#dkrRR?lXlc69@iI zEH9V)b#W}u=%9|q&iH7}^!>if+Ft==bZ`r7sNGiy-Np_uyJ>;}a? zNi2PA@H{=cH70Dx|UGyq&!*(mj3U4#j#{#bbT1{6uPFF>YFU-Ha{dcrfni~tCBgX!D{ zd+u73z@;wo1ViyQ!%^4$OR9Z-8$wOs2L&*Tuyl-5BlZMV)+b5GA*q`e7K&w!@kOB^F>-OUHP(6vXJiHYf= zU5^gZxP+s+Lxvf&TkyVUXF6~%4w!2E@ZMcbUyj8j*iB%QAj}3%?BP+?Zo>CFH(#UE z$vCQCx>j2S~ zS|}6gww4N;3@WqTnqE0-7*y9;$e9XZt4318zMMnL637aH=`Mi}Ot0O0Sd!MEvMD8l zKXm*Jgd=Dkt*U+y7bf}CGvN2}{E=(+B$+c`0 z91>%V;Ppdu1q?tKL8Ga1$*Of{H{D*9m}(y|D1O7{@uIslOO-b1b97`gRj0! zz|T1{WX`|!Esk5H|DIpH%1w#mCy$c7d?M$+^^QDD;K~>Oum4iEZ`_ov8?VcS_uo%r z{i!UUK4br98t?6MvU}?d*?sFRIZXBU^j9CrJFnl8tJiM{RD-WxxhyXZjuKGwOddUc zEawuiH{ZG-(>by(1-X1JfraTk!KOJ*^@r?C(29Y6)84bEf`Hnc1g0LQ?=Pi$P3Mg~ zdHPuP)BW)8K?0nwUArome)!vR@ybPcc6Y71V0~|4eQErp^~Eav{pj%n`Pt9^Ox}6z z^nP$6(PKhpZU<)ZsVd>uRSthH(1saHs&9 zQ;r(Uu@BU-l%Z47Zvd7yIYxu$iwwRG?tO)DssmJ@4F_E0BoN@waA2byIbR#vXxMHt zEUW#WGD{SY>8!74n0Xla!m-*rtw5bzFJ2zC8ba7uH8l8-s)5jLN3tg1`Nx z%cyq=`JOd+aiR_F**Pp{bYuorD2}jwp+26RYzO**#;Od%F9&s3s^Dw9uLFwXacq5G zLyCL@diX|lUu!DhI0G70KiwEU$**+H=aS&LZlkx{xVR^?_n}RFb6kcoVC0`q zmT4y?c-(Ms1WB^^Z?rHJH*{P`xkhR#NsS3SnUVIi+1`}Mz|%&N zCfAe=AdA;u+6#B;7<1tsg2g&3SWv;0>MTJ+z~b@3x}+af?GZD&LB&eZ(EagJ%kQ9y z?@V}DiR+^9o$-aLZ zj6l#aHQaRP92fsA9~lLa&JKV82q*@p81{VzWz0gAI91Djq|BK~?rX}xfzvWGLl<-A z6Hvs-0I81L5Iz_{cc2m=!M7QL2lot$LVZ9vwLxn6*s%JUaw=k+(_McVD0 zo>zxQ!$?|fE0H{&DB_wNgX#9RYI-Ec01iJ6IBAQt=-x`ZyG)7AG_|SkBP76tG*!@f zO2-S16L#nk>VyC*rZV1AW*oAX!09}G{4k9R)s;Z@C+bbK5Dnd8NJ^x3!vE2}8LAxVE zSq6aJs2O|Djhh31KsXdw>nii8#$or3x8wkeE@TFRBi=bksLU|*>1g3T42kJh8C2yY ziTB-V)6V&0>+j}lPBiSSv-dz)*o)6TO>MT#es+kADh!{QY8v2VEAae&sTw7kf_R~m z=UnXpLza?FUF~nPOb*}>*!JDZb$XBV1Ch}+**I#$P=8b|=h{g?(Y7y=N7LmGz^IHQqdr0I*y z^fUA?=DR-VC&*0SC8JCxlZ<9ENhWH90f%f1fB_oa=*R8*zPE0@D>KhyM=*T(a*x<2 zPgd0hK%U#xS#|Q9y<^A2!+pi_<*N6gYkgZ!*U!KF(ilc{j+|6rNtrvhzW)R3H)SNP z-V1${&66i`QtiPz?|-L)UOQ-WSPF|(Ljw?dYT6*X7yF8*-@w|QXJbaz4+_1h2EyoE zRUnr8fsbopYEs$`a^v0i>^b$Tg{eZjt%)1&jWMa(7;KGdiZ4Cggfil7iI#!neZ%A!#Qmfmmw!oVKPBLyYv;llo$AqfQ&Xcg)SffG_R#m!E!8LF@+sdF$s8)PZp%;%<-ynVK_x{uWRDS;-|3}y)&+9(=v%mg@d|204uHci30-xMIl}$a^did2> zGS%n50dV9LLcheN*ddYG*1~Uz01Tio*3uPseepU32#&v&;K0p{JR|XUmq}~R|9gvsyGM; z?S8MBr(M8y<#fM$mcPpj{U)vR0!!g!D&1l%@uwRdpLDz!`m6^l7Qaq^r}i$GC*IIk zuJePJ$8G&JUlH&wzgnb=nyYqUvyLlV= zJNgTyUrSL!t^tWxn*1#m)OFyB-=BAV({2&D&W3l_|2DHINAJ2cdy+V?Pvu)(>)XDf zZx?o67QnbqEeB}Y!s@QW@z39K{fsw1{GEU4DL$E%Kum{aPcg~rq&#~PEC+q*rmxO6 z=}a=+Dg~qXZ(opWITtrfpig1LD7@r8XW5%{r!$5 zNE@Klp0H6g?jB@bf)XQl=@P~uFe zJxfRXXON!4Q>kue@qW+%RbNOaqRxbkmEF(Mo(2S3t|_3W+GYTFK!?9Lb6Zi)s-Zp- zsP)Q@08P#WlbwZQH!J|$65BCMjagxW%uK!8yBM{^GkJ9q1;I1`!F=7%(RYB$SVc(z z6lEUhIPbmub_g$vfmklu>PwxJe*L=!8Bs|GX*HJmvc7i@C3962)BvG^ph1I{k=ipm zO(6oK!U8Kj@!!-FSJzAO6tc|upeNNgYCv{c?{B5LlU&q*_VPLPI9Aq23Y>)w461_- z+*ho^&-Tev00^p&adPJl=ZFPgV2bHyr>4boc-j@GZ2;sfrP3;|%}iSv+vXK1ZwVsV z`-_(hoD=4eGGbJ_LzxJwKjEwtJTp^D2Cg%t8fyQlh%fZ3a$C!T3p?A~TGcT{U+mqE z5@_BT&0Dkh|eg*d4GLYfYz=WA;JNQmwU_U0Nv+CU2;Bz`}R7iDo zcBc-YGI92*prdf-!M)bLpvOpBZbBo zA{2r3bPA@jg7tHvKrU0qoQcQJn60-m;HcD8gLA8ZWZ(mQ0O&Veh@}s1$yj0vEwnXk zWm;O{sig)@rwGIhU}p(g>S_(N9dR(=Kq7K=+=QCoEf|8c9Rhe6TCeuyC9Pqf!1gq7 zO@HsHP&%)b{bE{CRuxIpDK!mB=P>#QKqDE5dc8C<{YR|yHlIHM+`5D3K^on5%RR$f zeg#DpEOC2_d0jHW<%}@}%kR|pT?Ti~_Kcv{Dy3-!Gt)cjQp9-RW9-ZyHbt;y#o0TlXu__K*y_9nzg{|JL{A$N%(yD)%aw{^@6* zRN(epZrpoIF6;OI;;(-ypMU+Z&c|CQWBpR?Yi-wqyZ7sNFVJ<$MElb}|F`n-FMlD= z>VeN?eTEwqRQR1 zdv|VwiKT1cOl?nnj*HswUq5;*zxntR`RKpo&8nRu{hzYqti&{q@pMQH(P;pgz*;3tWOCKO4{$Mgf?`v03tJN&c&hp9Sb z(k8J=fg}AD!B#Lcb*YFSuB?xWdLQp)|KMA#(B{kuMhdfctC4TILR->1J}wpF-c7 zym;d>Vm_@=)9haQGbF%R8O!}Ud=b%r(L`)hK=jBX8k^SF3?Ewm?2 z@h@+WeP<94*Wr&A^H+Sn_;;YI=C-su5Y~Td8t|^nt*g@ETr1pn4%USKm)e@1jLPom zOBB-8z#b-dN-!Z+uxL~OuCnV`T)IFaUf5-8DAXP=cGB>BMiJ){jAhbGRN zY4oDvl5ZrWPHWjrK5*$YYNCn<>GXjdPc%sC@apf#R*5Pu>_BKxq(VKCmP%k0^AelE zJTRrmh3|S=75irpUu-4@oI0wdYnhm6qMuYv0RRCcW9dn+Jc2-8tJqL97W82-D-zQ~ zPEfH!Y3c!#aE$x~kW6XbxoP?Y-CRmc&{j&BL1MPlGW3tm4Ka~QGk8r)3? zw2GU&(_a$1AUJspvHO|7U>K^aY1DP%~& z;h^pSP~k2u%-A&9swpKJ+xmBi$FA2*8=~+v#3-h)DRvrQ&tyh&Krk!o0+0u5Dv`xR z-5W4!G>AS?tpsH^oK)kp!p0=bgB6aeia6W+_4OO@NR8Log1ASuEe_SgIC-`ck zYEXwj_R=awWv0}j>JW8^bgo-&rCK;IJshS5l}=K#Q%GXh|&p2jcI zwZzhWvTS267FH3PGlgQe*7u3_4T8#KIsnkv??OilEyeI}{oN9lbT9qg=(Hvj` zaDZiRb462Hp<}T#t)Db@eTXvdHXk%aCr*Newt2F&TMr173Bx61V1TXzUP}moAk9tp zJ!SSVsK+eBn5h=djnG8$zSOmr2H&^rp8Fz9@AQghW7rE%0Z?Et(ec0@px*RIXHSKO zWwf-CVIb>~_J$?7v9Bc?Lj<&A6A8sURThr6c{72X0q_kaxA(Rt_WRH1Q?g#X*y%quqx;w5q`0hyUb1 zlpp-T@5^uhd%q*MPPH6*1%m2LpL{A`{>7im%Z&;4KmF;? zGI| zZ;~jL;l2e|g8O#SmilKt2&k^U5*@|%!~x_CuFc@jZ$jF}@L?dwpu(SHunS1fvPtxh zQt^{~V*&+=K%WzAM$x@7HF4W)^TGrE2*v`K@=-p}kf85sEM~PUR%~GyJfLksuYFD& z?~1-GbfQb=H%Myt_de;Y6je&Vr%*k|2WSh9x5dXnX; z^Bzpy_ay@E(#^Tn$9_dghkcf4D>!!tzfRwa63^26?LAm$%_syys3R3?tF$(z_B{mk zY;&xib}?(}*xiFa1_yeiP$bxYl@|8RK_B%!hOin-W*F8l=f|5cHTpFk&(=Cx{BSf~ z{UYzb{CCV_PKxE&xqWN%m2bx-5F7e@3NzgOLz?hzTY06mHJ+iZ1GhMZ{}*dzIAlNi zXWI1?{PZyy$9528wuy(nv-P=--+&FU0eYp|+vH$4VlDB%DY4p7oJwmo29Ocg9lNh`Mc$jnOQa~?&lhj!eeb82-sW(?>0lY4Fvdxy>j_}ohJD*G_$M|^H$M7xJ?Yr*CB%Af z-i!(^&H`|K8xx$InXWV~CVLoV1V%FhtW_{5mYZOkcN$z^Au5OgG3Jqh4fP{bxRn|R z&TJWZdhY#1WXOW35TrB!2jH1%Bqc$rh@bGL0Ay%bso~@)V6%(kYTGp(Md$U2F=y;l zc#Bhb4MY?5R7PqC>CJG;yJlJFlT!-Wnz*-KbEN{M#rkOv5m$mGE7K#+r%($2?*MpOyYVx9=K|MPQy*wS_5dp z_KG>b)_MAq`YbN+tpV<2Ohh>A0jQ;zw;HI=6cJ7rFU3!~3LOjE2W^7^*g*SdDK2XS zVQx3)8l=_HMLFHw#f$po(^#JlURvL5DJ)Ncc};oSO4vMYw*rlxE@NmASsdD*ClgDo z-;mAYXQqe6R3keK$hIbip=kn@rZ0e{seqIN#q-ScvLV(WKs(hX(&;uC*qy;>nqY(7 z?%6KQeTe&-2WGxk7$8VnPQc95Qr+g5MotPAlFmy7&Xp+j{SUDRfaOBlQWVUa_tf7SaL*_MPVs+z7)_r7c;fbJG+m=eSH8Twx^E{tc<|F{ z8OMe5V<}L@QkNZ!=Ny2|q<&ZQQlxdx?EeA=qO6k5jg<*Vrrh==p^qRgd_T~3WV6qj zj)e7JflU`5*FJorg5Y}iQNN?luIo_K#}ZkuWz1lu4%CC&UK;qN^GR*->Aib(xvk{o zrysNI`h-1Wt>WDG?n1Za^Dn-DW4e90Mc4h!pZ$e=_LqNQOoa-JK7H~?p1yo8k3Rog zPCodsf*`Y;*57GWsK?4^1Ut)^uzKC8w&Tk$zd+#d@bM#g_~eOP>KN2@q8`{(LD#q5 zc~^e#5B^aFR&K(F8tLQgwc6guH_H}rY z+&8TMO|TgcFHn}BZ9n@U3>%F326WuZk^A*2Fr~bi?nRDBuJsXiM17k!1P3H#S%oNq zxomJl^T`5g&uf8;uTzev^W>|FeWEg&#+WsWWy(SA43QY@awVN7|W zbz*IhXhXawzF{1(t;y}3EZT~Fk~)Ja{yVrvZ}r_M5+iA!eEn;({P{u$PTB)AAksyq zA3>>Gb$Hc*j6Qfw(_X>eE=-f{2Ihd)xo; zi5(CKRtv9V)NBnRl6Z9_6K`deo77#;Jofs#0jn&kF415(U|>Oz=^h|m<*49?V6WSuUJILkAYo z$Pg&N$)LV5&rv4b+l!M?*RUD<+6kwFUim11ldhj}2@f2Y-h)$MJS)M#ypJ>mRN1)L z@ckxa9A&DhzXDKjm|O5lK*oU?d*(TwF@EPpP#6>_U{d>ff4Mgu9j297HI@xym=wWY zFpZpXm5l~!)mX%wd6pX!f;QI8o8nsgF)J6Z(l(dxz z59?_XMF9ZeZSC7?5m^S<8evaXvwN)Q@V zU)eSqgzvRP`iWLkxn-x+8x!-ynx9CS1}10%ojMmFg8FhcVO278tjsjQH_lavlL}cH z0m^Wm1`B4UP;;-1HISiZKq9Ij?W}r~u_;!j9Rz{seauA@2e#nXMPogsGtbGYzCd?o zq=4w2WtU5=UzGahwR{Z$T++{K@H@}c@2K-ZgTHBF`SYEXMh3WJsYV(&B8^YSn`O9X zma_)iXz;S$CHhGmAhd~A`=Npun&vanez}*Z*UYrvn%V`CV-w^Rl~gKbUlp{`z;*ZH zDdrE-pERI9DQwfuoaH)>yLuhf;8%#+w0`OoCeGAcxE@Js++QHpsF z5CDO8qP9>jt#7<^cxpNaZhM1Cr}M$9sS)7Lu5;xFA)H&Df@n;iYInAEZfJW-=Y%8= zW;1LOY=g5ZF(3AkdN-kp;u`D{XK~q*Z;pcRSO#)1AaeWV=>bfeP`xEEtn#+mj7)ID zZK&_9>??O1BfV1Dn=4j)3NVlRh3^feV4Xs=7uU+o-wOby=iHwTkAIkC?0?Okv#e2H}Xr>C92QAJAVN-;^o(0;eMLlr2V1-y=n_| z)x7_se^7yyEZf?(KmX;=0m9t4druyJ^@XhJT)LyFpepvRRkLc_&TAjue{dgtb5Q|j zWzjwO-uLB)|L}L^J0HGN=So2;_wy$&(MLCKoycVc$wf^$y zvkDMBmiu>q3(ugHpHAw22!_n|QXZc_#^^v8TJ3B$Zw^cku!0zZpLMr@u}p-j>08gFhhuEUt>T7aV&<)wT9e2(K^@ir`;z3-pH&%eo>?qQ_yL3r!LSn z-z3#{IBQEH=BIB8_93r25&=Gf;I>Pnz1q%|o$`4JWaQ$nO}rI=k(b*YeA4oIJ_*r2 zb2@Rtu0cow%CR^bBRMF&L033oDTcq}^V*`U474r0KD=cKklW0f?}OC4tDaIpL;QoSO` zADH%ZFy=9_C7gMqwAcG=2~;IJ!9l7APPyx~_u0})+;Alk*DexX%ND^-dU46c<}_Ge zgRx;sv+S4BfrtL-OIF6ok*1WqFSYws_W(LEg8@UFi?$woej7y?ng#0=x-`0u_Lm## zBUy@^YiEE8=M12cIp7SECU1`z`$hGBAh>u@gY>%oM&{-ZBk8PCT1ri_;0q;V74cQj z1QmxW3Jg|;K+stQF0ES64uLoVat(~Kl@PzI&$})IbT@1r762IfJEilbd-W`kr{AG*{#^;gg

9MjGmut>%jzV=deE-wC`&lKugMvyEBDQ zZKz&$*o4D6xPUlWb=mFB%F;b-KA4boTAyNE$2vY*Rv1-~<}FgDqzfj7Zq1{bM6$|C z+Fr1&sJ|l4GV?h;li7yUA_IWcmLr|%X$=aWJ(iOi04AQ&>oxY0iTe2Yt4E@v;I|7qWf&+=AarvsH=Um4W`Iw^R4H&HXOmfDiS*4ub)Re+W$p$f#R?NeaG(snPcIu++77$W=9v`B^$Ko`K- zJcnSou~R5at^osBU;A(tV1=m7hWWTMz;sswa^&()6dM-_yX$Ni9mnbB4G6i4>UNw@ z?4unuAm%pr<~dR%!G0lFqSr|7hH}2Qv^-^m7+|b=Q~*nz8RPlYU0`MYfU#|ZC8TqG zXMpGIDblX5CQYl%oE~Eo!OrWIMzf1K+CB2KISLcl+$Af{ucdvHc1%l4VT*-6O`aPl zubMDsx)U^yum>}3R6m2%ZR*Dytb8P?la9gPP8C{?(TNXZ8Ea zYEd>GG}ts9akuHpuJ7dZ?FV?zE9U8Xx_ITGZ`JF) z^VVH;WaP4b_U7%|a(e5AeE!L&@>hTH@8p+1{h6eCz0-H!l}CT^XY%D+Z^`ZYnGfE3 zTW%^iT#}LH;De3wS3mu8`S649$(=iQF|YT^m>CS1nj*}|1bB1A{1MI{2KLwd4Qoy2 z#lMrtA`mEVg6xP$56HZV5pfux^DjsIy*In(;$CD*;0&?J5ZXj$QgyghrTOV?U4b1uI7&?;&sq%xw{2nVx>i-P{dk*H& z>&7}o%)`$g3G!gg-(bod1zSp6aefFLetT(i$>M;nT@?NXK&E3N^J3`+xFym7TLj+9 zwXn~Xem)L5kVV>CjiC#&i)nDZ?p1R4@X7u7cHb+l?EmSXKbRKD9-_6S8@EOHUOd?E z`}jy34{X+g(IRagbGKVI@xcD{-}T=+_~~oUU!m30efHY+cw4&X3(%>%-_f~y@Z1sG zy1lkZ)FfQ&z9=lg(7AJ zF3d^ifaBE8L7ExWF@$9|ks48*kU`T|c$$}U%dSiv;D8sMc?4Dz>(!vxbzz(^r}^oq zu)$I8or%L!5n-U%Hcb0jxKSpz=05q#EWW&KztQVketq&2k6?O;QTK~gkpi1nkF z){Z%@Mtu7+#>`U&;6M#lAx9l})w3wjuSqzGv><^X8boe=D(y_b>Et9R|CkCXp&FE) z$RgEDfftm&y+JWy13~l4moX*?+z32CUDh zPVEQR&cTrB{cql|pPH_L%1o!`%m5rSpif8fqJDRMX6y}J8>`hCo9yMY=P1*y_t8$SMp<(VU0A=cZBU?x+?L>*PtT5zCH7?36cYi8hkKr=OvPo#auS!8sOEaI_X z3qreMV2plP=l6DR6_NBR`s^c9?-YbPRgIlGHs@b{&IMBpuq6=VV!L`B6B?f=(p(4t zjNm33P+Cwb-I;6vK+jE#)zTtQ4BSyx7C@<|2Gp!=ehd^G)p>}@FzyoiCPqyn1tnC_ zbo*pSAz(3Zh$%F%Z`r`ZX-zf`0!~X)8S&m|Y(S=$%@9n!q@LEmYI~MKq&5rHylQ}m za@e|NA>4j~63>^99$5t*fDJhUd{o;aQ=?GO9n2_#cXKgd&MN>ayGq#`3YGxK(Rs0F ziVhD5pc6!);@C=DCyY*lgGQ4JXXg@Yfv&vSL1(xO9jim6r6=tr_KO?>^4Zd7=LV{P zB~<6#yxxZ1l%=W8@qC4Q8ctv4nL2IRDxD2v@+cU|v6`v1;*7n))32bbazWrF1sDOd zmUBClNJH!ap33E?>cg;)>Q1=UW)p0$Z~}c>vkfUyo?WQZPu2bT5P;HWkI!{(j;>#~s-R_Q@)-`!j+y4CNQ+fZL3ZTr! zsC#k#LUs!LPB-L(-}#5KyLDH-`Rbv3^XGpq_kQPh<;VZQeq11Xi9@cw zdBv|<{_@&@=DO<~1}4{mBmH;W&XP#@iq=Yd)XrxwyasGcHak;Z)3!GQXWWk^GmIgc zFBj+?NMhQQ9`q5=WY9GyXU`-CC3$i02xP*4Z9&ap5ZFIQYhCK%-XlR?ZirnRZi%#m zieXrs-1m%{c)v8iID)zUdPjoG=wrVZ|E+V?^|}`69CCHu6**v26$vc~Bph@|NdQs@ zz*Y|y+9g`B==VAJiv8bk{haNewJ~X$zq@$;ausYl{JlRPy{R^>OB??~$g-RI4fN?i zx_kiUMJzI;gZmy~x1|(%EXgw^BrV2%p1&Q4T3!L(Im;ru<9+bGfrslp-u-+xUshxR z;FLBV*V?WCc3$!7Uw9wp~f40o#LB-sXLoDR`YiS4$7ShqO$$^f}$96Y6X9HT4GV zp0r9!3T8od(wK5o!pV1abfJG`PL@{>a>K6VknAslG&jhmAglyuh|naT1X_~kkl5E8v{7URm> z1;7BBak3NmvLAviB0U;fY)mr)0^iKgHk`T|D6_tM+d!#Iy7)W?U}iqLX*PI1p$l<> z3eS|PpqevyMn!{(5<`ezwwzBZ4bd_=@LftP_0=@tLh{@T#<(bo{m) z+k|mT41Vz4$#a=gM`1J8mk<~UhKBe&nPY=httETEt9GF6&{KKUDX0#)GB_N#EDS1K zWY5Rb+YFYMpZ@cD=rh$JkQ9Qso~9?v^#$ltKfkLd!_)2C61q@&&z+Sp*7f1{RN!P} z1rq}@I4!i#2(X?hIFMMDzTRt7pF8q4o@Kjd1mBoltO%F76b{VAlM}XeW@??SZD{ihCh9s<>k9o+n(*w!!!IFd z8hS`bx3Iatu0fRoDbGLp<-$qwpY4RQ8rJ$**HW^^NNk#!teFt}9ZZ9!Xy5I;pEE>S z0fNn~Dj3Q{*FY_Vopr7-<;B7EK7|hRWN*wLXo4_scFYdz9M5`c0COEf?;G?9f!G8V z(TMr#>;%;f>UCiNerpw&+jlESH_6Ki&|N}{r2a~~ac_(xz4MLt-#5GPXauklAft|b zr(fe$LZD&8bTCcl)02NKNBsO(zmRfv#(7#|KLWF-SgJ{@T;i^@Ir0F%vh7t`&Uvo$ z)t;L|t@ZZ`BpLX8(||0lyKta6Z=28|HOS~VlLrrEuKlYeobz@Q4mGN?sSTh&I}Tnn?MlCW*T69gGz5SqqlHZ^rmbOK;-*kO$zIlu` zt?%8D-}ztvZ{(X_{H&E(*S6I8{`8x#<^TKt{IBHY$G?&9{U?7U|NlSv*Rs<}b}y}@ z{N|gwm+<))3eER7lXxx1H^;hzwf;O5;wR`$l?*F6T12}#2&OHEuYWq)X zAKb1s^4>e6{QT#S<;hQfF3+jAV0-bqyqsVCHU0S{we`CMRwd?& zx6xyxXhUk(NwQq)J&PkrH~$Zw_uIU#`<{!!Vjog}=Ky~4@Ac2q|1LnLp6QX60e!Gd zJdU+5FRvvBeRl8}Z%6n9sXNq6X|X0!Y9k%sOKAY4udROE4(-AM$OxlZ7JyTUX>stm zgO|lNMXYG+;Y4G*<;};m2NDl2rLP6Ba&TRY^8mL28ime8!teC(IvBf|73UEl@Az=u9aKK*kNAJ*ct}LL`|fF3^EU zDFR7#0$sQ{ce*|Zz>1|SSg=?SxcJFEPC5I{8u}k&fNvo*OX~K(G><|DAF(?{HNB0( z)Hc*hPYoE+epi~aFxcerbOe_OZnjo(7o}fED>>`^>VeTf(4_^yX|XwTmBc;pOe-tJ z?u*|7UYk>e6l)dX^(tKfgoztvv9i%*lqFx7rHGf+?gfq$E4gT(xQBRY6WiR@Q_fXA znbi5ar{+oabR8`#dc(9k=FK@$8E}83`DD|1;^w7{oz<;7WFw_02W)yNJC?Q9wR!>V z4E$bMJHl#IIGx^NE?C-4W=hRID7Mfw;rf9ct8F;ZG^V@Nu-rVY z0L^pI`L*hZvB?G#1Xrfnx!DxxcrZ0?K;U^2W9SS5V`m8gC#GT*o3Dx0S@!3bthQ2u zC6KApk1CoTihk?%YAT5K>G!hM#Y425N60 znmM8Bl!VRma===4R@euj;#t9+vb!^&x37qAbl9u>~ArU8*@d|L}tw2X)-bCwSpHl2%Ilp zVooA;N(Ghyd?eVz%i2flQG>HvqA6K=s;*UBRM%#8=Pgv}*2YtD7R|%`LTIM2ygcm3(7=8$wIB*US~^d@6bE(IM%Jq_43oeOo|zWDf~+IM#=NcbVD zCn#%C*VpCOUju+Sd-q*ihe-Jnqz0o5ytD(L&66i}Jw5{yX1a9~wo!c#FZHe^vCrOl z55R>2zR)i^y&<>1|3mc2SO5Bt<=L-(CGY>yep8Vb){WJOS z!Q1kipZ+CuX71j7OFpXY+kX0~+4z-dQEi?-lk?h!Uw`(QTzvJFeDFvAy#DS)Zhr6k z02cqv|MmYSfAW9+FRj$~mtV;L_J8-km&-EBzx}trmS6q)SMq5EZeH%qUY>pM0p|Lz z|1bZgeDPoZ*Ye~4#eXi}`Th^&g9jB1t$n+z{@jCSZ_EGvzxsceLwdQBk3RoQ?)>5t z`K|XqkXtuQV@In&twt5e-h{ohK$VW0*t)d+nt^$0sUTNg-#)&2?duBQ;1qRx|+Ad=~%yj8k9R$oD)f(PNHrv^Hdxa`qGSKCmm| z077d^mKeFtZ|$BT_0P}^A^$SMw#@;sM3*yIht37rDs~n#Um1&~&$sAATlXnNIoklP z0_aGK_6$d^6LWzd8|$HAI>a>iH4pLjxuw+%?x&T;?16cl2ojYd?LUu+Iz9_?JK5=#`eXz~*}wSQiW63#*k0WdDXM?aBx2GJOqQw#jt>vL9x1f)*jWwzr@I(#2hcm?h!C$G%H>blR zZqPgC4HoM}5kP`5n%g|=tm6W)^`K@NnVukll4Agz83Ay{j8Tf>=Os2$4I1rBIcU-_ zu;Umss=1z4^_#ajp#sOx2gCc>yRr2D;LpBt$Ku1%fD&lp_-z<`#mS@pBxq(Q+Iveq zpyOPavLMvzaIFCg3S{w83NlUxZ&*$}f+7W`#5PI|)?CBD`Zq;CrLl9Xd_x;j(@W7{ zdN)KJcccfn_KE(tH%hoNE#P>s4B*2&f|#Z2!VpXmX@Sk`Cn7eN?2uF$2Q82Sn}BUv z&O;jPmI$A3w&kXz=K#=@6e(eE^Q9wgME(*QX}1Bmg(L-@k(QwrUDV+3jDdat1`*<&!5XnJ;}bQ_c_Jzs&Tt@atn-|Z9N?Y zIH=V@P%60TGGQF|#+b43+FP}@{XWtS#);`*(Wlu;TMJn;1m#p)3D!ab^NX^eKf}%E zMwh5{#R)0SoH5YXz)J;O0#M}dOUx0j>#n+&zvn=#YqLNXh~($yN;LT)Ec z?!ARSD4$*X6YG$A9*L=YCTwlCDwtGY5SVS!Kc-(Z;Y8clw$L6RAYHX|MSwdi&T*`- zb8(FhD@V@q?wns>^b}*S=zgGO*|l7?3BMLgMHBzH&3&C~^XXgzv)i!M8c14yB&0)W z33vr&rqg=>5-~sZIg#8sBfEEcW9)^=ZN( zNlE;W!tIALU}S9U!J%V=xg(@N8+4MG;)YZ=?lYJRH*X_#P*e4UtTU9kSCC3hFmGUY zS0?W4<6rg+zKT`Q(fO>Up%suvnwe@v&8&{sJ5{moOG}#^C^Rq9v22%4rj6MUHW`(! zbZ+_ywWP35`Wko`l%nra+*{~4slE2fi;?2XeX;fq^pF%pQB4_b-^Igkuvh5%KDqw@ z{fyMO+JDN(I(_dw%tvKTAstB5ps^>MVm{pegFlqZZyr`K<~eoiY#u8Brr@TgBU##9 zwFMQd+@Ejc>Cb*HE{v?}>BUFCk;{i)^Sy-h*o&vn<>TLcEDt~bLe|x;fAouAz&1Yk z;Xi=ip_b?D-4AP<-?H+k^;v%U|Nei;cmI<=lKU0N+0-%mqyj!V&Tsvr--oWvfSzYn|l=!?(gg|fze{5x{9 z0)`(|5a-?Z-jU}|UtkTNzVo00N?ZBmuYM_Kb$;Fd(GO*+VEnVMUm&Gv^I{{1uQU^#Lpeww=3jMezk;6Wu5Aj;?p}&p?x!#W=QAXHfkZ<$yfb>;;avc!npp0u7 z4rLjb_uqH0BZ7Ca)DaK+j=g$T$YK99JJJI8EB!0qvNPga>H6`wX2C8QNQHZ%waKrS zUh%BQZWGsFTzqW4_hZqwCH|yxWeqKClN?{y0sM7rzbn7zvwFc3KP+w^@@Gk}p5Jjz znyiDz?7_b`0%gkaEusfuP-vo9oY;{HTe=csvIR?s7jc`p*8{>~T(tA>1?@0-{cF7c z`~UI3#A4!!s!{4s@n>-6fr1{;1(=LE;VCGoqp|UX-cpt(I3QrAhy~nEv)5B8*A39$ zp#lo%n*s)fI{l`pF$PdztQ>X_#Uw`tmg3bJ5OA@?sfrAf`s}CVF7j%T+T3VblTJ$Sa1m^4{RfzUb{H4XN2M2J`0MS;5o=a ztqJ>ej)2V>7y}tNI1yZ}g84F#nPlJD1$7<_gO#y{%52wx*zw$G;F%?N#RH-B3F+S@ z0H4s6QBVfK%el>$8x%=o(9l>&WL2#!(C#aNpx>v7Wnc%>Sm0?gPBz(2+>5JJ0}t0< zNUq_rwn`%is1wB?y?nXdsNq@~WOh0Zo<3vW@v2(JOwc)F6<&d?RuvQJ!(4f{T>z`gdJF<=MI$r)fS(wk_*tsHg&fTnFQT@_=z>e#DYG!Vqb z1gstFWV2su+Cd6)gZ%1oop+jkr0IP6nH%rE2OG1kKn`rH zGOp^p#XVkLa2|~WN?DqG-jnHMtR0)9R_ffV$>|ur_~bY8{PWLbSLculhAJyk?S_hG zYqJ#4(Y9`0Jd=xhQ1JE-e%(OR(%t!6{EWvFXBM=8WM+zI4#0AZdwP)UfrGzXORz-bV@uM~fM&M0*L?GKx1Sg{ zVm)1$E=UpO0c&Hhwa+BlH!~9h=7F_yZfyj1+fpqS42mP5)&L!?#ze@TLa+0L@(BY| zyoc`Jo^tMU&p~?ltb0_+LwKs+}HL0%z&kslRc2+ed28B<#V+Tb&y2Y z?9hYH4#sdVcVF1t+_V71+T{x4`Ne?wC8P&~4uK>OuzTh}jDi10TO2@_v$gC3?Ot)c zZcfEt?eCZ(y4Muy1o1PAwaR}->IrRr^uIro_j_bSv@z;Ip*Ak~aE{m~*w8JnS*h*R01z!U` z?+)j|F#zOnUhC_yQd8g0ZRk3C?eB5T`5{cAjd#Wro+vvTC$aLa^wyWxk;OZO$d147 zEStW~4wChK;PyiQwFm2ZMjuXEz=ZyWzGiBx!deb(F8YrY4UzCyO8?vd3Snv(46S5{`xsh90 z#n`r!u&5jflBI(R%+WBCS~Hu^@;(%u;lb) z%!x7@uwjlf$H7IM2iFE^DIvy=Dh*H=tn91u-}K#y#|$U?8f(76DT@cljeXD~4>RQ#b4@!)s{^`3k6ZeSIb%<3LD z?EBeIt>|Qw6sbxgwjdA8f%@+i*Xgt(E5z7ODtugK11VEh0n0Oqzw1s zW+P!&J20lW9aM%K0LW}iF$n1nfc`zDNGBmuDeCpKqKnRp4b$e_Va6Rb&F=0!1bG09 z2!x|T6YWIN)ElNENsM7(8l){jPtCIaNCce8Qla*jen!Qt$1dH>@}o^FB@O($j=z@E zzMMmp7nQ%b?p+ifHZsw$P_#VHW_t`c9^~wucPzcD-dEQ)^p9L8shFJ|AqG54lqT^M zoF1%J+ZcE`!Jpn4&bD^I=24cINTj1dD`{($f)e#{Oh8-PT|q!H&D74OlN9Wlw0F)e5TM{tuHpzq_E>7Q<+OLnKa z32;VQpU+VOJLtQyY2JVx=z9(Bk)aU*ab8`E)SE+Ktk-aGG}#);>=R9C^0Zn605}*K zY;DwWepJDY(V3iThijjo+`EtV?4G~GSZ$s@r#6t=4SQ}}XC_d*XQ~x}3T5W#hgKha zASV@k+14>r0bxzo^mzjTV%TND{(a-YJMybv{!*Um=W73-yz?&Bl~!w0{h`9@gTMGU ze*$)-8m1{ufZhvdb&@%2==&cb$=i`*jtyZhJ zSAR0?{vP?h;kOrG3lW61cDjIM>h9ZDNtyFDT+HS<3T>Bt3sn2L<gU#)wzs6vMels-k`o2C01p6Sd@9zkrk}QA~;e8#*aN$*a zuLCz6Fj(l>&<08LL_{&-Pg%O(iL__$Kj4fL%)J=%)aKkUT$v~A*(()~77T^bT9V=( zt$m#%vgo_T^TpUM!2o~n5d84F9lnaRYsJUApua%_WpNFUw4hDckGVHHb@634FH(Ru z-F;K{9I0z(T%rX4VnCh00Rfh!)*n{@gIFU6dP>Ptkc#v`ROuF5%$G4OC=op<6Q4bt zzeoDFfdnP&L3H;4pwZr50y2wNH1#Tw)Zg#QTB5z}?aY<$+6U#>>kt4L$xO+KhcS`@ zeDTlcZvOXc%G+aYoTcj#Nmu5wM4D4v?#P(tzzWLZdb~gYb3647Vm==9p){b@E}a$~ z@1OA)u(gp=Bx3dy2NN3TA}>EN*ISqxkgYT(g0#7%#gxU<$CFlvTuSUY{^QAt(et9komC zr@t5JUY;V>85k?$+6DT0FH*A;HzTRj*K)CmM$c|LFhBGf{Dc!c5>p369f?3 zt;FuRcoDZ`e;L*M(nQ;$za-(5#|eGmJaqjU zDP12U0yE%YIthRUJ?QKt50>FHZ#fSKkwqXRB0ar6(N#(kY?=Vf1``psqe`LZv_$`U zy4@Zp?>XMb>9saz-^AmxgLe2g0~Y99?8(Y7a}U5rnG-zi#aL`CFmomv42||D83(pJ zxt1Ncs_VT%BLEitR9smssI*h>q<{*_b?f+5FvtTm6T-Z-rFKq7`qYqT)v+)ZlNmS_ z%2a26uPl??P71Bs%_%?-4O(5~6&IyG6_^=V_XDe!jP0~~NHLBYq=l0U*3CZVO>x7? zichYiMEfqTGX>V1o>q@m)eP%*vLM$^@l97~b$SN&7*akk_X*gFfkQ|EDT0&^1GgH8 z8(_$6BF*7kXuss#X>x5@5ywD5=zHupi{P_Gr5z)qW9?vr(e=y?rF4OB@&7N<*0%p) zb+rb(^}kZ$t= zz@{mZYqF&3c<2eet`h}`Y|kkHIM_+(z>G2zL)N_faaLWU4fhS&v1Dm~s=osE1sPI2 zAGK?#F3M%sr@qIDbPgr|sOEyMx7|hpXoJR0^Ka0Q02~P%}Uwjcd&9 zii{X@E9cI}mS8}+{jp)sWJxWZtxV=5?6;=WY_??j*j!Suz!*u*Ns03FvoR5HLM^`U zjj>LPG{;f@ttmT=fw{-&QS516)o(P01Hj0c_IbATTnJ_?dCTReHVcPi}j#e3%+Ka83DM0mhtaC#ju|lXI&;roh%^ zT@z}{RKEv$L`=0nT9Ptt_5~@b!6sHeC<#+}x&Ke5N2DUw686lhmgzdU{hja0TNN0& zsP}vM$tQSU?GDnco;@QVZ&lKseDQ^R@!}U4*MZl;zCdj>-7nN8J^$zxXjr&7)vW>LJi{dJ7DyuYd73^8DAoL`v>kzx}(iuYL8G|LXsT>rA(A z;ZWwQ`Wa38efG}V@`LYvSAOd|?_sVh0|qCbD+8gN!I0}g!91-ZxWf3j&XupnLhU$B z#ob>`2{{ZN7Qx7o;P>!*9uOX0>+p{p1V7R_`-~yu?~7?UjV-9a#v;Mg&hA%`LEGKn z%HM7Na$Tj)ujvBtZReM|kGVLtPhCn9i&=x0hs%#ys3C#z4(3C zD(SxC{c_za`Tv1kxdfHGeYisW{i+^Oe9i;y{+?aCeQqR1iz$BHVvqLx{(nhc_c{bQ z`+(oyn{lvxb)7luqm*mhNuC}jTuFcQuUf!m~d%Ug#aEI4$@T2c% z2V|~1QrBPK=4E3m)Duc_2$uL~vd~v$ep^2Hy_LegI&S^Xzpq!!g&~EV2pb#DS84Xr zzlV-2@^@*Dfu2RKF2Cix?)yR4-)h}#xV>-lO$EPm>hJ@(Y8o4eBd=~7`(@fQZ$E-m zq0?rcvf!Q7iiD1e1*$ZDdZH*2%nNnMgbWjd8Kj*?r6B?gW8EZH-r=bw(@}6zR9L-X z#qy+fkhI9$lm>%4Tm-yBE^3v)$CfMfpox!a7KqUgFPoFJAKlOm{CI1rr>V!P*H zj+xU-nI5JmxK`O>i(tltk;%kiu712c^?{;}o@#?&S<^C*M$w)AhBF~8&av56|KFH7 ziB*H5QW3>wRe;)0LTzsPbxQmR&4JuiQ}(08z!#>%xqvI~s)1`+ zH3K}DZVhsT&8x6E0AM05fG`uDZS&Xx0Ho$Hh}V9IK+Ng+I&T&9Q$U2NRGMyN+BWs{ z^JzWVeEg80<-jzU+2)PUhf)~ySg-*fMJymyFbQj@FntKDB(f0rS*tW+;(wySK)tV~ zU13;n7)a)6YpO4!tR9_5dMdj^%7j&;LHdpYXSMC)$pq$8q|cQS`bJi<&H6$CQJj=& zFgcJKEr)B#+Ps*X{W_zAh4c+A&pM2umt`y!Y2d?_BCe7G2ry%5qTZ;aLJ(8JfuJkH zO$K1(dfm0dL8rZacQAbtWi2=>tuGg!2q+@pcU!w~B9`VPp4ER}JcuQGAb!!=K{Pan zgQss=Du-CGi1||6HJPxsRasig#aCbBUaM`Li>GU(rvYTpXLoQ{*?QG}Y$`ahzuX|5 zW_82Tm5|D&EEoo23I>)H!Hqme+G2_IMJGAZ5!r6B69#30MfI)OPTrJ_d7@PXv2M0V zzW}R5=N>dvvI*xRINBrSNf}`h0`9_8QnLX`3Rl2AD{841SWCnLV{q|Gr^L603-% zy!5n_2OrqK$QI<9bdX5xjDlPG-t4wvG!_oDk{AF=1a}4`*@S4%6)dmZd~7pbW5Fxpsu4R!?vkYyJ`$SJG4mA z#vAW_ATC}kI}@(nX!&=f2n&8Hlg!4^wf6`xKuq84s-{S)%~WO~#GVtGmvvlr=NAAh zb&hHEDF@Z_Oo3}<`PH$0`spV~CB%2N{mPV74Ys=W6gbj*s5rPXcrG74luv&4v$|z( zu2-G=9#V|o$s5MFXh*N`V)Ef%U>8ZWS%Ds>Kf;d8dnT)pO%7w@ZwA2~OMOIkc*iO=-=gS$Ve zi^OB6EbSE84^ayPkN9}!tHsxjG`WEh9SVVx(AeZ4Yn0dVHt5&y{PYE*R&t zMu6}3MvlJ@83BuX&~J#p_t&9~F8y=yeY2$jcL*cT2%P0$t{#0Rao=@0?~Vb9efy5R zdiF{Wb}X*o{l@>Ud-YxNs#ktRV1IOd#(YhSb-M6-%Jt)T-RrvkebuYH;zmaSwXW^Q zFDURAmcLJn-yeQ8y-6n@eEoILSxUE?gT8@|BelfnZk3&j}6r*MyXlo^rotfLUj@|MNhjg+EA52l8vGgDW4N~WIwEX^= zIr5nf8FC$014U(>gz2CMpFA3rBE`ftAY8KsqEOIjSx0^>stQeZ`YNT-i;xCF-3fe` z=^8j$=Be5+TmCdu=(okd5h(#a32TwhOwR&_rNskWnMUy{4n9%M zF`98Yh$kMpXLj8kXW;nv+^D;LS_I&IZH~0(r|UQk3)Tz! zeC$$@ynj3x3s#kh*Cvx!x4EJLQ091!rp=?LcbSN8EVyFnQ4ken4s$s80FU-D{?@N2 z)d@9yB@eiQVIgEM-8g|p%Lx6VvwHe^N7ks$A^=}dX=OIXN7>~T%y@92YgNUu$0RP2 zTUZtsL20p62yF`-ew@IMJSnZ$LV#CKeYJAZ+QuGLlT=_;*E6e|w3F!*1R4M_6rkH| z2yk4WN{51CDh_FBUeYRXX`9EE`x#&rXayjE zLaTZbC@VPnd8A%ZvQujfYA_F#!GYk;D()y?Q7&pYe+ zBZZxjYNaQ|YU@xS9gktsl|q%+r`Zf3b_)!Nu!yu_F&Ah35w zOHcMUtOhslu*Ni)b|6?!*yrH5sB!v)p| zPoHoazGvk@iY^Q11WK8DETVvdZ7d83yMTcElsWf25zCgY=;Fu#MU{>#mePPZ#*_0X zXWcPJoIwd-QrkDSxmB#;mPR86c#WA_Tg9G9)0D8@(vGFJTe`EC#fA+O_bY}-Eh!Gj z3`5vS0JEImUTWJxmBqXlt7NBrKav^ex-~i2O9oIuABp`LhYJME!N8MU6TxOQ3t{(h z3cZJ&+BO1EI%1jnZka4#)pR*|>n%C|@(X*;(fk&#z@z}lbY^TZ1JK0!Tmr>#yYUg_Wwl`Qdlv;_I*3$F@gniXLo5ZP%s(qGxySK}!j1 ztFARoztVm@dGNN3_0RdIAJ^wRm6xA?CLjIeC-T+DpUTCTU!rOg^xbaU1ORaU#pe|q zs)qnK&Mb8tfY7eK|5ah;%o@;F&+spUlS?AhR(029F=4`2c`q}l^i78$aDDp**qN`cuckq3dFrFBVw&I?8_7B^C&qj$_ViDaM4ungT;9G{{E`@cQ9v@H=qqb z%!xFo2tZ?;`t3)qw(nK1W9w}3-6Tu!Ob*r~UxTEB=V%NHzkZ+kvbe{q=BHf!-61oh zzg9|zV37oPxwtpy$rWJd$aR-v|F@w)*rloCX0qI%M(ZelKc1H9p+9kPwsQSs@q(GMht@+P=J#M5y?`a zBr^wlzt{xbfWr}*CY+=~I208(&Ma_J4HRjhPM%n@7lH8vXGdT2-n2VR)O3YF+EN?{ zwuFW3MhK6RyMgikH84dhI)!ca6MPMtlo`ZwyfeiF;q=lGwQn#mXL;VkT^|Ef+VEv+ ztyn(3O-}E350Zy8*`)0;2@hT+Us*^cg0D{4lh26YTLX5SQV!_b85KNc2(sF^m@_&C zkm12#9~>E|1Cdf?U$9b(-dii$K)Bgy>Z1c=3>?+@R;2Q*X9u9ZICn`z=CyQ zAi#hsn=_ZnAP3W(DNUu@^sl%mac$^p%%f>lFko=)0Sy>6;M!jf#;kBA7OB#hr@q2C zKDfqA{TB}`2L|V;VnrrUX^#j&$+`}-6f*$O3W`8*d+2sc&M{~SX<9|5KE!0HYgV~s zh*Sy-fOjl=YikJLiHfGGevYPGX=R*x>I%VHoe$YWO_3IIVpN0>Z6E<%Gk!7}iRW_HV>j*%tP25^-J2YxAe=hOa{pO;A zx#zWSO$-)HBRn5-eaW)3bQ5qhsheX=m1(rmD2&YJh4>mo;ap@UMiE8pCX`65xqxv-pJepUxkq+x3F(XwTe4aQSk^R@;I@HaJ(=?C4wl`PVuw_o z7SZ->^jGZ<6*bqiH3iKTl+?AfqjL_nulg|;m%+RQfR2L?&aOcN?sdJ!GZRA}E!}&4 z`!=f%Zec?d+`-`kK_@$`NybL3YR&Uxz=n8Oazoxb;hy#4#XFYkT#yK=jNOQ-ei z^XD(+Cx7za%8!5eL%H+A?;AslU9LK0s;@Ou*Ur*9?XV-O?ol3OQh#P>{k#RkZXNR& ze9wH43X@vN(qjQi9J&m{mG@&m>8^DM%KU8t6=R~=1dD($=Xf9c&TIf%DXoId;fokL zzu&H#NnO#y&5`@+0*LUw=u&`|r^KDp(H$%-zzdNsW+ZT{r~hR6Ep$-&>vnGqOjDA` zzDmmgx<{e9ASr}Pk92)7D^hC3J9rNp;?}1Cl82$&_pV;c+j$7lIn%-WGao!@>%y)- z*!JArj>o<6@1c~%7`2v_xs-+Tl@Vp9sON8{(JjX16;0vF0#CT zYuJ&tOIeg%kFo4OpI+C?Z~i(4%J@6uFkETf|0u80)_AK#l@=xhe|JA6Ej6d)Z()bs z$A%QfHRJF1fbMK*skWzDgot`(Q~mc^4?$RLLA7SK)fe7wJ$1B1YWOEjP~bc(ufSj|4GRM-GU37@3VFF!G z6|+@+3lwj6=G zI_yb>emVD16=$%MdN5u%Irq<>+39O{>SmytQP}s-U&xD3KSkv&tMYU~hR1}UK~Ih~ zAVl>eZMOyo3Y=C)Tic*(RB7|B6*cdTVKJ~TacVEN9>M0(fOcSo6{&*uGRMk&2wcEgFczkc{kR%g ziKecJ?LPFl+@{2KitHPvP||r-&?OCLq5A_7aIFlr_R{L3Tt0dTFrdyzDXWtf%*R|9 zt=zQ&*=ywA#5f@>#=&TS8nl_i!Pbubi}Op{oSdO%b5ADIBN|bTc_%L99$)wCGmtVp zoPz6U+K90ka{wX8_8ct@b|9lMulLaN0rQOF(s{S*Y{CY zP!^1)q+x&L+;m_M)zh#~-jS8shYCc3L81Ti<%KZ^)z-lGImehOc&cendQfyy_wcgY7+XhyOVt-r zmdj_K%eLBZ)up-pgC8QzO0RkIJKw|FdGgc0loucU5}&{M;dj86QQ%$Mtk*ex=N-9$ zs!W&i0}&83P5nL&d}2rltiIfqn#$5;kBQ$3@WBuTRgUybid)=lw9w$Kqg( z_b8CD6rq~MW^=b^N1rY(B-aJ;SHY$3cWL?D zU?Ysfk%n3zo8|btJoeJj&P+3DAW$2po-yN}>47(&!&ldG`<;LOFv#YtkL&n4=zqVw zW;egC#L!*a3HUl-^hSMweO0aiHa!4!Xh+hw0A!NKsvV%*uY>-2NAKgm%U!RP^2WC9 zZ}aLarIoJD4%)S`?blYf#$|rvd!<*biv>GJy1AMp;!XXZ+RJwzydxKNkKJjEsUVG} ztg9bX=fm^5M_-^~DUDV!TtK)~tAl$cjOMPRDb_VwL+FiP8}HQ?Vpg|Sm-KC?6;*PECJ zZNQ5LuG4taoC0>bmx~J!#&rU`hf=?pFDI}DL3WCss7XMvKO$So3;_tG0eTVM(`f6K z8nEk5{QUCWy?oQ~Uv`dx2g244I;jkBOkI`}DqA0vw6}mZjI!lv67C_(U}LK_lQ!^TYE;1j|F=zJwWfPCz$*7d8;@yj1ia$ zPusv^N@sA$F&|woMW1`$427M}&IZIxNnDgyrUB?L{Nf6-=$5*B{(>4K*4N``6}Hqd z)&M}$MYIi88hItIi2}BQ0vM-f3estC$qSIkiMtivoy+~8CuK}26nYyRa96(#MQ~vw4aJmz7-VMK6?hQ#Zo!O zFc(9oSD~K;m7jo$i)6bNjLbRGIPe(+dSVQX6*V{lyxW6yW95kVXy>peQ{!X?W5+6A zIK!nZHelC8>RAJ^A@{mqw!pkoZ2fZS^q;XgUZBy1^a;Fg9ygdi+7~M_8fT`zZ9Hwv zDw}Ebr**aS+h>nW7(1Xq@%&Npb4>3xJlpl#n-x{LxW z)7gaQ*T7Uy_{Z9w8#O>YRklDKr_8eUI$zO-)kJp3h3shi9H8|oUsiRG{f&c&BrXD8 zSlLJeR%1k*+DSjkMxV;rJMW3HGleX&7Z76Ispv5d4E7C(a0d_Dmv3g)78CAXGx$#d z+}lDnz)@KP*(+FiaHC+&x}~`4IL=I+3SnLcX$CSml@YhI@wQ5bdacx$L}GeF2yDFS zn%dTj*+lSbzbHte={jIG5y+9=sm?ukY^=)&Ky}P{m{E8rkqLx@3B)#PFL=5o?vXnN zfIC{Vz{8WbX5#yuGm&>oe0SNTqfASw->|T8IarLo2tG_?5 zKGz*fn^Z8JK7zLY#`_=0jqiNN*1p=xr%z=6a)WfJ_3gLnTDUJ4wOuFo-jeVB;UCI7 z@4YLx>zez~_r4?F{qR)2_-uo<3xz=1s2RfNwg>4vcvf7lIHIXjRh~Ojjjaq!J1*RpQzjP6N;r-ojjiMC3pOlWq)4g=P3U3`1 zws5t^?#!j7Du!>DT5z57vXbKR;oF#w<0ywEj1K{sxeLIZS#!wXFfjfg4(I}C>mT~X zr3ZRg3GrQrF%}q#x2*#g`a_bCH1N+2t(urb|8!TRJ-XU8%_nH@mBsIUEnsX* zy2?!P_SO3hd3dA1Q}5>B+9J5`mW!|dJ{b40ywc{>eLwzM0`NfJ5ahT5#?b$hgWx+p zBZrTB{P_+UU5hm%a@B?$^i&Tx#dod)X430z%HqBUeRicS!TLOSb#^XO8}wB+Gas-L z|JJY9Pa*F0xwFs9dGc*u{c0-R|M$O-H9WLm``93Tsro-!++bJZe`CcMdtX^>=XJk6 zuW{Px=}Eh0YInu;-3=01LYpZ6e?>%!9(bIf_Fr_P&hz6|7LyIoL+;aDM%Z6c3( zGcPwXA8@2rOcpGktl?llXMxNc2P1H*S^*ag1}%uLLCM(~r$O@knUzl!qht$&fXz{k z&4%j!8uaLi)x|eo+dX$HF3J=X?>G&OUTf(_S6=;QwV%TwL>@F8ydBCmBUolmzFpc4 zLb2e{11LKALJ&c`AJ`WG;E;ji6=PhpM%D8Ctmll+k|bHXMpt$8}_} zG7LD;ruxaj?7+_yBB;q3CjWS#S z2FdGsda9?W8~yX_iLDF0g|fnGzn`3)$mYotu!cN+2aF>!Xp&dk(m;20Y9}8XW38zf zfSaVJzSU_zeeXTl*V9g`xH4F^Bn|TPI@%@5g3%4Np0uuSoY~yUIa2giXE!nK(@i_& z+CBdiWmW;w=p55i+xkaOpr37jDQngLII(I>m|GesY5JVDsm^VkSD@WfP!tt(s7+QSWQKmR$yd-iN-Mb8O#V2< z_wfz_Zk{yJzLa?%pO?-)OLwh-6^mTw!);fYsk>2uHKb@TtrRv}8G}0m554U2w$4vz z6sf(hW4^8STd%8gczy3~4e;KVr$75So&}Zv0Pb7@XwmOmdc;kna`ZORfk>24RbYNz z0kGHWDnOA2D>trdHWO&m{RDOm<7pzhduSxRV9JzLqS3V>&Th+1@E5E}mTQMlt2)}V zl~C7`@A^~Qsq$Z407TN*h!si^?XQ0WV%$Y8b6lcSDwW`!Po@k4$r?NF6V~G5xNun|$4|~M- zKR9!ie&^aXV7sX1*QCAzZ5y<8_GJEAbuB-1(D`f!4lDRO-lsxPd#v^jm9KVIf*ks4 zuvL55?EQRhF{t*7GXo1#gEhTqYzJC*e)QV_UG%!Eni5VYRl^yyJR>!7viPn0!?srygMzNT{J;aNd7kAeD}Xwe^Il%}>JO$5 z-*3VG;_9u%{(I@3sU&wF+OrkE53l9_1~{_#a5s(z_v`_qem{THSL`c?ZyyG+BJwTQ zh>zv9Yb!~BZ37R@2kA8+n=gL#;)@$e4?gyvY3_G7Kzr1t?+GfdYFqDDAM|{4DX(ouIkMimpXv#XcYpj({w0D88Kp0uY5}Ne zRlq@+Ncr{?EILcNiLP(n1_Q=s&3yJbaC>SQ0N3lW`g+XE$UBftkQrwrz<;=1Bzb1tEYJg>~cHh z0KhTy4z!6-q!>X?7CL)=(iw~(?UTKo-kG>q??kt}^uT~p17yN+uo=LVB%bmyoy#1+ z9o!Z>VN7r^-8ql^cD=0rel>M$3UBi^=-XaJ1^M@4;;5yWl7G>dJY>b^SYiZ^h1SqHq*3GsexR0MO zU2bKdC3Ok#(xCCg1ex8@fjDG!dKHvFptfg z9i73_m9xd#876`%mToqmzkuG2t+fHqfwZ)GT@QA=6uh=c19km5V9lCdhqfE@pX2GG ztlUY^@2b%fj)nsZb1PqO?1C{|DCmn1wzf5Z(Ur7f>Xqt*tZ&`IPcIX1RabT_d2PWn zrVUG4V|^h#=`_;WEd6hads<*;Dh@9oD(W=e*`5B>*hB#citVXbXUhOk zJk=EY3GFocX>VFh*h?9lkUh016g1CQ`s%bauv=mpIbVAU2riD?TV#J8Vhu`IgE;cC-BqM-%w`o z<>PPUWj!F+)^RvHxgo#xqj&0>%=IL31pan;v6B}s&f&zWzoIFxFDj^esg7=a=7&$8 z$VTrYHdoiWpVTh7rKP#^UYw0!hl3njv7mjN8iTlK#+Dz|dr|gSi+hW}XdX*MHB-va9_D%{T<82>`P8=P)!M zlRMTyaOKZuz!qlFV7^%n@3RHDCbG=xmZh-vL2AKpF^xm8x{7@VYqmRh@;2gosU2~m z-z3f(!}pr7@1zK(0`wus>UJWR#z0X&7`_P^#a@jqo=;;g&n5KTJup26gg_9rNL(kLnt-Z@jD`i8zpVBeb2RaAQ};Oq;!^96Zo=A3^JfcO zV)+^Sks_GwXcDvdhGI4gPnb zuW&?lD8A$+%yS3)hQPUW06-C0ve}y6-Oyzca0iaD?wNtE&*@;Z|M6k3N?dnHZ95?^tXm z^aIq!?z@zI>3{a?K@!Kwe)pZoy}j!%kVT-I#*V_f>MSN#c`oQ^ zPwjvZuhYN1?Be)B;vg{dOtdG zU>ZnCaMl+L7~eRMB4eAr>95k@IQTWRg&}NTZ;b6{%awQGM^B|e`O<8BD;so9UTv=% zAuwIW5X^(2#VLJ#?w!$x(LX5JN)QC;11AAQ$iAH%yS@y%ImA6vEDWRO7K)7ycKTd$ zENUSgKOWB=4ebvFkcMUeO#E?Yz@9plHyG$6-+YhfH59m=L?hs0AIsPo`b?GboI5av zrZw|)isG`iVNdAZqEl*Yi?=X1KpD{5-pNb0(|{D)UZ6XZ5sVk42iXL3K!)v0x-hL= zEz-tl;6gC7oT0xIl$cIN3c?OZIa4N6zO2C;#Bgs@7}ZXH!-Xq04jQB)*f}%NU=0F8 z6Jxce*s|pl>nW!`z-lrL6{Vx&nd>R3p783LEDTt*ou1ZMs11Nqp?$Ve*7aKR?xj`p zLcmrioID^6M#t5}Dz(K{@u&ESKZ5ol^6{hpol(T9K{meJtOh#k+7nE#gHx9FmKvE2 z4DmIVScT0`&zv4<>p_FYfoU^j9qml#2n?I9>XHfFvSQro#K0<6g8@rpHMNwL(E>tk z_8uA~L!*5oAS1?6GuMxYh127(ubTZ=m@01VB>Kn!i@0ADGgnId$85|^BB?)cc= zspFnb)14;z^+vOc3aU5unE|c{aw~YH!J`5>va&QK(}_`b$Y2bC8kp_#1$C!ZWaCJH zKEv2j^uSmu!T^wB+H@YUnN!nis6k)Z6HsC$k{Oi(_uR-eCGH%;ry8h2pQ?WL^5HkK zd1__dm8qowjtO40G}A%~wy=%R!O;T>7lKxsvNCpNy0{4Tp;ay0o719I+-m!km7woy zAdJ+$-L^6K;6U)cdoQ!SYH3OCA9cPtJvwuQX44u;URlo9K0ve$1j0?@Dx1(I)Anp? z7l6Fb#u?0+gh=-=1n6V)-85^gy!KxF^btbcdz*W`<}PRK zA-1M1HKGM^&L%5#xH84J4d`tFm^r53wCI=;z32m4pCNP_(vXu=+CVJc_p)-H)f|N+DrvL zD@dav>&ia6{OT)~khkht3Zx62Z3Sbje=P;tnUV^8x?nN(AAF|;%BUKq&$KZH8TO{B zRkIsaCuyxLxnu4>vUdks$cfiXJ5$AfAz7v_x{`R&fVK6i>+Y8q-kEY z0T*>2d!a1bIwzDRvr#ake)olfN%IcXz5vV?><+TlR6I=uo{aS{gg-Hu%D~+8)8fTB zRlJ)$=#%WB7?%?dxrBlGLC|bNlp^T#rI-n1WCpM^K$jVxQt@U45}rcg-z%lfYrk%! zxBK42wz*)c&yiUDesDO5KOwF$l1(Oa+{XgIv7}0CHK5Zg&ID(-eMhuvRqvk}1*_1JcIEbC;N_ z!uyx*IfGf@V^#Pm{_Lhl9G16sN!Yu^eD*1y4*SRVDuR%`7;-mfr2Fn6WD|qy*%L{m zEPJcPjr>`BQPPJ?ot-G%=S%ACTWdt?JHP#4g=_dye>=0!hmtyMgMNJX{QW^oq2CcP zUFlOMyFTdr&gB5K@4MbkVO2TzP4zDWeE?_F6zcnxgA~R78M}wzJS)8!o@&U@@zsqSYd%BBbSZvI8#c

hss&rJ`B!s1Uw32L2H|J0Gs8_9 z0u0i5s+B}1KOG6N-^?mZ!g9FkZ0O0jD)f zXbZAO%w=JuQupWJb!3;o)#2EV#@x{0{n9jhG<9eIP5ji@9Q$^H-=oKPuGJ)7MWs16 zsp~^K9nNx~?Cy)k^&7Ip{0#7h03rfSIERz5jq0x^O<`M`!<%Vz%^r29+qqBQO2#zU z?-ujRnMg)~Uy-d|7h>lbX^lZAki(+bFp8;sk@TlZvl@xnk$G0HvC z581&QSZI(|PK+%#aFfrTf|VH1q^=BVc8!?S>Ff-ws#NHRxl_{&F&xCzDge1wvFvbe z7E1-(71PTY##m!!Uu*-JqvFyGCR)>MvUxHfpyg@10-Smkh@48Wcp!d^IXTB#g8w~R z6}n8u7F^zOY)d9=#?UsYOpTIp9c!`_rX?cvq?PPmuD!N4y#I@Xl=|D!Ir4*TNIL)Z z#NHi^X*e?%LN~BF*Y?k!+CHIoy|na31rnv?uw&ZKBbksh84BnFT~j-&%A|8Js{FWd z?M_$qeXa1MpaP_#xmE{?1EUgKz25ofU!aNZxqTPoi)Yg%hBQF~CcIjd&V~6B6BO$bEC#*22BWpD%CJGu{OB9%!7#OyLA(iD z&j6XVBBD66kZC*CwmHB+7lHPaVhy@+z0haM0rYjzgY-^sq$!PdFoWk(XJNG_lV``z z8I!PnNP64ufv{_T+2sw4cjvc7DGo$PcyRbV8Hv%a2d~th$f>h*scAPF5R*O1d;1BQ zUJK&ooXchm2+XG;^c;liD3zH2IE>H+E{8o04_U7G1xdMgG=|O>EsNeKeR&Gdi7^{ehjR zZNI3_?0MbCKYj6q+&sB0@4tIfF1LGmUhV$5il`$UDg%(&)OEbWA&vpG$|58jrm;-fzIy5P%$8vHwVfjQsI{9HZ~C^uag0s{;t zG6DY_(Gqzjy|>O~J(y)m(r}}m#X}lE+*3vRiiN(|ctYAlkzdp;6 zt~>g2vEn}EAOf}V^%@iodMs{8{}HJzxQ8A3wm3rMjZ!Sq@qZiGn_Ma_?uj1+&@e>~ z^0!ipw&PjL5g%5H2kkw;z-Q%+Qp`6823mjgAi*nNM}ksW04Uw(=>NP?PFgNDOGagxn`# z*m5}5(t{9h(1m>yOMfBmcZcit@KwTbjRr=Wd>j_@>WED`{CEF(e;xCpM9!-0*rag`%|*@4}BW$x|q zZ`vu_N?HM(9-~02?(JI@yqO^O3tL{Vp{&S#{r%1A%U;&KZUn2(Q?L6;+H9nimWTP?K zNsT)<4PE5a%{j`LCOU^W&0qjB?_PjHJt#wF=SXy>Q(D`-rIv?x1`UW)`ax-?18aek z(u9&k*=Yp%oHcBt^ngR@+FH8L=)VcxnBEHh(ow~Scm`aC?eGAlIjqHJh>112lZ@}T zW-!v1r5C}rq#@Fge6uuUo;mBK1Hu3%6bt;PF?2H`g)KJJ(mi`>0lhoa&O9h3PWn-e zH+4?G$m@++&Yi$7gA3LA5NT-qJcrn@(dSD5NUan(ujNR7bXyANSp`T3sPhjYIw_qq zgp=5@8^ z?7841-?%BOJ6i<0s5r)|ReEy`3c)B~wG=oG6j@bp2SF~^iIo&Lwu4u1LdolmmDbi% zb~z{Y6n26P0i|fGcE-uhY{y>H5-&{%d!RPZ<;(j12EeVB5gylfLkB_ItfG_U$rB4y zd>szdWC>31(p5&p{LTX|GvE< zQKA^l^8giV+<-|7(u=Wes3YZT!tSqgg%xnLUxsc&4*+Qd!x7Agt?6d~$g_!LLDcr5 zf^3%%7hP#e5$$~m4FftP$%2Q_ixJ;E>w7H!t?SD{H==Oj8+Zv@u*1HxeQ_bf~Y;9Y1PP@V?}EJ$~1-=<8Wj8 zQ{y15VvwzW?28Q2R!pzO8e}S|_8+Y2L~yf^e%)1JYfL9u*fzI^K4)|HzONIMM^+m` z;r7gV8hZynk97%vhjx%@wCG;?869Ef1Q8vIlh1U{(bDV zK2Dk*sf?Iaz3zpUn6Lfz;^hmusDS91rm1UM%Q(Zwjt6+x z1=wLvyKCA{-)~;$uu0gcB?#7CZ)l9X>n~9P$nk*LTHYU0Ynuw<6_b%x&W7MtU(|I(}C`^EL56neCK31INU_K|WG zu=TO*0no$W2XON(x-?>+Mcdka%4;t6s?Qyc#hUbg^{( zxFu<}Y_Ttkr!2YHd4I36v`^~a=FY|(w*SiWxC>d@S}M!WdAd|#=!}*Oru7BjPy`2T z_uqPeYh2d-c)hL%fptH8QTNb|N~V-1M(!z7eVf`^7NlOS^-x3g4Z-TpC|aTGLCb1S zD;4V0Q}3;P-K*YUlB#o-EpNY29|Rf|+Sn6gk{I397#QI&(UCW&dyIt#`geVxdAk=c zQ=KN$lQ0HHwm^^uQcnOyK)S!Zufp93u)p{!Fv?xBf559v5$^Q<+-i&!+f1ytRD)=Owq z^3=2J13bf}Mo&rNf~8hU=3Ed4o|YD2noN2!sU@)$tXbcC3;m>RQO1d;IYHwG+6Tqv zUMc`iG~m>=KJRvsW-(5BQa`n499wD+ST$s7An#v;j%kcJkM+2&K{!s+_Yiv39@F)z zf~o~#kk8CS-*hE#a<4h3dukf3rnW(`joE`%1_&B710eChjOk?1S3&?giC5SY7u$B@#yPLm z+{`B*h&wgM+BIvOB?1s{W-u~0TbDK~({4FG$5@XVs58Z3Or32b5MZpM9JUqJ;IvxU z%<5OY=2L8_CG0&IHOi7wJ+pL*y=XkSVS=_~_~^Vnefw>U1q5v?D5I$zE?li5#ikK7 zSSj+e8)7V*9F?U^uV=*Gl*nMfx+HKu(vdN{HDXR?lp;3KSk>B5FvhA@?J@6#;0C4^ z^s8u>z;@f2-2xjkFYIRcUdhUSCl?K8idUw1cp+E_P*;VywL6?SLLp4wH*|cUQB~j5 zJ^(PK?cA8azv=^Rbze>rEK^V6%Ct`q-=0=slg*wD-8?a!lz5p18~fdd725#UN9lc?*w)PQ;4PxqJSreDSVIkUPJf(b1FO~$P6Gi~kk zYjSR^4ZTL130#_P4z8&bX-(&3ig#g}3+92c>9Bt#*()n%?ykk>5iPT>jFA^F@f~Qs zh*7LF(*&`{={!}I;+pze#roaThV?CI%}^9rtAime>CBjxU;wg8m^s*`b7*sboet9M z=dEZqXA=n>0|@iKAHJ3+ zsy=+2HyA=YT=Uc3J{YzjMH(oR^Aeole1$H9w!-JKB(gk~`XddyNLSkC|1MoH4_jxb zLB~XqMLYXfKi@qxNd0{nBes2f^*(_+pN^s?pHK z(t}k!#F!a>3=Di@o-#O=DdSlGi(hx3@hQqSf|{ryXqUUqojgHH1AyR9spuY2utS|g-q;G}DUw{qw^>t}~1 zZxQW~WqUCnX6`4nN28%3^iBFTb@jdhex&7H%3<4zo43Bd86Vh=fr+I%zwhlk9>(du zkJwGyR`;Qk>KDz$s#Lm(p0BR7VNCZ#dxYc0H7Sw@=PKSmf zVA$7SWi-|RichE$KCM{FIALSg@}(NEXuDAD;BpV=Nu6AE_|*|q+Pi~9W`y*i?c~H#N`F-<%;FQG*e0ibWjHNn zij#{C!`adxeP`MwvSaCLmZ8-(w7O|5mz9<+q_C+5dO8*eG^-=NzH7humxt=<|7u`8QMR%9^M_6BronDJ0wj*WS^j^C(|X;1rrUP_;+pQ!o&mcF;%apvtw4h2KL6q-%5 z57nbGE1mIxppG4wT&u~n$}~-Av?33iCy%Whb=@;3ouBF>u8l>lCA9Tm=JcI+p=+au zCcBr<;YSW9=1T&Qtoy+I_uiM6bwB&frytAD|N5`w=H0jIq024oGrQXN@4WYcNCivP z={?spCVe(NgwQHfb*-w;`RM5*IXzv=No}{DFnU!>DuwynVy*gm)+f0VuFto*d*jG!z7Asc)3 zb!b0Q_kQ>J01>)>7kPyN>HxRHm-p8pE2jr$g5f|}g5JZX{EbvY2bJKF2Dof{{1cH z$&qLDzxS{H+5bLYh&p{qcS~FFev0>Kg~UOpf$@&D*|yr&pW;T zw^c9$j-MG}q(PA=tT`m7SdIbxo9U2YV0Su>36jvJI06_j2267_n-j=J*wD_oEyG-5vNrELEdxgW3c2EgflB~b7`%ql zx^JbJ5mc;32G1=gTL=^tuTCQU1ojF`8!P`?T4`bcS4;^zN+&+pF#Xl1Dp<9ZJ;n#1 zjJ^jdx=?$_K3fy%cVy?oqK)HUTVHwV4w<_inTka<43g=dOQ-JGW)1s4P-6M8G&x z2HSjo5v;QS?uLQJ%m5j$R%PqR%FJ7Rh5>8F=2`C6DKQqE1{f+ZI@$B8*sM9cV(WNHz60C5 z$__@_31{+3LTRAK%5>Bg4@H&}& zfO9?=vycLyZWqBi7?_T!^J!%zaG^thw6oOgjRQLFG!G`yncePiy%wgBIY3n?GV1$` zF)UI5C~?~80WN}BT9$}Zaxi;r_v&)JXE9t?@2_)p9Ace0fTipxO?4Q^tkd95(}DmD z?dR4OGGzeJZ7&0G3Q%T0N6JNrD~F>iv{$Q0OT}ERAijzWEBn#yC>W6Q7C^=2*AF3Z zt<|)YiGTojYwQKpdAafK2YCMVox2D+_s?^)1&Q{qe&?j#L)Wnh#ES)-5IWWQxCbDT zkjAA;CfNLNsdma9+52|!}I*86^z;`B6hexyd^VY$M)J~<{ zapyV#t8A}=+B}#Usj)(4pY1XG1}KqzgE%x&evM59mg3W=crG1V?KAxc7%5LH*s&(q zt|xFveXZlcieO+!*6*Lb_YTvNO85&nXdaOdJN4eh6T5ZF#C)+_o;Jw*7V)s4ssfy!YX&`GU=7%W??3U%i(J znqTuO^2X(`(?Os0KfSMdcF!@;39hXi0g}3L>vfP8_v=9zf6s&0vh<4!-_Hj@KH4Qd zH?9v*-H(86^@HcK?E7doui*zQ{e2vii9q?Vue*T$5D+=`DhyH`Bylk73V85_W9s+w z=PHZ&l|q)`nlHu=>_vVMU6#zV)^_@6N1mG&#xtEIIy9M4OE25e zG!zZMrdv1BKMIi2$`bD?oU1d|>cy9}&2{arZ{9XRM`anPO;L70J{%T-(GDl@EWmqAV zhIS3>uM?*>ap9&Pvq!2}3A-7Nuznt5`7HAtd!#HJm)_>3RV#<>rMe64W}chQi@&G7 zgAn9IK&~ai=Ptm)depho*e+h3%H|lIOQikHu}+-%(+4}P!HwmhY!%pzo{7annM6=4 z9I!~=Y0jKEw~2Z{6v7r>b8XDssB9IbJsIqeL(>A|+*I}ns)p51tRUD<4XewGV8bmK zv+h(gaLr)mn(cMaSZyJMmf^3QNC^b6#Ub;X9flYpH717E4XE{mKQA^*hiHBVacKkT^gLSgGItr~l*s zLEioGk5O6u$u|$NZXSR72~w%<{ou#)+1YJbmvsefUdW?w9;3q2jXSph(r70>tM=k) z1^mzJUU<4algqkCDMxyh*Wo9bt8sO{0I2ICo19u;;9$$_YlpT?-^UISrr*+ZG7CIp zPs3z(^gt2xK5!f;B0c+oj{8Oj!70WmmE*xtvc0W8Fk1$i?)S2Ev3THBvTwsNiw|VJ|3(Nd05_{>ly=fD4ux$PApE)yX*O@4>&!T z1z13z+}7V90satlA*N%WNe3*7W2qe7c*d`i$d%H}3xGpj?GN{X_Yt;HT(ohMfr9rqP$uFZ)Fo>ic7nxNi3Ei?FVAzyCM;?$0#xpl9@$r2g)1 zJs8kELjNc$28%Vq2t7wj@p%o9syBOPMc#bQXT@S;wUp0eNk z@Hiq-``?)2&@VE;UcW8f#)20Yl; z1~4@^IY3=5a5x^zl-C?m3-F;;P}_U@;BC360hOiF?Lx=H#&WXCGu;AM?CxcG@|9M7 zDL!eR@t}wQhOr;}V3Z42`%s^BykQ#+nJ`69jE5TtlrjAKy||Dmg3(iB&_G;LD^Cno zrDyx-8=KD>ToeN+tgP?|>bzDVJFBOS%3RTkH9F@}>UMWxeWW1A=9w|1Anduee$kCj zQ#)=L@UgAe-aPsS4)t_)Q>{UJb~QrEcvDb9%Lt#ph*G!;W++1k<+Jr(FJA&w(No#v ztOsN852v$w@>x$(0d#8VS*5)1xw+T=P$wVHMaGd{9ludIFt2je!n-u>R^jEmhNk zBIrU;GXgp=9@OeHuB>kz=(II{Vvf#k*Ev=asg)k^!WOS+Yj=AF?Q|@)e|kp5nq|;K zh?H!D&K|ljt^w5tYlVg*5v)bq3Ch@dZ+)pYTH7~qod7_Hd)Yd^tU*_%=(7Tmu4m(- z*cv!1TLk^+z{}h~V*Siaq2Iyn-+?oN4N*0%?%byRC3{G0ohchr$FyEWR(J2n^N)Uw zpjiW31qvLMQ%;A2^u|Gvhb8^VOuxj7mqME z^f~~J_0(V2{$__g6eZAWTTX60Fq^Qs#OJgcl!ND9p$Vx8cV@GhIw$s~`6P4*H3eq`Fn%6Eaq_@jZS`dPj)I++)!EV%ptHB% z#ro1YbouZres-*&-+iIihtIpdl(Rc^p6M2!eeUTVuJd}Zl-R*RGZ9Oz^AsHFJ)t66 zU7KpRPTzjV=7y$XLK|pDn3x*5ymTEf`M72YW6YK%{z5-0=pMMTkqymW; z&y|5f0E#&mcM5o)5%3OMV$5k3bbt8EUjq32{LlW>Dz4RMyIBEGO|!lD@@o@{ukF2E z0iZ|qo{yhCuRzWkqTT!aSf141={;`Uz71zsPcPM>9VY@QxdjV{0fjY2t^__22#AE3 zY%rBs71QVDBJh>c1rhvvN?m|(0IYyv?&Y^r06~j(NCOj`S+Y0@E{9CzgXfUWzwrPl zUHx1ikRAr0E#Nv5Azt&!zF(CV{PzGxdCj%FFTE`bU`Cq1ZP${;b^8FazuxsXmvl#uf1HGZ~k8&?0Mh1gus(_4?4tWvyze)R##b$KZ<67~##TVtub6$6^(qHI}Ui7Ux zKkrRmi@7AS00^aD!w2)E-}jHU=3p*a3)9ihT{j1hUdw?eZ}4kg-p77$;P3Uo)!{w- z-xg<>Op2&U?$=S*aNBG%=-0L8M7uRzL8?xm7JZ z(L*TSOPMmu21yKm|GHUyDb=dE)QY5f@J(WXw)3L;hO4>ym-`nlc_KX_xZA2`i)uv7 zJaHe#$jh>_oF-`Lj+LLTsm?_hzW!8h))Sz*5a+r`tMjJ-K;EC*$)Z>1$cEk{Kz;gD zd@7n|i8&qWe8O?m7f<)V?(lRa=8>cHXmtctF97j`o-Rc-4sPJ}63QB|z_B{5CoF@S zP1``aN>Vtr9*2c~Oq`JA!7vdwxWz!17?m_MaD-JjQtAMKF4&KN(?9Fi;&%*rHwJ=% z9tEeW;uSOeBpbm>4rjJ7*c`?NKzPakQXc5sBj_Vz06~A=wDFu-UV0i$C0c>H!B{n* z`)i=4k;uOAbaH@`Y2!b0ld_fL6=v{8Zh4+yXh8^*r@Cyfr!Z(hX(>b7#!L{NMh%^A zj5_8%Zs-o3w?w|?W!Idg+4MQUuF+HOl?f>7$>O$xnJQ{H zpnNnd6Dhd({F#9)${1 zF*>;h018+tTLpRib!`C`p>vK(CVB#_%HZ?PKp1EWoG_pm7hpr2{A%xMI?9@w0D20m zfm*V)zN*eTSOhgVJ<0d5CPB}Kz%b5ZfST(G?Af~?;HUP-_UU7uFw*u& z{o5J9U>L!AvXH=nr5)XC z8jP-7y`NU)p}mDT_uA5C6rjT1&F{I8t?h@#0#dL5-%0I^-8IZSWzZf_3|N&SJp;=Q zE676f{aOwJ$jpByOZ7rZ4F!ya;A$eMrGT`y*#Ly@6qXJk(xem9V6*ACKq%TPrD;VW z^=p*1dHK@jX?4V~|0z(Xz?yu%S>0$~B5{yOJd9{^Hg;L;MnPGTOnMYzElCCdwJ<}BRk}oUh zf;B;KLjn7B1sHX$C~H|$^q`gIsbJYzPd1K)Oao}$=(qsrPd49p0JN{)z5n}vD0k{y ze4#0g%65MKR5leT)x(B+zx_M%#YZ2>vk$&68wF@oU#vd*zOKtnT_b0;&p&wY16ea2 z0RRTgQ0H!?o+uM2r>fju zg6|{h5dP)3yN**UJ>Peswl?ag7n<^TPG>*7cdzb>G|W=IB3-z1(L}e@gFhqCRi^x#MB| z%Cl4Gli-@_PYkYqp##5V>BHECEcZVQNp22SUCbz94t6KLMll}47xQ2!C9j;q z@90C&$jq*Jf_v>44A>^?0=|O_1LM?gvZney2Xl&d`GuX-4p!X+6`}xgltqxOr>1bG ziUln*^RxvOxl2n;5_hI-@^}#E0$w&7a!d>ue5XruaH0fUZ=4xaVlcP+=y!Sn(q?wz zY4RjJf-Gfu%HSy+o~{#h*ZT#gpHYWeSxRU&MF!RIkdln*LKQPO^vZo@1k#3={f-*4r9^5A zK07d|DYDo!TV)w)BXsnC16i8x4?E9j+Ovr%yDkJk0~fT_V0>#8hLAE;gH8pmtg6Z$ zx%jB|p-zUjYj0(*HCPW5!{7lGVb*JE0u=-VdK!%<)j({v(`N*q6HBP-qoLXo%X2I9 zq&mV{*-Z5%L>#~q34Nr2;+;(A0N|-&zY3seippSG0vbTTnWg5z=;$ysB`nW!KqaaZ z)0sNEjkdp3AxcTH<_!R%uynEw%^tqZ5i|Zg)%UfB)AvS`6dKxa8VA$e(~!gOU)Xewn1&78W<6g0>Ca7uI7(a3!rTj_T07M$EE=4=muN;q8E9JkU@ zxCx3Bem_nsJt!2bdZR(8eq~Q#-n#8jAIzRxPj&~|Wz3;fvQ#cj7p?P9bWN;AOPOFG z>3!g-PLU#*n{J4VV{EwLfUy#q=`cxDBGcy_$if7Os41GN$3zVt3m`0@RWVa-i?i=W z1m5caEp0C=CT{LQ0sGRJWM@|8NZYI+&}D(pb<9gLfUwS?v+)+byLtQwfTh}fV@2(( z3RzvVTEz^ato;eA2lKS4U;~jU;cO_c%oV`DSNXC|vpLQHtkAv|F(*UEeMaS>9Kbg~ zvRq8VM1MDPf8iVjyG(`ob^Nl;P1C~Ji=pEw0zMr>fCOIR-py(_<`On2_6T;_qhnB)K(FI4B%>L&c1#y6WBvqr?;QrCCrfr#KBhW zHK6v9{sg_5OVbAwif5aS&>qzev!^8v%T!HV8~dGUed#_h@3#SXIS@2Zb4UNID*(EM z*!By#cxv#RvP~^{Nx=Xn(o-dFjmitFMz5K9V=K|91o}?ynu(FCA&q;+_O#hMr09hm%Qy zEYJfa9?&K3^?n#=YkTfnZ#LAw!)v5&tfHTU=~JBs%>v*dm}S>%&vgit^}tC=DS|7z z-}1A4xo7`utYyRq^yTCLC~|OMkSp`VSvoEFUAD_(3%+STva#3Xnt9ZJKibiawSy5@ zEhS3>C6;q1fTDv}>Finb2iHL*@ ziuHf)z@~^XxX$O?4&qa{eh=3b>^1ySS#)&@aK`|pnJ8@lmuU&e>1?;EzwLf~UwVmU ze@^dHPeIH5`jX>duaCim3ZDdtWH}EqK?G0PJO;P*V6cC`@5`(AwC;gz_1LWq4)+8D zOva93t#eu{5NUfa>mkUg9*Wk_oRRRMrKk7%U1#UJ*qipNZ-@7f-MV!4WoZ{&kbD@e z`ccnToQW$a7_(Cy#JNe2=(iobv3P|AIl@e|A~fDI#J4$z-OG$ayx#%JXnFyv!fbXy z`^CnbOXMP3xk!5;bDD{GQ=C!exrxxtrORul^Tr3pVp-cM{op6ZGr^K<&Y6{SE+%qY zc%R&KElfzWUB|@+G3jt(w)atK!9<)A7!vP+xl@-D(?*Q3k;D!b&2TFE4prxFpfKK^ zUp%{rFlSu|i6sP@eq!yXWI|=|;?}8Oj0b5xm`?)(Xr3qzehTDMjlrgik$MmyJxCKP zqFs4r=`T2X1RhL)ssSQyK{0vQ4%D>v!+U?&%Y>VN|hh1sc~T9IVVU6*m=4%h;H<0rc7i&MlVpMn$!m6`3^6O4(U^ z(`5-U(t7=EJsq~7x6MIpL}zQOj0F(sgwFiLAeUvaRX>L*j1kOm?iDxO?o{hvU5Cjx z)^Nx;zF1m~W}diC(lji9PmljvFjxX$#^31>7P35?2?!Po=O`-noSD9q2I1%uuYyF- z$4k>%I?2=lNp|00Cc!-JBPB(~2FOHOhR|N=_x6UgH;`9M>{PE?fd<%Zf6xP`+W%2P z_eQU2PFGJ5W5*Cw&GWhpL}dSg0E)0+B8 z&|1iR-c0SEZWEvE^rWQ|BEYDVOUN03>}MseNl|kLc-%rgZ>Z zG$7n6;~47$+C$17P@pYYs-RVjGMnI9E0`11S{j_SsjQ3IKRXp%z1*O`bv;>G`Zdx3 zHEl%K@rGmIYu?fjO`~fC(R;29jEUvm4`eZ6KXPGd1f@3igH~6gZ5#;XVJ-W9?f?dz znbO%ox3{wJD+>D4)1<`r;j%WC2inAdS6t+M7q$zIxZ6GkuC`1Wz&T*5?@>dF231Ob z+Pl~gMCN=+GcnO<4o5*f{1p= zq7?-5uth-!?cZm={uRbn_oK_Nzm5{>bG^Qn)PDcRzbl`7`MI2`Z&=qzer~DrZ-4l{ zeE&y3tU%5SdGUOU@}sI_l~w;KfcX@Te*gpY(a>L*#%AkWR56WqSeM!7>Ka@ zp$Xusy&Af}=kOj8PA8uJN5I;o1pM&U4~4FPEbT$W4?X>$=gKq6vJYSN3NX&cGRc+i zA-L+^?+-@(USK)sKGpe_Jt$DP&o9TerJ>k0+kD_(mjC9x=Qk)}{>o>TiM1eb8(SsT^R^EA?%-zQAzIZH@OpOZ#Y9GGC%fZdovE#&KwYaL$XlAGf z+Am<=%o4yAd~PoT9iSxrsv~{t3=o!V$QgXw<~>{KQT^IBA#K7=+2(NCg#m1#K0$G( zMCn43!vTXc!BVVRzOg^`l?eJQKtg7No~Fe@l9+(*z==DPKINQYkUF$2FAaqAU`w0D z9K>#MckCM*@kVEkm$x~23V|)LI0cFT4i^*$Z6r2EX=CFvw7ZuD=jsd$;qT()%bluH zaEcr!A8Pofv1#DI!5whQYvaj)4%fH98~O2M1;oZ)B+BZ!K@kR=cy(Zq@IDS)gjPXJ z;?B|KA5S-leirrvk!oYtNPGvU#s1lYg^pkmPB9%@FSR-haS{sc5xvG_RjzUXG8Sy0 ztUEPVl>U}oGeyO083a#YnTYi*JIPZ!;?${LOSJ-oC;grhq5% z5J1X>(m797U{Wb?m!_L&yS7P#(IE_6TC9hK15z4zC;Ys{pXI8v1nZx8>YLj4{nx_~ zBFGY;AU7UQPs9`$#M8QrI;*oygZB;QdfqiKrazHIgOn*m27&2rWK{mPluK%bD4Rny z9&|kBW($I4IOK312C$LJ0_n%+d9pAJt0;*Z^H$_)T;OXBhL4T|+nngI2!r)JcPFRO z&wR$|1WcDajlonj`#xbFJ8-UhiE2g|bFJP_wUowHI7YbMO7)Hs`%wU_q-Km-N+-t2 zm<9pL$-p@$7PxAlc)|)bVDDrDg^L|D0Q7?mNd%vnhM+8(8&=UQV{MEr(AND8^JQzm z9Q2KLae9*azy-F;m{M9k(bAIkJgk@@jGuOsIG~7%I2&WsS*}XLfrdVpGi0)^O)_5$ zIAj`XvZ{LGI!AdXkT^4ijln#eBhzovHH~rI@5RM-Z5riZ%lKT7u#?A{hTmEfgbv)nea>rI9s0U3W%s-yka=ijL<OfCr`^x4(eKp5n3>N8Y2Iw`5LXS_sn}2uO8XDEo?Rp4RpQktxUZG zd6sgwla;bl_NK#xgBDFy+_!3ILWV?tO+PHa{sMoD!2Xvn<>q(4gK@%j>)0UuQ4cxp z-3L?jqpu#ykAD2)3cNg%^Ow)%#@##B1z5?8^B3~;;X^rp@<^sskgBxO!=NZR%x6np zJwq7Sl@3H<3iI5UF_~5BN?hRJmD=G^*gy8;)ewkZx#s<2uQve*j(xs#|NnP+^(XWP zTcx~Kq!-^A7Hv!2-#xfH44}K4x6cmk^uK{P5-gG>OQQvf>EOCU=O@z%mqQl9o4j5* zF1!>1xAgk!Bx&rIYx{!#zV5!Sdq2syn@6~xl!#Fe?-6~L{Il{#cQ^zUdtj!-;X>+u zznpW&UM;nRJHTRi+jS$nks*Tdc-DiycOXQ{k>9HsCJGX)C;rse*~u9g8@t^u`pWmG z(z~4383=E~kfL0?rv8v|yHX=+M$QHV$Z&UZvT@;V%JQ>=a-6$H`?o*ZEK#Dn8EsO&--DaV!JHS zoQ52ZJRCuuR!6Qh4CBz84|QmC51-8O0YEcakc)}p6R+^pt~C73Cn~DbBxBrcF1M!p zQ30dHB-FOACN2tJXr%>qxRg1PreWiiJ8Z~;a;e%W$td`s_X73OkLBh(r7p1J=56K8 zmJ8lDbO&GtffgEnq=e`-92L!}qe?H0Zes4A0~SG# z_Jyf=hMUd8fka%Y&Uz{Q?1*4B^+3<;!oo8q+ekoTsiAYQrjXLJ!XkEtj-E>UJOp!u z+9H_Dd$N<@B)8Ml&>14wl8Ynl$=F?`L|RwS$#WM}`v%}CRDN>HIhi;l|9xv$+9XMG zR3q}JzUI^((g=hJj7u^Z;v2@l7yz$gLu!Mdqh?D%&ahK zZMJ8+s`7}8@Nj?r{JCeK;aHM!w3^e68h_J;DZ%jJONjj{0EdQRIc{T3u}5jAB#A4B zNMrr%{P@b~brj`%&3421H%c-9p25IRAAL+P1;H?Wcc|G;Wb3I{0MV*56PYz<%5*}a zh3Bm9Fw_cp#cN`>C4mVPa;)#M%`ur0BkcekTIew>-cET)-j)nOr+1ox?!{O)Gzj4$ zXl0p~v@~S#n-%rBuZ_Vd^X3F*2hoz9%3JMnsdymTF-m-i`a1F~F$Hd1widNFX;=(&9weS>hT86L zQ~3f!HVKx?&KSEu`CVtX=ssg7I`N>qt6T`M=c1U`xG)}MdPlG$Kv~{}VY@*3O*;ev ztEN*mDj2VGe3qCpHst+AeG+TWYjjrrQL8F@?GWoOQnR_RIhv_xfFm;r&G5Gi#7V9o&9dXRwY_h8?{n1`QJ2sZo zYdoZp0!R#3&1Jcy%G}qW#twUOo?^#rvp4&ymAu^JTrgPICptX){?? zxVLM}mI>pYlT7cx>~G6l#tZl5BHgK#X0Wr?Y+W2Vj~_jvJ`rqgN~M*@BrD;=^P=A~ zG!TVjuyt8h>3TT;F0-TOwrO8jG>&Zz`QFL|m9s{dHNa9Y3C!+XOV1A_djyLh|F&2e zB*Fg8)(OgN;ZG6NL@xf!v}eeW2HSCK^T~fBB2_gP;5?eemK%`t-NIPIoWANpn5kS6_UQZoYk$rUmSyEj@nz zG@aME_~_B&bO!d_s1h!*|Ey7kx?#DmB|DA3dved7mqUh{FO7wQfkL8rYn>J2r*^`|FzwJZtonQl<)7Mr4N3+ z+%q*$zyti$#Tvs9LF=jSAJ-%M7U#%a%wq?)} z17mGW^!*3cP=IOj%N#^u>0qZL){b>@j3U4koqBYi)I{;H%lCkOd`gOP5r2d8a2#6M ziJyb(FdiDuKgpL0kS04|GHO0&>R9=7Rf)*Vxme>555{h#vHuSvfEhXE>ful$8)JHAsKXM4kN{i zeE~%zXwR%mI`kWK{M#8CKIyk+*wcxTYv0%V?&OU&ws5jsfHD5~iNfHg=Gft%6!4vb zz2xA<>i6!~3RV?@ESz>T9U|%^UcVjFK_0moOV9lvX)@5#W)>Tn}+|4y&+#S2C2n;OgfsH!1=Uh@}Lpqxi z&u{3cxcXdiwvJs_T8Cg;@SRnno&%oyYn5&6lj~a9Ikr}7ydG5gH!9#3K%n;Q0akkE zeQS(?Bvf$3Qwct%TXWLelP>>^=rW7nj;#KP;b$IY~m#!LH*b%(+{cvS<) zkt~M;0nC_4&N|&98%%GYY7&Ko(57RW0R{*$;MTvTH_Z%bn}o%r_^pdq_KW)w{F%yXcEB%`xhFfje-M8PQLcJ1oO_I&@GFkx2 zqXV@%cU(($06x2ib+WHzm0(#()%f(OF&Y8Bt%no>;koUngLGsDm4w-*Z~KCYEZcg( zJmD!;)9(rPZ?>*t)AWeG(~K@f_&OY2fNWs!OzTl8Ok1z1+viW7VRB#~#k%#tl|GCA z-Pb6Y!%LLHqJvU$u*pU5Rk|AGytt;t_GoCqp=60Rsm^x*S$F}wLBj=r9t0XwBEy9O zE4LB&Y=+#n}U|| zz}h(q6crr#ec3axcDP5r^B?hYCP07g5F6f30D^uV>F3xx{_bl;NG~=~>DUeVB!JHi zgzv}h^z}YK@APOryOelFMc330 z;bW8F7SB8{z@AUviGEs9jI{ zetXtO^RyViz_1gVd&3kZz>5+VBg+4#wnlxtnpJrFE7s@Ge7j{^0lXPQ=DLtFOT^ax z?SPd(?}q^3@*P*tzWQ3@&`QJ@3F>^5c0=OXoeTjZBmF6h?`I|6p+APwrpI9Z*Y86Z z7-Gl-m_{Y{miDaQc6Dz5d#lNBiJXCJeg6D=>CNj`>AJpq1D!)OOToMXFa&YoH?M1Q zXIJ;41FvCI+&=<~n7ovCNH^EFJjW!7kxl1jt81;RMY^S%vx#$xcJB0P0m^vbh)cz$ z>sedRDAR$3VBTWP0~(hxBHajX*Sk(dn|s+BPKP-$Hc8uY9XS?;uC0|rDd8g`eu9Emlq(kCe;93a!5v3nvLgDo*FNX@EE z>;>U`V}Ed6xWN!A+_-E>$8w5NlAcUDa>DrD&@?n+mic0LClOh<2!eA^u-dFE@g4qt z^vr&D(U^?qXB`;VIi+104?BSHo;sRppwq?-u*{e_{F`epOaj&hqcbBDCht0&m4>2= zx_XdsuD6FpCJW_H+ZJ;%g<%sS?yQNSmB_J_<7gZduq%ifR5KsvKj}i?8XydOQulJO zz>l@ry+eH0O|)kOy!PL+o;y+A9e5kGF)G`LYnXZwMxm)H*C{%u=~P@(SLUo{8V&Wf z&K!rDNlfP#>S#33QO0pbIIfqEIj_Cz3}}NqPkkoL9xwaQx?x#hP7-_E2t*;Xyb55L zNJ(FKtixf6z@AHrarGAS5}uyh4hp(LNLAU`)w-76D!x8Q&1SFYDL>)FCI=ydlG*d2K1m6~w{{T^zk1_AMPdN-l^V?sZnC zbZFP#I>j~no`ZEH$Lg>~3+A#|*#@88Xu&E4t8cFLY|xp?%9&^zDatGDvQhKB>>Dd) z>xCOqJYQQbTk18!nC(BC$>2&i#?l~jt^V27G2hkf$8>g~d1Z6TIz^2HWZ33cEe&b= zudfMaF8f;ryMwa-^&C?LWgb7V(xBZr8E1Lk#dQ(*tpANQ@IM^xV(ttoMIjJHji@_* z2c5`#u5d5poU#4R7^XJ=wj{uCGd5#;p7xAb`Y|-Rwrd=vL0zO43IF;6^{;1hu2atx z==UMrdjKrH<}l{e(K!n|h=mE3ULC*lk3Ool;7vMo^R{0zyd<#x zo;3cc>U|r%8och+gfJ8KbK->&U`kd$HPy*kG8DE&blr>?(zS;rgNYxR8J`@6qSk1L3J0Jw=j zsjj)3&przf_?N%<_w@Srze%@We8w_a>>XDx{v`d?-~Kdx|Iw3lRmc8==T9miGca3; zJ;?O5Y;0D716`Mvl#awLnLv^6v6k&YFr#$y&h-RZz?F``kp?`Zx4w=Nf&7K}iKkyV zDi^v3BINf5-b!tyKjzigC=Ldt2k+$+kQsYzw$d0#Ln@60;p1M)k=jYWZk!l_~g#N|IQ%Hd+ySs)y8TOP%(D4H>INl4Zl*}UiQ|{i$1{LPWBt! z+Q}7_`$y3pGWrdA5jg z3(#OzMG3&6yK3im^F_Ffr=XOd^Yr)kz(RmZ@L3Q0_WPk}`QRRLuU~!jWqMTiNUZVm z3dTDi2tdS{Jz%H|D&hSW;_#5tsK>axtOc?Hna{o9{q*7be%$?tir1NGom zj@JdR)fxq$ger84a6e*_VGmk8S*US#(csAigLPhlQpuA6c78Iyl7XHM5@IMOWWd&I z)t0lCc~($mLU^nrh7kr%1M2szmF$k8vYR=d^M;VA+?GzfPs{gXpQRl z!(*`&B$@LI<_1e4STXn`s>Nk4D4=J2xwYE&X(bfMvD9Ll1I&#v&@#D{t z;-jetG`gVBoiDF#OHqHuqCy!k0C%U8cojz51rP`Fowg*{g?U-8?)7P z6xqhYG!gK-bUOqf#ypb;&k8=>0m(hBJJ}rY1(Y|*m>mxHknnD$*)v*~`_?{n+VdbrRfF{` znzwaUn#Jg{@r|xXn=ucfG_+WGN`SIOw)u44;~V4DTFJX(*D=H#^oaJto&CJ??u+j({5(-f-2emzSMSU@yv?j?=@Nx)&=bkVi z3+c>&t;5T&IV^0=etkpmZMm_QiwG(yLcV!B@cLZ##!gwvZ3Q%6vaLM0r~zOk1hB6 zl(uVFj=@mAQ36a$!w?`KpZjR*u`I1L&Hyw6TGHCON)o)Q034DRehD zw_kovaB9A|qDV96SGBR8P+00b&BKu1_j1+?sYpDRv2na3mTCKRKWtFPK(hH(f-U9T%9L&1t>Jfguwsd} zY-PRmSg(KmKXvY3rQiL_KWj~*UHy4oueSt9zy8l(r0dTye1)L z*eiu2ml3#RlW9w(28MN?IRZsAm)3ClWh4Dxx$RHg z^yL4YvC#*C9?;sU-vXX=-x*@EHvs)!pwu5fwE#YS2Vllpxuz!8sicwleJ+|>jsOR{ zUA28?!YxztA#`9Id{K~ZfY^5ba$@N;21{0OLcqsM>GeF;Wr;ZzU{xo6djw!;{m0YL z9+I=qgYO8+oB}OFOIDabXE7i>b%AL<<}mO%Z+%Tz8_&?$Jhcbz19jj`Tt`2{N@+Ie z|L`jDzy5-yW#UsP>}hU$Vm}wsyMY;k^urL~LRL__b@sZAP4i#MiOo0cNDxQq#w1Ra zk79y+q6@}#jB=NG5}Vl>a49+*jTEELw%)Td7si;!__L5bu{Y_AB=&=nZ9Ioqh&Hq* zgWIM+d>-}{$)ly(wX^ESphRX78=LbBnvnEI(!F`ngN6@Hf!ytt+~e!9&Zmo(U@LAT zEmi_hLNF=a2M_%ir>r*zq1r&(|DX{wE15INzPbh<7&E&H!u<4SKc}|Lm!E%@URVDM zV|xuoGxnakcftnE(^&;+tkDKao4`nUToY}qme>%U+@|mH>c^)q8x5%z%~6cO`EH_p zK)KXa^{`yNxJ_^t(^0Q5#SpGsb#t%R)e2*ZE5-%)cN+ptgTlV1^+j8Td zjsEeJ9H2m^9Bh^ui%4ZGq*d2U*!7zTa4eX1I=V8S$izb|5fs>MZ-R@UwKFcX) zN*16KWgBRT?VE~&78rJBP`xXK{Rl9@7wTpJ(Z)J&bF>?1lN;iz&)K2E+zHwD1!>Qk zL5S-4sD%NCkn`d|KnmkMUp%fEvI^FL!p{uKU|mi;IOtd+26~N+=1io|#sbfR!T;^S z9EL#w06L{$ZlbK@LYYJfRoY5PasPI|!?E|SpG9b=i}%LP#IlVPSynn1^*A#+q*PSA z#JP$I_3p0;K)~_F`v`i*nyuVO9bXhUPN@gN1_4{P&Q^j<)-w8v4(aRv{*?tdqMEx- z0i8?<1CJ6=eN~;?xf<~4$rCXTD$4z=W;JUtdh_L1>HLEaH5OxvjGX_k9`ojl&qHL? z+M&AmW!tCu%plx4R!988*a*9tO&ujVi(qBls~f_$gwS@{o6xqGil93cSOpt`1P^vJ z*GK~f@RLj1r2PXi{~Kt~YccQL&#!?fg;Ow~3=a@vGH!H*Q7QcV2Dx(f^+TqNpmF5OF!b<}J643Xxbzn*?e_LoG zmc3iqcAf#Ix;ur21i_BIbwG--d&>*oS(|={gC60?V}r+9XCSvHppm4fQddKa1A{(lO<2eXGvFk#hy^y7I(6}a>uL=&xOe`fz`Ft&s>B2Q2 zClqCd=nl2F&OEq3*Sn&g2THz1b$dz*;Bb8qEk^dMg2#7X6<#w-7L%^y#yY}f1wVtb zQw@N$W3i`z>~L|L-UnENXV)j5bGo{;PIb_3+U*qBCb6jwEK?hHS7z(9ZjoqRx99a^o?8j^5ckGUV?1D+(BT2>t;GbYvr66Awq2ka)(G~1{i~M-!hzKY03BdX zU8{G0_{P|5&;_diJUh=pgJ(E|eKH~KlFsX1!~~w($%ENe*n<7~lJf*0%j;kLS3SoS zS!|=m0&@u(W|tp-pXYh>;~%H5|LtGX9o9;{p09rUoAe)bjsNI}f0lOjJqX(!&g;4d z@QQsAS?0;gpaBYPv7Pw-+e)W>p1|*5NnjE<(3#2JO>6--eyZdv9l!X56p){mgxq`G zi(Vi2NIHtBq8sM_=gR}r9?*#Lp*Y?BY&kD!X!f_Hlf9d3(@^))j-nOtZUn(W8YWo1 zR0M(J1HN>CSNT5U$YcEg!nE!kEc!05@Q3Zfnr$d0%H1q5zIS2A$B`}culLvQiAcM) z^3L&z;9K`=jIRccym#Kc_tmWe2M+XKC%bYVGy4TXU=;#&s@?g0#?P`sCOZyuwIE5_QjPgd&v4JH*JCWHgPnEE;SmXqtSIr^yD@FAP{?XrrQxtQO;y#i&>^>ep%e|lA~1J?t<1?{g{ z=34h#?AwR+ni?!GzV~7JVg1f|_1(dY{PfdLDu8p-o%ezJO%J%jC%{q*!gKl-{@s!c(c=>AH+*)s?;(kQ2j6%;q_cFv!=pS6Wl!Ta&@#^R zAc2*9q<0f#{q^Vg^e=w?PewntjBk+$B{Gi8Hs0POS8VnUN2VuXr40NxKCm8I>n<;Q zLcppzbGD^~5mK1|bvck>Ty5c4-S#ewCmkX<5jYOeDPFlDPKW9+P{439kw&x`9q9m` zMexdV*6$-Iw6>+@2n}NvL&386d6?Dp!vFNQ$NGS?T;3!$^=%(o)l%vf*W(kwk z_51Zv2g1r_j1rxiu&f7aMQuXYHAMR?(>X^+k}UKuDXVFjS8W`qslR$`B|Rt!0jf+# zak9@u7A-3y>OdA8Q!8`YR2CCp-k=T^cXwokv>?qLQHd!zn_yMxK^~4ans6RUQR#zP z=`QAMn`5l@>YHWM$pG`##(nlhfzbT;sRheq0Bptr5o^Pp!C+e8-0LAa%HaHSHIlm; zOoF{a)@ThB&#J?{d-{|?1?C+!d-gZ!{NoQv?dN)=BCS{+Nu^^qcRU^(TXz1)Hr~{g z0nh-1xqcVaaF!-jgNXK|?7)F_3PIjtB{q0LXMk%E8xS-#5J(sA#*|HmAQjEuElNi` z7~`HK0C%p}w0r)XKfU{r1(yODI8JRoHC$$hE+nr1WF;QSG!z7cawf6#N^Banl6IY? znA>7>kcRIfzATyBH5T7y!3G%z0t(X5G#F?XcDn%3j7>HYATZ!Uz+@I6Nn2ub!Wbiq z%28C(vwC@@chV_bJKpv->-q`!IY`3!*PPDCtf{Pr>>(GU<-8tso<!cp4E6{M?4s^wbK1vtN|C^En=8a?pTvC<|4=Ft72ka3;!7(0jsJFrBM=Wu93x4{VMZT%`hPhh4qMh4e| zF-EE-ZVv4}lLt4YtrbAA6fid?q}hI3bC!tlvf8s2lwrS;d$qAN}ah)8Ew0>a)5pf?ht= zyJDqFNT$4bW6aU3$5#~(zoU=2gCC(XGyrxt6|6d|NrpENI#xLv9C1+QZ|m>&bzOp9 zpN1SFjhaZYH@TDVu%P?CJ)n|&&gBNOdBE!~(4a0XJr}}@AFPX6Is!QQm$r-0C$K;; z#WySmAn-kPKm~1qCsvgZ6gz^V3fs-x%AR<{;ApXk6K!~yFK#C#C8^)8)F!ot``diaG%3T6BSmn86Jp}OB&h4KYTt_QO z$o2#%Xt$_+WXP>klt2dfUJih*+T&X?Hywj+IGtD?WRu7*hc*;i8{=D(n3C*Hqq%Ey zvIWkJ3gBA{2(vCVdP>=RJZC8n&aO?)TFwG#CU$RwjaZj89+5L0$dr&jit(PKB)RbS zbB$y0j1W`}fr$;+?)lQy4asa?I?5~=fM5ji?dH^YM z>a?DWZNhm|tdo&5{`wNY#t^f=KdVVwyzZ*a$1_0t>4UmR;(e@}YwQQkJWa(z7=?Pq z5CIr*d1)G<*be}vpo0=ixWV|T&l>k}5U_;jgy(x$4XC}WKGfrC$3Or4Gd_n=_kPe^ zfkqf+f~E6wh{)qQ@i~my4fYo#e5YA}X4ADQT1T2q1j`SyV?)jzKw4BjHu4^x)dW1g zd{g&Bj4Q75QB5f0IIo~J g4M&~o@ljUxztQlXdN;gBhX4Qo07*qoM6N<$g7E*B{r~^~ diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/channel_member.imageset/Contents.json b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/channel_member.imageset/Contents.json deleted file mode 100644 index 5c4d3b18..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/channel_member.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "Frame@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "Frame@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/channel_member.imageset/Frame@2x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/channel_member.imageset/Frame@2x.png deleted file mode 100644 index 4a4bc5c83b5ee0a57807ad19db4e4e479f40de71..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 979 zcmV;^11$WBP)u7K_DV=?20%NjOe8xDRuvRDy?* z#w=B8nlf**Zr+cN>7)}!RC9z7=Rm>)u!jT%BAv-)-2$A0a|xPF%};7X*96hgfXF){ zdXUe$UUwf(nov32t`mWqTV9+8ApsC#Ruz<5XE8Us8X<<+@xFq_CN>{ zw%o%<^Df8`JyRrzbYLBXgs4_&9wX-}5I~x?B=#afx$LU~AJ?AXmVCA?7xALFAR$O1 zd-1WYwVLu{#~I%XXuZ%rZx)4RWxyAd$-S0U4C2IEE`9QbMx)ybF$P^WxDi8D{b*&y z-RbD#Yw^R#SgfBdW8I!ZL~FU_bP|M!1sT4TiaTQ?(G3mI&xzKQPq*tq@P_ACp1E~H zPc1EVFMA9|)KK)^Hb>rvfaZQvd6)y>3n?{~TUwNTnik9dLEJu=+AMGYaRL}OXo)=@XvkNM)kFBcK`Ck3iF+BwxuO2@v4i|;R z@f%n_PrG0`V#LJAV05!w zF8*k~)KdB+l1`*9Mqc8J;l}Od^sLj;>?z(S;GZyXtS06bAI*c1LgzBX9D_miqIvwg zkd>TjVH0!nL~C(MY5*>maI$TM`Plyn0@%K#ixyYgR~;+ps$&IRb*`PDVDmsjErXy$ ze_1X9YVc0|L?P{f;D;t2k@!!P#bU8oEEdZ(;TI$yLcwYB03iSX002ovPDHLkV1jv9 BxoZFb diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/channel_member.imageset/Frame@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/channel_member.imageset/Frame@3x.png deleted file mode 100644 index 907d325df3a92c2c86c6084613e8a86b3c62e178..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1330 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�R3(5L6)XBoW%C4N2g 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 diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/deny.imageset/Contents.json b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/deny.imageset/Contents.json deleted file mode 100644 index 5c4d3b18..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/deny.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "Frame@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "Frame@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/deny.imageset/Frame@2x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/deny.imageset/Frame@2x.png deleted file mode 100644 index bebef76f66dbd65fcbebcc7f59db429bb3c5c7f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 360 zcmeAS@N?(olHy`uVBq!ia0vp^G9b*s1|*Ak?@s|zoCO|{#S9E$svykh8Km+7D9BhG zaq5UF6u627s z!Gnud7C*%7x=Jrz4NMYPzrfLJ;_kz)hv%1Q?yd7JW;ie;JH)l)oHJ0*5z?yrA3Tyq?E8y;_B7Hg8Z{54}avsOoNxe@29M6>nZK7HpGON)pI z3GY4}w9dRm^;m?^3D=c3+$VGuZE!5$c$%cLfj{gTe~DWM4f Dn`@4- diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/deny.imageset/Frame@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/deny.imageset/Frame@3x.png deleted file mode 100644 index c1f6128da803da9ba125e2beb16a453f9ad0cb4d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 518 zcmV+h0{Q)kP)ugK~#7F?btg~ z!!QsA;9r>#3MkxDaf2KIZV-A3bAxaK!cAPzXE;HU8{`J5=-r0NU{-*~JiM}`U8O<) zOk#~6$~Trr+8D^m$@yO~+<}+!_JI!0skz=`e0Nz@H4(2>9Oy; z5!V4B7qltpGn?SB+LdL21jq@_Ru=iSYtEfJa`dxq8-$)}V_T$wnRa`d4R<~ZrQyDz z%@zr;eMlPi?JG`7?i%Cnu%zebV29>chvVzmXO>60`!pErSPvVE^nz+(B}i|m6e~pr zL1VER$Y5wFRtp&g^~Gu;qoG4spoS(=1a)EUw9Qi5eyrc_89+sFQMVfe9v5q`;C<9MZ$ z2I<10d$sc?ER=BcvdUQ4MjP3t#ZsC5Y=7$w%{_8*a&kWM4isUU`L0cmdKI;Vst0I76UA^-pY diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/denySelected.imageset/Frame@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/denySelected.imageset/Frame@3x.png deleted file mode 100644 index 005a1f90dd7646e139e091c9904b6e74df04dbbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 327 zcmeAS@N?(olHy`uVBq!ia0vp^S|H591|*LjJ{b+9I14-?iy0UcEkKyjb(&!UP>``W z$lZxy-8q?;Kn_c~qpu?a!^VE@KZ&eB{vA&j$B+ufw=?eYHaQ5in1>~-ENhVUWWT|< zG~iIhftd+PCk~zad*tt=+LUL_&9x3k3T4un9E8(2K64a{3MH4#;4|*cIH+#xZ07Z? zd!FMKop+Oze!CVe5!KapRNM6ICQsxo<_$b)^Cm?y#$H;aG4sjHLr*5TcWw5}V%g;V zPEgaWs6EGWl6}hQNi~}lv(+jm)-UW@y#7(L6YpzIQ=OV#2eX^XM^C1n7g3wMRb$cV zD6tDEk_Vs7JhRy7EZfhg@e|*=a0eH8hiz%eemA3jk}c!CroK(NZ+3M)wm5f$JE+X& V;)_uOrwd?b5?7PzHdwGGYLwpY_&%sFt19Uih4lX(vp~K~Ku<2lk4#$%NdmQ!7 za6dT`=a~0KaLR!^N6j;wUP{d^U_k%? diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/extend.imageset/Frame@3x-2.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/extend.imageset/Frame@3x-2.png deleted file mode 100644 index ea5767010a2df764e49dfbe3e43690d6b4cd5656..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 394 zcmV;50d@X~P)B=ddz|5tMxe=Pp_kB!XEcqUUep9#0g~ah{bylh8x*AQs_4l@ty2!z=$d% zIp>$tA&q6{NuYI+BJ0p5NRd@&85uDCJnqw>%3W(erYhv1&u6Olt$d;~WR_(w)fvX2 zI*_<$FkML8HIz;y?i)xq5;HVs0*N^qGlj$~O_@Yuo`y^#F|%bhkeJ&dTS&}qm`x<+ zH^?>;J8DLO#GV>aA+bv_N+k9vM2*DGKe>R!-XFPw6iNRxEtW~j96^etP#%QI=baiU ol0u8`#I|?{SWb=f`FvgM4KOL*PfrPL-~a#s07*qoM6N<$f&i_c-2eap diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/extendSelected.imageset/Contents.json b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/extendSelected.imageset/Contents.json deleted file mode 100644 index 535209c9..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/extendSelected.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "Frame@2x-2.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "Frame@3x-2.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/extendSelected.imageset/Frame@2x-2.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/extendSelected.imageset/Frame@2x-2.png deleted file mode 100644 index a39d14c18cffa8b6141f2c3c3ad3cc973ed8fe4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 181 zcmeAS@N?(olHy`uVBq!ia0vp^G9b*s1|*Ak?@s|zoCO|{#S9E$svykh8Km+7D9BhG zTQRvuU~o2-6BP|9tp#wBRzLEzW?~TdV0qTCOzi9 X{ht1cy+vPurZRZC`njxgN@xNAPHZ{v diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/extendSelected.imageset/Frame@3x-2.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/extendSelected.imageset/Frame@3x-2.png deleted file mode 100644 index 0a0c2a52825de884ecdf79158b2a79b3d28e60fb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 222 zcmeAS@N?(olHy`uVBq!ia0vp^S|H591|*LjJ{b+9I14-?iy0UcEkKyjb(&!UP>``W z$lZxy-8q?;Kn_c~qpu?a!^VE@KZ&eBezB*EV@L(#+j9qb9UMelFUB|Zy=>sqaAo%j zJoMv6$C*#A_fFWJynCO6;YW;Ss@`_H7+W>{hc9erE-MJ08FPqtvewj-x_7RqZPuG( zu=3CnuE|bVYDUpF%0iN@b6` z7p!;Ol@F8cyJoWXsEAYI)2zhLH@`fe`@8kr^z1J)`gheuZMEN7o)@4k@OkQU!rP?EBHH=J!BnUaReQo*4?Umyoo1K-6l5$8 za(7}_cTVOdki(Mh=m!9wP@`FrQ`91&6-#t?5@;1pm$&nx4{#p rJ+68O3K{i^8SgRXDn_t)yeX4gcOHBI%3|F}45?szdvzmkg8`4r#oZl@5{+kHOwicu zctb%st;I(`SRi-GC6Vu1)78!AAD8^@md2!QGjr-bMO`mdKI;Vst E067ju7XSbN diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/server_menu.imageset/Group 329@3x.png b/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/channel/server_menu.imageset/Group 329@3x.png deleted file mode 100644 index 667e2fd5e22585487b298775d66971e572fbd86a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 266 zcmeAS@N?(olHy`uVBq!ia0vp^W{u7Q^e6h32?0vA$#=B`oM`u4dc6raFNWUQWM$wfY3oYfh zcbm+78tXYNbmF4xxBdhxhpL@?w#;kh{i|_THLqX$T)6)$`{8x^8=mXu9=-Nsk=gRY zd741`AGCjw6e$r9DRBXjCP0yYixwy^T%f#YLGur>FVdcCecHP&G;{zZ7(8A5T-G@y GGywnuk7TI; diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/en.lproj/Localizable.strings b/NEQChatUIKit/NEQChatUIKit/Assets/en.lproj/Localizable.strings deleted file mode 100644 index ac1a8db2..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Assets/en.lproj/Localizable.strings +++ /dev/null @@ -1,165 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -//MAKR:common -"ok"="Ok"; -"exceed"="Exceed"; -"person"="Member"; -"limit"="Limit"; - - -//MARK: Server -"qchat_setting"="Server Settings"; -"qchat_delete_server"="Delete Server"; -"qchat_leave_server"="Exit Server"; -"qchat_permisssion"="Permission"; -"qchat_server_theme"="Server Theme"; -"qchat_server_name"="Server Name"; -"qchat_id_group"="Role"; -"qchat_group_default_permission"="Default Permission for everyone"; -"qchat_sort"="sort"; -"qchat_create_new_id_group"="Create new Role"; -"qchat_group_name"="Role Name"; -"qchat_manager_member"="Role management"; -"qchat_edit"="Edit"; -"qchat_save"="Save"; -"qchat_nickname"="Nick Name"; -"qcaht_edit_nickname"="Edit Nick Name"; -"qchat_kick_out"="Kick out"; -"qchat_prohibit"="Prohibit"; -"qchat_manager_server"="Manage Server"; -"qchat_manager_channel"="Manage all cannel info"; -"qchat_manager_role"="Manage Role"; -"qchat_send_message"="Send Message"; -"qchat_delete_message"="Delete other's message in Server"; -"qchat_recall_message"="Recall other's message in Server"; -"qchat_at_any"="@ anyone"; -"qchat_at_all"="@ everyone"; -"qchat_modify_own_server"="Edit my info in Server"; -"qchat_modify_other_server"="Edit other's Server info"; -"qchat_invite_member"="Invite Permission"; -"qchat_kickout_member"="Kick out"; -"qchat_manager_channel_list"="Manage channel members"; -"qchat_common_permission"="Common Permission"; -"qchat_message_permission"="Message Permission"; -"qchat_member_permission"="Member Permission"; -"qchat_member"="Member"; -"qchat_id_group_sort"="Role Sort"; -"qchat_sure"="Ok"; -"qchat_cancel"="cancel"; -"qchat_tip"="Tip"; -"qchat_select"="Select"; -"qchat_please_input_topic"="Please enter the theme"; -"qchat_not_empty_servername"="Please Name the server"; -"qchat_not_empty_header_url"="Please upload Avator"; -"qchat_not_empty_select_memeber"="Please Select member"; -"qchat_please_input_role_name"="Please set the role name"; -"qchat_sure_delete_user"="wether to delete this member"; -"qchat_delete_success"="Delete successfully"; -"qchat_add_success"="Add successfully"; -"qchat_add_Server"="create Server"; -"qchat_mine_add"="create"; -"qchat_join_otherServer"="Join other Server"; - -//MARK: Channel -"create_channel"="Create New Channel"; -"delete_channel"="Delete Channel"; -"confirm_delete_channel"="Sure to Remove ?"; - -"create"="Creat"; -"cancel"="Cancel"; -"channel_name"="Channel Name"; -"channel_topic"="Channel Theme"; -"channel_type"="Channel Type"; -"input_channel_name"="Enter Name"; -"input_channel_topic"="Enter Theme"; -"public"="Public"; -"private"="Private"; -"online"="Online"; -"offline"="Offline"; -"first_channel"="Channel 1"; -"second_channel"="channel 2"; -"more"="More"; -"has_no_role"="No more role"; -"send_to"="Send to"; -"image_is_nil"= "No picture"; - - -//MARK:toast -"update_channel_suscess"="Save Successfully"; -"delete_channel_suscess"="Delete Successfully"; -"open_soon"="Not Open"; - -//MARK: channel_setting -"channel_setting"="Channel Setting"; -"save"="Save"; -"close"="Close"; -"authority"="Permission"; -"authority_setting"="Permission Setting"; -"list"="List"; -"white_list"="whitelist"; -"black_list"="blacklist"; -"channel_member"="Channel Member"; -"delete_channel"="Delete Channel"; - -"add_group"="Add Role"; -"add_member"="Add member"; -"member_permission_setting"="Member Permission Setting"; -"finish"="Finish"; -"removeMember"="Remove Memebr"; -"removeRole"="Remove Role"; - -//MARK:身份组权限设置 -"auth1"="ManageServer"; -"auth2"="Manage Channel Info"; -"auth3"="Manage Channel Permission"; -"auth4"="Send Message"; -"auth5"="ModifySelfInfo"; -"auth6"="InviteToServer"; -"auth7"="KickOthersInServer"; -"auth8"="ModifyOthersInfoInServer"; -"auth9"="Recall other's Message"; -"auth10"="Delete other's Message"; -"auth11"="RemindOther"; -"auth12"="RemindAll"; -"auth13"="Manage Channel Memeber"; - -//supplement -"delete"="delete"; -"share_thoughts"="Share Thoughts"; -"noMember_add"="No member to add"; -"search_serverId"="Search ServerID"; -"no_serverId"="Not Found"; -"know"="ok"; -"upload_headImage"="Upload Avator"; -"enter_serverName"="Please enter server name"; -"request_sended"="invit sent"; -"message_channel"="Message Channel"; -"server_nochannel"="No Channel"; -"applied"="Applied"; -"join"="Join"; -"modify_nickname"="Click to edit nick name"; -"sure_exit_server"="wether to exit server?"; -"sure_delete_server"="wether to delete server?"; -"serverId_notbe_empty"="Cannot be empty "; -"enter_name"="Enter Name"; -"kick_currentMember"="Wether to kick out this member?"; -"sure_delete"=" Wether to delete?"; -"current_identity"="Current Identity Group"; -"hm"="HH:mm"; -"mdhm"="MM.dd HH:mm"; -"ymdhm"="yyyy.MM.dd HH:mm"; - -//MARK:error toast -"param_error"="Parameter error"; -"no_Permession"="No permission to send message"; -"channelName_cannot_be_empty"="Cannot be empty"; -"network_error"="No internet"; -"cant_join"="Cannot join?"; -"blocked_from_server_cant_join"="You are blocked by this server and cannot join"; -"serverName_limit"="Cannot exceed 50 characters"; -"add_favorite_service"="No Server, Let's join or create one"; -"nickName_not_empty"="Cannot be empty "; -"accid_not_empty"="Cannot be empty"; diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/zh-Hans.lproj/Localizable.strings b/NEQChatUIKit/NEQChatUIKit/Assets/zh-Hans.lproj/Localizable.strings deleted file mode 100644 index 2adab88c..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Assets/zh-Hans.lproj/Localizable.strings +++ /dev/null @@ -1,168 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -//MAKR:common -"ok"="确认"; -"exceed"="超出"; -"person"="人"; -"limit"="限制"; - - -//MARK: Server -"qchat_setting"="服务器设置"; -"qchat_delete_server"="删除服务器"; -"qchat_leave_server"="退出服务器"; -"qchat_permisssion"="权限"; -"qchat_server_theme"="服务器主题"; -"qchat_server_name"="服务器名称"; -"qchat_id_group"="身份组"; -"qchat_group_default_permission"="所有服务器成员默认权限"; -"qchat_sort"="排序"; -"qchat_create_new_id_group"="创建新身份组"; -"qchat_group_name"="身份组名称"; -"qchat_manager_member"="成员管理"; -"qchat_edit"="编辑"; -"qchat_save"="保存"; -"qchat_nickname"="昵称"; -"qcaht_edit_nickname"="编辑昵称"; -"qchat_kick_out"="踢除"; -"qchat_prohibit"="封禁"; -"qchat_manager_server"="管理服务器"; -"qchat_manager_channel"="管理所有频道属性"; -"qchat_manager_role"="管理角色"; -"qchat_send_message"="发送消息"; -"qchat_delete_message"="所有频道中删除他人消息"; -"qchat_recall_message"="所有频道撤回他人消息"; -"qchat_at_any"="@任意人的权限"; -"qchat_at_all"="@所有人的权限"; -"qchat_modify_own_server"="修改自己服务器成员信息"; -"qchat_modify_other_server"="修改他人服务器成员信息"; -"qchat_invite_member"="邀请他人进入server权限"; -"qchat_kickout_member"="踢人"; -"qchat_manager_channel_list"="管理频道名单"; -"qchat_common_permission"="通用权限"; -"qchat_message_permission"="消息权限"; -"qchat_member_permission"="成员权限"; -"qchat_member"="成员"; -"qchat_id_group_sort"="身份组排序"; -"qchat_sure"="确定"; -"qchat_cancel"="取消"; -"qchat_tip"="提示"; -"qchat_select"="选择"; -"qchat_please_input_topic"="请输入主题"; -"qchat_not_empty_servername"="服务器名不能为空"; -"qchat_not_empty_header_url"="请先上传头像"; -"qchat_not_empty_select_memeber"="请选择用户"; -"qchat_please_input_role_name"="请输入身份组名称"; -"qchat_sure_delete_user"="确定删除当前用户?"; -"qchat_delete_success"="删除成功"; -"qchat_add_success"="添加成功"; -"qchat_add_Server"="创建服务器"; -"qchat_mine_add"="自己创建"; -"qchat_join_otherServer"="加入别人服务器"; - -//MARK: Channel -"create_channel"="创建新频道"; -"delete_channel"="删除频道"; -"confirm_delete_channel"="确认要移除"; - -"create"="创建"; -"cancel"="取消"; -"channel_name"="频道名称"; -"channel_topic"="频道主题"; -"channel_type"="频道类型"; -"input_channel_name"="请输入名称"; -"input_channel_topic"="请输入主题"; -"public"="公开"; -"private"="私密"; -"online"="在线"; -"offline"="离线"; -"first_channel"="频道1"; -"second_channel"="频道2"; -"more"="更多"; -"has_no_role"="暂无身份组可添加"; -"send_to"="发送给"; -"image_is_nil"= "图片为空"; - - - -//MARK:toast -"update_channel_suscess"="保存成功"; -"delete_channel_suscess"="删除成功"; -"open_soon"="暂未开放"; - -//MARK: channel_setting -"channel_setting"="频道设置"; -"save"="保存"; -"close"="关闭"; -"authority"="权限"; -"authority_setting"="权限设置"; -"list"="名单"; -"white_list"="白名单"; -"black_list"="黑名单"; -"channel_member"="频道成员"; -"delete_channel"="删除频道"; - - -"add_group"="添加身份组"; -"add_member"="添加成员"; -"member_permission_setting"="成员权限设置"; - -"finish"="完成"; -"removeMember"="移除成员"; -"removeRole"="移除身份组"; - -//MARK:身份组权限设置 -"auth1"="ManageServer"; -"auth2"="管理频道属性"; -"auth3"="管理频道权限"; -"auth4"="发送消息"; -"auth5"="ModifySelfInfo"; -"auth6"="InviteToServer"; -"auth7"="KickOthersInServer"; -"auth8"="ModifyOthersInfoInServer"; -"auth9"="频道中撤回他人消息"; -"auth10"="频道中删除他人消息"; -"auth11"="RemindOther"; -"auth12"="RemindAll"; -"auth13"="管理频道名单"; - -//supplement -"delete"="删除"; -"share_thoughts"="分享心得"; -"noMember_add"="无成员可添加"; -"search_serverId"="搜索服务器ID"; -"no_serverId"="暂无你要的服务器ID"; -"know"="知道了"; -"upload_headImage"="上传头像"; -"enter_serverName"=" 请输入服务器名称"; -"request_sended"="请求已发送"; -"message_channel"="消息频道"; -"server_nochannel"="该服务器下暂无频道"; -"applied"="已申请"; -"join"="加入"; -"modify_nickname"="请点击编辑后修改昵称"; -"sure_exit_server"="确定退出当前服务器?"; -"sure_delete_server"="确定删除当前服务器?"; -"serverId_notbe_empty"="服务器id不能为空"; -"enter_name"="输入名称"; -"kick_currentMember"="确定踢出当前成员?"; -"sure_delete"="确定删除"; -"current_identity"="当前身份组"; -"hm"="HH:mm"; -"mdhm"="MM月dd日 HH:mm"; -"ymdhm"="yyyy年MM月dd日 HH:mm"; - -//MARK:error toast -"param_error"="Parameter error"; -"no_Permession"="暂无权限在该频道发言"; -"channelName_cannot_be_empty"="频道名称不能为空"; -"network_error"="当前网络错误"; -"cant_join"="无法加入?"; -"blocked_from_server_cant_join"="你被该服务器封禁,无法加入。"; -"serverName_limit"="服务器命名不超过50个字符"; -"add_favorite_service"="暂无服务器,\n赶紧去添加心仪的服务器吧"; -"nickName_not_empty"="昵称不能为空"; -"accid_not_empty"="accid 不能为空"; diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatBaseCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatBaseCell.swift deleted file mode 100644 index 21d370da..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatBaseCell.swift +++ /dev/null @@ -1,17 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class QChatBaseCell: UITableViewCell { - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - selectionStyle = .none - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatCenterTextCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatCenterTextCell.swift deleted file mode 100644 index 7d80e99d..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatCenterTextCell.swift +++ /dev/null @@ -1,40 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class QChatCenterTextCell: QChatCornerCell { - public var titleLabel: UILabel = .init() - public var line = UIView() - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - - titleLabel.font = UIFont.systemFont(ofSize: 16) - titleLabel.translatesAutoresizingMaskIntoConstraints = false - titleLabel.textColor = .ne_redText - titleLabel.textAlignment = .center - contentView.addSubview(titleLabel) - NSLayoutConstraint.activate([ - titleLabel.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 36), - titleLabel.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -36), - titleLabel.topAnchor.constraint(equalTo: contentView.topAnchor), - titleLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor), - ]) - titleLabel.text = "title" - line.backgroundColor = .ne_greyLine - line.translatesAutoresizingMaskIntoConstraints = false - contentView.addSubview(line) - NSLayoutConstraint.activate([ - line.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 20), - line.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -20), - line.heightAnchor.constraint(equalToConstant: 1.0), - line.bottomAnchor.constraint(equalTo: contentView.bottomAnchor), - ]) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatImageTextCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatImageTextCell.swift deleted file mode 100644 index 914d115d..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatImageTextCell.swift +++ /dev/null @@ -1,89 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class QChatImageTextCell: QChatStateCell { - var circleView = UIImageView() - override public init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - // circle view - circleView.translatesAutoresizingMaskIntoConstraints = false - circleView.layer.cornerRadius = 16 - circleView.clipsToBounds = true - circleView.backgroundColor = .ne_defautAvatarColor - contentView.addSubview(circleView) - NSLayoutConstraint.activate([ - circleView.widthAnchor.constraint(equalToConstant: 36), - circleView.heightAnchor.constraint(equalToConstant: 36), - circleView.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 40), - circleView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor, constant: 0), - ]) -// short name label - contentView.addSubview(shortNameLabel) - NSLayoutConstraint.activate([ - shortNameLabel.widthAnchor.constraint(equalTo: circleView.widthAnchor), - shortNameLabel.heightAnchor.constraint(equalTo: circleView.heightAnchor), - shortNameLabel.leftAnchor.constraint(equalTo: circleView.leftAnchor), - shortNameLabel.topAnchor.constraint(equalTo: circleView.topAnchor), - ]) -// name label - contentView.addSubview(nameLabel) - NSLayoutConstraint.activate([ - nameLabel.leftAnchor.constraint(equalTo: circleView.rightAnchor, constant: 12), - nameLabel.topAnchor.constraint(equalTo: contentView.topAnchor), - nameLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor), - ]) -// line - let line = UIView() - line.backgroundColor = .ne_greyLine - line.translatesAutoresizingMaskIntoConstraints = false - contentView.addSubview(line) - NSLayoutConstraint.activate([ - line.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 20), - line.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -20), - line.heightAnchor.constraint(equalToConstant: 1), - line.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -1), - ]) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - public lazy var avatarImage: UIImageView = { - let avatar = UIImageView() - avatar.translatesAutoresizingMaskIntoConstraints = false - avatar.clipsToBounds = true - avatar.backgroundColor = .ne_defautAvatarColor - return avatar - }() - - public lazy var shortNameLabel: UILabel = { - let name = UILabel() - name.translatesAutoresizingMaskIntoConstraints = false - name.textColor = .white - name.textAlignment = .center - name.font = UIFont.systemFont(ofSize: 14.0) - return name - }() - - public lazy var nameLabel: UILabel = { - let label = UILabel() - label.textAlignment = .left - label.translatesAutoresizingMaskIntoConstraints = false - label.font = UIFont.systemFont(ofSize: 14.0) - label.textColor = .ne_darkText - return label - }() - - public func setup(accid: String?, nickName: String?) { - let name = nickName?.count ?? 0 > 0 ? nickName : accid - nameLabel.text = name - guard let n = name else { return } - shortNameLabel.text = n.count > 2 ? String(n[n.index(n.endIndex, offsetBy: -2)...]) : n - circleView.backgroundColor = UIColor.colorWithString(string: accid) - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatSectionView.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatSectionView.swift deleted file mode 100644 index 98e024d0..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatSectionView.swift +++ /dev/null @@ -1,33 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class QChatSectionView: UITableViewHeaderFooterView { - public var titleLabel = UILabel() - override init(reuseIdentifier: String?) { - super.init(reuseIdentifier: reuseIdentifier) - commonUI() - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - func commonUI() { - contentView.backgroundColor = .ne_lightBackgroundColor - titleLabel.font = UIFont.systemFont(ofSize: 12) - titleLabel.textColor = .ne_greyText - titleLabel.translatesAutoresizingMaskIntoConstraints = false - - contentView.addSubview(titleLabel) - NSLayoutConstraint.activate([ - titleLabel.leftAnchor.constraint(equalTo: leftAnchor, constant: 33), - titleLabel.topAnchor.constraint(equalTo: topAnchor, constant: 8), - titleLabel.bottomAnchor.constraint(equalTo: bottomAnchor), - titleLabel.rightAnchor.constraint(equalTo: rightAnchor, constant: -33), - ]) - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatStateCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatStateCell.swift deleted file mode 100644 index 3d2bd6fa..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatStateCell.swift +++ /dev/null @@ -1,65 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -enum RightStyle { - case none - case indicate - case delete -} - -class QChatStateCell: QChatCornerCell { - private var style: RightStyle = .none - public var rightImage = UIImageView() - var rightImageMargin: NSLayoutConstraint? - public var rightStyle: RightStyle { - get { - style - } - set { - style = newValue - switch style { - case .none: - rightImage.image = nil - case .indicate: - rightImage.image = UIImage.ne_imageNamed(name: "arrowRight") - case .delete: - rightImage.image = UIImage.ne_imageNamed(name: "delete") - } - } - } - - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - rightImage.contentMode = .center - rightImage.translatesAutoresizingMaskIntoConstraints = false - contentView.addSubview(rightImage) - rightImageMargin = rightImage.rightAnchor.constraint( - equalTo: contentView.rightAnchor, - constant: -36 - ) - rightImageMargin?.isActive = true - NSLayoutConstraint.activate([ - rightImage.widthAnchor.constraint(equalToConstant: 20), - rightImage.heightAnchor.constraint(equalToConstant: 20), - rightImage.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), - ]) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override func awakeFromNib() { - super.awakeFromNib() - // Initialization code - } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - // Configure the view for the selected state - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatTextArrowCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatTextArrowCell.swift deleted file mode 100644 index a4dcc855..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatTextArrowCell.swift +++ /dev/null @@ -1,17 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class QChatTextArrowCell: QChatTextCell { - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - rightStyle = .indicate - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatTextCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatTextCell.swift deleted file mode 100644 index baf04109..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatTextCell.swift +++ /dev/null @@ -1,68 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class QChatTextCell: QChatStateCell { - public var titleLabel: UILabel = .init() - public var detailLabel: UILabel = .init() - public var line = UIView() - - var titleLeftMargin: NSLayoutConstraint? - - var detailRightMargin: NSLayoutConstraint? - - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - - titleLabel.font = UIFont.systemFont(ofSize: 16) - titleLabel.translatesAutoresizingMaskIntoConstraints = false - titleLabel.textColor = .ne_darkText - contentView.addSubview(titleLabel) - titleLeftMargin = titleLabel.leftAnchor.constraint( - equalTo: contentView.leftAnchor, - constant: 36 - ) - titleLeftMargin?.isActive = true - NSLayoutConstraint.activate([ - // self.titleLabel.widthAnchor.constraint(lessThanOrEqualToConstant: 120), - titleLabel.topAnchor.constraint(equalTo: contentView.topAnchor), - titleLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor), - ]) - titleLabel.text = localizable("delete") - - detailLabel.font = UIFont.systemFont(ofSize: 16) - detailLabel.translatesAutoresizingMaskIntoConstraints = false - detailLabel.textColor = .ne_lightText - contentView.addSubview(detailLabel) - - detailRightMargin = detailLabel.rightAnchor.constraint( - equalTo: contentView.rightAnchor, - constant: -60 - ) - detailRightMargin?.isActive = true - NSLayoutConstraint.activate([ - detailLabel.leftAnchor.constraint(equalTo: titleLabel.rightAnchor, constant: 0), - detailLabel.widthAnchor.constraint(lessThanOrEqualToConstant: 40), - detailLabel.topAnchor.constraint(equalTo: contentView.topAnchor), - detailLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor), - ]) - detailLabel.textAlignment = .right - - line.backgroundColor = .ne_greyLine - line.translatesAutoresizingMaskIntoConstraints = false - contentView.addSubview(line) - NSLayoutConstraint.activate([ - line.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 20), - line.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -20), - line.heightAnchor.constraint(equalToConstant: 1.0), - line.bottomAnchor.constraint(equalTo: contentView.bottomAnchor), - ]) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatUnfoldCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatUnfoldCell.swift deleted file mode 100644 index 39eed2b4..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatUnfoldCell.swift +++ /dev/null @@ -1,65 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class QChatUnfoldCell: QChatCornerCell { - lazy var arrowImage: UIImageView = { - let arrow = UIImageView() - arrow.translatesAutoresizingMaskIntoConstraints = false - arrow.image = UIImage.ne_imageNamed(name: "arrowDown") - return arrow - }() - - lazy var contentLabel: UILabel = { - let label = UILabel() - label.translatesAutoresizingMaskIntoConstraints = false - label.textColor = .ne_greyText - label.font = DefaultTextFont(14) - return label - }() - - override func awakeFromNib() { - super.awakeFromNib() - // Initialization code - } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - - // Configure the view for the selected state - } - - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - setupUI() - } - - required init?(coder: NSCoder) { - super.init(coder: coder) - } - - func setupUI() { - contentView.addSubview(contentLabel) - NSLayoutConstraint.activate([ - contentLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), - contentLabel.centerXAnchor.constraint(equalTo: contentView.centerXAnchor), - ]) - - contentView.addSubview(arrowImage) - NSLayoutConstraint.activate([ - arrowImage.leftAnchor.constraint(equalTo: contentLabel.rightAnchor, constant: 5), - arrowImage.centerYAnchor.constraint(equalTo: contentLabel.centerYAnchor), - ]) - } - - func changeToArrowUp() { - arrowImage.image = UIImage.ne_imageNamed(name: "arrowUp") - } - - func changeToArrowDown() { - arrowImage.image = UIImage.ne_imageNamed(name: "arrowDown") - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseViewController/QChatBaseViewController.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseViewController/QChatBaseViewController.swift deleted file mode 100644 index 5001c10a..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseViewController/QChatBaseViewController.swift +++ /dev/null @@ -1,25 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NECoreKit - -class QChatBaseViewController: NEBaseViewController { - override func viewDidLoad() { - super.viewDidLoad() - - // Do any additional setup after loading the view. - } - - /* - // MARK: - Navigation - - // In a storyboard-based application, you will often want to do a little preparation before navigation - override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - // Get the new view controller using segue.destination. - // Pass the selected object to the new view controller. - } - */ -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseViewController/QChatNavigationController.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseViewController/QChatNavigationController.swift deleted file mode 100644 index 53418ac4..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseViewController/QChatNavigationController.swift +++ /dev/null @@ -1,22 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -public class QChatNavigationController: UINavigationController { - override public func viewDidLoad() { - super.viewDidLoad() - } - - override public func pushViewController(_ viewController: UIViewController, animated: Bool) { - if children.count > 0 { - viewController.hidesBottomBarWhenPushed = true - if children.count > 1 { - viewController.hidesBottomBarWhenPushed = false - } - } - super.pushViewController(viewController, animated: true) - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseViewController/QChatTableViewController.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseViewController/QChatTableViewController.swift deleted file mode 100644 index 3d019589..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseViewController/QChatTableViewController.swift +++ /dev/null @@ -1,67 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NECoreKit - -public class QChatTableViewController: NEBaseViewController, UITableViewDelegate, - UITableViewDataSource { - public var tableView: UITableView = .init(frame: .zero, style: .grouped) - public var topConstraint: NSLayoutConstraint? - public var bottomConstraint: NSLayoutConstraint? - - override public func viewDidLoad() { - super.viewDidLoad() - tableView.separatorStyle = .none - tableView.delegate = self - tableView.dataSource = self - tableView.translatesAutoresizingMaskIntoConstraints = false - view.addSubview(tableView) - NSLayoutConstraint.activate([ - tableView.leftAnchor.constraint(equalTo: view.leftAnchor), - tableView.rightAnchor.constraint(equalTo: view.rightAnchor), - ]) - - if #available(iOS 11.0, *) { - self.topConstraint = self.tableView.topAnchor.constraint( - equalTo: self.view.safeAreaLayoutGuide.topAnchor, - constant: 0 - ) - self.bottomConstraint = self.tableView.bottomAnchor - .constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor) - - } else { - // Fallback on earlier versions - topConstraint = tableView.topAnchor.constraint(equalTo: view.topAnchor) - bottomConstraint = tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor) - } - topConstraint?.isActive = true - bottomConstraint?.isActive = true - - tableView.sectionHeaderHeight = 38 - tableView.sectionFooterHeight = 0 - tableView.rowHeight = 62 - tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: 0.1)) - } - - public func tableView(_ tableView: UITableView, - cellForRowAt indexPath: IndexPath) -> UITableViewCell { - tableView.dequeueReusableCell(withIdentifier: "UITableViewCell", for: indexPath) - } - - public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - 0 - } - - /* - // MARK: - Navigation - - // In a storyboard-based application, you will often want to do a little preparation before navigation - override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - // Get the new view controller using segue.destination. - // Pass the selected object to the new view controller. - } - */ -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/Model/QChatRoles.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Channel/Model/QChatRoles.swift deleted file mode 100644 index e248e2d1..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/Model/QChatRoles.swift +++ /dev/null @@ -1,28 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -import NECoreIMKit - -public enum RoundedType { - case none - case top - case bottom - case all -} - -public struct RoleModel { - public var role: ChannelRole? - public var member: MemberRole? - public var title: String? - public var corner: RoundedType? - public var isPlacehold: Bool = false -} - -public struct QChatRoles { - public var roles: [RoleModel] = .init() - public var timeTag: TimeInterval? - public var pageSize: Int = 5 -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/Model/RoleStatusInfoExt.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Channel/Model/RoleStatusInfoExt.swift deleted file mode 100644 index 024e7bc6..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/Model/RoleStatusInfoExt.swift +++ /dev/null @@ -1,16 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -import NECoreIMKit - -public struct RoleStatusInfoExt { - public var status: RoleStatusInfo? - public var title: String? - - public init(status: RoleStatusInfo?) { - self.status = status - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/ChannelHeaderView.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/ChannelHeaderView.swift deleted file mode 100644 index a9a39a57..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/ChannelHeaderView.swift +++ /dev/null @@ -1,66 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class ChannelHeaderView: UIView { - var titleLabel = UILabel() - var detailLabel = UILabel() - var settingButton = UIButton() - private var prefixLabel = UILabel() - - override init(frame: CGRect) { - super.init(frame: frame) - prefixLabel.font = .systemFont(ofSize: 16) - prefixLabel.textColor = .ne_lightText - prefixLabel.text = "#" - prefixLabel.translatesAutoresizingMaskIntoConstraints = false - addSubview(prefixLabel) - NSLayoutConstraint.activate([ - prefixLabel.topAnchor.constraint(equalTo: topAnchor, constant: 20), - prefixLabel.leftAnchor.constraint(equalTo: leftAnchor, constant: 20), - prefixLabel.widthAnchor.constraint(equalToConstant: 20), - prefixLabel.heightAnchor.constraint(equalToConstant: 26), - ]) - - titleLabel.font = .systemFont(ofSize: 18) - titleLabel.textColor = .ne_darkText - titleLabel.text = localizable("first_channel") - titleLabel.translatesAutoresizingMaskIntoConstraints = false - addSubview(titleLabel) - NSLayoutConstraint.activate([ - titleLabel.topAnchor.constraint(equalTo: topAnchor, constant: 20), - titleLabel.leftAnchor.constraint(equalTo: prefixLabel.rightAnchor, constant: 0), - titleLabel.rightAnchor.constraint(equalTo: rightAnchor, constant: -81), - titleLabel.heightAnchor.constraint(equalToConstant: 26), - ]) - - detailLabel.textColor = .ne_greyText - detailLabel.font = .systemFont(ofSize: 14) - detailLabel.text = localizable("share_thoughts") - detailLabel.translatesAutoresizingMaskIntoConstraints = false - addSubview(detailLabel) - NSLayoutConstraint.activate([ - detailLabel.leftAnchor.constraint(equalTo: prefixLabel.leftAnchor), - detailLabel.topAnchor.constraint(equalTo: prefixLabel.bottomAnchor, constant: 0), - detailLabel.heightAnchor.constraint(equalToConstant: 20), - detailLabel.rightAnchor.constraint(equalTo: titleLabel.rightAnchor), - ]) - - settingButton.setImage(UIImage.ne_imageNamed(name: "Setting"), for: .normal) - settingButton.translatesAutoresizingMaskIntoConstraints = false - addSubview(settingButton) - NSLayoutConstraint.activate([ - settingButton.topAnchor.constraint(equalTo: topAnchor, constant: 10), - settingButton.rightAnchor.constraint(equalTo: rightAnchor, constant: -16), - settingButton.widthAnchor.constraint(equalToConstant: 40), - settingButton.heightAnchor.constraint(equalToConstant: 32), - ]) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/CornerButton.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/CornerButton.swift deleted file mode 100644 index 7dc01feb..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/CornerButton.swift +++ /dev/null @@ -1,123 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class CornerButton: UIButton { - var cornerLayer = CAShapeLayer() - override var isSelected: Bool { - get { - super.isSelected - } - set { - cornerLayer.fillColor = newValue ? selectedColor.cgColor : color.cgColor - super.isSelected = newValue - } - } - - override var isUserInteractionEnabled: Bool { - get { - super.isUserInteractionEnabled - } - set { - super.isUserInteractionEnabled = newValue - alpha = newValue ? 1.0 : 0.5 - } - } - -// public var ne_selected: Bool { -// get { -// return self.isSelected -// } -// set { -// if newValue { - //// cornerLayer.fillColor = UIColor.purple.cgColor -// }else { - //// cornerLayer.fillColor = color.cgColor -// } -// self.isSelected = newValue -// } -// } - -// public var fillColor: UIColor = .white - public var color: UIColor = .white - public var selectedColor: UIColor = .white - private var type: CornerType = .none - public var edgeInset: UIEdgeInsets = .init(top: 0, left: 0, bottom: 0, right: 0) - public var cornerType: CornerType { - get { type } - set { - if type != newValue { - type = newValue - sizeToFit() - } - } - } - - override init(frame: CGRect) { - super.init(frame: frame) - translatesAutoresizingMaskIntoConstraints = false - clipsToBounds = true - cornerLayer.fillColor = color.cgColor - cornerLayer.strokeColor = UIColor.ne_borderColor.cgColor -// self.backgroundColor = .ne_lightBackgroundColor - layer.insertSublayer(cornerLayer, below: imageView?.layer) - } - - required init?(coder: NSCoder) { - super.init(coder: coder) - } - - override func layoutSublayers(of layer: CALayer) { - super.layoutSublayers(of: layer) - drawRoundedCorner(rect: bounds) - - print(#function) - } - -// public override func draw(_ rect: CGRect) { -// drawRoundedCorner(rect: rect) -// } - - public func drawRoundedCorner(rect: CGRect) { - var path = UIBezierPath() - let roundRect = CGRect( - x: rect.origin.x + edgeInset.left, - y: rect.origin.y + edgeInset.top, - width: rect.width - (edgeInset.left + edgeInset.right), - height: rect.height - (edgeInset.top + edgeInset.bottom) - ) - if type == .none { - path = UIBezierPath(rect: roundRect) - } - var corners = UIRectCorner() - if type.contains(CornerType.topLeft) { - corners = corners.union(.topLeft) - } - if type.contains(CornerType.topRight) { - corners = corners.union(.topRight) - } - if type.contains(CornerType.bottomLeft) { - corners = corners.union(.bottomLeft) - } - if type.contains(CornerType.bottomRight) { - corners = corners.union(.bottomRight) - } - - path = UIBezierPath( - roundedRect: roundRect, - byRoundingCorners: corners, - cornerRadii: CGSize(width: 10, height: 10) - ) - cornerLayer.path = path.cgPath -// cornerLayer.fillColor = self.isSelected ? selectedColor.cgColor : color.cgColor -// cornerLayer.strokeColor = UIColor.ne_borderColor.cgColor - } - -// @objc -// private func didSelect(sender: AnyObject) { -// self.isSelected = !self.isSelected -// } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/QChatImageTextOnlineCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/QChatImageTextOnlineCell.swift deleted file mode 100644 index 2b53f906..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/QChatImageTextOnlineCell.swift +++ /dev/null @@ -1,41 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class QChatImageTextOnlineCell: QChatImageTextCell { - var online: Bool { - get { - onlineView.isHidden - } - set { - onlineView.isHidden = !newValue - alpha = newValue ? 1.0 : 0.5 - } - } - - private var onlineView = UIView() - - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - onlineView.backgroundColor = .ne_greenColor - onlineView.layer.borderColor = UIColor.white.cgColor - onlineView.layer.borderWidth = 2 - onlineView.clipsToBounds = true - onlineView.layer.cornerRadius = 6 - onlineView.translatesAutoresizingMaskIntoConstraints = false - contentView.addSubview(onlineView) - NSLayoutConstraint.activate([ - onlineView.centerXAnchor.constraint(equalTo: circleView.centerXAnchor, constant: 16), - onlineView.centerYAnchor.constraint(equalTo: circleView.centerYAnchor, constant: 16), - onlineView.widthAnchor.constraint(equalToConstant: 12), - onlineView.heightAnchor.constraint(equalToConstant: 12), - ]) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/QChatMemberInfoView.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/QChatMemberInfoView.swift deleted file mode 100644 index ed985d70..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/QChatMemberInfoView.swift +++ /dev/null @@ -1,319 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -protocol QChatMemberInfoViewDelegate: AnyObject { - func didClickUserHeader(_ accid: String?) -} - -class QChatMemberInfoView: UIView { - var contentView: UIView = .init() - public var avatar = UIImageView() - public var shortName = UILabel() - public var name = UILabel() - public var groupView = UIView() - -// private var onlineView = UIView() - private var originY: CGFloat = 0 - private var originMaxY: CGFloat = 0 - private var topConstaint: NSLayoutConstraint = .init() -// var online:Bool { -// get { -// return onlineView.backgroundColor == .ne_greenColor -// } -// set { -// onlineView.backgroundColor = newValue ? .ne_greenColor : .ne_greyText -// } -// } - - public var labelsWidth: CGFloat = 0 - public var maxWidth: CGFloat = kScreenWidth - 2 * kScreenInterval - public var labelMargin: CGFloat = 6 - public var labelHeight: CGFloat = 25 - public var isFirstRow = true - public weak var delegate: QChatMemberInfoViewDelegate? - - public var accid: String? - - init(inView: UIView) { - super.init(frame: inView.bounds) - translatesAutoresizingMaskIntoConstraints = false - backgroundColor = UIColor(white: 0, alpha: 0.4) - inView.addSubview(self) - NSLayoutConstraint.activate([ - topAnchor.constraint(equalTo: inView.topAnchor), - leftAnchor.constraint(equalTo: inView.leftAnchor), - rightAnchor.constraint(equalTo: inView.rightAnchor), - bottomAnchor.constraint(equalTo: inView.bottomAnchor), - ]) - commonUI() - addPanGesture() - originMaxY = inView.frame.size.height - 360 - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - func commonUI() { - addSubview(contentView) - contentView.translatesAutoresizingMaskIntoConstraints = false - topConstaint = contentView.topAnchor.constraint(equalTo: bottomAnchor, constant: 0) -// topConstaint = contentView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 360) - NSLayoutConstraint.activate([ - topConstaint, - contentView.leftAnchor.constraint(equalTo: leftAnchor), - contentView.rightAnchor.constraint(equalTo: rightAnchor), - contentView.heightAnchor.constraint(equalToConstant: 360), - ]) - - let indicatorView = UIView() - indicatorView.translatesAutoresizingMaskIntoConstraints = false - indicatorView.backgroundColor = .white - indicatorView.layer.cornerRadius = 4 - contentView.addSubview(indicatorView) - NSLayoutConstraint.activate([ - indicatorView.topAnchor.constraint(equalTo: contentView.topAnchor), - indicatorView.centerXAnchor.constraint(equalTo: contentView.centerXAnchor), - indicatorView.widthAnchor.constraint(equalToConstant: 41), - indicatorView.heightAnchor.constraint(equalToConstant: 4), - ]) - - let imageView = UIImageView(image: UIImage.ne_imageNamed(name: "bgImage")) - imageView.translatesAutoresizingMaskIntoConstraints = false - imageView.layer.cornerRadius = 10 - imageView.clipsToBounds = true - contentView.addSubview(imageView) - NSLayoutConstraint.activate([ - imageView.topAnchor.constraint(equalTo: indicatorView.bottomAnchor, constant: 5), - imageView.leftAnchor.constraint(equalTo: contentView.leftAnchor), - imageView.rightAnchor.constraint(equalTo: contentView.rightAnchor), - imageView.heightAnchor.constraint(equalToConstant: 70), - ]) - let whiteBgView = UIView() - whiteBgView.backgroundColor = .white - whiteBgView.translatesAutoresizingMaskIntoConstraints = false - contentView.addSubview(whiteBgView) - NSLayoutConstraint.activate([ - whiteBgView.topAnchor.constraint(equalTo: imageView.bottomAnchor, constant: -5), - whiteBgView.leftAnchor.constraint(equalTo: contentView.leftAnchor), - whiteBgView.rightAnchor.constraint(equalTo: contentView.rightAnchor), - whiteBgView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor), - ]) - - avatar.translatesAutoresizingMaskIntoConstraints = false - avatar.backgroundColor = .ne_defautAvatarColor - avatar.layer.borderWidth = 2 - avatar.layer.borderColor = UIColor.white.cgColor - avatar.layer.cornerRadius = 30 - avatar.clipsToBounds = true - contentView.addSubview(avatar) - NSLayoutConstraint.activate([ - avatar.topAnchor.constraint(equalTo: indicatorView.bottomAnchor, constant: 50), - avatar.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 20), - avatar.heightAnchor.constraint(equalToConstant: 60), - avatar.widthAnchor.constraint(equalToConstant: 60), - ]) - avatar.isUserInteractionEnabled = true - let tap = UITapGestureRecognizer() - tap.numberOfTapsRequired = 1 - tap.numberOfTouchesRequired = 1 - avatar.addGestureRecognizer(tap) - tap.addTarget(self, action: #selector(headerClick)) - -// onlineView.translatesAutoresizingMaskIntoConstraints = false -// onlineView.backgroundColor = .ne_greenColor -// onlineView.layer.borderWidth = 2 -// onlineView.layer.borderColor = UIColor.white.cgColor -// onlineView.layer.cornerRadius = 7 -// onlineView.clipsToBounds = true -// contentView.addSubview(onlineView) -// NSLayoutConstraint.activate([ -// onlineView.centerXAnchor.constraint(equalTo: avatar.centerXAnchor, constant: 23), -// onlineView.centerYAnchor.constraint(equalTo: avatar.centerYAnchor, constant: 23), -// onlineView.heightAnchor.constraint(equalToConstant: 14), -// onlineView.widthAnchor.constraint(equalToConstant: 14) -// ]) - - shortName.translatesAutoresizingMaskIntoConstraints = false - shortName.font = .systemFont(ofSize: 22) - shortName.textColor = .white - shortName.textAlignment = .center - contentView.addSubview(shortName) - NSLayoutConstraint.activate([ - shortName.topAnchor.constraint(equalTo: avatar.topAnchor), - shortName.leftAnchor.constraint(equalTo: avatar.leftAnchor), - shortName.rightAnchor.constraint(equalTo: avatar.rightAnchor), - shortName.bottomAnchor.constraint(equalTo: avatar.bottomAnchor), - ]) - - name.translatesAutoresizingMaskIntoConstraints = false - name.font = .boldSystemFont(ofSize: 24) - name.textColor = .ne_darkText - contentView.addSubview(name) - NSLayoutConstraint.activate([ - name.topAnchor.constraint(equalTo: avatar.bottomAnchor, constant: 14), - name.leftAnchor.constraint(equalTo: avatar.leftAnchor), - name.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -20), - name.heightAnchor.constraint(equalToConstant: 30), - ]) - - let groupName = UILabel() - groupName.translatesAutoresizingMaskIntoConstraints = false - groupName.font = .systemFont(ofSize: 14) - groupName.text = localizable("qchat_id_group") - groupName.textColor = .ne_darkText - contentView.addSubview(groupName) - NSLayoutConstraint.activate([ - groupName.topAnchor.constraint(equalTo: name.bottomAnchor, constant: 30), - groupName.leftAnchor.constraint(equalTo: name.leftAnchor), - groupName.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -20), - groupName.heightAnchor.constraint(equalToConstant: 20), - ]) - - let line = UIView() - line.translatesAutoresizingMaskIntoConstraints = false - line.backgroundColor = .ne_greyLine - contentView.addSubview(line) - NSLayoutConstraint.activate([ - line.topAnchor.constraint(equalTo: groupName.bottomAnchor, constant: 8), - line.leftAnchor.constraint(equalTo: name.leftAnchor), - line.rightAnchor.constraint(equalTo: name.rightAnchor), - line.heightAnchor.constraint(equalToConstant: 1), - ]) - - groupView.translatesAutoresizingMaskIntoConstraints = false - groupView.backgroundColor = .white - contentView.addSubview(groupView) - NSLayoutConstraint.activate([ - groupView.topAnchor.constraint(equalTo: line.bottomAnchor, constant: 2), - groupView.leftAnchor.constraint(equalTo: name.leftAnchor), - groupView.rightAnchor.constraint(equalTo: name.rightAnchor), - groupView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor), - ]) - } - - public func setupRoles(dataArray: [String]) { - for i in 0 ..< dataArray.count { - let label = IDGroupLabel(content: dataArray[i]) - label.textInsets = UIEdgeInsets(top: 4, left: 8, bottom: 4, right: 8) - label.translatesAutoresizingMaskIntoConstraints = false - groupView.addSubview(label) - let labelSize = label.sizeThatFits(CGSize(width: maxWidth, height: labelHeight)) - - // 剩余宽度是否满足,下一个label的宽度,如不满足则换行 - if (maxWidth - labelsWidth) >= labelSize.width, isFirstRow { - NSLayoutConstraint.activate([ - i == 0 ? label.leftAnchor.constraint( - equalTo: groupView.leftAnchor, - constant: kScreenInterval - ) : label.leftAnchor.constraint( - equalTo: groupView.leftAnchor, - constant: kScreenInterval + labelsWidth - ), - label.topAnchor.constraint(equalTo: groupView.topAnchor, constant: 8), - label.widthAnchor.constraint(equalToConstant: labelSize.width), - label.heightAnchor.constraint(equalToConstant: labelSize.height), - ]) - } else { - // 换行重置,labels总宽度 - if isFirstRow { - labelsWidth = kScreenInterval - } - isFirstRow = false - NSLayoutConstraint.activate([ - label.leftAnchor.constraint( - equalTo: groupView.leftAnchor, - constant: labelsWidth - ), - label.topAnchor.constraint( - equalTo: groupView.topAnchor, - constant: 8 + labelHeight + labelMargin - ), - label.widthAnchor.constraint(equalToConstant: labelSize.width), - label.heightAnchor.constraint(equalToConstant: labelSize.height), - ]) - } - -// if i == dataArray.count - 1 { -// NSLayoutConstraint.activate([ -// label.bottomAnchor.constraint(equalTo: groupView.bottomAnchor) -// ]) -// } - labelsWidth += (labelSize.width + labelMargin) - } - } - - func addPanGesture() { - addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(pan))) - addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(tap))) - } - - @objc func tap(pan: UIPanGestureRecognizer) { - dismiss() - } - - @objc func pan(pan: UIPanGestureRecognizer) { - let position = pan.translation(in: superview) - let velocity = pan.velocity(in: superview) - print("velocity:\(velocity) position:\(position)") - switch pan.state { - case .began: - print("start pan") - originY = contentView.frame.origin.y - - case .changed: - if (originY + position.y) > originMaxY { - contentView.frame.origin.y = originY + position.y - } - - case .ended: - print("ended pan") - if velocity.y > 600 || contentView.frame.origin.y > originMaxY + 160 { - dismiss() - } - - default: - print("default pan") - } - } - - func present() { - DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { - self.topConstaint.constant = -360 - UIView.animate(withDuration: 0.3) { - self.layoutIfNeeded() - } completion: { result in - } - } - } - - func dismiss() { - if superview == nil { - return - } - topConstaint.constant = 0 - UIView.animate(withDuration: 0.3) { - self.layoutIfNeeded() - } completion: { result in - self.removeFromSuperview() - } - } - - public func setup(accid: String?, nickName: String?) { - let name = nickName?.count ?? 0 > 0 ? nickName : accid - self.name.text = name - self.accid = accid - guard let n = name else { return } - shortName.text = n.count > 2 ? String(n[n.index(n.endIndex, offsetBy: -2)...]) : n - avatar.backgroundColor = UIColor.colorWithString(string: accid) - } - - @objc func headerClick() { - delegate?.didClickUserHeader(accid) - removeFromSuperview() - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/QChatPermissionSettingCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/QChatPermissionSettingCell.swift deleted file mode 100644 index b5951b47..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/QChatPermissionSettingCell.swift +++ /dev/null @@ -1,148 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NECoreIMKit - -protocol QChatPermissionSettingCellDelegate: AnyObject { - func didSelected(cell: QChatPermissionSettingCell?, model: RoleStatusInfo?) -} - -class QChatPermissionSettingCell: QChatCornerCell { - public weak var delegate: QChatPermissionSettingCellDelegate? - private var model: RoleStatusInfoExt? - private var button: UIButton? - private var titleLabel = UILabel() - private var enable: Bool { - get { - (buttons.first?.isUserInteractionEnabled) != nil - } - set { - for button in buttons { - button.isUserInteractionEnabled = newValue - } - } - } - - private var index: Int { - get { - selectedIndex - } - set { - selectedIndex = newValue - button = buttons[selectedIndex] - button?.isSelected = true - } - } - - private var selectedIndex = -1 - private var buttons = [CornerButton]() - - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - titleLabel.font = UIFont.systemFont(ofSize: 16) - titleLabel.translatesAutoresizingMaskIntoConstraints = false - titleLabel.textColor = .ne_darkText - titleLabel.text = localizable("delete") - contentView.addSubview(titleLabel) - NSLayoutConstraint.activate([ - titleLabel.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 35), - titleLabel.topAnchor.constraint(equalTo: contentView.topAnchor), - titleLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor), - ]) - - let denyButton = CornerButton(frame: .zero) - denyButton.color = .white - denyButton.selectedColor = UIColor.red - denyButton.tag = 0 + 10 - denyButton.setImage(UIImage.ne_imageNamed(name: "deny"), for: .normal) - denyButton.setImage(UIImage.ne_imageNamed(name: "denySelected"), for: .selected) - denyButton.addTarget(self, action: #selector(buttonEvent), for: .touchUpInside) - denyButton.cornerType = CornerType.topLeft.union(CornerType.bottomLeft) - buttons.append(denyButton) - - let midButton = CornerButton(frame: .zero) - midButton.tag = 1 + 10 - midButton.color = .white - midButton.selectedColor = UIColor.ne_borderColor - midButton.setImage(UIImage.ne_imageNamed(name: "extend"), for: .normal) - midButton.setImage(UIImage.ne_imageNamed(name: "extendSelected"), for: .selected) - midButton.addTarget(self, action: #selector(buttonEvent), for: .touchUpInside) - buttons.append(midButton) - - let allowButton = CornerButton(frame: .zero) - allowButton.tag = 2 + 10 - allowButton.color = .white - allowButton.selectedColor = UIColor.ne_greenColor - allowButton.setImage(UIImage.ne_imageNamed(name: "allow"), for: .normal) - allowButton.setImage(UIImage.ne_imageNamed(name: "allowSeleted"), for: .selected) - allowButton.cornerType = CornerType.topRight.union(CornerType.bottomRight) - allowButton.addTarget(self, action: #selector(buttonEvent), for: .touchUpInside) - buttons.append(allowButton) - - contentView.addSubview(allowButton) - NSLayoutConstraint.activate([ - allowButton.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -35), - allowButton.widthAnchor.constraint(equalToConstant: 32), - allowButton.heightAnchor.constraint(equalToConstant: 26), - allowButton.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), - ]) - - contentView.addSubview(midButton) - NSLayoutConstraint.activate([ - midButton.rightAnchor.constraint(equalTo: allowButton.leftAnchor, constant: 0), - midButton.widthAnchor.constraint(equalToConstant: 32), - midButton.heightAnchor.constraint(equalToConstant: 26), - midButton.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), - ]) - - contentView.addSubview(denyButton) - NSLayoutConstraint.activate([ - denyButton.rightAnchor.constraint(equalTo: midButton.leftAnchor, constant: 0), - denyButton.widthAnchor.constraint(equalToConstant: 32), - denyButton.heightAnchor.constraint(equalToConstant: 26), - denyButton.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), - denyButton.leftAnchor.constraint(equalTo: titleLabel.rightAnchor), - ]) - } - - public func updateModel(model: RoleStatusInfoExt?) { - self.model = model - titleLabel.text = model?.title - index = (model?.status?.status.rawValue ?? 0) + 1 - } - - @objc func buttonEvent(sender: CornerButton) { - if sender.tag - 10 == selectedIndex { - return - } - selectedIndex = sender.tag - 10 - if let type = model?.status?.type { - let update = RoleStatusInfo( - type: type, - status: status(rawValue: selectedIndex - 1) ?? .Extend - ) - delegate?.didSelected(cell: self, model: update) - } - } - - public func selectedSuccess(success: Bool) { - if success { - if let button = button { - button.isSelected = !button.isSelected - } - if selectedIndex >= 0, selectedIndex < buttons.count { - let new = buttons[selectedIndex] - new.isSelected = !new.isSelected - button = new - } - model?.status?.status = status(rawValue: selectedIndex - 1) ?? .Extend - } - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/QChatTextEditCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/QChatTextEditCell.swift deleted file mode 100644 index 341ae5a0..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/QChatTextEditCell.swift +++ /dev/null @@ -1,86 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -@objc protocol QChatTextEditCellDelegate: AnyObject { -// @objc optional func textFieldDidChangeSelection(cell: QChatTextEditCell, -// _ textField: UITextField) - @objc optional func textDidChange(_ textField: UITextField) -} - -class QChatTextEditCell: QChatCornerCell, UITextFieldDelegate { - var limit: Int? - var canEdit = true - var editTotast = "" - public var textFied = UITextField() - public weak var delegate: QChatTextEditCellDelegate? - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - textFied.textColor = .ne_darkText - textFied.font = UIFont.systemFont(ofSize: 16) - textFied.clearButtonMode = .whileEditing - textFied.translatesAutoresizingMaskIntoConstraints = false - NotificationCenter.default.addObserver( - self, - selector: #selector(textFieldDidChangeValue(_:)), - name: UITextField.textDidChangeNotification, - object: textFied - ) - contentView.addSubview(textFied) - NSLayoutConstraint.activate([ - textFied.leftAnchor.constraint(equalTo: leftAnchor, constant: 36), - textFied.topAnchor.constraint(equalTo: topAnchor), - textFied.bottomAnchor.constraint(equalTo: bottomAnchor), - textFied.rightAnchor.constraint(equalTo: rightAnchor, constant: -36), - ]) - textFied.delegate = self - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - // MAKR: UITextFieldDelegate - func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, - replacementString string: String) -> Bool { - if let l = limit { - let text = "\(textField.text ?? "")\(string)" - if text.count > l { - return false - } - } - return true - } - - func textFieldShouldEndEditing(_ textField: UITextField) -> Bool { - print("1 textFieldShouldEndEditing") - return true - } - - func textFieldDidEndEditing(_ textField: UITextField) { - print("2 textFieldDidEndEditing") - } - - func textFieldDidChangeSelection(_ textField: UITextField) { - print("3 textFieldDidChangeSelection:\(textField.text)") -// if let d = delegate { -// d.textFieldDidChangeSelection?(cell: self, textField) -// } - } - - func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool { - if canEdit == false, editTotast.count > 0 { - UIApplication.shared.keyWindow?.makeToast(editTotast) - } - return canEdit - } - - @objc func textFieldDidChangeValue(_ noti: Notification) { - if let d = delegate, let text = noti.object as? UITextField { - d.textDidChange?(text) - } - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/QChatTextSelectionCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/QChatTextSelectionCell.swift deleted file mode 100644 index 5b1ab2cc..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/View/QChatTextSelectionCell.swift +++ /dev/null @@ -1,43 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class QChatTextSelectionCell: QChatTextCell { - var selectedImageView = UIImageView(image: UIImage.ne_imageNamed(name: "selection")) - - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - selectedImageView.contentMode = .center - selectedImageView.translatesAutoresizingMaskIntoConstraints = false - selectedImageView.image = UIImage.ne_imageNamed(name: "Selection") - contentView.addSubview(selectedImageView) - NSLayoutConstraint.activate([ - selectedImageView.rightAnchor.constraint( - equalTo: contentView.rightAnchor, - constant: -36 - ), - selectedImageView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 0), - selectedImageView.bottomAnchor.constraint( - equalTo: contentView.bottomAnchor, - constant: 0 - ), - selectedImageView.widthAnchor.constraint(equalToConstant: 15), - ]) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - public func selected(selected: Bool) { - selectedImageView.isHidden = !selected - } - -// override func setSelected(_ selected: Bool, animated: Bool) { -// super.setSelected(selected, animated: animated) -// selectedImageView.isHidden = !selected -// } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatAddMemberVC.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatAddMemberVC.swift deleted file mode 100644 index 7bacebba..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatAddMemberVC.swift +++ /dev/null @@ -1,233 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NECoreIMKit -import CoreAudio -import MJRefresh - -typealias AddMemberRoleBlock = (_ memberRole: MemberRole?) -> Void -public class QChatAddMemberVC: QChatSearchVC { - public var channel: ChatChannel? - private var serverMembers: [ServerMemeber]? - private var channelMembers: [ServerMemeber]? - private var lastTimeTag: Double? -// public var didAddMemberRole: AddMemberRoleBlock? - - public init(channel: ChatChannel?) { - super.init(nibName: nil, bundle: nil) - self.channel = channel - } - - required init?(coder: NSCoder) { - super.init(coder: coder) - } - - override public func viewDidLoad() { - super.viewDidLoad() - title = localizable("add_member") - tableView.register( - QChatImageTextCell.self, - forCellReuseIdentifier: "\(QChatImageTextCell.self)" - ) - tableView.rowHeight = 60 - tableView.mj_header = MJRefreshNormalHeader( - refreshingTarget: self, - refreshingAction: #selector(loadData) - ) - tableView.mj_footer = MJRefreshBackNormalFooter( - refreshingTarget: self, - refreshingAction: #selector(loadMore) - ) - loadData() - } - - @objc func loadData() { - lastTimeTag = 0 - var param = GetServerMembersByPageParam() - param.serverId = channel?.serverId - param.limit = 50 - param.timeTag = lastTimeTag - QChatServerProvider.shared.getServerMembers(param) { [weak self] error, sMembers in - print("sMembers:\(sMembers) error:\(error)") - if error != nil { - self?.view.makeToast(error?.localizedDescription) - self?.emptyView.isHidden = false - - } else { - if !sMembers.isEmpty { - self?.lastTimeTag = sMembers.last?.createTime -// var filteredMemberArray = sMembers - if let sid = self?.channel?.serverId, let cid = self?.channel?.channelId { - // 过滤掉已经存在在channel中的成员 - var ids = [String]() - for member in sMembers { - if let id = member.accid { - ids.append(id) - } - } - let param = GetExistingAccidsOfMemberRolesParam( - serverId: sid, - channelId: cid, - accids: ids - ) - QChatRoleProvider.shared - .getExistingMemberRoles(param: param) { error, existMemberArray in - var filterMembers = [ServerMemeber]() - if let existMembers = existMemberArray, !existMembers.isEmpty { - for m in sMembers { - if existMembers.contains(where: { existMember in - m.accid == existMember.accid - }) { - } else { - filterMembers.append(m) - } - } - self?.serverMembers = filterMembers - self?.emptyView.isHidden = !filterMembers.isEmpty - - } else { - self?.serverMembers = sMembers - self?.emptyView.isHidden = !sMembers.isEmpty - } - self?.tableView.mj_footer?.resetNoMoreData() - self?.tableView.mj_header?.endRefreshing() - self?.tableView.reloadData() - } - } else { - self?.emptyView.isHidden = !sMembers.isEmpty - self?.serverMembers = sMembers - self?.tableView.mj_footer?.resetNoMoreData() - self?.tableView.mj_header?.endRefreshing() - self?.tableView.reloadData() - } - } else { - // 空白页 - self?.emptyView.isHidden = false - } - } - } - } - - @objc func loadMore() { - var param = GetServerMembersByPageParam() - param.serverId = channel?.serverId - param.limit = 50 - param.timeTag = lastTimeTag - QChatServerProvider.shared.getServerMembers(param) { [weak self] error, sMembers in - print("sMembers:\(sMembers) error:\(error)") - if error != nil { - self?.view.makeToast(error?.localizedDescription) - } else { - if !sMembers.isEmpty { - self?.lastTimeTag = sMembers.last?.createTime - if let sid = self?.channel?.serverId, let cid = self?.channel?.channelId { - // 过滤掉已经存在在channel中的成员 - var ids = [String]() - for member in sMembers { - if let id = member.accid { - ids.append(id) - } - } - let param = GetExistingAccidsOfMemberRolesParam( - serverId: sid, - channelId: cid, - accids: ids - ) - QChatRoleProvider.shared - .getExistingMemberRoles(param: param) { error, existMemberArray in - if let existMembers = existMemberArray, !existMembers.isEmpty { - for m in sMembers { - if existMembers.contains(where: { existMember in - m.accid == existMember.accid - }) { - } else { - self?.serverMembers?.append(m) - } - } - } - self?.emptyView.removeFromSuperview() - self?.tableView.mj_footer?.endRefreshing() - self?.tableView.reloadData() - } - } else { - for m in sMembers { - self?.serverMembers?.append(m) - } - self?.emptyView.isHidden = true - self?.tableView.mj_footer?.endRefreshing() - self?.tableView.reloadData() - } - } else { - self?.emptyView.isHidden = true - self?.tableView.mj_footer?.endRefreshingWithNoMoreData() - } - } - } - } - - override public func tableView(_ tableView: UITableView, - numberOfRowsInSection section: Int) -> Int { - serverMembers?.count ?? 0 - } - - override public func tableView(_ tableView: UITableView, - cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatImageTextCell.self)", - for: indexPath - ) as! QChatImageTextCell - cell.backgroundColor = .white - cell.rightStyle = .indicate - let member = serverMembers?[indexPath.row] - cell.setup(accid: member?.accid, nickName: member?.nick) - return cell - } - - func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - // 成员权限设置 - let member = serverMembers?[indexPath.row] - addMemberInChannel(member: member, index: indexPath.row) - } - - private func addMemberInChannel(member: ServerMemeber?, index: Int) { - let param = AddMemberRoleParam( - serverId: channel?.serverId, - channelId: channel?.channelId, - accid: member?.accid - ) - QChatRoleProvider.shared.addMemberRole(param) { error, memberRole in - if error != nil { - self.showToast(error?.localizedDescription ?? "") - } else { - self.serverMembers?.remove(at: index) - self.tableView.reloadData() - let settingVC = QChatMemberPermissionSettingVC( - channel: self.channel, - memberRole: memberRole - ) - self.navigationController?.pushViewController(settingVC, animated: true) -// if let block = self.didAddMemberRole { -// block(memberRole) -// } - } - } - } - - private lazy var emptyView: EmptyDataView = { - let view = EmptyDataView( - imageName: "memberPlaceholder", - content: localizable("noMember_add"), - frame: CGRect( - x: 0, - y: 60, - width: self.view.bounds.size.width, - height: self.view.bounds.size.height - ) - ) - self.view.addSubview(view) - return view - }() -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatAddRoleGroupVC.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatAddRoleGroupVC.swift deleted file mode 100644 index c0070a1b..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatAddRoleGroupVC.swift +++ /dev/null @@ -1,234 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NECoreIMKit -import MJRefresh - -typealias AddChannelRoleBlock = (_ role: ChannelRole?) -> Void -public class QChatAddRoleGroupVC: QChatSearchVC { - public var channel: ChatChannel? - private var serverRoles: [ServerRole]? - private var channelRoles: [ChannelRole]? -// public var didAddChannelRole: AddChannelRoleBlock? - private var priority: Int? - private lazy var placeholderView: EmptyDataView = .init( - imageName: "rolePlaceholder", - content: localizable("has_no_role"), - frame: CGRect( - x: 0, - y: 60, - width: self.view.bounds.size.width, - height: self.view.bounds.size.height - ) - ) - - override public func viewDidLoad() { - super.viewDidLoad() - title = localizable("add_group") - tableView.register( - QChatTextArrowCell.self, - forCellReuseIdentifier: "\(QChatTextArrowCell.self)" - ) - tableView.mj_header = MJRefreshNormalHeader( - refreshingTarget: self, - refreshingAction: #selector(loadData) - ) - tableView.mj_footer = MJRefreshBackNormalFooter( - refreshingTarget: self, - refreshingAction: #selector(loadMore) - ) - view.addSubview(placeholderView) - loadData() - } - - init(channel: ChatChannel?) { - super.init(nibName: nil, bundle: nil) - self.channel = channel - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - @objc func loadData() { - priority = 0 - // 加载server的身份组 - var param = GetServerRoleParam() - param.serverId = channel?.serverId - param.limit = 50 - param.priority = priority - print("thread:\(Thread.current)") - QChatRoleProvider.shared.getRoles(param) { [weak self] error, roles, sets in - print("sRoles:\(roles) error:\(error)") - if error != nil { - self?.view.makeToast(error?.localizedDescription) - // 空白页 - self?.placeholderView.isHidden = false - } else { - if let roleArray = roles, !roleArray.isEmpty { - self?.priority = roleArray.last?.priority - if let sid = self?.channel?.serverId, let cid = self?.channel?.channelId { - // 过滤掉已经存在在channel中的身份组 - var ids = [UInt64]() - for role in roleArray { - if let id = role.roleId { - ids.append(id) - } - } - let param = GetExistingChannelRolesByServerRoleIdsParam( - serverId: sid, - channelId: cid, - roleIds: ids - ) - QChatRoleProvider.shared - .getExistingChannelRoles(param: param) { error, channelRoles in - if let existRoles = channelRoles, !existRoles.isEmpty { - var tmp = [ServerRole]() - print("roleArray: \(roleArray)") - for role in roleArray { - if existRoles.contains(where: { existRole in - role.roleId == existRole.parentRoleId - }) { - } else { - tmp.append(role) - } - } - self?.serverRoles = tmp - self?.placeholderView.isHidden = !tmp.isEmpty - - } else { - self?.serverRoles = roleArray - self?.placeholderView.isHidden = !roleArray.isEmpty - } - self?.tableView.mj_footer?.resetNoMoreData() - self?.tableView.mj_header?.endRefreshing() - self?.tableView.reloadData() - } - } else { - self?.serverRoles = roleArray - self?.tableView.mj_footer?.resetNoMoreData() - self?.tableView.mj_header?.endRefreshing() - self?.tableView.reloadData() - } - } else { - // 空白页 - self?.placeholderView.isHidden = false - } - } - } - } - - @objc func loadMore() { - // 加载server的身份组 - var param = GetServerRoleParam() - param.serverId = channel?.serverId - param.limit = 50 - param.priority = priority - QChatRoleProvider.shared.getRoles(param) { [weak self] error, roles, sets in - print("sRoles:\(roles) error:\(error)") - if error != nil { - self?.view.makeToast(error?.localizedDescription) - } else { - if let roleArray = roles, !roleArray.isEmpty { - self?.priority = roleArray.last?.priority - if let sid = self?.channel?.serverId, let cid = self?.channel?.channelId { - // 过滤掉已经存在在channel中的身份组 - var ids = [UInt64]() - for role in roleArray { - if let id = role.roleId { - ids.append(id) - } - } - let param = GetExistingChannelRolesByServerRoleIdsParam( - serverId: sid, - channelId: cid, - roleIds: ids - ) - QChatRoleProvider.shared - .getExistingChannelRoles(param: param) { error, channelRoles in - if let existRoles = channelRoles, !existRoles.isEmpty { - for role in roleArray { - if existRoles.contains(where: { existRole in - role.roleId == existRole.parentRoleId - }) { - } else { - self?.serverRoles?.append(role) - } - } - } else { - for role in roleArray { - self?.serverRoles?.append(role) - } - } - - self?.placeholderView.isHidden = true - self?.tableView.mj_footer?.endRefreshing() - self?.tableView.reloadData() - } - } else { - for role in roleArray { - self?.serverRoles?.append(role) - } - self?.placeholderView.isHidden = true - self?.tableView.mj_footer?.endRefreshing() - self?.tableView.reloadData() - } - - } else { - self?.tableView.mj_footer?.endRefreshingWithNoMoreData() - } - } - } - } - - override public func tableView(_ tableView: UITableView, - numberOfRowsInSection section: Int) -> Int { - serverRoles?.count ?? 0 - } - - override public func tableView(_ tableView: UITableView, - cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatTextArrowCell.self)", - for: indexPath - ) as! QChatTextArrowCell - cell.backgroundColor = .white - cell.titleLabel.text = serverRoles?[indexPath.row].name - return cell - } - - func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - let role = serverRoles?[indexPath.row] - guard let sId = channel?.serverId, let cId = channel?.channelId, - let roleId = role?.roleId else { - return - } - // 1.添加到频道下 - let param = AddChannelRoleParam(serverId: sId, channelId: cId, parentRoleId: roleId) - QChatRoleProvider.shared.addChannelRole(param: param) { [weak self] error, cRole in - if error == nil { - // 2.跳转到身份组权限设置 - self?.navigationController?.pushViewController( - QChatGroupPermissionSettingVC(cRole: cRole), - animated: true - ) - // 3.此页面移除该数据并刷新 - self?.serverRoles?.remove(at: indexPath.row) - if self?.serverRoles?.count ?? 0 > 0 { - self?.placeholderView.isHidden = true - self?.tableView.reloadData() - } else { - self?.placeholderView.isHidden = false - } -// if let block = self?.didAddChannelRole { -// block(cRole) -// } - } else { - self?.view.makeToast(error?.localizedDescription) - } - } - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatChannelAuthoritySettingVC.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatChannelAuthoritySettingVC.swift deleted file mode 100644 index 3b4893d6..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatChannelAuthoritySettingVC.swift +++ /dev/null @@ -1,377 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NECoreIMKit - -public class QChatChannelAuthoritySettingVC: QChatTableViewController { - var channel: ChatChannel? - var viewModel: QChatAuthoritySettingViewModel? - var sectionTitle: [String] = ["", localizable("qchat_id_group"), localizable("qchat_member")] - var staticData: [String] = [localizable("add_group"), localizable("add_member")] - var memberData: [String] = [localizable("add_member"), localizable("add_group")] - var isEdit = false - private let className = "QChatChannelAuthoritySettingVC" - - init(channel: ChatChannel?) { - super.init(nibName: nil, bundle: nil) - self.channel = channel - viewModel = QChatAuthoritySettingViewModel(channel: self.channel) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override public func viewWillAppear(_ animated: Bool) { - print("viewWillAppear") - loadData() - } - - override public func viewDidLoad() { - super.viewDidLoad() - commonUI() - } - - func commonUI() { - title = localizable("authority_setting") - navigationItem.rightBarButtonItem = UIBarButtonItem( - title: localizable("qchat_edit"), - style: .plain, - target: self, - action: #selector(edit) - ) - tableView.rowHeight = 50 - tableView.register( - QChatTextArrowCell.self, - forCellReuseIdentifier: "\(QChatTextArrowCell.self)" - ) - tableView.register( - QChatImageTextCell.self, - forCellReuseIdentifier: "\(QChatImageTextCell.self)" - ) - tableView.register( - QChatCenterTextCell.self, - forCellReuseIdentifier: "\(QChatCenterTextCell.self)" - ) - tableView.register( - QChatSectionView.self, - forHeaderFooterViewReuseIdentifier: "\(QChatSectionView.self)" - ) - } - - func loadData() { - // 获取频道下的身份组 - viewModel?.firstGetChannelRoles { [weak self] error, roles in - NELog.infoLog( - ModuleName + " " + (self?.className ?? "QChatChannelAuthoritySettingVC"), - desc: "CALLBACK firstGetChannelRoles " + (error?.localizedDescription ?? "no error") - ) - if error != nil { - self?.view.makeToast(error?.localizedDescription) - } else { - self?.tableView.reloadData() - } - } - - // 获取频道下的成员 - viewModel?.firstGetMembers { [weak self] error, members in - NELog.infoLog( - ModuleName + " " + (self?.className ?? "QChatChannelAuthoritySettingVC"), - desc: "CALLBACK firstGetMembers " + (error?.localizedDescription ?? "no error") - ) - if error != nil { - self?.view.makeToast(error?.localizedDescription) - } else { - self?.tableView.reloadData() - } - } - } - - // MARK: - event - - @objc func edit() { - isEdit = !isEdit - let title = isEdit ? localizable("finish") : localizable("qchat_edit") - navigationItem.rightBarButtonItem = UIBarButtonItem( - title: title, - style: .plain, - target: self, - action: #selector(edit) - ) - tableView.reloadData() - } - - // MARK: - delegate - - func numberOfSections(in tableView: UITableView) -> Int { - sectionTitle.count - } - - override public func tableView(_ tableView: UITableView, - numberOfRowsInSection section: Int) -> Int { - switch section { - case 0: - return staticData.count - case 1: - return viewModel?.rolesData.roles.count ?? 0 - case 2: - return viewModel?.membersData.roles.count ?? 0 - default: - return 0 - } - } - - override public func tableView(_ tableView: UITableView, - cellForRowAt indexPath: IndexPath) -> UITableViewCell { - switch indexPath.section { - case 0: - let cell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatTextArrowCell.self)", - for: indexPath - ) as! QChatTextArrowCell - if indexPath.row == 0 { - cell.cornerType = CornerType.topLeft.union(CornerType.topRight) - } else { - cell.cornerType = CornerType.bottomLeft.union(CornerType.bottomRight) - } - cell.titleLabel.text = staticData[indexPath.row] - cell.rightStyle = .indicate - return cell - case 1: - let role = viewModel?.rolesData.roles[indexPath.row] - if role!.isPlacehold { - let cell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatCenterTextCell.self)", - for: indexPath - ) as! QChatCenterTextCell - cell.titleLabel.text = role?.title - cell.titleLabel.textColor = .ne_greyText - cell.titleLabel.font = .systemFont(ofSize: 14) - switch role?.corner { - case .top: - cell.cornerType = CornerType.topLeft.union(CornerType.topRight) - case .bottom: - cell.cornerType = CornerType.bottomLeft.union(CornerType.bottomRight) - case .all: - cell.cornerType = CornerType.topLeft.union(CornerType.topRight) - .union(CornerType.bottomLeft).union(CornerType.bottomRight) - default: - cell.cornerType = .none - } - return cell - } else { - let cell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatTextArrowCell.self)", - for: indexPath - ) as! QChatTextArrowCell - cell.titleLabel.text = role?.role?.name - if role?.role?.type == .everyone { - cell.rightStyle = .none - } else { - cell.rightStyle = isEdit ? .delete : .none - } - switch role?.corner { - case .top: - cell.cornerType = CornerType.topLeft.union(CornerType.topRight) - case .bottom: - cell.cornerType = CornerType.bottomLeft.union(CornerType.bottomRight) - case .all: - cell.cornerType = CornerType.topLeft.union(CornerType.topRight) - .union(CornerType.bottomLeft).union(CornerType.bottomRight) - default: - cell.cornerType = .none - } - return cell - } - - case 2: - let role = viewModel?.membersData.roles[indexPath.row] - if role!.isPlacehold { - let cell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatCenterTextCell.self)", - for: indexPath - ) as! QChatCenterTextCell - cell.titleLabel.textColor = .ne_greyText - cell.titleLabel.font = .systemFont(ofSize: 14) - cell.titleLabel.text = role?.title - switch role?.corner { - case .top: - cell.cornerType = CornerType.topLeft.union(CornerType.topRight) - case .bottom: - cell.cornerType = CornerType.bottomLeft.union(CornerType.bottomRight) - case .all: - cell.cornerType = CornerType.topLeft.union(CornerType.topRight) - .union(CornerType.bottomLeft).union(CornerType.bottomRight) - default: - cell.cornerType = .none - } - return cell - } else { - let cell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatImageTextCell.self)", - for: indexPath - ) as! QChatImageTextCell - cell.rightStyle = isEdit ? .delete : .none - let member = viewModel?.membersData.roles[indexPath.row].member - cell.setup(accid: member?.accid, nickName: member?.nick) - switch role?.corner { - case .top: - cell.cornerType = CornerType.topLeft.union(CornerType.topRight) - case .bottom: - cell.cornerType = CornerType.bottomLeft.union(CornerType.bottomRight) - case .all: - cell.cornerType = CornerType.topLeft.union(CornerType.topRight) - .union(CornerType.bottomLeft).union(CornerType.bottomRight) - default: - cell.cornerType = .none - } - return cell - } - default: - return UITableViewCell() - } - } - - func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { - let head = tableView - .dequeueReusableHeaderFooterView( - withIdentifier: "\(QChatSectionView.self)" - ) as! QChatSectionView - head.titleLabel.text = sectionTitle[section] - if section == 2, viewModel?.membersData.roles.count == 0 { - head.titleLabel.text = "" - } - return head - } - - func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - switch indexPath.section { - case 0: - if indexPath.row == 0 { - // add group - let addRoleVC = QChatAddRoleGroupVC(channel: viewModel?.channel) - navigationController?.pushViewController(addRoleVC, animated: true) - - } else { - // add member - let addMemberVC = QChatAddMemberVC(channel: viewModel?.channel) - navigationController?.pushViewController(addMemberVC, animated: true) - } - - case 1: -// group - guard let model = viewModel?.rolesData.roles[indexPath.row] else { - return - } - if model.isPlacehold { - // 加载更多 - viewModel?.getChannelRoles { [weak self] error, roles in - NELog.infoLog( - ModuleName + " " + (self?.className ?? "QChatChannelAuthoritySettingVC"), - desc: "CALLBACK getChannelRoles " + (error?.localizedDescription ?? "no error") - ) - if error != nil { - self?.view.makeToast(error?.localizedDescription) - } else { - self?.tableView.reloadData() - } - } - } else { - if isEdit { - // delete role - deleteRole(role: model.role, index: indexPath.row) - } else { - // enter authority setting - let settingVC = QChatGroupPermissionSettingVC(cRole: model.role) - navigationController?.pushViewController(settingVC, animated: true) - } - } - - case 2: -// member - guard let model = viewModel?.membersData.roles[indexPath.row] else { - return - } - if model.isPlacehold { - // 加载更多 - viewModel?.getMembers { [weak self] error, members in - NELog.infoLog( - ModuleName + " " + (self?.className ?? "QChatChannelAuthoritySettingVC"), - desc: "CALLBACK getMembers " + (error?.localizedDescription ?? "no error") - ) - if error != nil { - self?.view.makeToast(error?.localizedDescription) - } else { - self?.tableView.reloadData() - } - } - } else { - if isEdit { - // delete member - deleteMember(member: model.member, index: indexPath.row) - } else { - // enter member authority setting - let settingVC = QChatMemberPermissionSettingVC( - channel: channel, - memberRole: model.member - ) - navigationController?.pushViewController(settingVC, animated: true) - } - } - default: - break - } - } - - private func deleteRole(role: ChannelRole?, index: Int) { - let name = role?.name ?? "" - let message = localizable("confirm_delete_channel") + name + localizable("qchat_id_group") + - "?" - let alertVC = UIAlertController.reconfimAlertView( - title: localizable("removeRole"), - message: message - ) { - self.viewModel?.removeChannelRole(role: role, index: index) { [weak self] error in - NELog.infoLog( - ModuleName + " " + (self?.className ?? "QChatChannelAuthoritySettingVC"), - desc: "CALLBACK removeChannelRole " + (error?.localizedDescription ?? "no error") - ) - if error != nil { - self?.view.makeToast(error?.localizedDescription) - } else { - self?.tableView.reloadData() - } - } - } - present(alertVC, animated: true, completion: nil) - } - - private func deleteMember(member: MemberRole?, index: Int) { - var name = member?.accid ?? "" - if let n = member?.nick, n.count > 0 { - name = n - } - let message = localizable("confirm_delete_channel") + name + localizable("qchat_member") + - "?" - let alertVC = UIAlertController.reconfimAlertView( - title: localizable("removeMember"), - message: message - ) { - self.viewModel?.removeMemberRole(member: member, index: index) { [weak self] error in - NELog.infoLog( - ModuleName + " " + (self?.className ?? "QChatChannelAuthoritySettingVC"), - desc: "CALLBACK removeMemberRole " + (error?.localizedDescription ?? "no error") - ) - if error != nil { - self?.view.makeToast(error?.localizedDescription) - } else { - self?.tableView.reloadData() - } - } - } - present(alertVC, animated: true, completion: nil) - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatChannelMembersVC.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatChannelMembersVC.swift deleted file mode 100644 index da2832ca..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatChannelMembersVC.swift +++ /dev/null @@ -1,186 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NECoreIMKit -import MJRefresh - -public class QChatChannelMembersVC: QChatTableViewController, QChatMemberInfoViewDelegate { - public var channel: ChatChannel? - private var channelMembers: [ServerMemeber]? - var memberInfoView: QChatMemberInfoView? - var lastMember: ServerMemeber? - - override public func viewDidLoad() { - super.viewDidLoad() - commonUI() - loadData() - } - - func commonUI() { - title = localizable("channel_member") - let header = - ChannelHeaderView(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: 78)) - header.settingButton.addTarget( - self, - action: #selector(enterChannelSetting), - for: .touchUpInside - ) - header.titleLabel.text = channel?.name - header.detailLabel.text = channel?.topic - tableView.tableHeaderView = header - tableView.register( - QChatImageTextOnlineCell.self, - forCellReuseIdentifier: "\(QChatImageTextOnlineCell.self)" - ) - tableView.mj_footer = MJRefreshBackNormalFooter( - refreshingTarget: self, - refreshingAction: #selector(loadMoreData) - ) - tableView.mj_header = MJRefreshNormalHeader( - refreshingTarget: self, - refreshingAction: #selector(loadData) - ) - } - - @objc func loadData() { - var param = ChannelMembersParam( - serverId: channel?.serverId ?? 0, - channelId: channel?.channelId ?? 0 - ) - param.limit = 50 - QChatChannelProvider.shared - .getChannelMembers(param: param) { [weak self] error, cMembersResult in - print( - "cMembersResult.memberArray:\(cMembersResult?.memberArray) thread:\(Thread.current) " - ) - self?.channelMembers = cMembersResult?.memberArray - self?.lastMember = cMembersResult?.memberArray?.last - self?.tableView.reloadData() - self?.tableView.mj_footer?.resetNoMoreData() - self?.tableView.mj_header?.endRefreshing() - } - } - - @objc func loadMoreData() { - var param = ChannelMembersParam( - serverId: channel?.serverId ?? 0, - channelId: channel?.channelId ?? 0 - ) - param.timeTag = lastMember?.createTime - param.limit = 50 - QChatChannelProvider.shared - .getChannelMembers(param: param) { [weak self] error, cMembersResult in - print( - "more cMembersResult.memberArray:\(cMembersResult?.memberArray) thread:\(Thread.current) " - ) - if error != nil { - self?.view.makeToast(error?.localizedDescription) - return - } - if let members = cMembersResult?.memberArray, members.count > 0 { - for m in members { - self?.channelMembers?.append(m) - } - self?.lastMember = members.last - self?.tableView.reloadData() - } else { -// end - self?.tableView.mj_footer?.endRefreshingWithNoMoreData() - } - } - } - - override public func tableView(_ tableView: UITableView, - numberOfRowsInSection section: Int) -> Int { - channelMembers?.count ?? 0 - } - - override public func tableView(_ tableView: UITableView, - cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatImageTextOnlineCell.self)", - for: indexPath - ) as! QChatImageTextOnlineCell - let member = channelMembers![indexPath.row] as ServerMemeber - cell.setup(accid: member.accid, nickName: member.nick) - cell.online = false - if channelMembers?.count == 1 { - cell.cornerType = CornerType.topLeft.union(CornerType.topRight) - .union(CornerType.bottomLeft).union(CornerType.bottomRight) - } else { - if indexPath.row == 0 { - cell.cornerType = CornerType.topLeft.union(CornerType.topRight) - } else if indexPath.row == channelMembers!.count - 1 { - cell.cornerType = CornerType.bottomLeft.union(CornerType.bottomRight) - } - } - return cell - } - - func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - let m = channelMembers![indexPath.row] - memberInfoView = QChatMemberInfoView(inView: UIApplication.shared.keyWindow!) - memberInfoView?.setup(accid: m.accid, nickName: m.nick) - memberInfoView?.delegate = self - memberInfoView?.present() - loadRolesOfMember(member: m) - } - - func loadRolesOfMember(member: ServerMemeber) { - let param = GetServerRolesByAccIdParam(serverId: channel?.serverId, accid: member.accid) - QChatRoleProvider.shared.getServerRolesByAccId(param: param) { [weak self] error, roles in - print("roles:\(roles?.count) error: \(error)") - guard let roleList = roles else { - return - } - var names = [String]() - - for r in roleList { - names.append(r.name ?? "") - } - self?.memberInfoView?.setupRoles(dataArray: names) - } - } - - @objc func enterChannelSetting() { - let settingVC = QChatChannelSettingVC() - settingVC.didUpdateChannel = { [weak self] channel in - self?.channel = channel - guard let head = self?.tableView.tableHeaderView as? ChannelHeaderView else { - return - } - head.titleLabel.text = channel?.name - head.detailLabel.text = channel?.topic - } - - settingVC.didDeleteChannel = { [weak self] channel in - self?.navigationController?.popViewController(animated: true) - } - - settingVC.viewModel = QChatUpdateChannelViewModel(channel: channel) - let nav = UINavigationController(rootViewController: settingVC) - nav.modalPresentationStyle = .fullScreen - present(nav, animated: true, completion: nil) - } - - func didClickUserHeader(_ accid: String?) { - if let uid = accid { - if IMKitEngine.instance.isMySelf(uid) { - Router.shared.use( - MeSettingRouter, - parameters: ["nav": navigationController as Any], - closure: nil - ) - } else { - Router.shared.use( - ContactUserInfoPageRouter, - parameters: ["nav": navigationController as Any, "uid": uid as Any], - closure: nil - ) - } - } - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatChannelSettingVC.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatChannelSettingVC.swift deleted file mode 100644 index 5a09449b..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatChannelSettingVC.swift +++ /dev/null @@ -1,276 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NECoreIMKit - -typealias UpdateChannelSuccess = (_ channel: ChatChannel?) -> Void - -public class QChatChannelSettingVC: QChatTableViewController, QChatTextEditCellDelegate { - var viewModel: QChatUpdateChannelViewModel? - var didUpdateChannel: UpdateChannelSuccess? - var didDeleteChannel: UpdateChannelSuccess? - - var sections: [String]? - var cells = [String]() - private let className = "QChatChannelSettingVC" - - override public func viewDidLoad() { - super.viewDidLoad() - loadData() - commonUI() - } - - func loadData() { - sections = [ - localizable("channel_name"), - localizable("channel_topic"), - localizable("authority"), - localizable("list"), - "", - ] - - let listName = viewModel?.channel? - .visibleType == .isPublic ? localizable("black_list") : localizable("white_list") - - cells = [ - viewModel?.channel?.name ?? "", - viewModel?.channel?.topic ?? "", - localizable("authority_setting"), - listName, - localizable("delete_channel"), - ] - } - - func commonUI() { - title = localizable("channel_setting") - navigationItem.rightBarButtonItem = UIBarButtonItem( - title: localizable("save"), - style: .plain, - target: self, - action: #selector(save) - ) - navigationItem.leftBarButtonItem = UIBarButtonItem( - title: localizable("close"), - style: .plain, - target: self, - action: #selector(close) - ) - navigationItem.rightBarButtonItem?.tintColor = .ne_blueText - tableView.rowHeight = 50 - tableView.register( - QChatTextEditCell.self, - forCellReuseIdentifier: "\(QChatTextEditCell.self)" - ) - tableView.register( - QChatTextArrowCell.self, - forCellReuseIdentifier: "\(QChatTextArrowCell.self)" - ) - tableView.register( - QChatCenterTextCell.self, - forCellReuseIdentifier: "\(QChatCenterTextCell.self)" - ) - tableView.register( - QChatSectionView.self, - forHeaderFooterViewReuseIdentifier: "\(QChatSectionView.self)" - ) - } - -// MARK: deletgate - - func numberOfSections(in tableView: UITableView) -> Int { - sections?.count ?? 0 - } - - override public func tableView(_ tableView: UITableView, - numberOfRowsInSection section: Int) -> Int { - 1 - } - - override public func tableView(_ tableView: UITableView, - cellForRowAt indexPath: IndexPath) -> UITableViewCell { - switch indexPath.section { - case 0: - let cell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatTextEditCell.self)", - for: indexPath - ) as! QChatTextEditCell - cell.cornerType = CornerType.topLeft.union(CornerType.topRight) - .union(CornerType.bottomLeft).union(CornerType.bottomRight) - cell.textFied.text = cells[indexPath.section] - cell.textFied.tag = 20 - cell.delegate = self - return cell - case 1: - let cell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatTextEditCell.self)", - for: indexPath - ) as! QChatTextEditCell - cell.cornerType = CornerType.topLeft.union(CornerType.topRight) - .union(CornerType.bottomLeft).union(CornerType.bottomRight) - cell.textFied.text = cells[indexPath.section] - cell.textFied.tag = 21 - cell.delegate = self - return cell - case 2, 3: - let cell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatTextArrowCell.self)", - for: indexPath - ) as! QChatTextArrowCell - cell.cornerType = CornerType.topLeft.union(CornerType.topRight) - .union(CornerType.bottomLeft).union(CornerType.bottomRight) - cell.titleLabel.text = cells[indexPath.section] - return cell - case 4: - let cell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatCenterTextCell.self)", - for: indexPath - ) as! QChatCenterTextCell - cell.cornerType = CornerType.topLeft.union(CornerType.topRight) - .union(CornerType.bottomLeft).union(CornerType.bottomRight) - cell.titleLabel.text = cells[indexPath.section] - return cell - default: - return UITableViewCell() - } - } - - func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { - let head = tableView - .dequeueReusableHeaderFooterView( - withIdentifier: "\(QChatSectionView.self)" - ) as! QChatSectionView - head.titleLabel.text = sections?[section] - return head - } - - func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - switch indexPath.section { - case 2: - // authority - enterAuthoritySettingVC() - case 3: - // name list - enterListVC() - case 4: -// delete - deleteChannel() - default: - break - } - } - -// MARK: private method - - private func enterAuthoritySettingVC() { - navigationController?.pushViewController( - QChatChannelAuthoritySettingVC(channel: viewModel?.channel), - animated: true - ) - } - - private func enterListVC() { - let listVC = QChatWhiteBlackListVC() - listVC.channel = viewModel?.channel - listVC.type = viewModel?.channel?.visibleType == .isPublic ? .black : .white - navigationController?.pushViewController(listVC, animated: true) - } - - private func deleteChannel() { - let message: String? - if let name = viewModel?.channel?.name { - message = localizable("confirm_delete_channel") + name + "?" - } else { - message = localizable("confirm_delete_channel") + "?" - } - let alertVC = UIAlertController.reconfimAlertView( - title: localizable("delete_channel"), - message: message - ) { - self.viewModel?.deleteChannel(completion: { [weak self] error in - NELog.infoLog( - ModuleName + " " + (self?.className ?? "QChatChannelSettingVC"), - desc: "CALLBACK deleteChannel " + (error?.localizedDescription ?? "no error") - ) - if error != nil { - self?.view.makeToast(error?.localizedDescription) - } else { - self?.view.makeToast( - localizable("delete_channel_suscess"), - duration: 1, - completion: { didTap in - // 通知上级页面 - NotificationCenter.default.post( - name: NotificationName.deleteChannel, - object: self?.viewModel?.channel - ) - self?.didDeleteChannel?(self?.viewModel?.channel) - self?.close() - } - ) - } - }) - } - present(alertVC, animated: true, completion: nil) - } - -// MARK: QChatTextEditCellDelegate - - func textDidChange(_ textField: UITextField) { - if textField.tag == 20 { - if textField.text?.count == 0 { - navigationItem.rightBarButtonItem?.tintColor = .ne_greyText - } else { - if var str = textField.text, str.count > 50 { - str = str.substring(to: str.index(str.startIndex, offsetBy: 50)) - print("str:\(str)") - textField.text = str - } - navigationItem.rightBarButtonItem?.tintColor = .ne_blueText - } - viewModel?.channelTmp?.name = textField.text - } else if textField.tag == 21 { - if var str = textField.text, str.count > 64 { - str = str.substring(to: str.index(str.startIndex, offsetBy: 64)) - print("str:\(str)") - textField.text = str - } - viewModel?.channelTmp?.topic = textField.text - } - } - -// MARK: event - - @objc func save() { - viewModel?.updateChannelInfo(completion: { [weak self] error, channel in - NELog.infoLog( - ModuleName + " " + (self?.className ?? "QChatChannelSettingVC"), - desc: "CALLBACK updateChannelInfo " + (error?.localizedDescription ?? "no error") - ) - if error != nil { - self?.view.makeToast(error?.localizedDescription) - return - } - self?.view.makeToast( - localizable("update_channel_suscess"), - duration: 2, - position: .center, - completion: { didTap in - self?.didUpdateChannel?(channel) - NotificationCenter.default.post( - name: NotificationName.updateChannel, - object: channel - ) - // 通知上级页面 - self?.close() - } - ) - }) - } - - @objc func close() { - navigationController?.dismiss(animated: true, completion: nil) - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatChannelTypeVC.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatChannelTypeVC.swift deleted file mode 100644 index a1e99795..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatChannelTypeVC.swift +++ /dev/null @@ -1,74 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NECoreIMKit - -struct ChannelSelection { - var sectionName = "" - var isSeleted = false -} - -protocol QChatChannelTypeVCDelegate: AnyObject { - func didSelected(type: Int) -} - -public class QChatChannelTypeVC: QChatTableViewController { - var dataList = [ChannelSelection]() - weak var delegate: QChatChannelTypeVCDelegate? - var isPrivate: Bool = false - - override public func viewDidLoad() { - super.viewDidLoad() - loadData() - commonUI() - } - - func commonUI() { - title = localizable("channel_type") - tableView.register( - QChatTextSelectionCell.self, - forCellReuseIdentifier: "\(QChatTextSelectionCell.self)" - ) - tableView.selectRow( - at: IndexPath(row: 0, section: 0), - animated: false, - scrollPosition: .top - ) - } - - func loadData() { - dataList.append(ChannelSelection(sectionName: localizable("public"), isSeleted: !isPrivate)) - dataList.append(ChannelSelection(sectionName: localizable("private"), isSeleted: isPrivate)) - } - - override public func tableView(_ tableView: UITableView, - numberOfRowsInSection section: Int) -> Int { - dataList.count - } - - override public func tableView(_ tableView: UITableView, - cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell: QChatTextSelectionCell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatTextSelectionCell.self)", - for: indexPath - ) as! QChatTextSelectionCell - let item = dataList[indexPath.row] - cell.titleLabel.text = item.sectionName - if indexPath.row == 0 { - cell.cornerType = CornerType.topLeft.union(CornerType.topRight) - } else { - cell.cornerType = CornerType.bottomLeft.union(CornerType.bottomRight) - cell.setSelected(true, animated: true) - } - cell.selected(selected: item.isSeleted) - return cell - } - - public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - delegate?.didSelected(type: indexPath.row) - navigationController?.popViewController(animated: true) - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatChannelViewController.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatChannelViewController.swift deleted file mode 100644 index 75d31ce9..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatChannelViewController.swift +++ /dev/null @@ -1,219 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NECoreIMKit - -struct Channel { - var sectionName = "" - var contentName = "" -} - -public class QChatChannelViewController: QChatTableViewController, QChatTextEditCellDelegate, - QChatChannelTypeVCDelegate { - var viewModel: QChatChannelViewModel? - var dataList = [Channel]() - // 防重点击创建频道 - var isCreatedChannel = false - private let className = "QChatChannelViewController" - - public init(serverId: UInt64) { - viewModel = QChatChannelViewModel(serverId: serverId) - super.init(nibName: nil, bundle: nil) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override public func viewDidLoad() { - super.viewDidLoad() - commonUI() - loadData() - } - - func commonUI() { - title = localizable("create_channel") - navigationItem.rightBarButtonItem = UIBarButtonItem( - title: localizable("create"), - style: .plain, - target: self, - action: #selector(createChannel) - ) - navigationItem.leftBarButtonItem = UIBarButtonItem( - title: localizable("cancel"), - style: .plain, - target: self, - action: #selector(cancelEvent) - ) - navigationItem.rightBarButtonItem?.tintColor = .ne_greyText - tableView.register( - QChatTextEditCell.self, - forCellReuseIdentifier: "\(QChatTextEditCell.self)" - ) - tableView.register( - QChatTextArrowCell.self, - forCellReuseIdentifier: "\(QChatTextArrowCell.self)" - ) - tableView.register( - QChatSectionView.self, - forHeaderFooterViewReuseIdentifier: "\(QChatSectionView.self)" - ) - } - - func loadData() { - dataList - .append(Channel(sectionName: localizable("channel_name"), - contentName: localizable("input_channel_name"))) - dataList.append(Channel( - sectionName: localizable("channel_topic"), - contentName: localizable("input_channel_topic") - )) - dataList - .append(Channel(sectionName: localizable("channel_type"), - contentName: localizable("public"))) - } - - func numberOfSections(in tableView: UITableView) -> Int { - dataList.count - } - - override public func tableView(_ tableView: UITableView, - numberOfRowsInSection section: Int) -> Int { - 1 - } - - override public func tableView(_ tableView: UITableView, - cellForRowAt indexPath: IndexPath) -> UITableViewCell { - if indexPath.section == 0 { - let cell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatTextEditCell.self)", - for: indexPath - ) as! QChatTextEditCell - cell.cornerType = CornerType.bottomLeft.union(CornerType.bottomRight) - .union(CornerType.topLeft).union(CornerType.topRight) - cell.textFied.placeholder = dataList[indexPath.section].contentName - cell.delegate = self - cell.textFied.tag = 11 - return cell - } else if indexPath.section == 1 { - let cell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatTextEditCell.self)", - for: indexPath - ) as! QChatTextEditCell - cell.cornerType = CornerType.bottomLeft.union(CornerType.bottomRight) - .union(CornerType.topLeft).union(CornerType.topRight) - cell.textFied.placeholder = dataList[indexPath.section].contentName - cell.delegate = self - cell.textFied.tag = 12 - return cell - } else { - let cell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatTextArrowCell.self)", - for: indexPath - ) as! QChatTextArrowCell - cell.titleLabel.text = dataList[indexPath.section].contentName - cell.cornerType = CornerType.bottomLeft.union(CornerType.bottomRight) - .union(CornerType.topLeft).union(CornerType.topRight) - return cell - } - } - - func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { - let sectionView = tableView - .dequeueReusableHeaderFooterView( - withIdentifier: "\(QChatSectionView.self)" - ) as! QChatSectionView - sectionView.titleLabel.text = dataList[section].sectionName - return sectionView - } - - func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - if indexPath.section == 2 { - // select channel type - let vc = QChatChannelTypeVC() - vc.delegate = self - vc.isPrivate = viewModel?.isPrivate ?? false - navigationController?.pushViewController(vc, animated: true) - } - } - -// MARK: event - - @objc func createChannel() { - guard let name = viewModel?.name, name.count > 0 else { - showToast(localizable("channelName_cannot_be_empty")) - return - } - - if !isCreatedChannel { - isCreatedChannel = true - viewModel?.createChannel { error, channel in - NELog.errorLog( - ModuleName + " " + self.className, - desc: "error:\(error?.localizedDescription) channel:\(channel)" - ) - if error == nil { - // success to chatVC - self.navigationController?.dismiss(animated: true, completion: { - NotificationCenter.default.post( - name: NotificationName.createChannel, - object: channel - ) - }) - } else { - self.view.makeToast(error?.localizedDescription) { didTap in - self.navigationController?.dismiss(animated: true, completion: nil) - } - } - } - } - } - - @objc func cancelEvent() { - print(#function) - dismiss(animated: true, completion: nil) - } - -// MARK: QChatTextEditCellDelegate - - func textDidChange(_ textField: UITextField) { - print("textFieldDidChangeSelection textField:\(textField.text)") - if textField.tag == 11 { - if textField.text?.count == 0 { - navigationItem.rightBarButtonItem?.tintColor = .ne_greyText - } else { - if var str = textField.text, str.count > 50 { - str = str.substring(to: str.index(str.startIndex, offsetBy: 50)) - print("str:\(str)") - textField.text = str - } - navigationItem.rightBarButtonItem?.tintColor = .ne_blueText - } - viewModel?.name = textField.text - } else if textField.tag == 12 { - if var str = textField.text, str.count > 64 { - str = str.substring(to: str.index(str.startIndex, offsetBy: 64)) - print("str:\(str)") - textField.text = str - } - viewModel?.topic = textField.text - } - } - -// MARK: QChatChannelTypeVCDelegate - - func didSelected(type: Int) { - viewModel?.isPrivate = type == 0 ? false : true - if dataList.count >= 3 { - dataList.removeLast() - dataList.append(Channel( - sectionName: localizable("channel_type"), - contentName: type == 0 ? localizable("public") : localizable("private") - )) - tableView.reloadData() - } - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatGroupPermissionSettingVC.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatGroupPermissionSettingVC.swift deleted file mode 100644 index 9b832f88..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatGroupPermissionSettingVC.swift +++ /dev/null @@ -1,155 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NECoreIMKit - -typealias ChannelUpdateSettingBlock = (_ channelRole: ChannelRole?) -> Void - -public class QChatGroupPermissionSettingVC: QChatTableViewController, - QChatPermissionSettingCellDelegate { -// public var didUpdateBlock: ChannelUpdateSettingBlock? - public var cRole: ChannelRole? - private var commonAuths = [RoleStatusInfoExt]() - private var messageAuths = [RoleStatusInfoExt]() - private var memberAuths = [RoleStatusInfoExt]() - private var auths = [[RoleStatusInfoExt]]() - - public init(cRole: ChannelRole?) { - super.init(nibName: nil, bundle: nil) - self.cRole = cRole - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override public func viewDidLoad() { - super.viewDidLoad() - if let name = cRole?.name { - title = name + localizable("authority_setting") - } else { - title = localizable("authority_setting") - } - tableView.register( - QChatPermissionSettingCell.self, - forCellReuseIdentifier: "\(QChatPermissionSettingCell.self)" - ) - tableView.register( - QChatSectionView.self, - forHeaderFooterViewReuseIdentifier: "\(QChatSectionView.self)" - ) - tableView.sectionHeaderHeight = 42 - tableView.rowHeight = 48 - reloadData() - } - - private func reloadData() { - if let auths = cRole?.auths { - for auth in auths { - var authExt = RoleStatusInfoExt(status: auth) - let key = "auth" + String(auth.type.rawValue) - authExt.title = localizable(key) - switch auth.type { - case .ManageChannel: - commonAuths.insert(authExt, at: 0) - case .ManageRole: - commonAuths.append(authExt) - case .SendMsg: - messageAuths.append(authExt) -// case .DeleteOtherMsg: -// messageAuths.append(authExt) -// case .RevokeMsg: -// messageAuths.append(authExt) - case .BlackWhiteList: - memberAuths.append(authExt) - default: - break - } - } - if !commonAuths.isEmpty { - self.auths.append(commonAuths) - } - if !messageAuths.isEmpty { - self.auths.append(messageAuths) - } - if !memberAuths.isEmpty { - self.auths.append(memberAuths) - } - tableView.reloadData() - } - } - - func numberOfSections(in tableView: UITableView) -> Int { - auths.count - } - - override public func tableView(_ tableView: UITableView, - numberOfRowsInSection section: Int) -> Int { - auths[section].count - } - - override public func tableView(_ tableView: UITableView, - cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatPermissionSettingCell.self)", - for: indexPath - ) as! QChatPermissionSettingCell - let auths = auths[indexPath.section] - let authExt = auths[indexPath.row] - cell.updateModel(model: authExt) - cell.delegate = self - if indexPath.row == 0 { - cell.cornerType = CornerType.topLeft.union(CornerType.topRight) - } else if indexPath.row == auths.count - 1 { - cell.cornerType = CornerType.bottomLeft.union(CornerType.bottomRight) - } - return cell - } - - func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { - let view = tableView - .dequeueReusableHeaderFooterView( - withIdentifier: "\(QChatSectionView.self)" - ) as? QChatSectionView - if section == 0 { - view?.titleLabel.text = localizable("qchat_common_permission") - } else if section == 1 { - view?.titleLabel.text = localizable("qchat_message_permission") - } else { - view?.titleLabel.text = localizable("qchat_member_permission") - } - return view - } - - func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { - 42 - } - - // MARK: QChatPermissionSettingCellDelegate - - func didSelected(cell: QChatPermissionSettingCell?, model: RoleStatusInfo?) { - if let auth = model { - let param = UpdateChannelRoleParam( - serverId: cRole?.serverId, - channelId: cRole?.channelId, - roleId: cRole?.roleId, - commands: [auth] - ) - QChatRoleProvider.shared - .updateChannelRole(param: param) { [weak self] error, channelRole in - if error != nil { - self?.view.makeToast(error?.localizedDescription) - cell?.selectedSuccess(success: false) - } else { - cell?.selectedSuccess(success: true) -// if let block = self?.didUpdateBlock { -// block(channelRole) -// } - } - } - } - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatMemberPermissionSettingVC.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatMemberPermissionSettingVC.swift deleted file mode 100644 index 881c877b..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatMemberPermissionSettingVC.swift +++ /dev/null @@ -1,189 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NECoreIMKit - -typealias UpdateSettingBlock = (_ memberRole: MemberRole?) -> Void -public class QChatMemberPermissionSettingVC: QChatTableViewController, - QChatPermissionSettingCellDelegate { - public var channel: ChatChannel? - public var memberRole: MemberRole? -// public var didUpdateBlock: UpdateSettingBlock? - private var commonAuths = [RoleStatusInfoExt]() - private var messageAuths = [RoleStatusInfoExt]() - private var memberAuths = [RoleStatusInfoExt]() - - private var auths = [[Any]]() - - init(channel: ChatChannel?, memberRole: MemberRole?) { - super.init(nibName: nil, bundle: nil) - self.channel = channel - self.memberRole = memberRole - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override public func viewDidLoad() { - super.viewDidLoad() - title = localizable("member_permission_setting") - tableView.register( - QChatPermissionSettingCell.self, - forCellReuseIdentifier: "\(QChatPermissionSettingCell.self)" - ) - tableView.register( - QChatImageTextCell.self, - forCellReuseIdentifier: "\(QChatImageTextCell.self)" - ) - tableView.register( - QChatSectionView.self, - forHeaderFooterViewReuseIdentifier: "\(QChatSectionView.self)" - ) - tableView.sectionHeaderHeight = 42 - tableView.rowHeight = 48 - reloadData() - } - - private func reloadData() { - let members = [memberRole] - auths.append(members as [Any]) - - if let auths = memberRole?.auths { - for auth in auths { - var authExt = RoleStatusInfoExt(status: auth) - let key = "auth" + String(auth.type.rawValue) - authExt.title = localizable(key) - switch auth.type { - case .ManageChannel: - commonAuths.insert(authExt, at: 0) - case .ManageRole: - commonAuths.append(authExt) - case .SendMsg: - messageAuths.append(authExt) -// case .DeleteOtherMsg: -// messageAuths.append(authExt) -// case .RevokeMsg: -// messageAuths.append(authExt) - case .BlackWhiteList: - memberAuths.append(authExt) - default: - break - } - } - - if !commonAuths.isEmpty { - self.auths.append(commonAuths) - } - if !messageAuths.isEmpty { - self.auths.append(messageAuths) - } - if !memberAuths.isEmpty { - self.auths.append(memberAuths) - } - } - tableView.reloadData() - } - - func numberOfSections(in tableView: UITableView) -> Int { - auths.count - } - - override public func tableView(_ tableView: UITableView, - numberOfRowsInSection section: Int) -> Int { - auths[section].count - } - - override public func tableView(_ tableView: UITableView, - cellForRowAt indexPath: IndexPath) -> UITableViewCell { - if indexPath.section == 0 { - // 用户 - let cell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatImageTextCell.self)", - for: indexPath - ) as! QChatImageTextCell - let members = auths[indexPath.section] - let m = members[indexPath.row] as? MemberRole - cell.setup(accid: m?.accid, nickName: m?.nick) - if indexPath.row == 0 { - cell.cornerType = CornerType.topLeft.union(CornerType.topRight) - } else if indexPath.row == auths.count - 1 { - cell.cornerType = CornerType.bottomLeft.union(CornerType.bottomRight) - } - return cell - } else { - let cell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatPermissionSettingCell.self)", - for: indexPath - ) as! QChatPermissionSettingCell - let auths = auths[indexPath.section] - let authExt = auths[indexPath.row] as? RoleStatusInfoExt - cell.updateModel(model: authExt) - cell.delegate = self - if indexPath.row == 0 { - cell.cornerType = CornerType.topLeft.union(CornerType.topRight) - } else if indexPath.row == auths.count - 1 { - cell.cornerType = CornerType.bottomLeft.union(CornerType.bottomRight) - } - return cell - } - } - - func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { - let view = tableView - .dequeueReusableHeaderFooterView( - withIdentifier: "\(QChatSectionView.self)" - ) as? QChatSectionView - if section == 1 { - view?.titleLabel.text = localizable("qchat_common_permission") - } else if section == 2 { - view?.titleLabel.text = localizable("qchat_message_permission") - } else if section == 3 { - view?.titleLabel.text = localizable("qchat_member_permission") - } - return view - } - - func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { - if indexPath.section == 0 { - return 56 - } else { - return 48 - } - } - - func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { - if section == 0 { - return 0 - } - return 42 - } - -// MARK: QChatPermissionSettingCellDelegate - - func didSelected(cell: QChatPermissionSettingCell?, model: RoleStatusInfo?) { - if let auth = model { - let param = UpdateMemberRoleParam( - serverId: channel?.serverId, - channelId: channel?.channelId, - accid: memberRole?.accid, - commands: [auth] - ) - QChatRoleProvider.shared - .updateMemberRole(param: param) { [weak self] error, memberRole in - if error != nil { - self?.view.makeToast(error?.localizedDescription) - cell?.selectedSuccess(success: false) - } else { - cell?.selectedSuccess(success: true) -// if let block = self?.didUpdateBlock { -// block(memberRole) -// } - } - } - } - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatSearchVC.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatSearchVC.swift deleted file mode 100644 index f12f898f..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatSearchVC.swift +++ /dev/null @@ -1,84 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -public class QChatSearchVC: NEBaseViewController, UITableViewDelegate, UITableViewDataSource { - var textField = UITextField() - var tableView = UITableView(frame: .zero, style: .plain) - - override public func viewDidLoad() { - super.viewDidLoad() - commonUI() - } - - func commonUI() { -// textField.placeholder = "ddd"; -// textField.leftView = UIImageView(image: UIImage.ne_imageNamed(name: "search")) -// textField.leftViewMode = .always -// textField.layer.cornerRadius = 8; -// textField.clipsToBounds = true -// textField.translatesAutoresizingMaskIntoConstraints = false -// textField.backgroundColor = .ne_lightBackgroundColor -// self.view.addSubview(textField) -// if #available(iOS 11.0, *) { -// NSLayoutConstraint.activate([ -// textField.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 0), -// textField.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 20), -// textField.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: -20), -// textField.heightAnchor.constraint(equalToConstant: 32), -// ]) -// } else { -// NSLayoutConstraint.activate([ -// textField.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 20), -// textField.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 20), -// textField.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: -20), -// textField.heightAnchor.constraint(equalToConstant: 32), -// ]) -// } - tableView.separatorStyle = .none - tableView.delegate = self - tableView.dataSource = self - tableView.translatesAutoresizingMaskIntoConstraints = false - view.addSubview(tableView) - if #available(iOS 11.0, *) { - NSLayoutConstraint.activate([ - self.tableView.topAnchor - .constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor), - self.tableView.leftAnchor.constraint(equalTo: self.view.leftAnchor), - self.tableView.rightAnchor.constraint(equalTo: self.view.rightAnchor), - self.tableView.bottomAnchor - .constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor), - ]) - } else { - NSLayoutConstraint.activate([ - tableView.topAnchor.constraint(equalTo: textField.bottomAnchor), - tableView.leftAnchor.constraint(equalTo: view.leftAnchor), - tableView.rightAnchor.constraint(equalTo: view.rightAnchor), - tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor), - ]) - } - tableView.sectionHeaderHeight = 0 - tableView.sectionFooterHeight = 0 - tableView.rowHeight = 40 - tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: 0.1)) - tableView.register(UITableViewCell.self, forCellReuseIdentifier: "\(UITableViewCell.self)") - } - -// MARK: UITableViewDataSource - - public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - 0 - } - - public func tableView(_ tableView: UITableView, - cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell( - withIdentifier: "\(UITableViewCell.self)", - for: indexPath - ) - return cell - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatWhiteBlackListVC.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatWhiteBlackListVC.swift deleted file mode 100644 index 0a1d6ff1..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewController/QChatWhiteBlackListVC.swift +++ /dev/null @@ -1,254 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NECoreIMKit -import NECoreKit - -public class QChatWhiteBlackListVC: QChatTableViewController, QChatMemberSelectControllerDelegate { - public var type: RoleType = .white - public var channel: ChatChannel? - private var memberArray: [ServerMemeber]? - private var isEdited: Bool = false - - override public func viewDidLoad() { - super.viewDidLoad() - isEdited = false - title = type == .white ? localizable("white_list") : localizable("black_list") - navigationItem.rightBarButtonItem = UIBarButtonItem( - title: localizable("qchat_edit"), - style: .plain, - target: self, - action: #selector(edit) - ) - - tableView.backgroundColor = .white - tableView.sectionHeaderHeight = 0 - tableView.sectionFooterHeight = 0 - tableView.register(QChatTextCell.self, forCellReuseIdentifier: "\(QChatTextCell.self)") - tableView.register( - QChatImageTextCell.self, - forCellReuseIdentifier: "\(QChatImageTextCell.self)" - ) - loadData() - } - - func loadData() { - let type: ChannelMemberRoleType = type == .white ? .white : .black - let param = GetChannelBlackWhiteMembers( - serverId: channel?.serverId, - channelId: channel?.channelId, - timeTag: 0, - limit: 20, - type: type - ) - QChatChannelProvider.shared - .getBlackWhiteMembersByPage(param: param) { [weak self] error, result in - self?.memberArray = result?.memberArray - self?.tableView.reloadData() - } - } - - func numberOfSections(in tableView: UITableView) -> Int { - 2 - } - - override public func tableView(_ tableView: UITableView, - numberOfRowsInSection section: Int) -> Int { - if section == 0 { - return 1 - } else { - return memberArray?.count ?? 0 - } - } - - override public func tableView(_ tableView: UITableView, - cellForRowAt indexPath: IndexPath) -> UITableViewCell { - if indexPath.section == 0 { - let cell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatTextCell.self)", - for: indexPath - ) as! QChatTextCell - cell.backgroundColor = .white - cell.rightStyle = .indicate - cell.titleLabel.text = localizable("add_member") - return cell - } else { - let cell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatImageTextCell.self)", - for: indexPath - ) as! QChatImageTextCell - cell.backgroundColor = .white - let member = memberArray?[indexPath.row] - cell.setup(accid: member?.accid, nickName: member?.nick) - cell.rightStyle = isEdited ? .delete : .none -// if CoreKitEngine.instance.imAccid == member?.accid, self.type == .white { -// cell.rightStyle = .none -// } - if IMKitEngine.instance.imAccid == member?.accid, type == .white { - cell.rightStyle = .none - } - return cell - } - } - - func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - if indexPath.section == 0 { - // present add memeber VC - let memberSelect = QChatMemberSelectController() - memberSelect.serverId = channel?.serverId -// memberSelect.selectType = .ServerMember - memberSelect.delegate = self - memberSelect.completion = { [weak self] datas in - // 选中成员 - if datas.count > 0 { - var seletedMembers = [ServerMemeber]() - for data in datas { - if let m = data.serverMember { - seletedMembers.append(m) - } - } - self? - .addMemberList(members: seletedMembers, type: self?.type ?? .white) { error in - if error != nil { - self?.view.makeToast(error?.localizedDescription) - } else { - for m in seletedMembers { - self?.memberArray?.append(m) - } - self?.tableView.reloadData() - } - } - } - } - navigationController?.pushViewController(memberSelect, animated: true) - } else { - if isEdited { - guard let member = memberArray?[indexPath.row] else { - return - } - -// if CoreKitEngine.instance.imAccid == member.accid, self.type == .white { -// return -// } - - if IMKitEngine.instance.imAccid == member.accid, type == .white { - return - } - - let name = (member.nick != nil ? member.nick : member.accid) ?? "" - let message = localizable("confirm_delete_channel") + name + - localizable("qchat_member") + "?" - let alertVC = UIAlertController.reconfimAlertView( - title: localizable("removeMember"), - message: message - ) { - let members = [member] - self.removeMemberList(members: members, type: self.type) { [weak self] error in - if error != nil { - self?.view.makeToast(error?.localizedDescription) - } else { - if var members = self?.memberArray { - var index = -1 - for (i, m) in members.enumerated() { - if m.accid == member.accid { - index = i - break - } - } - if index >= 0 { - members.remove(at: index) - self?.memberArray = members - self?.tableView.reloadData() - } - } - } - } - } - present(alertVC, animated: true, completion: nil) - } - } - } - - // 添加黑白名单 - private func addMemberList(members: [ServerMemeber]?, type: RoleType, - _ completion: @escaping (NSError?) -> Void) { - guard let ms = members else { - return - } - var accids = [String]() - for m in ms { - accids.append(m.accid ?? "") - } - let param = UpdateChannelBlackWhiteMembersParam( - serverId: channel?.serverId, - channelId: channel?.channelId, - type: type == .white ? .white : .black, - opeType: .add, - accids: accids - ) - QChatChannelProvider.shared.updateBlackWhiteMembers(param: param, completion) - } - - // 移除黑白名单 - private func removeMemberList(members: [ServerMemeber]?, type: RoleType, - _ completion: @escaping (NSError?) -> Void) { - guard let ms = members else { - return - } - var accids = [String]() - for m in ms { - if let id = m.accid { - accids.append(id) - } - } - let param = UpdateChannelBlackWhiteMembersParam( - serverId: channel?.serverId, - channelId: channel?.channelId, - type: type == .white ? .white : .black, - opeType: .remove, - accids: accids - ) - QChatChannelProvider.shared.updateBlackWhiteMembers(param: param, completion) - } - - // MARK: - event - - @objc func edit() { - isEdited = !isEdited - if isEdited { - navigationItem.rightBarButtonItem?.title = localizable("qchat_save") - // TODO: reload data - } else { - navigationItem.rightBarButtonItem?.title = localizable("qchat_edit") - // TODO: reload data - } - tableView.reloadData() - } - - public func filterMembers(accid: [String]?, _ filterMembers: @escaping ([String]?) -> Void) { - let type: ChannelMemberRoleType = type == .white ? .white : .black - let param = GetExistingChannelBlackWhiteMembersParam( - serverId: channel?.serverId, - channelId: channel?.channelId, - type: type, - accIds: accid - ) - QChatChannelProvider.shared - .getExistingChannelBlackWhiteMembers(param: param) { error, result in - if let members = result?.memberArray, !members.isEmpty { - var accidArray = [String]() - for member in members { - if let id = member.accid { - accidArray.append(id) - } - } - filterMembers(accidArray) - } else { - filterMembers(nil) - } - } - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewModel/QChatAuthoritySettingViewModel.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewModel/QChatAuthoritySettingViewModel.swift deleted file mode 100644 index 8d6b61ac..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewModel/QChatAuthoritySettingViewModel.swift +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -import NECoreIMKit -import NEQChatKit - -@objcMembers -public class QChatAuthoritySettingViewModel: NSObject { - public var channel: ChatChannel? - public var rolesData = QChatRoles() - public var membersData = QChatRoles() - - private var repo = QChatRepo() - private let className = "QChatAuthoritySettingViewModel" - - init(channel: ChatChannel?) { - self.channel = channel - } - - func firstGetChannelRoles(_ completion: @escaping (Error?, [RoleModel]?) -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function) - rolesData.timeTag = 0 - rolesData.roles = [RoleModel]() - getChannelRoles(completion) - } - - func getChannelRoles(_ completion: @escaping (Error?, [RoleModel]?) -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function) - guard let sid = channel?.serverId, let cid = channel?.channelId else { - completion(NSError.paramError(), nil) - return - } - var param = ChannelRoleParam(serverId: sid, channelId: cid) - param.limit = rolesData.pageSize - param.timeTag = rolesData.timeTag - repo.getChannelRoles(param) { [weak self] error, roleList in - print("error:\(error) roleList:\(roleList)") - if error != nil { - completion(error, self?.rolesData.roles) - } else { - // 移除占位 - if let last = self?.rolesData.roles.last, last.isPlacehold { - self?.rolesData.roles.removeLast() - } - - if let roles = roleList, roles.count > 0 { - // 添加身份组 - for role in roles { - var model = RoleModel() - model.role = role - self?.rolesData.roles.append(model) - } - // 记录最后一个身份组的时间戳 用于下页请求 - self?.rolesData.timeTag = self?.rolesData.roles.last?.role?.createTime - - // 添加占位 - if roles.count >= self?.rolesData.pageSize ?? 5 { - var placeholdModel = RoleModel() - placeholdModel.title = localizable("more") - placeholdModel.isPlacehold = true - self?.rolesData.roles.append(placeholdModel) - } - self?.setRoundedCorner() - // 设置圆角 - completion(error, self?.rolesData.roles) - } else { - // 设置圆角 - self?.setRoundedCorner() - completion(error, self?.rolesData.roles) - } - } - } - } - - func firstGetMembers(_ completion: @escaping (Error?, [RoleModel]?) -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function) - membersData.pageSize = 50 - membersData.timeTag = 0 - membersData.roles = [RoleModel]() - getMembers(completion) - } - - func getMembers(_ completion: @escaping (Error?, [RoleModel]?) -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function) - guard let sid = channel?.serverId, let cid = channel?.channelId else { - completion(NSError.paramError(), nil) - return - } - var param = GetMemberRolesParam() - param.serverId = sid - param.channelId = cid - param.limit = membersData.pageSize - param.timeTag = membersData.timeTag - - repo.getMemberRoles(param: param) { [weak self] error, memberRoles in - print("error:\(error) memberArray:\(memberRoles)") - if error != nil { - completion(error, self?.membersData.roles) - } else { - // 移除占位 - if let last = self?.membersData.roles.last, last.isPlacehold { - self?.membersData.roles.removeLast() - } - if let members = memberRoles, members.count > 0 { - // 添加成员 - for member in members { - var model = RoleModel() - model.member = member - self?.membersData.roles.append(model) - } - // 记录最后一个身份组的时间戳 用于下页请求 - self?.membersData.timeTag = self?.membersData.roles.last?.member?.createTime - - // 添加占位 - if members.count == self?.rolesData.pageSize { - var placeholdModel = RoleModel() - placeholdModel.title = localizable("more") - placeholdModel.isPlacehold = true - self?.membersData.roles.append(placeholdModel) - } - self?.setRoundedCorner() - // 设置圆角 - completion(error, self?.membersData.roles) - } else { - // 设置圆角 - self?.setRoundedCorner() - completion(error, self?.membersData.roles) - } - } - } - } - - public func removeChannelRole(role: ChannelRole?, index: Int, - _ completion: @escaping (NSError?) -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(role?.serverId ?? 0)") - var param = RemoveChannelRoleParam() - param.serverId = role?.serverId - param.roleId = UInt64(role?.roleId ?? 0) - param.channelId = role?.channelId - repo.removeChannelRole(param: param) { [weak self] anError in - if anError == nil { - self?.rolesData.roles.remove(at: index) - completion(anError) - } - completion(anError) - } - } - - public func removeMemberRole(member: MemberRole?, index: Int, - _ completion: @escaping (NSError?) -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(member?.serverId ?? 0)") - let param = RemoveMemberRoleParam( - serverId: channel?.serverId, - channelId: channel?.channelId, - accid: member?.accid - ) - repo.removeMemberRole(param: param) { [weak self] anError in - if anError == nil { - self?.membersData.roles.remove(at: index) - } - completion(anError) - } - } - -// 本地插入成员 - public func insertLocalMemberAtHead(member: MemberRole) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(member.serverId ?? 0)") - let model = RoleModel(member: member, isPlacehold: false) - membersData.roles.insert(model, at: 0) - setRoundedCorner() - } - -// 本地插入身份组 - public func insertLocalRoleAtHead(role: ChannelRole) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(role.serverId ?? 0)") - let model = RoleModel(role: role, isPlacehold: false) - rolesData.roles.insert(model, at: 0) - setRoundedCorner() - } - - private func setRoundedCorner() { - NELog.infoLog(ModuleName + " " + className, desc: #function) - if rolesData.roles.count > 0 { - if rolesData.roles.count == 1 { - rolesData.roles[0].corner = .all - } else { - rolesData.roles[0].corner = .top - rolesData.roles[rolesData.roles.count - 1].corner = .bottom - } - } - if membersData.roles.count > 0 { - if membersData.roles.count == 1 { - membersData.roles[0].corner = .all - } else { - membersData.roles[0].corner = .top - membersData.roles[membersData.roles.count - 1].corner = .bottom - } - } - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewModel/QChatChannelViewModel.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewModel/QChatChannelViewModel.swift deleted file mode 100644 index 3e22b096..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewModel/QChatChannelViewModel.swift +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -import NECoreIMKit - -@objcMembers -public class QChatChannelViewModel: NSObject { - public var serverId: UInt64 - public var name: String? - public var topic: String? - public var type: ChannelType = .messageType - public var isPrivate: Bool = false - private let className = "QChatChannelViewModel" - - public init(serverId: UInt64) { - self.serverId = serverId - } - - override public init() { - serverId = 0 - } - - public func createChannel(_ completion: @escaping (NSError?, ChatChannel?) -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function) - let visibleType: ChannelVisibleType = isPrivate ? .isPrivate : .isPublic - let param = CreatChannelParam( - serverId: serverId, - name: name ?? "", - topic: topic, - visibleType: visibleType - ) - QChatChannelProvider.shared.createChannel(param: param) { error, channel in - completion(error, channel) - } - } - - public func getChannelsByPage(parameter: QChatGetChannelsByPageParam, - _ completion: @escaping (NSError?, QChatGetChannelsByPageResult?) - -> Void) { - NELog.infoLog( - ModuleName + " " + className, - desc: #function + ", serverId:\(parameter.serverId ?? 0)" - ) - QChatChannelProvider.shared.getChannelsByPage(param: parameter) { error, channelResult in - completion(error, channelResult) - } - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewModel/QChatUpdateChannelViewModel.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewModel/QChatUpdateChannelViewModel.swift deleted file mode 100644 index 10052991..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Channel/ViewModel/QChatUpdateChannelViewModel.swift +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -import NECoreIMKit -import NEQChatKit - -@objcMembers -public class QChatUpdateChannelViewModel: NSObject { - public var channel: ChatChannel? - // 临时记录修改的值 - public var channelTmp: ChatChannel? - private let className = "QChatUpdateChannelViewModel" - - init(channel: ChatChannel?) { - NELog.infoLog(ModuleName + " " + className, desc: #function) - self.channel = channel - channelTmp = channel - } - - func updateChannelInfo(completion: @escaping (NSError?, ChatChannel?) -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function) - var param = UpdateChannelParam(channelId: channel?.channelId) - param.name = channelTmp?.name - param.topic = channelTmp?.topic - param.custom = channelTmp?.custom - QChatRepo().updateChannelInfo(param) { [weak self] error, channel in - if error == nil { - self?.channel = channel - } - completion(error, channel) - } - } - - func deleteChannel(completion: @escaping (NSError?) -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function) - QChatChannelProvider.shared.deleteChannel(channelId: channel?.channelId, completion) - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Chat/Controller/QChatViewController.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Chat/Controller/QChatViewController.swift deleted file mode 100644 index 9d386367..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Chat/Controller/QChatViewController.swift +++ /dev/null @@ -1,445 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NECoreIMKit -// import IQKeyboardManagerSwift -import NIMSDK -import MJRefresh -import NECommonUIKit -import NECommonKit -import NECoreKit - -public class QChatViewController: NEBaseViewController, UINavigationControllerDelegate, - QChatInputViewDelegate, QChatViewModelDelegate, UITableViewDataSource, UITableViewDelegate { - private let tag = "QChatViewController" - private var viewmodel: QChatViewModel? - private var inputViewBottomConstraint: NSLayoutConstraint? - private var tableViewBottomConstraint: NSLayoutConstraint? - - public init(channel: ChatChannel?) { - super.init(nibName: nil, bundle: nil) - viewmodel = QChatViewModel(channel: channel) - viewmodel?.delegate = self - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override public func viewDidLoad() { - super.viewDidLoad() - commonUI() - addObseve() - loadData() - print("current view frame :", view.frame) - } - - // MARK: lazy Method - - private lazy var brokenNetworkView: NEBrokenNetworkView = { - let view = - NEBrokenNetworkView(frame: CGRect(x: 0, y: kNavigationHeight + KStatusBarHeight, - width: kScreenWidth, height: 36)) - return view - }() - - private lazy var tableView: UITableView = { - let tableView = UITableView(frame: .zero, style: .plain) - tableView.translatesAutoresizingMaskIntoConstraints = false - tableView.separatorStyle = .none - tableView.showsVerticalScrollIndicator = false - tableView.delegate = self - tableView.dataSource = self - tableView.backgroundColor = .white - tableView.mj_header = MJRefreshNormalHeader( - refreshingTarget: self, - refreshingAction: #selector(loadMoreData) - ) - return tableView - }() - - deinit { - NELog.infoLog(ModuleName + " " + self.tag, desc: "✅ QChatViewController release") - } - - func commonUI() { - title = viewmodel?.channel?.name - addLeftAction(UIImage.ne_imageNamed(name: "server_menu"), #selector(enterServerVC), self) - addRightAction( - UIImage.ne_imageNamed(name: "channel_member"), - #selector(enterChannelMemberVC), - self - ) - - view.addSubview(tableView) - tableViewBottomConstraint = tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -100) - tableViewBottomConstraint?.isActive = true - - NSLayoutConstraint.activate([ - tableView.topAnchor.constraint( - equalTo: view.topAnchor, - constant: kNavigationHeight + KStatusBarHeight - ), - tableView.leftAnchor.constraint(equalTo: view.leftAnchor), - tableView.rightAnchor.constraint(equalTo: view.rightAnchor), - ]) - - tableView.register( - QChatBaseTableViewCell.self, - forCellReuseIdentifier: "\(QChatBaseTableViewCell.self)" - ) - tableView.register( - QChatTextTableViewCell.self, - forCellReuseIdentifier: "\(QChatTextTableViewCell.self)" - ) - tableView.register( - QChatImageTableViewCell.self, - forCellReuseIdentifier: "\(QChatImageTableViewCell.self)" - ) - tableView.register( - QChatTimeTableViewCell.self, - forCellReuseIdentifier: "\(QChatTimeTableViewCell.self)" - ) - // IQKeyboardManager.shared.enable = false - -// NEKeyboardManager.shared.keyboardDistanceFromTextField = 60 - NEKeyboardManager.shared.enable = true - NEKeyboardManager.shared.enableAutoToolbar = false - let inputView = QChatInputView() - var tip = localizable("send_to") - if let cName = viewmodel?.channel?.name { - tip += cName - } - inputView.textField.placeholder = tip - - inputView.translatesAutoresizingMaskIntoConstraints = false - inputView.delegate = self - view.addSubview(inputView) - if #available(iOS 11.0, *) { - self.inputViewBottomConstraint = inputView.bottomAnchor - .constraint(equalTo: self.view.bottomAnchor) -// self.inputViewBottomConstraint = inputView.bottomAnchor.constraint(equalTo: -// self.view.safeAreaLayoutGuide.bottomAnchor) - NSLayoutConstraint.activate([ - inputView.leftAnchor.constraint(equalTo: self.view.leftAnchor), - inputView.rightAnchor.constraint(equalTo: self.view.rightAnchor), - inputView.heightAnchor.constraint(equalToConstant: 100), - ]) - } else { - // Fallback on earlier versions - inputViewBottomConstraint = inputView.bottomAnchor - .constraint(equalTo: view.bottomAnchor) - NSLayoutConstraint.activate([ - inputView.leftAnchor.constraint(equalTo: view.leftAnchor), - inputView.rightAnchor.constraint(equalTo: view.rightAnchor), - inputView.heightAnchor.constraint(equalToConstant: 100), - ]) - } - inputViewBottomConstraint?.isActive = true - - weak var weakSelf = self - NEChatDetectNetworkTool.shareInstance.netWorkReachability { status in - if status == .notReachable, let networkView = weakSelf?.brokenNetworkView { - weakSelf?.view.addSubview(networkView) - } else { - weakSelf?.brokenNetworkView.removeFromSuperview() - } - } - } - - // MARK: event - - @objc func enterChannelMemberVC() { - let memberVC = QChatChannelMembersVC() - memberVC.channel = viewmodel?.channel - navigationController?.pushViewController(memberVC, animated: true) - } - - @objc func enterServerVC() { - navigationController?.popViewController(animated: true) - } - - func loadData() { - weak var weakSelf = self - viewmodel?.getMessageHistory { error, messages in - - if let err = error { - NELog.errorLog(ModuleName + " " + self.tag, desc: "❌getMessageHistory error, error:\(err)") - } else { - if let tempArray = weakSelf?.viewmodel?.messages, tempArray.count > 0 { - weakSelf?.tableView.reloadData() - weakSelf?.tableView.scrollToRow( - at: IndexPath(row: tempArray.count - 1, section: 0), - at: .bottom, - animated: false - ) - if let time = messages?.first?.message?.timestamp { - weakSelf?.viewmodel?.markMessageRead(time: time) - } - } - } - } - } - - @objc func loadMoreData() { - weak var weakSelf = self - viewmodel?.getMoreMessageHistory { error, messageFrames in - NELog.infoLog( - ModuleName + " " + self.tag, - desc: "CALLBACK getMoreMessageHistory " + (error?.localizedDescription ?? "no error") - ) - weakSelf?.tableView.reloadData() - weakSelf?.tableView.mj_header?.endRefreshing() - } - } - - func addObseve() { - NotificationCenter.default.addObserver( - self, - selector: #selector(onUpdateChannel), - name: NotificationName.updateChannel, - object: nil - ) - NotificationCenter.default.addObserver( - self, - selector: #selector(onDeleteChannel), - name: NotificationName.deleteChannel, - object: nil - ) - NotificationCenter.default.addObserver(self, - selector: #selector(keyBoardWillShow(_:)), - name: UIResponder.keyboardWillShowNotification, - object: nil) - - NotificationCenter.default.addObserver(self, - selector: #selector(keyBoardWillHide(_:)), - name: UIResponder.keyboardWillHideNotification, - object: nil) - } - - @objc func onUpdateChannel(noti: Notification) { - // enter ChatVC - guard let channel = noti.object as? ChatChannel else { - return - } - viewmodel?.channel = channel - title = viewmodel?.channel?.name - } - - @objc func onDeleteChannel(noti: Notification) { - navigationController?.popToRootViewController(animated: true) - } - - // MARK: 键盘通知相关操作 - - @objc func keyBoardWillShow(_ notification: Notification) { - let keyboardRect = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as! - NSValue).cgRectValue - inputViewBottomConstraint?.constant = -keyboardRect.size.height - tableViewBottomConstraint?.constant = -100 - keyboardRect.size.height - UIView.animate(withDuration: 0.25, animations: { - // self.view.layoutIfNeeded() - }) - if let count = viewmodel?.messages.count, count > 0 { - print("count \(count)") - tableView.scrollToRow(at: IndexPath(row: count - 1, section: 0), at: .bottom, animated: true) - } - } - - @objc func keyBoardWillHide(_ notification: Notification) { - inputViewBottomConstraint?.constant = 0 - tableViewBottomConstraint?.constant = -100 - UIView.animate(withDuration: 0.25, animations: { - // self.view.layoutIfNeeded() - }) - } - - // MARK: QChatInputViewDelegate - - func sendText(text: String?) { - NELog.infoLog(ModuleName + " " + tag, desc: "sendText:\(text ?? "")") - guard let content = text, content.count > 0 else { - return - } - viewmodel?.sendTextMessage(text: content) { [weak self] error in - NELog.infoLog( - ModuleName + " " + (self?.tag ?? "QChatViewController"), - desc: "CALLBACK sendTextMessage " + (error?.localizedDescription ?? "no error") - ) - if error != nil { - self?.view.makeToast(error?.localizedDescription) - } else {} - } - } - - func willSelectItem(button: UIButton, index: Int) { - if index == 2 { - showBottomAlert(self, false) - } else { - showToast(localizable("open_soon")) - } - } - - // MARK: UIImagePickerControllerDelegate - - public func imagePickerController(_ picker: UIImagePickerController, - didFinishPickingMediaWithInfo info: [UIImagePickerController - .InfoKey: Any]) { - picker.dismiss(animated: true, completion: nil) - guard let image = info[.originalImage] as? UIImage else { - showToast(localizable("image_is_nil")) - return - } - // 发送消息 - viewmodel?.sendImageMessage(image: image) { [weak self] error in - NELog.infoLog( - ModuleName + " " + (self?.tag ?? "QChatViewController"), - desc: "CALLBACK sendImageMessage " + (error?.localizedDescription ?? "no error") - ) - if error != nil { - self?.view.makeToast(error?.localizedDescription) - } - } - } - - // MARK: QChatViewModelDelegate - - public func onRecvMessages(_ messages: [NIMQChatMessage]) { - tableView.reloadData() - if let messageCount = viewmodel?.messages.count, messageCount > 1 { - tableView.scrollToRow( - at: IndexPath(row: messageCount - 1, section: 0), - at: .bottom, - animated: false - ) - if let time = viewmodel?.messages.last?.message?.timestamp { - viewmodel?.markMessageRead(time: time) - } - } - } - - public func send(_ message: NIMQChatMessage, progress: Float) {} - - public func send(_ message: NIMQChatMessage, didCompleteWithError error: Error?) { - if let e = error as NSError? { - if e.code == 403 { - showAlert(message: localizable("no_Permession")) {} - } - } - tableView.reloadData() - if let messageCount = viewmodel?.messages.count, messageCount > 1 { - tableView.scrollToRow( - at: IndexPath(row: messageCount - 1, section: 0), - at: .bottom, - animated: false - ) - } - } - - public func willSend(_ message: NIMQChatMessage) { - tableView.reloadData() - if let messageCount = viewmodel?.messages.count, messageCount > 1 { - tableView.scrollToRow( - at: IndexPath(row: messageCount - 1, section: 0), - at: .bottom, - animated: false - ) - } - } - - // MARK: UITableViewDataSource, UITableViewDelegate - - public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - viewmodel?.messages.count ?? 0 - } - - public func tableView(_ tableView: UITableView, - cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let messageFrame = viewmodel?.messages[indexPath.row] - var reuseIdentifier = "\(QChatBaseTableViewCell.self)" - - guard let msgFrame = messageFrame else { - return tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) - } - - if msgFrame.showTime { - reuseIdentifier = "\(QChatTimeTableViewCell.self)" - } else { - // 根据cell类型区分identify - switch msgFrame.message?.messageType { - case .text: - reuseIdentifier = "\(QChatTextTableViewCell.self)" - case .image: - reuseIdentifier = "\(QChatImageTableViewCell.self)" - default: - reuseIdentifier = "\(QChatBaseTableViewCell.self)" - } - } - - if msgFrame.showTime { - let cell = tableView.dequeueReusableCell( - withIdentifier: reuseIdentifier, - for: indexPath - ) as! QChatTimeTableViewCell - cell.messageFrame = messageFrame - return cell - } else { - let cell = tableView.dequeueReusableCell( - withIdentifier: reuseIdentifier, - for: indexPath - ) as! QChatBaseTableViewCell - cell.messageFrame = messageFrame - cell.delegate = self - return cell - } - } - - public func tableView(_ tableView: UITableView, - heightForRowAt indexPath: IndexPath) -> CGFloat { - let messageFrame = viewmodel?.messages[indexPath.row] - return messageFrame?.cellHeight ?? 0 - } -} - -// MARK: =============== QChatBaseCellDelegate ================ - -extension QChatViewController: QChatBaseCellDelegate { - func didSelectWithCell(cell: QChatBaseTableViewCell, type: QChatMessageClickType, - message: NIMQChatMessage) { - if type == .message { - didClickMessage(messgae: message) - } else if type == .LongPressMessage {} - } - - func didClickHeader(_ message: NIMQChatMessage) { - if IMKitEngine.instance.isMySelf(message.from) == true { - Router.shared.use( - MeSettingRouter, - parameters: ["nav": navigationController as Any], - closure: nil - ) - } else { - Router.shared.use( - ContactUserInfoPageRouter, - parameters: ["nav": navigationController as Any, "uid": message.from as Any], - closure: nil - ) - } - } - - // click action - func didClickMessage(messgae: NIMQChatMessage) { - if messgae.messageType == .image { - let imageObject = messgae.messageObject as! NIMImageObject - if let imageUrl = imageObject.url { - let showController = PhotoBrowserController(urls: [imageUrl], url: imageUrl) - showController.modalPresentationStyle = .overFullScreen - present(showController, animated: false, completion: nil) - } - - } else if messgae.messageType == .audio {} - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Chat/Helper/QChatMessageHelper.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Chat/Helper/QChatMessageHelper.swift deleted file mode 100644 index ca13a866..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Chat/Helper/QChatMessageHelper.swift +++ /dev/null @@ -1,35 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation - -class QChatMessageHelper { - // 获取图片合适尺寸 - class func getSizeWithMaxSize(_ maxSize: CGSize, size: CGSize, miniWH: CGFloat) -> CGSize { - var realSize = CGSize.zero - - if min(size.width, size.height) > 0 { - if size.width > size.height { - // 宽大 按照宽给高 - let width = CGFloat(min(maxSize.width, size.width)) - realSize = CGSize(width: width, height: width * size.height / size.width) - if realSize.height < miniWH { - realSize.height = miniWH - } - } else { - // 高大 按照高给宽 - let height = CGFloat(min(maxSize.height, size.height)) - realSize = CGSize(width: height * size.width / size.height, height: height) - if realSize.width < miniWH { - realSize.width = miniWH - } - } - } else { - realSize = maxSize - } - - return realSize - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Chat/Model/QChatMessageFrame.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Chat/Model/QChatMessageFrame.swift deleted file mode 100644 index a14fc714..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Chat/Model/QChatMessageFrame.swift +++ /dev/null @@ -1,119 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NIMSDK -public class QChatMessageFrame: NSObject { - // 是否显示时间 - public var showTime: Bool = false - // 具体时间 - public var time: String? - // 是否显示头像 - public var showAvatar: Bool = true - // 用户头像地址 - public var avatar: String? - // nickname - public var nickname: String? - // 发送者是否为自己 -// public var isSender:Bool? - // 头像frame - public var headFrame: CGRect? - // 内容frame - public var contentFrame: CGRect? - // cell整体高度 - public var cellHeight: CGFloat = 0.0 - // X初始位置 - public var startX: CGFloat = 0.0 - -// public init(isSender:Bool) { -// self.isSender = isSender -// } - - public var message: NIMQChatMessage? { - didSet { - var contentSize = CGSize.zero - - switch message?.messageType { - case .text: // 计算文本 - - contentSize = String.getTextRectSize( - message?.text ?? "", - font: DefaultTextFont(16), - size: CGSize(width: qChat_content_maxW, height: CGFloat.greatestFiniteMagnitude) - ) - if contentSize.height < qChat_min_h { // 小于一行高度,就保持一行 - contentSize.height = qChat_min_h - } - contentSize.width += 2 * qChat_margin - case .image: // 计算图片类型 - if let imageObject = message?.messageObject, - imageObject.isKind(of: NIMImageObject.self) { - let obj = (imageObject as! NIMImageObject) - contentSize = QChatMessageHelper.getSizeWithMaxSize( - qChat_pic_size, - size: obj.size, - miniWH: qChat_min_h - ) - } else { - contentSize = qChat_pic_size - } - - default: - print("others") - } - - // 计算头像 - var headFrameX = qChat_cell_margin - let headFrameY = qChat_margin - - guard let msg = message else { - return - } - - if msg.isOutgoingMsg { // 消息发送者 - headFrameX = kScreenWidth - headFrameX - qChat_headWH - } - headFrame = CGRect( - x: headFrameX, - y: headFrameY, - width: qChat_headWH, - height: qChat_headWH - ) - - let viewY = qChat_margin - - // 聊天气泡的frame - var viewX = 0.0 - - viewX = headFrame!.maxX + qChat_margin - if msg.isOutgoingMsg { // 消息发送者 - viewX = kScreenWidth - contentSize - .width - qChat_margin - qChat_headWH - qChat_cell_margin - } - contentFrame = CGRect( - x: viewX, - y: viewY, - width: contentSize.width, - height: contentSize.height - ) - - // cell 高度 - cellHeight = contentSize.height + qChat_margin - - if let type = message?.messageType { - if type == .text, contentSize.height > qChat_min_h { - if let height = contentFrame?.size.height { - contentFrame?.size.height = height + qChat_margin * 2 - } - cellHeight += qChat_margin * 2 - } - } - - // 起始位置 -// _startX = isSend ? 0 : kChat_angle_w; - startX = 0 - } - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Chat/View/Cell/QChatBaseTableViewCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Chat/View/Cell/QChatBaseTableViewCell.swift deleted file mode 100644 index 5e0a4d07..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Chat/View/Cell/QChatBaseTableViewCell.swift +++ /dev/null @@ -1,166 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NIMSDK -import NECoreKit - -@objc class QChatBubbleButton: UIButton { - // 设置气泡背景图片 - public func setBubbleImage(image: UIImage) { - let image = image - .resizableImage(withCapInsets: UIEdgeInsets(top: 35, left: 25, bottom: 10, right: 25)) - setBackgroundImage(image, for: .normal) - setBackgroundImage(image, for: .highlighted) - } - - override init(frame: CGRect) { - super.init(frame: frame) - imageView?.contentMode = .scaleAspectFill - } - - required init?(coder: NSCoder) { - super.init(coder: coder) - } -// //设置气泡背景色 -// public func setBubbleImage(color:UIColor){ -// let image = self.currentBackgroundImage -// } -} - -enum QChatMessageClickType: String { - case message - case LongPressMessage - case head - case retry -} - -protocol QChatBaseCellDelegate: NSObjectProtocol { - // click action - func didSelectWithCell(cell: QChatBaseTableViewCell, type: QChatMessageClickType, - message: NIMQChatMessage) - - func didClickHeader(_ message: NIMQChatMessage) -} - -class QChatBaseTableViewCell: UITableViewCell { - weak var delegate: QChatBaseCellDelegate? - - override func awakeFromNib() { - super.awakeFromNib() - // Initialization code - } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - - // Configure the view for the selected state - } - - public var messageFrame: QChatMessageFrame? { - didSet { - self.btnHeadImage.frame = messageFrame?.headFrame ?? CGRect.zero - self.contentBtn.frame = messageFrame?.contentFrame ?? CGRect.zero - - // TODO: 头像赋值 - if let icon = messageFrame?.avatar { - btnHeadImage.setTitle("") - btnHeadImage.sd_setImage(with: URL(string: icon), completed: nil) - } else { - if let sendName = messageFrame?.message?.senderName { - btnHeadImage.setTitle(sendName) - } else { - btnHeadImage.setTitle(messageFrame?.message?.from ?? "") - } - btnHeadImage.sd_setImage(with: nil, completed: nil) - btnHeadImage.backgroundColor = UIColor.colorWithNumber(number: 0) - } - - guard let msg = messageFrame?.message else { - return - } - if msg.isOutgoingMsg { - self.contentBtn - .setBubbleImage(image: UIImage.ne_imageNamed(name: "chat_message_send")!) - // 设置消息状态 判断消息发送是否成功 - if msg.deliveryState == NIMMessageDeliveryState.delivering { - self.activityView.frame = CGRect( - x: contentBtn.left - (5 + 20), - y: contentBtn.top + (contentBtn.height - 20) / 2, - width: 20, - height: 20 - ) - self.activityView.messageStatus = .sending - } else if msg.deliveryState == NIMMessageDeliveryState.deliveried { - self.activityView.messageStatus = .successed - } else { - self.activityView.messageStatus = .failed - } - - } else { - self.contentBtn - .setBubbleImage(image: UIImage.ne_imageNamed(name: "chat_message_receive")!) - } - } - } - - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - selectionStyle = .none - contentView.backgroundColor = .white - addContentSubviews() - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - public func addContentSubviews() { - contentView.addSubview(btnHeadImage) - contentView.addSubview(contentBtn) - contentView.addSubview(activityView) - } - - override func draw(_ rect: CGRect) { - btnHeadImage.addCorner(conrners: .allCorners, radius: 16) - } - - private lazy var btnHeadImage: NEUserHeaderView = { - let view = NEUserHeaderView(frame: .zero) - let tap = UITapGestureRecognizer() - view.addGestureRecognizer(tap) - tap.numberOfTapsRequired = 1 - tap.numberOfTouchesRequired = 1 - tap.addTarget(self, action: #selector(headerClick)) - return view - }() - - public lazy var contentBtn: QChatBubbleButton = { - let btn = QChatBubbleButton(frame: .zero) - btn.addTarget(self, action: #selector(bubbleClick), for: .touchUpInside) - return btn - }() - - public lazy var activityView: QChatActivityIndicatorView = { - let activityView = QChatActivityIndicatorView() - activityView.isHidden = true - return activityView - }() -} - -extension QChatBaseTableViewCell { - @objc func bubbleClick(sender: UIButton) { - if let message = messageFrame?.message { - delegate?.didSelectWithCell(cell: self, type: .message, message: message) - } - } - - @objc func headerClick() { - NELog.infoLog("chat base cell", desc: "header click") - if let message = messageFrame?.message { - delegate?.didClickHeader(message) - } - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Chat/View/Cell/QChatImageTableViewCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Chat/View/Cell/QChatImageTableViewCell.swift deleted file mode 100644 index 1e8dbce8..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Chat/View/Cell/QChatImageTableViewCell.swift +++ /dev/null @@ -1,49 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -import UIKit -import NIMSDK -class QChatImageTableViewCell: QChatBaseTableViewCell { - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - private lazy var contentImageView: UIImageView = { - let imageView = UIImageView() - imageView.contentMode = .scaleAspectFill - self.contentBtn.addSubview(imageView) - imageView.clipsToBounds = true - return imageView - }() - - override public var messageFrame: QChatMessageFrame? { - didSet { - let imageObject = messageFrame?.message?.messageObject as! NIMImageObject - contentImageView.frame = CGRect( - x: qChat_margin, - y: qChat_margin, - width: contentBtn.width - 2 * qChat_margin, - height: contentBtn.height - 2 * qChat_margin - ) - - if let imageUrl = imageObject.url { - contentImageView.sd_setImage( - with: URL(string: imageUrl), - placeholderImage: nil, - options: .retryFailed, - progress: nil, - completed: nil - ) - } else { - contentImageView.image = UIImage() - } - } - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Chat/View/Cell/QChatTextTableViewCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Chat/View/Cell/QChatTextTableViewCell.swift deleted file mode 100644 index b57484fd..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Chat/View/Cell/QChatTextTableViewCell.swift +++ /dev/null @@ -1,92 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class QChatTextTableViewCell: QChatBaseTableViewCell { - override func awakeFromNib() { - super.awakeFromNib() - // Initialization code - } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - - // Configure the view for the selected state - } - - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - } - - override public var messageFrame: QChatMessageFrame? { - didSet { -// // SHMessage *message = messageFrame.message; - textView.text = messageFrame?.message?.text - var viewY = qChat_margin - if contentBtn.height == qChat_min_h { - viewY = (qChat_min_h - DefaultTextFont(16).lineHeight) / 2 - } - - // 此处要根据发送者还是接收者判断起始x值 - let leftStartMargin = messageFrame?.startX - textView.frame = CGRect( - x: (leftStartMargin ?? 0) + qChat_margin, - y: viewY, - width: contentBtn.width - 2 * qChat_margin - qChat_angle_w, - height: contentBtn.height - 2 * viewY - ) - } - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - private lazy var textView: QChatTextView = { - let textview = QChatTextView() - textview.isEditable = false - textview.isScrollEnabled = false - textview.showsVerticalScrollIndicator = false - textview.textContainer.maximumNumberOfLines = 0 - self.contentBtn.addSubview(textview) - return textview - }() -} - -class QChatTextView: UITextView { - override init(frame: CGRect, textContainer: NSTextContainer?) { - super.init(frame: frame, textContainer: textContainer) - setupUI() - } - - public required init?(coder aDecoder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - func setupUI() { - backgroundColor = .clear - textContainer.lineFragmentPadding = 0 - textContainerInset = .zero - dataDetectorTypes = .all - autoresizingMask = [.flexibleWidth, .flexibleHeight] - font = DefaultTextFont(16) - } - - override var textContainerInset: UIEdgeInsets { - set { - let padding = textContainer.lineFragmentPadding - super.textContainerInset = UIEdgeInsets( - top: newValue.top, - left: newValue.left - padding, - bottom: newValue.bottom, - right: newValue.right - padding - ) - } - get { - super.textContainerInset - } - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Chat/View/Cell/QChatTimeTableViewCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Chat/View/Cell/QChatTimeTableViewCell.swift deleted file mode 100644 index 7c0816cc..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Chat/View/Cell/QChatTimeTableViewCell.swift +++ /dev/null @@ -1,39 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class QChatTimeTableViewCell: UITableViewCell { - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - selectionStyle = .none - contentView.addSubview(timeLabel) - NSLayoutConstraint.activate([ - timeLabel.topAnchor.constraint(equalTo: contentView.topAnchor), - timeLabel.leftAnchor.constraint(equalTo: contentView.leftAnchor), - timeLabel.rightAnchor.constraint(equalTo: contentView.rightAnchor), - timeLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor), - ]) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - public var messageFrame: QChatMessageFrame? { - didSet { - timeLabel.text = messageFrame?.time - } - } - - private lazy var timeLabel: UILabel = { - let label = UILabel() - label.font = DefaultTextFont(12) - label.textColor = UIColor.ne_emptyTitleColor - label.textAlignment = .center - label.translatesAutoresizingMaskIntoConstraints = false - return label - }() -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Chat/View/QChatActivityIndicatorView.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Chat/View/QChatActivityIndicatorView.swift deleted file mode 100644 index 8ee76554..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Chat/View/QChatActivityIndicatorView.swift +++ /dev/null @@ -1,81 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -enum QChatSendMessageStatus { - case successed - case sending - case failed -} - -class QChatActivityIndicatorView: UIButton { - public var messageStatus: QChatSendMessageStatus? { - didSet { - failBtn.isHidden = true - activity.isHidden = true - activity.stopAnimating() - - switch messageStatus { - case .sending: - self.isHidden = false - activity.isHidden = false - activity.startAnimating() - case .failed: - self.isHidden = false - failBtn.isHidden = false - case .successed: - self.isHidden = true - - default: - print("") - } - } - } - - override init(frame: CGRect) { - super.init(frame: frame) - commonUI() - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - func commonUI() { - addSubview(failBtn) - addSubview(activity) - NSLayoutConstraint.activate([ - failBtn.topAnchor.constraint(equalTo: topAnchor), - failBtn.leftAnchor.constraint(equalTo: leftAnchor), - failBtn.bottomAnchor.constraint(equalTo: bottomAnchor), - failBtn.rightAnchor.constraint(equalTo: rightAnchor), - ]) - - NSLayoutConstraint.activate([ - activity.topAnchor.constraint(equalTo: topAnchor), - activity.leftAnchor.constraint(equalTo: leftAnchor), - activity.bottomAnchor.constraint(equalTo: bottomAnchor), - activity.rightAnchor.constraint(equalTo: rightAnchor), - ]) - } - - // MARK: lazy Method - - private lazy var failBtn: UIButton = { - let button = UIButton() - button.translatesAutoresizingMaskIntoConstraints = false - button.isUserInteractionEnabled = false - button.setBackgroundImage(UIImage.ne_imageNamed(name: "sendMessage_failed"), for: .normal) - return button - }() - - private lazy var activity: UIActivityIndicatorView = { - let activity = UIActivityIndicatorView() - activity.translatesAutoresizingMaskIntoConstraints = false - activity.color = .gray - return activity - }() -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Chat/View/QChatInputView.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Chat/View/QChatInputView.swift deleted file mode 100644 index 03cc6bd7..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Chat/View/QChatInputView.swift +++ /dev/null @@ -1,80 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -protocol QChatInputViewDelegate: AnyObject { - func sendText(text: String?) - func willSelectItem(button: UIButton, index: Int) -} - -class QChatInputView: UIView, UITextFieldDelegate { - public weak var delegate: QChatInputViewDelegate? - var textField = UITextField() - override init(frame: CGRect) { - super.init(frame: frame) - commonUI() - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - func commonUI() { - backgroundColor = UIColor(hexString: "#EFF1F3") - textField.layer.cornerRadius = 8 - textField.clipsToBounds = true - textField.translatesAutoresizingMaskIntoConstraints = false - textField.backgroundColor = .white - textField.leftViewMode = .always - textField.returnKeyType = .send - textField.leftView = UIView(frame: CGRect(x: 0, y: 0, width: 20, height: 40)) - textField.delegate = self - addSubview(textField) - NSLayoutConstraint.activate([ - textField.leftAnchor.constraint(equalTo: leftAnchor, constant: 7), - textField.topAnchor.constraint(equalTo: topAnchor, constant: 6), - textField.rightAnchor.constraint(equalTo: rightAnchor, constant: -7), - textField.heightAnchor.constraint(equalToConstant: 40), - ]) - let imageNames = ["mic", "emoji", "photo", "file", "add"] - var items = [UIButton]() - for i in 0 ... 4 { - let button = UIButton(type: .custom) - button.setImage(UIImage.ne_imageNamed(name: imageNames[i]), for: .normal) - button.translatesAutoresizingMaskIntoConstraints = false - button.addTarget(self, action: #selector(buttonEvent), for: .touchUpInside) - button.tag = i + 5 - items.append(button) - if i != 2 { - button.alpha = 0.5 - } - } - let stackView = UIStackView(arrangedSubviews: items) - stackView.translatesAutoresizingMaskIntoConstraints = false - stackView.distribution = .fillEqually - addSubview(stackView) - NSLayoutConstraint.activate([ - stackView.leftAnchor.constraint(equalTo: leftAnchor), - stackView.rightAnchor.constraint(equalTo: rightAnchor), - stackView.heightAnchor.constraint(equalToConstant: 54), - stackView.topAnchor.constraint(equalTo: textField.bottomAnchor, constant: 0), - ]) - } - - func textFieldShouldReturn(_ textField: UITextField) -> Bool { - guard let text = textField.text?.trimmingCharacters(in: CharacterSet.whitespaces) else { - return true - } - textField.text = "" - delegate?.sendText(text: text) - textField.resignFirstResponder() - return true - } - - @objc func buttonEvent(button: UIButton) { - delegate?.willSelectItem(button: button, index: button.tag - 5) - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Chat/ViewModel/QChatViewModel.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Chat/ViewModel/QChatViewModel.swift deleted file mode 100644 index 7eaa9af0..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Chat/ViewModel/QChatViewModel.swift +++ /dev/null @@ -1,310 +0,0 @@ -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -import NECoreIMKit -import NIMSDK - -@objc -public protocol QChatViewModelDelegate: NSObjectProtocol { - func onRecvMessages(_ messages: [NIMQChatMessage]) - func willSend(_ message: NIMQChatMessage) - func send(_ message: NIMQChatMessage, didCompleteWithError error: Error?) - func send(_ message: NIMQChatMessage, progress: Float) -} - -@objcMembers -public class QChatViewModel: NSObject, NIMQChatMessageManagerDelegate { - public var channel: ChatChannel? - public var messages: [QChatMessageFrame] = .init() - public weak var delegate: QChatViewModelDelegate? - private var lastMsg: NIMQChatMessage? - private let className = "QChatViewModel" - - init(channel: ChatChannel?) { - NELog.infoLog(ModuleName + " " + className, desc: #function) - super.init() - self.channel = channel - QChatSystemMessageProvider.shared.addDelegate(delegate: self) - } - - public func sendTextMessage(text: String, _ completion: @escaping (Error?) -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", text.count:\(text.count)") - if text.count <= 0 { - return - } - if let cid = channel?.channelId, let sid = channel?.serverId { - let message = NIMQChatMessage() - message.text = text - message.from = IMKitEngine.instance.imAccid - QChatSystemMessageProvider.shared.sendMessage( - message: message, - session: NIMSession(forQChat: Int64(cid), qchatServerId: Int64(sid)) - ) { error in - print("sendText error:\(error) ") - completion(error) - } - } - } - - public func sendImageMessage(image: UIImage, _ completion: @escaping (Error?) -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function) - if let cid = channel?.channelId, let sid = channel?.serverId { - let message = NIMQChatMessage() - message.messageObject = NIMImageObject(image: image) - message.from = IMKitEngine.instance.imAccid - QChatSystemMessageProvider.shared.sendMessage( - message: message, - session: NIMSession(forQChat: Int64(cid), qchatServerId: Int64(sid)) - ) { error in - print("sendImage error:\(error) ") - completion(error) - } - } - } - - public func getMessageHistory(_ completion: @escaping (Error?, [QChatMessageFrame]?) -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function) - if let cid = channel?.channelId, let sid = channel?.serverId { - lastMsg = nil - var param = GetMessageHistoryParam(serverId: sid, channelId: cid) - param.lastMsg = lastMsg - QChatSystemMessageProvider.shared - .getMessageHistory(param: param) { [weak self] error, messages in - if let messageArray = messages, messageArray.count > 0 { - self?.lastMsg = messageArray.last - self?.getUserInfo(messages: messageArray) { error, messageExts in - NELog.infoLog( - ModuleName + " " + (self?.className ?? "QChatViewModel"), - desc: "CALLBACK getUserInfo " + (error?.localizedDescription ?? "no error") - ) - for msgExt in messageExts { - self?.addTimeForHistoryMessage(msgExt) - self?.messages.insert(msgExt, at: 0) - } - if let last = messageExts.last, let msg = self?.timeModel(last) { - self?.messages.insert(msg, at: 0) - } - completion(error, messageExts) - } - } else { - completion(error, nil) - } - } - } else { - completion(NSError.paramError(), nil) - } - } - - public func getMoreMessageHistory(_ completion: @escaping (Error?, [QChatMessageFrame]?) - -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function) - if let cid = channel?.channelId, let sid = channel?.serverId { - var param = GetMessageHistoryParam(serverId: sid, channelId: cid) - param.lastMsg = lastMsg - QChatSystemMessageProvider.shared - .getMessageHistory(param: param) { [weak self] error, messages in - if let messageArray = messages, messageArray.count > 0 { - self?.lastMsg = messageArray.last - self?.getUserInfo(messages: messageArray) { error, messageExts in - NELog.infoLog( - ModuleName + " " + (self?.className ?? "QChatViewModel"), - desc: "CALLBACK getUserInfo " + (error?.localizedDescription ?? "no error") - ) - for msgExt in messageExts { - self?.addTimeForHistoryMessage(msgExt) - self?.messages.insert(msgExt, at: 0) - } - if let last = messageExts.last, let msg = self?.timeModel(last) { - self?.messages.insert(msg, at: 0) - } - completion(error, messageExts) - } - } else { - completion(error, nil) - } - } - } else { - completion(NSError.paramError(), nil) - } - } - - public func getUserInfo(messages: [NIMQChatMessage], - _ completion: @escaping (Error?, [QChatMessageFrame]) -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", messages.count:\(messages.count)") - var userIds = [String]() - var lastMsg: NIMQChatMessage? - var tmp = [QChatMessageFrame]() - - for message in messages { -// let isSend = message.from == CoreKitIMEngine.instance.imAccid - let msgExt = QChatMessageFrame() - msgExt.message = message - msgExt.showAvatar = lastMsg?.from != message.from - tmp.append(msgExt) - lastMsg = message - if let userId = message.from, msgExt.showAvatar { - userIds.append(userId) - } - } - if userIds.isEmpty { - completion(nil, tmp) - } else { - FriendProvider.shared.getUserInfoAdvanced(userIds: userIds) { userInfoList, error in - var result = [QChatMessageFrame]() - for msg in tmp { - for u in userInfoList { - if msg.message?.from == u.userId { - msg.avatar = u.userInfo?.thumbAvatarUrl - msg.nickname = u.userInfo?.nickName - } - } - result.append(msg) - } - completion(error, result) - } - } - } - - public func markMessageRead(time: TimeInterval) { - NELog.infoLog(ModuleName + " " + className, desc: #function) - if let cid = channel?.channelId, let sid = channel?.serverId { - var param = MarkMessageReadParam(serverId: sid, channelId: cid) - param.ackTimestamp = time - weak var weakSelf = self - QChatSystemMessageProvider.shared.markMessageRead(param: param) { error in - if error != nil { - NELog.errorLog( - ModuleName + " " + (weakSelf?.className ?? "QChatViewModel"), - desc: "❌markMessageRead failed,error = \(error!)" - ) - } - } - } - } - - // MARK: NIMChatManagerDelegate - - public func onRecvMessages(_ messages: [NIMQChatMessage]) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", messages.count:\(messages.count)") - print("\(#function) messages:\(messages.count)") - var channelMsgs = [NIMQChatMessage]() - for msg in messages { - if msg.qchatChannelId == channel?.channelId { - channelMsgs.append(msg) - } - } - getUserInfo(messages: channelMsgs) { error, msgExts in - NELog.infoLog( - ModuleName + " " + self.className, - desc: "CALLBACK getUserInfo " + (error?.localizedDescription ?? "no error") - ) - for msgExt in msgExts { - self.addTimeMessage(msgExt) - self.messages.append(msgExt) - } - } - delegate?.onRecvMessages(channelMsgs) - } - - public func willSend(_ message: NIMQChatMessage) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", messageId:\(message.messageId)") - print("\(#function)") - if lastMsg == nil { - lastMsg = message - } - getUserInfo(messages: [message]) { error, msgExts in - NELog.infoLog( - ModuleName + " " + self.className, - desc: "CALLBACK getUserInfo " + (error?.localizedDescription ?? "no error") - ) - for msgExt in msgExts { - self.addTimeMessage(msgExt) - self.messages.append(msgExt) - } - } - delegate?.willSend(message) - } - - public func send(_ message: NIMQChatMessage, progress: Float) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", messageId:\(message.messageId)") - print("\(#function) progress\(progress)") - delegate?.send(message, progress: progress) - } - - public func send(_ message: NIMQChatMessage, didCompleteWithError error: Error?) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", messageId:\(message.messageId)") - print("\(#function) message deliveryState:\(message.deliveryState) error:\(error)") - if let e = error as NSError? { - if e.code == 403 { - var index = 0 - for (i, msg) in messages.enumerated() { - if message.messageId == msg.message?.messageId { - index = i - } - } - messages.remove(at: index) - } - } else { - for (i, msg) in messages.enumerated() { - if message.messageId == msg.message?.messageId { - messages[i].message = message - break - } - } - } - delegate?.send(message, didCompleteWithError: error) - } - - private func modelFromMessage(_ message: NIMQChatMessage) -> QChatMessageFrame { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", messageId:\(message.messageId)") -// let isSend = message.from == CoreKitIMEngine.instance.imAccid - let model = QChatMessageFrame() - model.showAvatar = message.from != messages.last?.message?.from - model.message = message - return model - } - - // history message insert message at first of messages, send message add last of messages - private func addTimeMessage(_ message: QChatMessageFrame) { - NELog.infoLog(ModuleName + " " + className, desc: #function) - let lastTs = messages.last?.message?.timestamp ?? 0.0 - let curTs = message.message?.timestamp ?? 0.0 - let dur = curTs - lastTs - if (dur / 60) > 5 { -// let model = QChatMessageFrame(isSender: true) -// model.showTime = true -// model.time = String.stringFromDate(date:Date(timeIntervalSince1970: curTs)) -// model.showAvatar = false -// model.cellHeight = 35 - messages.append(timeModel(message)) - } - } - - private func addTimeForHistoryMessage(_ message: QChatMessageFrame) { - NELog.infoLog(ModuleName + " " + className, desc: #function) - let firstTs = messages.first?.message?.timestamp ?? 0.0 - let curTs = message.message?.timestamp ?? 0.0 - let dur = firstTs - curTs - if (dur / 60) > 5 { - let model = QChatMessageFrame() - model.showTime = true - model.time = String.stringFromDate(date: Date(timeIntervalSince1970: firstTs)) - model.showAvatar = false - model.cellHeight = 35 - messages.insert(model, at: 0) - } - } - - private func timeModel(_ message: QChatMessageFrame) -> QChatMessageFrame { - NELog.infoLog(ModuleName + " " + className, desc: #function) - let curTs = message.message?.timestamp ?? 0.0 - let model = QChatMessageFrame() - model.showTime = true - model.time = String.stringFromDate(date: Date(timeIntervalSince1970: curTs)) - model.showAvatar = false - model.cellHeight = 35 - return model - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Common/QChatAuthManager.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Common/QChatAuthManager.swift deleted file mode 100644 index 8f775b6e..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Common/QChatAuthManager.swift +++ /dev/null @@ -1,51 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import AVFoundation -import Photos - -public typealias QChatAuthCompletion = (_ granted: Bool) -> Void - -@objc -public class QChatAuthManager: NSObject { - /// 查询相机授权 - @objc - public class func hasCameraAuthorization() -> Bool { - let state = AVCaptureDevice.authorizationStatus(for: .video) - return state == .authorized - } - - /// 请求相机权限 - /// @param completion 结果 - @objc - public class func requestCameraAuthorization(_ completion: QChatAuthCompletion?) { - AVCaptureDevice.requestAccess(for: .video) { granted in - DispatchQueue.main.async { - completion?(granted) - } - } - } - - /// 相册权限 - /// - Parameter completion: 结果 - class func photoAlbumPermissions(_ completion: QChatAuthCompletion?) { - let authStatus = PHPhotoLibrary.authorizationStatus() - // .notDetermined .authorized .restricted .denied - if authStatus == .notDetermined { - // 第一次触发授权 alert - PHPhotoLibrary.requestAuthorization { (status: PHAuthorizationStatus) in - self.photoAlbumPermissions(completion) - } - } else if authStatus == .authorized { - if completion != nil { - completion!(true) - } - } else { - if completion != nil { - completion!(false) - } - } - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Common/QChatConstantValue.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Common/QChatConstantValue.swift deleted file mode 100644 index 895acfab..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Common/QChatConstantValue.swift +++ /dev/null @@ -1,31 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation - -// 距离cell边缘的距离 -public let qChat_cell_margin = 16.0 -// 控件之间的间距 -public let qChat_margin = 8.0 -// 头像宽高 -public let qChat_headWH = 32.0 -// 时间cell的高度(固定) -public let qChat_timeCellH = 21.0 - -// 图片最大宽高 -public let qChat_pic_size = CGSize(width: 150, height: 200) - -// 聊天小气泡角的宽度(后期扩展使用,目前默认为 0) -public let qChat_angle_w = 0.0 - -// 单行气泡高度 -public let qChat_min_h = 46.0 - -// 内容尾部距离cell边框的间距 -public let qChat_content_margin = 48.0 - -// 内容最大宽度 -public let qChat_content_maxW = - (kScreenWidth - qChat_headWH - qChat_cell_margin - qChat_content_margin - qChat_margin) diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Common/QChatConstants.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Common/QChatConstants.swift deleted file mode 100644 index 65292032..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Common/QChatConstants.swift +++ /dev/null @@ -1,104 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -@_exported import NECoreKit -@_exported import NECommonUIKit - -let coreLoader = CoreLoader() -func localizable(_ key: String) -> String { - coreLoader.localizable(key) -} - -func getJSONStringFromDictionary(_ dictionary: [String: Any]) -> String { - if !JSONSerialization.isValidJSONObject(dictionary) { - print("not parse to json string") - return "" - } - if let data = try? JSONSerialization.data(withJSONObject: dictionary, options: []), - let JSONString = String(data: data, encoding: .utf8) { - return JSONString - } - return "" -} - -func getDictionaryFromJSONString(_ jsonString: String) -> NSDictionary? { - if let jsonData = jsonString.data(using: .utf8), - let dict = try? JSONSerialization.jsonObject( - with: jsonData, - options: .mutableContainers - ) as? NSDictionary { - return dict - } - return nil -} - -@objc public protocol ViewModelDelegate: NSObjectProtocol { - func dataDidChange() - func dataDidError(_ error: Error) - @objc optional func dataNoMore() -} - -// MARK: 常量 - -let kScreenWidth: CGFloat = UIScreen.main.bounds.size.width -let kScreenHeight: CGFloat = UIScreen.main.bounds.size.height -let kUISreenWidthScale = kScreenWidth / 375.0 -let kUISreenHeightScale = kScreenHeight / 667.0 -let kNavigationHeight = 44.0 -let KStatusBarHeight = UIApplication.shared.statusBarFrame.height // 获取statusBar的高度 -/// 屏幕间隔 -let kScreenInterval: CGFloat = 20 - -// MARK: 字体 - -let TextFont: ((String, Float) -> UIFont) = { - (fontName: String, fontSize: Float) -> UIFont in - if #available(iOS 9.0, macOS 10,*) { - return UIFont(name: fontName, size: CGFloat(fontSize))! - } else { - return UIFont.systemFont(ofSize: CGFloat(fontSize)) - } -} - -let DefaultTextFont: ((Float) -> UIFont) = { - (fontSize: Float) -> UIFont in - TextFont("PingFangSC-Regular", fontSize) -} - -// MARK: 颜色 - -let TextNormalColor: UIColor = HexRGB(0x333333) -let SubTextColor: UIColor = HexRGB(0x666666) -let PlaceholderTextColor: UIColor = HexRGB(0xA6ADB6) - -let HexRGB: ((Int) -> UIColor) = { (rgbValue: Int) -> UIColor in - HexRGBAlpha(rgbValue, 1.0) -} - -let HexRGBAlpha: ((Int, Float) -> UIColor) = { (rgbValue: Int, alpha: Float) -> UIColor in - UIColor( - red: CGFloat(CGFloat((rgbValue & 0xFF0000) >> 16) / 255), - green: CGFloat(CGFloat((rgbValue & 0xFF00) >> 8) / 255), - blue: CGFloat(CGFloat(rgbValue & 0xFF) / 255), - alpha: CGFloat(alpha) - ) -} - -// MARK: notificationkey - -enum NotificationName { - // 参数 serverId: string - static let createServer = Notification.Name(rawValue: "qchat.createServer") - // param channel: ChatChannel - static let createChannel = Notification.Name(rawValue: "qchat.createChannel") - static let updateChannel = Notification.Name(rawValue: "qchat.updateChannel") - static let deleteChannel = Notification.Name(rawValue: "qchat.deleteChannel") - -// static let login = Notification.Name(rawValue:"qchat.login") - static let logout = Notification.Name(rawValue: "qchat.logout") -} - -public let ModuleName = "NEQChatUIKit" diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Extension/AlertVCExtention.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Extension/AlertVCExtention.swift deleted file mode 100644 index be30513b..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Extension/AlertVCExtention.swift +++ /dev/null @@ -1,17 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -extension UIAlertController { - class func reconfimAlertView(title: String?, message: String?, - confirm: @escaping () -> Void) -> UIAlertController { - let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) - alert.addAction(UIAlertAction(title: localizable("cancel"), style: .cancel, handler: nil)) - alert.addAction(UIAlertAction(title: localizable("ok"), style: .default) { action in - confirm() - }) - return alert - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Extension/ColorExtension.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Extension/ColorExtension.swift deleted file mode 100644 index 46bae3db..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Extension/ColorExtension.swift +++ /dev/null @@ -1,32 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -import UIKit -public extension UIColor { -// MARK: text color - - static let ne_darkText = UIColor(hexString: "#333333") - static let ne_greyText = UIColor(hexString: "#666666") - static let ne_lightText = UIColor(hexString: "#999999") - static let ne_blueText = UIColor(hexString: "#337EFF") - static let ne_redText = UIColor(hexString: "#E6605C") - static let ne_disableRedText = UIColor(hexString: "#E6605C", 0.5) - static let ne_backcolor = UIColor(hexString: "F2F4F5") - static let ne_emptyTitleColor = UIColor(hexString: "B3B7BC") - -// MARK: view background color - static let ne_lightBackgroundColor = UIColor(hexString: "#F1F1F6") - static let ne_defautAvatarColor = UIColor(hexString: "#537FF4") - static let ne_greenColor = UIColor(hexString: "#42C294") - -// MARK: border color - static let ne_borderColor = UIColor(hexString: "#DBDDE4") - -// MARK: line color - static let ne_greyLine = UIColor(hexString: "#F5F8FC") - - static let ne_redColor = UIColor(hexString: "#F24957") -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Extension/NEErrorExtension.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Extension/NEErrorExtension.swift deleted file mode 100644 index 25e9ae94..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Extension/NEErrorExtension.swift +++ /dev/null @@ -1,15 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -extension NSError { - class func paramError() -> NSError { - NSError( - domain: "com.qchat.doamin", - code: 600, - userInfo: ["message": localizable("param_error")] - ) - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Extension/QChatImageExtension.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Extension/QChatImageExtension.swift deleted file mode 100644 index 7a727bf5..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Extension/QChatImageExtension.swift +++ /dev/null @@ -1,25 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -import CoreGraphics -import UIKit -public extension UIImage { - class func ne_imageNamed(name: String?) -> UIImage? { - guard let imageName = name else { - return nil - } - return coreLoader.loadImage(imageName) -// guard let path = Bundle(for: -// QChatBaseCell.self).resourcePath?.appending("/NEQChatUIKit.bundle") else { -// print("Image:\(imageName) path: nil") -// return nil -// } -// let image = UIImage(named: imageName, in: Bundle(path: path), compatibleWith: nil) -// print("Bundle:\(Bundle(path: path))") -// print("imageName:\(imageName) image:\(image)") -// return image - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Extension/QChatStringExtension.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Extension/QChatStringExtension.swift deleted file mode 100644 index e2801047..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Extension/QChatStringExtension.swift +++ /dev/null @@ -1,43 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation - -extension String { - // 计算文字size - static func getTextRectSize(_ text: String, font: UIFont, size: CGSize) -> CGSize { - let attributes = [NSAttributedString.Key.font: font] - let option = NSStringDrawingOptions.usesLineFragmentOrigin - let rect: CGRect = text.boundingRect(with: size, options: option, - attributes: attributes, context: nil) - return rect.size - } - - static func stringFromDate(date: Date) -> String { - let fmt = DateFormatter() - if Calendar.current.isDateInToday(date) { - fmt.dateFormat = localizable("hm") - } else { - if let firstDayYear = firstDayInYear() { - let dur = date.timeIntervalSince(firstDayYear) - if dur > 0 { - fmt.dateFormat = localizable("mdhm") - } else { - fmt.dateFormat = localizable("ymdhm") - } - } else { - fmt.dateFormat = localizable("ymdhm") - } - } - return fmt.string(from: date) - } - - static func firstDayInYear() -> Date? { - let format = DateFormatter() - format.dateFormat = "yyyy-MM-dd" - let year = Calendar.current.component(.year, from: Date()) - return format.date(from: "\(year)-01-01") - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Controller/CreateServerViewController.swift b/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Controller/CreateServerViewController.swift deleted file mode 100644 index dc0b4968..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Controller/CreateServerViewController.swift +++ /dev/null @@ -1,86 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -public class CreateServerViewController: NEBaseViewController, UITableViewDelegate, - UITableViewDataSource { - public var serverViewModel = CreateServerViewModel() - - override public func viewDidLoad() { - super.viewDidLoad() - initializeConfig() - setupSubviews() - } - - func initializeConfig() { - title = localizable("qchat_add_Server") - addLeftAction(localizable("close"), #selector(closeAction), self) - } - - func setupSubviews() { - view.addSubview(tableView) - NSLayoutConstraint.activate([ - tableView.topAnchor.constraint( - equalTo: view.topAnchor, - constant: KStatusBarHeight + CGFloat(kNavigationHeight) + 52 - ), - tableView.leftAnchor.constraint(equalTo: view.leftAnchor), - tableView.rightAnchor.constraint(equalTo: view.rightAnchor), - tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor), - ]) - } - - private lazy var tableView: UITableView = { - let tableView = UITableView(frame: .zero, style: .plain) - tableView.translatesAutoresizingMaskIntoConstraints = false - tableView.separatorStyle = .none - tableView.delegate = self - tableView.dataSource = self - tableView.register( - NECreateServerCell.self, - forCellReuseIdentifier: "\(NSStringFromClass(NECreateServerCell.self))" - ) - tableView.rowHeight = 60 - tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: 0.1)) - return tableView - }() - - @objc func closeAction(sender: UIButton) { - navigationController?.dismiss(animated: true, completion: nil) - } - - // MARK: UITableViewDelegate, UITableViewDataSource - - public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - serverViewModel.dataArray.count - } - - public func tableView(_ tableView: UITableView, - cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell( - withIdentifier: "\(NSStringFromClass(NECreateServerCell.self))", - for: indexPath - ) as! NECreateServerCell - let model = serverViewModel.dataArray[indexPath.row] - cell.model = model - return cell - } - - public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - if indexPath.row == 0 { - let mineCreateCtrl = MineCreateServerController() - navigationController?.pushViewController(mineCreateCtrl, animated: true) - } else if indexPath.row == 1 { - let otherCtrl = JoinOtherServiceController() - navigationController?.pushViewController(otherCtrl, animated: true) - } - } - - public func tableView(_ tableView: UITableView, - heightForRowAt indexPath: IndexPath) -> CGFloat { - 76 - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Controller/JoinOtherServiceController.swift b/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Controller/JoinOtherServiceController.swift deleted file mode 100644 index 5af2c620..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Controller/JoinOtherServiceController.swift +++ /dev/null @@ -1,234 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NECoreKit -import NECoreIMKit -import NECommonKit -// import NEKeyboardManagerSwift - -public class JoinOtherServiceController: NEBaseViewController, UITableViewDelegate, - UITableViewDataSource { - private let tag = "JoinOtherServiceController" - public var serversArray = [QChatServer]() - public var serverViewModel = CreateServerViewModel() - public var channelViewModel = QChatChannelViewModel() - - override public func viewDidLoad() { - super.viewDidLoad() - initializeConfig() - setupSubviews() - } - - func initializeConfig() { - title = localizable("qchat_join_otherServer") - NEKeyboardManager.shared.enableAutoToolbar = true - } - - func setupSubviews() { - view.addSubview(searchTextField) - view.addSubview(tableView) - NSLayoutConstraint.activate([ - searchTextField.topAnchor.constraint( - equalTo: view.topAnchor, - constant: CGFloat(kNavigationHeight) + KStatusBarHeight + 20 - ), - searchTextField.leftAnchor.constraint( - equalTo: view.leftAnchor, - constant: kScreenInterval - ), - searchTextField.rightAnchor.constraint( - equalTo: view.rightAnchor, - constant: -kScreenInterval - ), - searchTextField.heightAnchor.constraint(equalToConstant: 32), - ]) - - NSLayoutConstraint.activate([ - tableView.topAnchor.constraint(equalTo: searchTextField.bottomAnchor, constant: 20), - tableView.leftAnchor.constraint(equalTo: view.leftAnchor), - tableView.rightAnchor.constraint(equalTo: view.rightAnchor), - tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor), - ]) - } - - // MARK: lazyMethod - - private lazy var searchTextField: SearchTextField = { - let textField = SearchTextField() - - let image = UIImage(named: "otherService_search_icon", - in: Bundle(for: type(of: self)), - compatibleWith: nil) - let leftImageView = UIImageView(image: image) - textField.contentMode = .center - textField.leftView = leftImageView - textField.leftViewMode = .always - textField.placeholder = localizable("search_serverId") - textField.font = DefaultTextFont(14) - textField.textColor = TextNormalColor - textField.translatesAutoresizingMaskIntoConstraints = false - textField.layer.cornerRadius = 8 - textField.backgroundColor = HexRGB(0xEFF1F4) - textField.clearButtonMode = .whileEditing - textField.addTarget(self, action: #selector(searchTextFieldChange), for: .editingDidEnd) - textField.keyboardType = .numberPad - return textField - }() - - private lazy var tableView: UITableView = { - let tableView = UITableView(frame: .zero, style: .plain) - tableView.translatesAutoresizingMaskIntoConstraints = false - tableView.separatorStyle = .none - tableView.delegate = self - tableView.dataSource = self - tableView.register( - NESearchServerCell.self, - forCellReuseIdentifier: "\(NSStringFromClass(NESearchServerCell.self))" - ) - tableView.rowHeight = 60 - tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: 0.1)) - return tableView - }() - - private lazy var emptyView: EmptyDataView = { - let view = EmptyDataView( - imageName: "searchServer_noMoreData", - content: localizable("no_serverId"), - frame: tableView.bounds - ) - return view - }() - - @objc func searchTextFieldChange(textfield: SearchTextField) { - // 选择高亮文本在进行搜索 - // let textRange = textfield.markedTextRange - // if textRange == nil || ((textRange?.isEmpty) == nil) { - // print("111") - // } - - if !NEChatDetectNetworkTool.shareInstance.isNetworkRecahability() { - showToast(localizable("network_error")) - return - } - - guard let content = textfield.text else { - return - } - // 空字符串判断 - if content.isBlank { - emptyView.removeFromSuperview() - return - } - - let param = QChatGetServersParam(serverIds: [NSNumber(value: UInt64(content)!)]) - serverViewModel.getServers(parameter: param) { error, serversArray in - NELog.infoLog( - ModuleName + " " + self.tag, - desc: "CALLBACK getServers " + (error?.localizedDescription ?? "no error") - ) - if error == nil { - self.serversArray = serversArray?.servers ?? Array() - if self.serversArray.isEmpty { - self.tableView.addSubview(self.emptyView) - return - } else { - self.emptyView.removeFromSuperview() - } - self.tableView.reloadData() - } else { - NELog.errorLog(ModuleName + " " + self.tag, desc: "❌getServers failed,error = \(error!)") - } - } - } - - // MARK: UITableViewDelegate UITableViewDataSource - - public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - serversArray.count - } - - public func tableView(_ tableView: UITableView, - cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell( - withIdentifier: "\(NSStringFromClass(NESearchServerCell.self))", - for: indexPath - ) as! NESearchServerCell - cell.serverModel = serversArray[indexPath.row] - weak var weakSelf = self - cell.joinServerCallBack = { - let successView = - InviteMemberView(frame: CGRect(x: (kScreenWidth - 176) / 2, y: KStatusBarHeight, - width: 176, height: 55)) - successView.showSuccessView() - } - return cell - } - - public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - guard let serverId = serversArray[indexPath.row].serverId else { return } - let param = QChatGetChannelsByPageParam(timeTag: 0, serverId: serverId) - weak var weakSelf = self - channelViewModel.getChannelsByPage(parameter: param) { error, result in - NELog.infoLog( - ModuleName + " " + self.tag, - desc: "CALLBACK getChannelsByPage " + (error?.localizedDescription ?? "no error") - ) - if error == nil { - guard let dataArray = result?.channels else { return } - let chatVC = QChatViewController(channel: dataArray.first) - weakSelf?.navigationController?.pushViewController(chatVC, animated: true) - } else { - print("getChannelsByPage failed,error = \(error!)") - } - } - } -} - -// MARK: private Method - -extension JoinOtherServiceController { - func showAlert() { - let alertCtrl = UIAlertController( - title: localizable("cant_join"), - message: localizable("blocked_from_server_cant_join"), - preferredStyle: .alert - ) - let okAction = UIAlertAction(title: localizable("know"), style: .default, handler: nil) - alertCtrl.addAction(okAction) - present(alertCtrl, animated: true, completion: nil) - } -} - -// MARK: SearchTextField - -// class SearchTextField:UITextField { -// -// override func leftViewRect(forBounds bounds: CGRect) -> CGRect { -// var rect = super.leftViewRect(forBounds: bounds) -// rect.origin.x += 10 -// return rect -// } -// -// override func placeholderRect(forBounds bounds: CGRect) -> CGRect { -// var rect = super.placeholderRect(forBounds: bounds) -// rect.origin.x += 1 -// return rect -// } -// -// override func editingRect(forBounds bounds: CGRect) -> CGRect { -// -// var rect = super.editingRect(forBounds: bounds) -// rect.origin.x += 5 -// return rect -// -// } -// -// override func textRect(forBounds bounds: CGRect) -> CGRect { -// var rect = super.textRect(forBounds: bounds) -// rect.origin.x += 5 -// return rect -// } -// } diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Controller/MemberListViewController.swift b/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Controller/MemberListViewController.swift deleted file mode 100644 index fc8e2a06..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Controller/MemberListViewController.swift +++ /dev/null @@ -1,154 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NECoreIMKit -import NECoreKit -public class MemberListViewController: NEBaseViewController, UITableViewDelegate, - UITableViewDataSource { - public var serverViewModel = CreateServerViewModel() - public var memberViewModel = MemberListViewModel() - private let className = "MemberListViewController" - - var dataArray: [ServerMemeber]? - var serverId: UInt64? - - override public func viewDidLoad() { - super.viewDidLoad() - initializeConfig() - requestData() - addSubviews() - // Do any additional setup after loading the view. - } - - func requestData() { - guard let id = serverId else { - print("serverId is nil") - return - } - let param = QChatGetServerMembersByPageParam(timeTag: 0, serverId: id) - weak var weakSelf = self - memberViewModel.requestServerMemebersByPage(param: param) { error, serverMemberArray in - NELog.infoLog( - ModuleName + " " + self.className, - desc: "CALLBACK requestServerMemebersByPage " + - (error?.localizedDescription ?? "no error") - ) - if error == nil { - weakSelf?.dataArray = serverMemberArray - weakSelf?.tableView.reloadData() - } else {} - } - } - - func initializeConfig() { - title = localizable("qchat_member") - addRightAction(UIImage.ne_imageNamed(name: "sign_add"), #selector(addMemberClick), self) - } - - func addSubviews() { - view.addSubview(tableView) - NSLayoutConstraint.activate([ - tableView.topAnchor.constraint(equalTo: view.topAnchor), - tableView.leftAnchor.constraint(equalTo: view.leftAnchor), - tableView.rightAnchor.constraint(equalTo: view.rightAnchor), - tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor), - ]) - } - - // MARK: lazy method - - private lazy var tableView: UITableView = { - let tableView = UITableView(frame: .zero, style: .plain) - tableView.translatesAutoresizingMaskIntoConstraints = false - tableView.separatorStyle = .none - tableView.delegate = self - tableView.dataSource = self - tableView.register( - NEGroupIdentityMemberCell.self, - forCellReuseIdentifier: "\(NSStringFromClass(NEGroupIdentityMemberCell.self))" - ) - tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: 0.1)) - tableView.estimatedRowHeight = 125 - return tableView - }() - - // MAKR: UITableViewDelegate, UITableViewDataSource - @objc func addMemberClick(sender: UIButton) { - Router.shared.register(ContactSelectedUsersRouter) { [weak self] param in - print("param\(param)") - if let userIds = param["accids"] as? [String] { - print("userIds:\(userIds)") - guard let serverId = self?.serverId else { return } - self?.serverViewModel - .inviteMembersToServer(serverId: serverId, accids: userIds) { error in - NELog.infoLog( - ModuleName + " " + (self?.className ?? "MemberListViewController"), - desc: "CALLBACK inviteMembersToServer " + - (error?.localizedDescription ?? "no error") - ) - if error == nil { - self?.requestData() - } - } - } - } - - Router.shared - .use(ContactUserSelectRouter, - parameters: ["nav": navigationController]) { obj, routerState, str in - print("obj:\(obj) routerState:\(routerState) str:\(str)") - } - - // FIXME: router - // let contactCtrl = ContactsSelectedViewController() - // self.navigationController?.pushViewController(contactCtrl, animated: true) - // weak var weakSelf = self - // - // contactCtrl.CallBack = {(selectMemberarray)->Void in - // - // guard let serverId = weakSelf?.serverId else { return } - // var accidArray = [String]() - // selectMemberarray.forEach { memberInfo in - // accidArray.append(memberInfo.user?.userId ?? "") - // } - // weakSelf?.serverViewModel.inviteMembersToServer(serverId: serverId, accids: accidArray) { error in - // if error == nil{ - // weakSelf?.requestData() - // } - // } - // } - } - - public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - dataArray?.count ?? 0 - } - - public func tableView(_ tableView: UITableView, - cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell( - withIdentifier: "\(NSStringFromClass(NEGroupIdentityMemberCell.self))", - for: indexPath - ) as! NEGroupIdentityMemberCell - cell.memberModel = dataArray?[indexPath.row] - return cell - } - - public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - // let user = viewModel.limitUsers[indexPath.row] - if let member = dataArray?[indexPath.row] { - let editMember = QChatEditMemberViewController() - editMember.deleteCompletion = { - self.requestData() - } - editMember.changeCompletion = { - self.requestData() - } - let user = UserInfo(member) - editMember.user = user - navigationController?.pushViewController(editMember, animated: true) - } - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Controller/MineCreateServerController.swift b/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Controller/MineCreateServerController.swift deleted file mode 100644 index b74e4406..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Controller/MineCreateServerController.swift +++ /dev/null @@ -1,239 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NECoreIMKit -import NIMSDK -import NECommonKit - -public class MineCreateServerController: NEBaseViewController, UINavigationControllerDelegate, - UITextFieldDelegate { - private let tag = "MineCreateServerController" - public var serverViewModel = CreateServerViewModel() - var headImageUrl: String? - - override public func viewDidLoad() { - super.viewDidLoad() - initializeConfig() - setupSubviews() - } - - func initializeConfig() { - title = localizable("qchat_mine_add") - } - - func setupSubviews() { - view.addSubview(uploadBgView) - uploadBgView.addSubview(cameraImageView) - uploadBgView.addSubview(uploadDesLabel) - view.addSubview(selectHeadImage) - view.addSubview(textField) - view.addSubview(bottomBtn) - - NSLayoutConstraint.activate([ - uploadBgView.centerXAnchor.constraint(equalTo: view.centerXAnchor), - uploadBgView.topAnchor.constraint( - equalTo: view.topAnchor, - constant: CGFloat(kNavigationHeight) + KStatusBarHeight + 40 - ), - uploadBgView.widthAnchor.constraint(equalToConstant: 80), - uploadBgView.heightAnchor.constraint(equalToConstant: 80), - ]) - - NSLayoutConstraint.activate([ - selectHeadImage.centerXAnchor.constraint(equalTo: view.centerXAnchor), - selectHeadImage.topAnchor.constraint( - equalTo: view.topAnchor, - constant: CGFloat(kNavigationHeight) + KStatusBarHeight + 40 - ), - selectHeadImage.widthAnchor.constraint(equalToConstant: 80), - selectHeadImage.heightAnchor.constraint(equalToConstant: 80), - ]) - NSLayoutConstraint.activate([ - cameraImageView.centerXAnchor.constraint(equalTo: uploadBgView.centerXAnchor), - cameraImageView.topAnchor.constraint(equalTo: uploadBgView.topAnchor, constant: 18), - ]) - - NSLayoutConstraint.activate([ - uploadDesLabel.centerXAnchor.constraint(equalTo: uploadBgView.centerXAnchor), - uploadDesLabel.topAnchor.constraint(equalTo: cameraImageView.bottomAnchor, constant: 9), - ]) - - NSLayoutConstraint.activate([ - textField.leftAnchor.constraint(equalTo: view.leftAnchor, constant: kScreenInterval), - textField.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -kScreenInterval), - textField.topAnchor.constraint(equalTo: uploadBgView.bottomAnchor, constant: 40), - textField.heightAnchor.constraint(equalToConstant: 40), - ]) - - NSLayoutConstraint.activate([ - bottomBtn.leftAnchor.constraint(equalTo: view.leftAnchor, constant: kScreenInterval), - bottomBtn.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -kScreenInterval), - bottomBtn.topAnchor.constraint(equalTo: textField.bottomAnchor, constant: 40), - bottomBtn.heightAnchor.constraint(equalToConstant: 40), - ]) - } - - // MARK: lazyMethod - - private lazy var uploadBgView: UIButton = { - let button = UIButton() - button.setBackgroundImage(UIImage.ne_imageNamed(name: "uploadPic_bg_icon"), for: .normal) - button.setBackgroundImage( - UIImage.ne_imageNamed(name: "uploadPic_bg_icon"), - for: .highlighted - ) - button.translatesAutoresizingMaskIntoConstraints = false - button.addTarget(self, action: #selector(uploadBgViewClick), for: .touchUpInside) - return button - - }() - - private lazy var selectHeadImage: UIImageView = { - let imageView = UIImageView() - imageView.translatesAutoresizingMaskIntoConstraints = false - imageView.layer.cornerRadius = 40 - imageView.clipsToBounds = true - return imageView - }() - - private lazy var cameraImageView: UIImageView = { - let imageView = UIImageView(image: UIImage.ne_imageNamed(name: "upload_camera")) - imageView.translatesAutoresizingMaskIntoConstraints = false - return imageView - }() - - private lazy var uploadDesLabel: UILabel = { - let label = UILabel() - label.translatesAutoresizingMaskIntoConstraints = false - label.text = localizable("upload_headImage") - label.textColor = HexRGB(0x656A72) - label.font = DefaultTextFont(12) - return label - }() - - private lazy var textField: UITextField = { - let textField = UITextField() - textField.setValue(NSNumber(value: 10), forKey: "paddingLeft") - textField.placeholder = localizable("enter_serverName") - textField.font = DefaultTextFont(16) - textField.textColor = TextNormalColor - textField.translatesAutoresizingMaskIntoConstraints = false - textField.layer.cornerRadius = 8 - textField.backgroundColor = HexRGB(0xEFF1F4) - textField.delegate = self - textField.addTarget(self, action: #selector(textContentChanged), for: .editingChanged) - textField.clearButtonMode = .whileEditing - return textField - }() - - private lazy var bottomBtn: UIButton = { - let button = UIButton() - button.translatesAutoresizingMaskIntoConstraints = false - button.setTitle(localizable("create"), for: .normal) - button.setTitleColor(UIColor.white, for: .normal) - button.titleLabel?.font = DefaultTextFont(16) - button.backgroundColor = HexRGBAlpha(0x337EFF, 0.5) - button.layer.cornerRadius = 8 - button.addTarget(self, action: #selector(createServerBtnClick), for: .touchUpInside) - return button - }() - - @objc func createServerBtnClick(sender: UIButton) { - guard let serverName = textField.text, serverName.count > 0 else { return } - - if NEChatDetectNetworkTool.shareInstance.isNetworkRecahability() { - sender.isEnabled = false - } else { - showToast(localizable("network_error")) - return - } - - let param = CreateServerParam(name: textField.text!, icon: headImageUrl ?? "") - serverViewModel.createServer(parameter: param) { error, result in - if error != nil { - NELog.errorLog(ModuleName + " " + self.tag, desc: "❌createServer failed,error = \(error!)") - } else { - // 创建服务器成功后,默认创建好两个频道 - if let serverId = result?.server?.serverId { - NotificationCenter.default.post( - name: NotificationName.createServer, - object: serverId - ) - self.navigationController?.dismiss(animated: true, completion: nil) - } else { - print("serverId is nil") - return - } - } - } - // 应对wifi切换4G请求没有回调的处理结果 - DispatchQueue.main.asyncAfter(deadline: .now() + 1) { - sender.isEnabled = true - } - } - - // MARK: UITextFieldDelegate - - public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, - replacementString string: String) -> Bool { - let text = "\(textField.text ?? "")\(string)" - if text.count > 50 { - showToast(localizable("serverName_limit")) - return false - } - - return true - } - - // Upload the picture - @objc func uploadBgViewClick(sender: UIButton) { - showBottomAlert(self) - } - - @objc func textContentChanged() { - if textField.text?.count != 0 { - bottomBtn.isEnabled = true - bottomBtn.backgroundColor = HexRGB(0x337EFF) - } else { - bottomBtn.isEnabled = false - bottomBtn.backgroundColor = HexRGBAlpha(0x337EFF, 0.5) - } - } - - // MARK: UIImagePickerControllerDelegate - - func imagePickerController(_ picker: UIImagePickerController, - didFinishPickingMediaWithInfo info: [UIImagePickerController - .InfoKey: Any]) { - let image: UIImage = info[UIImagePickerController.InfoKey.editedImage] as! UIImage - uploadHeadImage(image: image) - dismiss(animated: true, completion: nil) - } - - public func uploadHeadImage(image: UIImage) { - view.makeToastActivity(.center) - if let imageData = image.jpegData(compressionQuality: 0.6) as NSData? { - let filePath = NSHomeDirectory().appending("/Documents/") - .appending(IMKitEngine.instance.imAccid) - let succcess = imageData.write(toFile: filePath, atomically: true) - - if succcess { - NIMSDK.shared().resourceManager - .upload(filePath, progress: nil) { urlString, error in - if error == nil { - // 显示设置的照片 - self.selectHeadImage.image = image - self.headImageUrl = urlString - print("upload image success") - } else { - print("upload image failed,error = \(error!)") - } - self.view.hideToastActivity() - } - } - } - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Controller/QChatHomeViewController.swift b/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Controller/QChatHomeViewController.swift deleted file mode 100644 index 8da3e46f..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Controller/QChatHomeViewController.swift +++ /dev/null @@ -1,378 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -import UIKit -import NECoreIMKit -import MJRefresh -import NIMSDK -import NEQChatKit -import NECommonUIKit -import NECommonKit - -public class QChatHomeViewController: UIViewController, ViewModelDelegate { - public var serverViewModel = CreateServerViewModel() - public var serverListArray = [QChatServer]() - fileprivate var selectIndex = 0 - private let className = "QChatHomeViewController" - - override public func viewWillAppear(_ animated: Bool) { - navigationController?.navigationBar.isHidden = true - } - - override public func viewWillDisappear(_ animated: Bool) { - navigationController?.navigationBar.isHidden = false - } - - override public func viewDidAppear(_ animated: Bool) { - super.viewDidAppear(animated) - weak var weakSelf = self - NEChatDetectNetworkTool.shareInstance.netWorkReachability { status in - if status == .notReachable, let networkView = weakSelf?.brokenNetworkView { - weakSelf?.qChatBgView.addSubview(networkView) - } else { - weakSelf?.brokenNetworkView.removeFromSuperview() - } - } - } - - override public func viewDidLoad() { - super.viewDidLoad() - serverViewModel.delegate = self - qChatBgView.viewmodel = serverViewModel - weak var weakSelf = self - serverViewModel.updateServerList = { - weakSelf?.tableView.reloadData() - } - initializeConfig() - addSubviews() - requestData(timeTag: 0) - addObserve() - } - - func initializeConfig() { - QChatSystemMessageProvider.shared.addDelegate(delegate: self) - } - - func addSubviews() { - view.addSubview(addServiceBtn) - view.addSubview(qChatBgView) - view.addSubview(tableView) - - NSLayoutConstraint.activate([ - addServiceBtn.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 12), - addServiceBtn.widthAnchor.constraint(equalToConstant: 42), - addServiceBtn.heightAnchor.constraint(equalToConstant: 42), - addServiceBtn.topAnchor.constraint(equalTo: view.topAnchor, constant: 46), - ]) - NSLayoutConstraint.activate([ - qChatBgView.leftAnchor.constraint(equalTo: addServiceBtn.rightAnchor, constant: 12), - qChatBgView.topAnchor.constraint(equalTo: addServiceBtn.topAnchor), - qChatBgView.rightAnchor.constraint(equalTo: view.rightAnchor), - qChatBgView.bottomAnchor.constraint(equalTo: view.bottomAnchor), - ]) - - NSLayoutConstraint.activate([ - tableView.topAnchor.constraint(equalTo: addServiceBtn.bottomAnchor, constant: 7), - tableView.leftAnchor.constraint(equalTo: view.leftAnchor), - tableView.rightAnchor.constraint(equalTo: qChatBgView.leftAnchor), - tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor), - ]) - } - - func requestData(timeTag: TimeInterval) { - let param = GetServersByPageParam(timeTag: timeTag, limit: 20) - weak var weakSelf = self - serverViewModel.getServerList(parameter: param) { error, response in - NELog.infoLog( - ModuleName + " " + self.className, - desc: "CALLBACK getServerList " + (error?.localizedDescription ?? "no error") - ) - if error == nil { - guard let dataArray = response?.servers else { return } - if timeTag == 0 { - self.serverListArray.removeAll() - self.serverListArray = dataArray - if let first = dataArray.first { - self.qChatBgView.qchatServerModel = first - self.qChatBgView.dismissEmptyView() - } else { - // 服务器列表为空 - self.qChatBgView.showEmptyServerView() - } - } else { - self.serverListArray += dataArray - } - - // 未读数入口 - weakSelf?.serverViewModel.getUnread(dataArray) - - self.tableView.reloadData() - } else { - print("getServerList failed,error = \(error!)") - } - } - } - - func addObserve() { - NotificationCenter.default.addObserver( - self, - selector: #selector(onCreateServer), - name: NotificationName.createServer, - object: nil - ) - NotificationCenter.default.addObserver( - self, - selector: #selector(onCreateChannel), - name: NotificationName.createChannel, - object: nil - ) - } - - // MARK: lazy method - - private lazy var addServiceBtn: UIButton = { - let btn = UIButton() - btn.setBackgroundImage(UIImage.ne_imageNamed(name: "addService_icon"), for: .normal) - btn.translatesAutoresizingMaskIntoConstraints = false - btn.addTarget(self, action: #selector(addServiceBtnClick), for: .touchUpInside) - return btn - }() - - private lazy var qChatBgView: NEHomeChannelView = { - let view = NEHomeChannelView() - view.translatesAutoresizingMaskIntoConstraints = false - weak var weakSelf = self - view.viewmodel = serverViewModel - view.setUpBlock = { () in - if weakSelf?.serverListArray.count == 0 { - return - } - if let index = weakSelf?.selectIndex, - let server = weakSelf?.serverListArray[index] { - let setting = QChatServerSettingViewController() - setting.server = server - setting.hidesBottomBarWhenPushed = true - weakSelf?.navigationController?.pushViewController(setting, animated: true) - } - } - - view.addChannelBlock = { [weak self] in - if self?.serverListArray.count ?? 0 > 0 { - let server = self?.serverListArray[self?.selectIndex ?? 0] - guard let serverId = server?.serverId, serverId > 0 else { - print("error: serverId:\(server?.serverId ?? 0)") - return - } - let nav = - QChatNavigationController( - rootViewController: QChatChannelViewController(serverId: serverId) - ) - nav.modalPresentationStyle = .fullScreen - weakSelf?.present(nav, animated: true, completion: nil) - } - } - - view.selectedChannelBlock = { [weak self] channel in - self?.enterChatVC(channel: channel) - } - return view - }() - - private lazy var tableView: UITableView = { - let tableView = UITableView(frame: .zero, style: .plain) - tableView.translatesAutoresizingMaskIntoConstraints = false - tableView.separatorStyle = .none - tableView.showsVerticalScrollIndicator = false - tableView.delegate = self - tableView.dataSource = self - tableView.register( - NEHomeServerCell.self, - forCellReuseIdentifier: "\(NSStringFromClass(NEHomeServerCell.self))" - ) - tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: 0.1)) - tableView.backgroundColor = HexRGB(0xE9EFF5) - let mjfooter = MJRefreshBackNormalFooter( - refreshingTarget: self, - refreshingAction: #selector(loadMoreData) - ) - mjfooter.stateLabel?.isHidden = true - tableView.mj_footer = mjfooter - return tableView - }() - - private lazy var brokenNetworkView: NEBrokenNetworkView = { - let view = - NEBrokenNetworkView(frame: CGRect(x: 0, y: 38, width: qChatBgView.width, height: 33)) - return view - }() -} - -extension QChatHomeViewController { - @objc func addServiceBtnClick(sender: UIButton) { - let nav = UINavigationController(rootViewController: CreateServerViewController()) - nav.modalPresentationStyle = .fullScreen - present(nav, animated: true, completion: nil) - } - - @objc func loadMoreData() { - if let time = serverListArray.last?.createTime { - requestData(timeTag: time) - } - tableView.mj_footer?.endRefreshing() - } -} - -// MARK: tableviewDelegate dataSource - -extension QChatHomeViewController: UITableViewDelegate, UITableViewDataSource { - public func dataDidChange() { - qChatBgView.tableView.reloadData() - } - - public func dataDidError(_ error: Error) {} - - public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - serverListArray.count - } - - public func tableView(_ tableView: UITableView, - cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell( - withIdentifier: "\(NSStringFromClass(NEHomeServerCell.self))", - for: indexPath - ) as! NEHomeServerCell - cell.showSelectState(isShow: indexPath.row == selectIndex ? true : false) - cell.serverModel = serverListArray[indexPath.row] - return cell - } - - public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - let serverModel = serverListArray[indexPath.row] - qChatBgView.qchatServerModel = serverModel - serverViewModel.currentServerId = serverModel.serverId - selectIndex = indexPath.row - tableView.reloadData() - } - - public func tableView(_ tableView: UITableView, - heightForRowAt indexPath: IndexPath) -> CGFloat { - 50 - } - -// MARK: action - - @objc func onCreateServer(noti: Notification) { - print("noti create server id:\(String(describing: noti.object))") - guard let serverId: UInt64 = noti.object as? UInt64 else { - return - } - - weak var weakSelf = self - let viewModel = QChatChannelViewModel(serverId: serverId) - viewModel.name = localizable("second_channel") - let className = className() - viewModel.createChannel { error, channel in - if error == nil { - NELog.infoLog(ModuleName + " " + className, desc: "✅CALLBACK second_channel create success") - viewModel.name = localizable("first_channel") - - viewModel.createChannel { error, channel in - if let err = error { - NELog.errorLog( - ModuleName + " " + className, - desc: "❌createChannel first_channel failed,error = \(err)" - ) - } else { - NELog.infoLog(ModuleName + " " + className, desc: "✅CALLBACK enter first channel success") - weakSelf?.enterChatVC(channel: channel) - } - } - } - } - } - - @objc func onCreateChannel(noti: Notification) { - // enter ChatVC - guard let channel = noti.object as? ChatChannel else { - return - } - enterChatVC(channel: channel) - } - - private func enterChatVC(channel: ChatChannel?) { - let chatVC = QChatViewController(channel: channel) - navigationController?.pushViewController(chatVC, animated: true) - } -} - -extension QChatHomeViewController: NIMQChatMessageManagerDelegate { - public func onRecvSystemNotification(_ result: NIMQChatReceiveSystemNotificationResult) { - result.systemNotifications?.forEach { systemNotification in - - switch systemNotification.type { - case .channelCreate, .channelRemove, .updateChannelCategoryBlackWhiteRole, - .channelUpdate: - self.channelChange(notificationInfo: systemNotification) - case .serverMemberKick, .serverMemberInviteDone: - - if systemNotification.fromAccount != IMKitEngine.instance.imAccid, - (systemNotification.toAccids?.contains(IMKitEngine.instance.imAccid)) != - nil { - self.requestData(timeTag: 0) - } - case .serverMemberApplyDone, .serverCreate, .serverRemove, .serverMemberLeave: - - if systemNotification.type == .serverRemove { - selectIndex = 0 - self.requestData(timeTag: 0) - } else { - if systemNotification.fromAccount == IMKitEngine.instance.imAccid { - selectIndex = 0 - self.requestData(timeTag: 0) - } - } - - case .serverUpdate: - // 刷新发生更新的cell - self.reloadUpdateCell(targetServerId: systemNotification.serverId) - default: - print("") - } - } - } - - private func reloadUpdateCell(targetServerId: UInt64) { - var targetIndex = 0 - for (index, serverModel) in serverListArray.enumerated() { - if targetServerId == serverModel.serverId { - targetIndex = index - break - } - } - - let indexPath = IndexPath(row: targetIndex, section: 0) - let param = QChatGetServersParam(serverIds: [NSNumber(value: targetServerId)]) - weak var weakSelf = self - serverViewModel.getServers(parameter: param) { error, result in - NELog.infoLog( - ModuleName + " " + self.className, - desc: "CALLBACK getServers " + (error?.localizedDescription ?? "no error") - ) - if let serverArray = result?.servers,!serverArray.isEmpty { - weakSelf?.serverListArray[targetIndex] = serverArray.first! - weakSelf?.tableView.reloadRows(at: [indexPath], with: .none) - - if targetIndex == weakSelf?.selectIndex { - weakSelf?.qChatBgView.qchatServerModel = serverArray.first! - } - } - } - } - - private func channelChange(notificationInfo: NIMQChatSystemNotification) { - qChatBgView.channelChange(noticeInfo: notificationInfo) - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Model/AllChannelData.swift b/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Model/AllChannelData.swift deleted file mode 100644 index 4d1af5df..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Model/AllChannelData.swift +++ /dev/null @@ -1,57 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -import NEQChatKit -import NECoreIMKit - -protocol AllChannelDataDelegate: NSObjectProtocol { - func dataGetSuccess(_ serverId: UInt64, _ channels: [ChatChannel]) - func dataGetError(_ serverId: UInt64, _ error: Error) -} - -@objcMembers -public class AllChannelData: NSObject { - var repo = QChatRepo() - let limit = 200 - weak var delegate: AllChannelDataDelegate? - var serverId: UInt64 = 0 - var channelInfos = [ChatChannel]() - public var nextTimetag: TimeInterval = 0 - - init(sid: UInt64) { - super.init() - serverId = sid - getChannelData() - } - - func getChannelData() { - var param = QChatGetChannelsByPageParam(timeTag: nextTimetag, serverId: serverId) - param.limit = 200 - weak var weakSelf = self - repo.getChannelsByPage(param: param) { error, result in - if let err = error { - if let sid = weakSelf?.serverId { - weakSelf?.delegate?.dataGetError(sid, err) - } - } else { - if let datas = result?.channels { - weakSelf?.channelInfos.append(contentsOf: datas) - } - if let nextTimeTag = result?.nextTimetag { - weakSelf?.nextTimetag = nextTimeTag - } - if let hasMore = result?.hasMore, hasMore == true { - weakSelf?.getChannelData() - } else { - print("getChannelData finish : ", weakSelf?.serverId as Any) - if let sid = weakSelf?.serverId, let channels = weakSelf?.channelInfos { - weakSelf?.delegate?.dataGetSuccess(sid, channels) - } - } - } - } - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Model/ServerMemberModel.swift b/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Model/ServerMemberModel.swift deleted file mode 100644 index 9986b183..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/Model/ServerMemberModel.swift +++ /dev/null @@ -1,15 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -import NECoreIMKit - -// 服务器下成员列表数据模型 -@objcMembers -public class ServerMemberModel: NSObject { - public var serverMemberModel: ServerMemeber? - public var imName: String? - public var idGroupData: [String]? -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/EmptyDataView.swift b/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/EmptyDataView.swift deleted file mode 100644 index 2c00f3bd..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/EmptyDataView.swift +++ /dev/null @@ -1,69 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. -import UIKit - -class EmptyDataView: UIView { - private var imageName: String? - private var content: String? - - public init(imageName: String, content: String, frame: CGRect) { - self.imageName = imageName - self.content = content - super.init(frame: frame) - setupSubviews() - setupSubviewStyle() - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - func setupSubviews() { - backgroundColor = .white - addSubview(emptyImageView) - addSubview(contentLabel) - - NSLayoutConstraint.activate([ - emptyImageView.topAnchor.constraint(equalTo: topAnchor, constant: 176), - emptyImageView.centerXAnchor.constraint(equalTo: centerXAnchor), - emptyImageView.widthAnchor.constraint(equalToConstant: 122), - emptyImageView.heightAnchor.constraint(equalToConstant: 91), - ]) - - NSLayoutConstraint.activate([ - contentLabel.topAnchor.constraint(equalTo: emptyImageView.bottomAnchor, constant: 8), - contentLabel.centerXAnchor.constraint(equalTo: centerXAnchor), - ]) - } - - func setupSubviewStyle() { - emptyImageView.image = UIImage.ne_imageNamed(name: imageName) - contentLabel.text = content - } - - private lazy var emptyImageView: UIImageView = { - let avatar = UIImageView() - avatar.translatesAutoresizingMaskIntoConstraints = false - return avatar - }() - - private lazy var contentLabel: UILabel = { - let label = UILabel() - label.translatesAutoresizingMaskIntoConstraints = false - label.textColor = UIColor.ne_emptyTitleColor - label.font = DefaultTextFont(14) - label.numberOfLines = 0 - label.textAlignment = .center - return label - }() - - public func setttingContent(content: String) { - contentLabel.text = content - } - - public func setEmptyImage(name: String) { - emptyImageView.image = UIImage.ne_imageNamed(name: name) - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/InviteMemberView.swift b/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/InviteMemberView.swift deleted file mode 100644 index 9795bead..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/InviteMemberView.swift +++ /dev/null @@ -1,60 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class InviteMemberView: UIView { - override init(frame: CGRect) { - super.init(frame: frame) - addSubview(content) - addSubview(successImageView) - layer.cornerRadius = 26 - layer.borderWidth = 1 - layer.borderColor = HexRGB(0xE3E3E3).cgColor - layer.masksToBounds = true - backgroundColor = .white - - NSLayoutConstraint.activate([ - successImageView.leftAnchor.constraint(equalTo: leftAnchor, constant: kScreenInterval), - successImageView.centerYAnchor.constraint(equalTo: centerYAnchor), - successImageView.widthAnchor.constraint(equalToConstant: kScreenInterval), - successImageView.heightAnchor.constraint(equalToConstant: kScreenInterval), - ]) - - NSLayoutConstraint.activate([ - content.leftAnchor.constraint(equalTo: successImageView.rightAnchor, constant: 6), - content.centerYAnchor.constraint(equalTo: successImageView.centerYAnchor), - ]) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - public func showSuccessView() { - let window = UIApplication.shared.keyWindow - window?.addSubview(self) - DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { - self.removeFromSuperview() - } - } - - // MARK: lazyMethod - - private lazy var content: UILabel = { - let label = UILabel() - label.translatesAutoresizingMaskIntoConstraints = false - label.text = localizable("request_sended") - label.font = DefaultTextFont(16) - label.textColor = UIColor.ne_darkText - return label - }() - - private lazy var successImageView: UIImageView = { - let imageView = UIImageView(image: UIImage.ne_imageNamed(name: "invitemember_success")) - imageView.translatesAutoresizingMaskIntoConstraints = false - return imageView - }() -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NECreateServerCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NECreateServerCell.swift deleted file mode 100644 index bd667bd6..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NECreateServerCell.swift +++ /dev/null @@ -1,108 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class NECreateServerCell: UITableViewCell { - override func awakeFromNib() { - super.awakeFromNib() - // Initialization code - } - - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - selectionStyle = .none - setupSubviews() - } - - var model: (image: String, title: String)? { - didSet { - headImageView.image = UIImage.ne_imageNamed(name: model?.image) - content.text = model?.title - } - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - func setupSubviews() { - contentView.addSubview(serviceBgView) - serviceBgView.addSubview(headImageView) - serviceBgView.addSubview(content) - serviceBgView.addSubview(arrowImageView) - - NSLayoutConstraint.activate([ - serviceBgView.leftAnchor.constraint( - equalTo: contentView.leftAnchor, - constant: kScreenInterval - ), - serviceBgView.rightAnchor.constraint( - equalTo: contentView.rightAnchor, - constant: -kScreenInterval - ), - serviceBgView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8), - serviceBgView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -8), - ]) - - NSLayoutConstraint.activate([ - headImageView.leftAnchor.constraint(equalTo: serviceBgView.leftAnchor, constant: 16), - headImageView.centerYAnchor.constraint(equalTo: serviceBgView.centerYAnchor), - headImageView.widthAnchor.constraint(equalToConstant: 36), - headImageView.heightAnchor.constraint(equalToConstant: 36), - ]) - - NSLayoutConstraint.activate([ - arrowImageView.centerYAnchor.constraint(equalTo: serviceBgView.centerYAnchor), - arrowImageView.rightAnchor.constraint( - equalTo: serviceBgView.rightAnchor, - constant: -kScreenInterval - ), - arrowImageView.widthAnchor.constraint(equalToConstant: 5), - ]) - - NSLayoutConstraint.activate([ - content.leftAnchor.constraint(equalTo: headImageView.rightAnchor, constant: 16), - content.centerYAnchor.constraint(equalTo: headImageView.centerYAnchor), - content.rightAnchor.constraint(equalTo: arrowImageView.leftAnchor, constant: -16), - ]) - } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - - // Configure the view for the selected state - } - - // MARK: lazyMethod - - private lazy var serviceBgView: UIView = { - let view = UIView() - view.translatesAutoresizingMaskIntoConstraints = false - view.backgroundColor = HexRGB(0xEFF1F4) - view.layer.cornerRadius = 8 - return view - }() - - private lazy var headImageView: UIImageView = { - let imageView = UIImageView() - imageView.translatesAutoresizingMaskIntoConstraints = false - return imageView - }() - - private lazy var content: UILabel = { - let label = UILabel() - label.translatesAutoresizingMaskIntoConstraints = false - label.font = DefaultTextFont(16) - label.textColor = TextNormalColor - return label - }() - - private lazy var arrowImageView: UIImageView = { - let imageView = UIImageView(image: UIImage.ne_imageNamed(name: "arrowRight")) - imageView.translatesAutoresizingMaskIntoConstraints = false - return imageView - }() -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NEGroupIdentityMemberCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NEGroupIdentityMemberCell.swift deleted file mode 100644 index b61c0b9b..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NEGroupIdentityMemberCell.swift +++ /dev/null @@ -1,282 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import MapKit -import NECoreIMKit -class NEGroupIdentityMemberCell: UITableViewCell { - var dataArray = [String]() - - var maxWidth: CGFloat = kScreenWidth - 2 * kScreenInterval - var labelMargin: CGFloat = 6 - var labelHeight: CGFloat = 25 - var isFirstRow = true - var titleTopConstraint: NSLayoutConstraint? - - public var memberModel: ServerMemeber? { - didSet { - guard let model = memberModel else { return } - - if let imageName = model.avatar,!imageName.isEmpty { - avatarImage.sd_setImage(with: URL(string: imageName), completed: nil) - avatarImage.setTitle("") - } else { - if let name = model.nick,!name.isEmpty { - avatarImage.setTitle(name) - } else { - avatarImage.setTitle(model.accid ?? "") - } - avatarImage.backgroundColor = .colorWithString(string: memberModel?.accid) - } - var labelContentArray = [String]() - memberModel?.roles?.forEach { roleModel in - labelContentArray.append(roleModel.name ?? "") - } - self.dataArray = labelContentArray - setupSubviews() - - if let nick = model.nick,!nick.isEmpty { - titleLabel.text = nick - subTitleLabel.text = model.accid - titleTopConstraint?.constant = 14 - } else { - titleLabel.text = model.accid - subTitleLabel.text = "" - titleTopConstraint?.constant = 22 - } - } - } - - override func awakeFromNib() { - super.awakeFromNib() - // Initialization code - } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - } - - override public init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - selectionStyle = .none - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override func draw(_ rect: CGRect) { - avatarImage.addCorner(conrners: .allCorners, radius: 18) - } - - func setupSubviews() { - contentView.addSubview(avatarImage) - contentView.addSubview(titleLabel) - contentView.addSubview(subTitleLabel) - contentView.addSubview(arrowImageView) - contentView.addSubview(labelContainerView) - contentView.addSubview(lineView) - - NSLayoutConstraint.activate([ - avatarImage.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 12), - avatarImage.leftAnchor.constraint( - equalTo: contentView.leftAnchor, - constant: kScreenInterval - ), - avatarImage.widthAnchor.constraint(equalToConstant: 36), - avatarImage.heightAnchor.constraint(equalToConstant: 36), - ]) - - titleTopConstraint = titleLabel.topAnchor.constraint( - equalTo: contentView.topAnchor, - constant: 14 - ) - titleTopConstraint?.isActive = true - NSLayoutConstraint.activate([ - titleLabel.leftAnchor.constraint(equalTo: avatarImage.rightAnchor, constant: 12), - ]) - - NSLayoutConstraint.activate([ - subTitleLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor), - subTitleLabel.leftAnchor.constraint(equalTo: titleLabel.leftAnchor), - ]) - - NSLayoutConstraint.activate([ - arrowImageView.centerYAnchor.constraint(equalTo: avatarImage.centerYAnchor), - arrowImageView.rightAnchor.constraint( - equalTo: contentView.rightAnchor, - constant: -labelHeight - ), - ]) - - NSLayoutConstraint.activate([ - labelContainerView.topAnchor.constraint(equalTo: avatarImage.bottomAnchor, constant: 8), - labelContainerView.leftAnchor.constraint(equalTo: contentView.leftAnchor), - labelContainerView.rightAnchor.constraint(equalTo: contentView.rightAnchor), - labelContainerView.bottomAnchor.constraint( - equalTo: contentView.bottomAnchor, - constant: -10 - ), - ]) - - // 移除contentview上复用的label - labelContainerView.subviews.forEach { label in - label.removeFromSuperview() - } - var labelsWidth: CGFloat = 0 - for i in 0 ..< dataArray.count { - let label = IDGroupLabel(content: dataArray[i]) - label.textInsets = UIEdgeInsets(top: 4, left: 8, bottom: 4, right: 8) - label.translatesAutoresizingMaskIntoConstraints = false - labelContainerView.addSubview(label) - let labelSize = label.sizeThatFits(CGSize(width: maxWidth, height: labelHeight)) - - // 剩余宽度是否满足,下一个label的宽度,如不满足则换行 - if (maxWidth - labelsWidth) >= labelSize.width, isFirstRow { - NSLayoutConstraint.activate([ - i == 0 ? label.leftAnchor.constraint( - equalTo: labelContainerView.leftAnchor, - constant: kScreenInterval - ) : label.leftAnchor.constraint( - equalTo: labelContainerView.leftAnchor, - constant: kScreenInterval + labelsWidth - ), - label.topAnchor.constraint(equalTo: labelContainerView.topAnchor, constant: 8), - label.widthAnchor.constraint(equalToConstant: labelSize.width), - label.heightAnchor.constraint(equalToConstant: labelSize.height), - ]) - } else { - // 换行重置,labels总宽度 - if isFirstRow { - labelsWidth = kScreenInterval - } - isFirstRow = false - NSLayoutConstraint.activate([ - label.leftAnchor.constraint( - equalTo: labelContainerView.leftAnchor, - constant: labelsWidth - ), - label.topAnchor.constraint( - equalTo: labelContainerView.topAnchor, - constant: 8 + labelHeight + labelMargin - ), - label.widthAnchor.constraint(equalToConstant: labelSize.width), - label.heightAnchor.constraint(equalToConstant: labelSize.height), - ]) - } - - if i == dataArray.count - 1 { - NSLayoutConstraint.activate([ - label.bottomAnchor.constraint(equalTo: labelContainerView.bottomAnchor), - ]) - } - labelsWidth += (labelSize.width + labelMargin) - } - - NSLayoutConstraint.activate([ - lineView.topAnchor.constraint(equalTo: labelContainerView.bottomAnchor, constant: 12), - lineView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor), - lineView.rightAnchor.constraint(equalTo: contentView.rightAnchor), - lineView.heightAnchor.constraint(equalToConstant: 1), - lineView.leftAnchor.constraint( - equalTo: contentView.leftAnchor, - constant: kScreenInterval - ), - ]) - } - - lazy var avatarImage: NEUserHeaderView = { - let view = NEUserHeaderView(frame: .zero) - view.titleLabel.textColor = .white - view.titleLabel.font = DefaultTextFont(14) - view.translatesAutoresizingMaskIntoConstraints = false - return view - }() - - private lazy var titleLabel: UILabel = { - let name = UILabel() - name.translatesAutoresizingMaskIntoConstraints = false - name.textColor = .ne_darkText - name.font = DefaultTextFont(14) - return name - }() - - private lazy var subTitleLabel: UILabel = { - let label = UILabel() - label.translatesAutoresizingMaskIntoConstraints = false - label.font = DefaultTextFont(12) - label.textColor = UIColor.ne_emptyTitleColor - return label - }() - - private lazy var labelContainerView: UIView = { - let view = UIView() - view.translatesAutoresizingMaskIntoConstraints = false - return view - }() - - private lazy var lineView: UIView = { - let view = UIView() - view.backgroundColor = .ne_greyLine - view.translatesAutoresizingMaskIntoConstraints = false - return view - }() - - private lazy var arrowImageView: UIImageView = { - let arrow = UIImageView(image: UIImage.ne_imageNamed(name: "arrowRight")) - arrow.translatesAutoresizingMaskIntoConstraints = false - return arrow - }() -} - -class IDGroupLabel: UILabel { - private var content: String? - - init(content: String) { - super.init(frame: CGRect.zero) - self.content = content - setupStyle() - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override func draw(_ rect: CGRect) { - super.draw(rect) - addCorner(conrners: .allCorners, radius: 4) - } - - func setupStyle() { - font = DefaultTextFont(12) - textColor = HexRGB(0x656A72) - backgroundColor = HexRGB(0xF2F4F5) - text = content - } - - // 定义一个接受间距的属性 - var textInsets = UIEdgeInsets.zero - - // 返回 label 重新计算过 text 的 rectangle - override func textRect(forBounds bounds: CGRect, - limitedToNumberOfLines numberOfLines: Int) -> CGRect { - guard text != nil else { - return super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines) - } - - let insetRect = bounds.inset(by: textInsets) - let textRect = super.textRect(forBounds: insetRect, limitedToNumberOfLines: numberOfLines) - let invertedInsets = UIEdgeInsets(top: -textInsets.top, - left: -textInsets.left, - bottom: -textInsets.bottom, - right: -textInsets.right) - return textRect.inset(by: invertedInsets) - } - - // 3. 绘制文本时,对当前 rectangle 添加间距 - override func drawText(in rect: CGRect) { - super.drawText(in: rect.inset(by: textInsets)) - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NEHomeChannelCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NEHomeChannelCell.swift deleted file mode 100644 index 9747d56f..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NEHomeChannelCell.swift +++ /dev/null @@ -1,92 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NECoreIMKit - -class NEHomeChannelCell: UITableViewCell { - override func awakeFromNib() { - super.awakeFromNib() - // Initialization code - } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - - // Configure the view for the selected state - } - - public var channelModel: ChatChannel? { - didSet { - guard var name = channelModel?.name else { return } - name = "# \(name)" - let attrStr = NSMutableAttributedString(string: name) - attrStr.addAttribute( - NSAttributedString.Key.foregroundColor, - value: PlaceholderTextColor, - range: NSRange(location: 0, length: 1) - ) - attrStr.addAttribute( - NSAttributedString.Key.foregroundColor, - value: TextNormalColor, - range: NSRange(location: 1, length: name.count - 1) - ) - channelNameLabel.attributedText = attrStr - } - } - - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - selectionStyle = .none - setupSubviews() - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - func setupSubviews() { - contentView.addSubview(channelNameLabel) - contentView.addSubview(redAngleView) - - NSLayoutConstraint.activate([ - channelNameLabel.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 18), - channelNameLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), - channelNameLabel.rightAnchor.constraint( - equalTo: contentView.rightAnchor, - constant: -50 - ), - - ]) - - NSLayoutConstraint.activate([ - redAngleView.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -18), - redAngleView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), - redAngleView.heightAnchor.constraint(equalToConstant: 18), - ]) - } - - private lazy var channelNameLabel: UILabel = { - let label = UILabel() - label.translatesAutoresizingMaskIntoConstraints = false - label.font = DefaultTextFont(16) - label.textColor = TextNormalColor - return label - }() - - lazy var redAngleView: RedAngleLabel = { - let label = RedAngleLabel() - label.translatesAutoresizingMaskIntoConstraints = false - label.font = DefaultTextFont(12) - label.textColor = .white - label.text = "99+" - label.backgroundColor = HexRGB(0xF24957) - label.textInsets = UIEdgeInsets(top: 3, left: 7, bottom: 3, right: 7) - label.layer.cornerRadius = 9 - label.clipsToBounds = true - label.isHidden = true - return label - }() -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NEHomeChannelView.swift b/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NEHomeChannelView.swift deleted file mode 100644 index 5376a6e8..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NEHomeChannelView.swift +++ /dev/null @@ -1,319 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NECoreIMKit -import MJRefresh -import NIMSDK - -class NEHomeChannelView: UIView { - private let className = "NEHomeChannelView" - typealias CallBack = () -> Void - typealias SelectedChannelBlock = (_ channel: ChatChannel?) -> Void - public var channelViewModel = QChatChannelViewModel() - public var channelArray = [ChatChannel]() - - public var setUpBlock: CallBack? - public var addChannelBlock: CallBack? - public var selectedChannelBlock: SelectedChannelBlock? - public var hasMore = true - public var nextTimeTag: TimeInterval = 0 - - public var viewmodel: CreateServerViewModel? - - public var qchatServerModel: QChatServer? { - didSet { - hasMore = true - nextTimeTag = 0 - self.titleLabel.text = qchatServerModel?.name - channelArray.removeAll() - requestData(timeTag: 0) - } - } - - override init(frame: CGRect) { - super.init(frame: frame) - setupSubviews() - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override func draw(_ rect: CGRect) { - addCorner(conrners: [.topLeft, .topRight], radius: 8) - } - - func setupSubviews() { - backgroundColor = .white - - addSubview(titleLabel) - addSubview(setUpBtn) - addSubview(divideLineView) - addSubview(addChannelBtn) - addSubview(subTitleLable) - addSubview(tableView) - addSubview(emptyView) - - NSLayoutConstraint.activate([ - titleLabel.topAnchor.constraint(equalTo: topAnchor, constant: 16), - titleLabel.leftAnchor.constraint(equalTo: leftAnchor, constant: 12), - titleLabel.rightAnchor.constraint(equalTo: rightAnchor, constant: -30), - - ]) - - NSLayoutConstraint.activate([ - setUpBtn.centerYAnchor.constraint(equalTo: titleLabel.centerYAnchor), - setUpBtn.rightAnchor.constraint(equalTo: rightAnchor, constant: -16), - ]) - - NSLayoutConstraint.activate([ - divideLineView.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 16), - divideLineView.leftAnchor.constraint(equalTo: leftAnchor, constant: 12), - divideLineView.rightAnchor.constraint(equalTo: rightAnchor, constant: -12), - divideLineView.heightAnchor.constraint(equalToConstant: 1), - ]) - - NSLayoutConstraint.activate([ - subTitleLable.topAnchor.constraint(equalTo: divideLineView.bottomAnchor, constant: 16), - subTitleLable.leftAnchor.constraint(equalTo: leftAnchor, constant: 18), - ]) - - NSLayoutConstraint.activate([ - addChannelBtn.centerYAnchor.constraint(equalTo: subTitleLable.centerYAnchor), - addChannelBtn.rightAnchor.constraint(equalTo: rightAnchor, constant: -15), - ]) - - NSLayoutConstraint.activate([ - tableView.topAnchor.constraint(equalTo: subTitleLable.bottomAnchor, constant: 8), - tableView.leftAnchor.constraint(equalTo: leftAnchor), - tableView.rightAnchor.constraint(equalTo: rightAnchor), - tableView.bottomAnchor.constraint(equalTo: bottomAnchor), - ]) - - NSLayoutConstraint.activate([ - emptyView.topAnchor.constraint(equalTo: subTitleLable.bottomAnchor, constant: 8), - emptyView.leftAnchor.constraint(equalTo: leftAnchor), - emptyView.rightAnchor.constraint(equalTo: rightAnchor), - emptyView.bottomAnchor.constraint(equalTo: bottomAnchor), - ]) - } - - @objc func updateChannelList() { - requestData(timeTag: 0) - } - - public func channelChange(noticeInfo: NIMQChatSystemNotification) { - switch noticeInfo.type { - case .channelRemove, .channelCreate, .channelUpdate: - if noticeInfo.serverId == qchatServerModel?.serverId { - requestData(timeTag: 0) - } - case .updateChannelCategoryBlackWhiteRole: - if noticeInfo.serverId == qchatServerModel?.serverId, - (noticeInfo.toAccids?.contains(IMKitEngine.instance.imAccid)) != nil { - requestData(timeTag: 0) - } - - default: - print("") - } - } - - // MARK: lazy method - - private lazy var titleLabel: UILabel = { - let title = UILabel() - title.translatesAutoresizingMaskIntoConstraints = false - title.textColor = UIColor.ne_darkText - title.font = UIFont.systemFont(ofSize: 16.0, weight: .medium) - return title - }() - - private lazy var setUpBtn: ExpandButton = { - let button = ExpandButton() - button.translatesAutoresizingMaskIntoConstraints = false - button.setImage(UIImage.ne_imageNamed(name: "home_setupServer"), for: .normal) - button.setImage(UIImage.ne_imageNamed(name: "home_setupServer"), for: .highlighted) - button.addTarget(self, action: #selector(setupBtnClick), for: .touchUpInside) - return button - }() - - private lazy var divideLineView: UIView = { - let view = UIView() - view.translatesAutoresizingMaskIntoConstraints = false - view.backgroundColor = UIColor.ne_greyLine - return view - }() - - private lazy var subTitleLable: UILabel = { - let title = UILabel() - title.translatesAutoresizingMaskIntoConstraints = false - title.text = localizable("message_channel") - title.textColor = PlaceholderTextColor - title.font = DefaultTextFont(14) - return title - }() - - private lazy var addChannelBtn: UIButton = { - let button = UIButton() - button.translatesAutoresizingMaskIntoConstraints = false - button.setImage(UIImage.ne_imageNamed(name: "home_addChannel"), for: .normal) - button.setImage(UIImage.ne_imageNamed(name: "home_addChannel"), for: .highlighted) - button.addTarget(self, action: #selector(addChannelBtnClick), for: .touchUpInside) - return button - }() - - lazy var tableView: UITableView = { - let tableView = UITableView(frame: .zero, style: .plain) - tableView.translatesAutoresizingMaskIntoConstraints = false - tableView.separatorStyle = .none - tableView.delegate = self - tableView.dataSource = self - tableView.register( - NEHomeChannelCell.self, - forCellReuseIdentifier: "\(NSStringFromClass(NEHomeChannelCell.self))" - ) - tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: 0.1)) - let mjfooter = MJRefreshBackNormalFooter( - refreshingTarget: self, - refreshingAction: #selector(loadMoreData) - ) - mjfooter.stateLabel?.isHidden = true - tableView.mj_footer = mjfooter - return tableView - }() - - private lazy var emptyView: EmptyDataView = { - let view = EmptyDataView( - imageName: "channel_noMoreData", - content: localizable("server_nochannel"), - frame: tableView.bounds - ) - view.translatesAutoresizingMaskIntoConstraints = false - view.isHidden = true - return view - }() -} - -extension NEHomeChannelView { - @objc func setupBtnClick(sender: UIButton) { - if setUpBlock != nil { - setUpBlock!() - } - } - - @objc func addChannelBtnClick(sender: UIButton) { - if addChannelBlock != nil { - addChannelBlock!() - } - } - - @objc func loadMoreData() { - requestData(timeTag: nextTimeTag) - tableView.mj_footer?.endRefreshing() - } - - public func requestData(timeTag: TimeInterval) { - if timeTag != 0, !hasMore { - // 上拉加载无多余数据,无需请求 - return - } - - guard let serverId = qchatServerModel?.serverId else { return } - let param = QChatGetChannelsByPageParam(timeTag: timeTag, serverId: serverId) - channelViewModel.getChannelsByPage(parameter: param) { [self] error, result in - if error == nil { - NELog.infoLog(self.className, desc: "✅CALLBACK getChannelsByPage SUCCESS") - guard let dataArray = result?.channels else { return } - if timeTag == 0 { - self.channelArray.removeAll() - self.channelArray = dataArray - if dataArray.isEmpty { - emptyView.setttingContent(content: localizable("server_nochannel")) - emptyView.setEmptyImage(name: "channel_noMoreData") - emptyView.isHidden = false - } else { - emptyView.isHidden = true - } - - } else { - self.channelArray += dataArray - } - self.hasMore = result?.hasMore ?? false - self.nextTimeTag = result?.nextTimetag ?? 0 - tableView.reloadData() - } else { - NELog.errorLog(self.className, desc: "❌CALLBACK getChannelsByPage failed,error = \(error!)") - } - } - } - - public func showEmptyServerView() { - titleLabel.isHidden = true - setUpBtn.isHidden = true - divideLineView.isHidden = true - subTitleLable.isHidden = true - addChannelBtn.isHidden = true - emptyView.isHidden = false - emptyView.setttingContent(content: localizable("add_favorite_service")) - emptyView.setEmptyImage(name: "servers_noMore") - } - - public func dismissEmptyView() { - titleLabel.isHidden = false - setUpBtn.isHidden = false - divideLineView.isHidden = false - subTitleLable.isHidden = false - addChannelBtn.isHidden = false - emptyView.isHidden = true - } -} - -extension NEHomeChannelView: UITableViewDataSource, UITableViewDelegate { - public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - channelArray.count - } - - public func tableView(_ tableView: UITableView, - cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell( - withIdentifier: "\(NSStringFromClass(NEHomeChannelCell.self))", - for: indexPath - ) as! NEHomeChannelCell - if indexPath.row < channelArray.count { - let channel = channelArray[indexPath.row] - cell.channelModel = channel - if let sid = qchatServerModel?.serverId, let cid = channel.channelId, - let unreadCount = viewmodel?.getChannelUnreadCount( - sid, - cid - ) { - cell.redAngleView.isHidden = false - if unreadCount <= 0 { - cell.redAngleView.isHidden = true - } else if unreadCount <= 99 { - cell.redAngleView.text = "\(unreadCount)" - } else { - cell.redAngleView.text = "99+" - } - } else { - cell.redAngleView.isHidden = true - } - } - return cell - } - - public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - if let block = selectedChannelBlock, channelArray.count > 0 { - block(channelArray[indexPath.row]) - } - } - - public func tableView(_ tableView: UITableView, - heightForRowAt indexPath: IndexPath) -> CGFloat { - 36 - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NEHomeServerCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NEHomeServerCell.swift deleted file mode 100644 index cdcdd667..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NEHomeServerCell.swift +++ /dev/null @@ -1,120 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NECoreIMKit -import NECoreKit -class NEHomeServerCell: UITableViewCell { - lazy var redDot: UIView = { - let view = UIView() - view.translatesAutoresizingMaskIntoConstraints = false - view.backgroundColor = .ne_redColor - view.clipsToBounds = true - view.layer.cornerRadius = 4.0 - view.layer.borderColor = UIColor.white.cgColor - view.layer.borderWidth = 1 - view.isHidden = true - return view - }() - - override func awakeFromNib() { - super.awakeFromNib() - // Initialization code - } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - - // Configure the view for the selected state - } - - public var serverModel: QChatServer? { - didSet { - if let imageUrl = serverModel?.icon { - headView.sd_setImage(with: URL(string: imageUrl), completed: nil) - headView.setTitle("") - } else { - if let name = serverModel?.name { - headView.setTitle(name) - } - headView.sd_setImage(with: URL(string: ""), completed: nil) - headView.backgroundColor = .colorWithNumber(number: serverModel?.serverId) - } - - if let hasUnread = serverModel?.hasUnread { - redDot.isHidden = !hasUnread - } - } - } - - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - selectionStyle = .none - contentView.backgroundColor = HexRGB(0xE9EFF5) - setupSubviews() - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - func setupSubviews() { - contentView.addSubview(leftSelectView) - contentView.addSubview(headView) - - NSLayoutConstraint.activate([ - headView.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 12), - headView.topAnchor.constraint(equalTo: contentView.topAnchor), - headView.widthAnchor.constraint(equalToConstant: 42), - headView.heightAnchor.constraint(equalToConstant: 42), - ]) - - NSLayoutConstraint.activate([ - leftSelectView.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: -4), - leftSelectView.topAnchor.constraint(equalTo: contentView.topAnchor), - leftSelectView.widthAnchor.constraint(equalToConstant: 8), - leftSelectView.heightAnchor.constraint(equalToConstant: 36), - ]) - - contentView.addSubview(redDot) - let factor = cos(45 * Double.pi / 180) - let x = 12 + 21 * factor + 21 - let y = 21 - 21 * factor - NSLayoutConstraint.activate([ - redDot.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: x), - redDot.topAnchor.constraint(equalTo: contentView.topAnchor, constant: y), - redDot.widthAnchor.constraint(equalToConstant: 8), - redDot.heightAnchor.constraint(equalToConstant: 8), - ]) - } - - override func draw(_ rect: CGRect) { - super.draw(rect) - headView.addCorner(conrners: .allCorners, radius: 21) - } - - // MARK: lazy method - - private lazy var leftSelectView: UIView = { - let view = UIView() - view.translatesAutoresizingMaskIntoConstraints = false - view.backgroundColor = HexRGB(0x337EFF) - view.layer.cornerRadius = 4 - view.isHidden = true - return view - }() - - lazy var headView: NEUserHeaderView = { - let view = NEUserHeaderView(frame: .zero) - view.titleLabel.textColor = .white - view.titleLabel.font = DefaultTextFont(14) - view.translatesAutoresizingMaskIntoConstraints = false - return view - }() - - public func showSelectState(isShow: Bool) { - leftSelectView.isHidden = isShow ? false : true - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NEMemberListCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NEMemberListCell.swift deleted file mode 100644 index d0b6cfdf..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NEMemberListCell.swift +++ /dev/null @@ -1,87 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class NEMemberListCell: UITableViewCell { - override func awakeFromNib() { - super.awakeFromNib() - // Initialization code - } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - - // Configure the view for the selected state - } - - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - selectionStyle = .none - setupSubviews() - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - func setupSubviews() { - contentView.addSubview(avatarImage) - contentView.addSubview(contentLabel) - contentView.addSubview(arrowImage) - contentView.addSubview(lineView) - - NSLayoutConstraint.activate([ - avatarImage.leftAnchor.constraint( - equalTo: contentView.leftAnchor, - constant: kScreenInterval - ), - avatarImage.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -12), - avatarImage.widthAnchor.constraint(equalToConstant: 36), - avatarImage.heightAnchor.constraint(equalToConstant: 36), - ]) - - NSLayoutConstraint.activate([ - lineView.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 20), - lineView.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -20), - lineView.heightAnchor.constraint(equalToConstant: 1.0), - lineView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor), - ]) - - NSLayoutConstraint.activate([ - arrowImage.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -32), - arrowImage.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), - ]) - } - - private lazy var avatarImage: UIImageView = { - let avatar = UIImageView() - avatar.translatesAutoresizingMaskIntoConstraints = false - avatar.backgroundColor = .ne_defautAvatarColor - return avatar - }() - - private lazy var contentLabel: UILabel = { - let label = UILabel() - label.translatesAutoresizingMaskIntoConstraints = false - label.textColor = TextNormalColor - label.font = DefaultTextFont(14) - return label - }() - - private lazy var lineView: UIView = { - let line = UIView() - line.translatesAutoresizingMaskIntoConstraints = false - line.backgroundColor = .ne_greyLine - return line - }() - - private lazy var arrowImage: UIImageView = { - let arrow = UIImageView() - arrow.translatesAutoresizingMaskIntoConstraints = false - arrow.image = UIImage.ne_imageNamed(name: "") - return arrow - }() -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NESearchServerCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NESearchServerCell.swift deleted file mode 100644 index 23e57c0d..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/View/NESearchServerCell.swift +++ /dev/null @@ -1,236 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NECoreIMKit - -class NESearchServerCell: UITableViewCell { - typealias CallBack = (() -> Void)? - @objc var joinServerCallBack: CallBack = nil - public var serverViewModel = CreateServerViewModel() - private let className = "NESearchServerCell" - - public var serverModel: QChatServer? { - didSet { - if let imageUrl = serverModel?.icon { - headImageView.sd_setImage(with: URL(string: imageUrl), completed: nil) - headImageView.setTitle("") - } else { - if let name = serverModel?.name { - headImageView.setTitle(name) - } - headImageView.sd_setImage(with: URL(string: ""), completed: nil) - headImageView.backgroundColor = .colorWithNumber(number: serverModel?.serverId) - } - - self.content.text = serverModel?.name - - guard let serverId = serverModel?.serverId else { - return - } - self.subContent.text = "\(serverId)" - - let item = QChatGetServerMemberItem( - serverId: serverId, - accid: IMKitEngine.instance.imAccid - ) - let param = QChatGetServerMembersParam(serverAccIds: [item]) - - serverViewModel.getServerMemberList(parameter: param) { error, membersResult in - NELog.infoLog( - self.className, - desc: "CALLBACK getServerMemberList " + (error?.localizedDescription ?? "no error") - ) - if error == nil { - guard let dataArray = membersResult?.memberArray else { return } - if dataArray.isEmpty { - self.rightContent.isHidden = true - self.joinBtn.isHidden = false - } else { - self.rightContent.isHidden = false - self.joinBtn.isHidden = true - } - } else { - print("getServerMemberList failed,error = \(error!)") - } - } - } - } - - override func awakeFromNib() { - super.awakeFromNib() - // Initialization code - } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - // Configure the view for the selected state - } - - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - selectionStyle = .none - setupSubviews() - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override func draw(_ rect: CGRect) { - serviceBgView.addCorner(conrners: .allCorners, radius: 8) - headImageView.addCorner(conrners: .allCorners, radius: 18) - } - - func setupSubviews() { - contentView.addSubview(serviceBgView) - serviceBgView.addSubview(headImageView) - serviceBgView.addSubview(content) - serviceBgView.addSubview(subContent) - serviceBgView.addSubview(rightContent) - serviceBgView.addSubview(rightContentImageView) - serviceBgView.addSubview(joinBtn) - - NSLayoutConstraint.activate([ - serviceBgView.leftAnchor.constraint( - equalTo: contentView.leftAnchor, - constant: kScreenInterval - ), - serviceBgView.rightAnchor.constraint( - equalTo: contentView.rightAnchor, - constant: -kScreenInterval - ), - serviceBgView.topAnchor.constraint(equalTo: contentView.topAnchor), - serviceBgView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -6), - ]) - - NSLayoutConstraint.activate([ - headImageView.leftAnchor.constraint(equalTo: serviceBgView.leftAnchor, constant: 16), - headImageView.centerYAnchor.constraint(equalTo: serviceBgView.centerYAnchor), - headImageView.widthAnchor.constraint(equalToConstant: 36), - headImageView.heightAnchor.constraint(equalToConstant: 36), - ]) - - NSLayoutConstraint.activate([ - subContent.leftAnchor.constraint(equalTo: content.leftAnchor), - subContent.bottomAnchor.constraint(equalTo: headImageView.bottomAnchor), - ]) - - NSLayoutConstraint.activate([ - rightContent.centerYAnchor.constraint(equalTo: serviceBgView.centerYAnchor), - rightContent.rightAnchor.constraint(equalTo: serviceBgView.rightAnchor, constant: -16), - ]) - - NSLayoutConstraint.activate([ - rightContentImageView.centerYAnchor.constraint(equalTo: rightContent.centerYAnchor), - rightContentImageView.rightAnchor.constraint( - equalTo: serviceBgView.rightAnchor, - constant: 16 - ), - ]) - - NSLayoutConstraint.activate([ - joinBtn.centerYAnchor.constraint(equalTo: serviceBgView.centerYAnchor), - joinBtn.widthAnchor.constraint(equalToConstant: 56), - joinBtn.heightAnchor.constraint(equalToConstant: 24), - joinBtn.rightAnchor.constraint(equalTo: serviceBgView.rightAnchor, constant: -16), - ]) - - NSLayoutConstraint.activate([ - content.topAnchor.constraint(equalTo: headImageView.topAnchor), - content.leftAnchor.constraint(equalTo: headImageView.rightAnchor, constant: 12), - content.rightAnchor.constraint(equalTo: joinBtn.leftAnchor), - ]) - } - - // MARK: lazyMethod - - private lazy var serviceBgView: UIView = { - let view = UIView() - view.translatesAutoresizingMaskIntoConstraints = false - view.backgroundColor = HexRGB(0xEFF1F4) - return view - }() - - lazy var headImageView: NEUserHeaderView = { - let view = NEUserHeaderView(frame: .zero) - view.titleLabel.textColor = .white - view.titleLabel.font = DefaultTextFont(14) - view.translatesAutoresizingMaskIntoConstraints = false -// view.clipsToBounds = true - return view - }() - - private lazy var content: UILabel = { - let label = UILabel() - label.translatesAutoresizingMaskIntoConstraints = false - label.font = DefaultTextFont(14) - label.textColor = TextNormalColor - return label - }() - - private lazy var subContent: UILabel = { - let label = UILabel() - label.translatesAutoresizingMaskIntoConstraints = false - label.font = DefaultTextFont(12) - label.textColor = .ne_blueText - return label - }() - - private lazy var rightContent: UILabel = { - let label = UILabel() - label.translatesAutoresizingMaskIntoConstraints = false - label.text = localizable("applied") - label.font = DefaultTextFont(12) - label.textColor = UIColor.ne_emptyTitleColor - label.isHidden = true - return label - }() - - private lazy var rightContentImageView: UIImageView = { - let imageView = UIImageView(image: UIImage.ne_imageNamed(name: "addOther_icon")) - imageView.translatesAutoresizingMaskIntoConstraints = false - imageView.isHidden = true - return imageView - }() - - private lazy var joinBtn: UIButton = { - let button = UIButton() - button.translatesAutoresizingMaskIntoConstraints = false - button.setTitle(localizable("join"), for: .normal) - button.setTitleColor(UIColor.white, for: .normal) - button.titleLabel?.font = DefaultTextFont(12) - button.backgroundColor = HexRGB(0x337EFF) - button.layer.cornerRadius = 4 - button.addTarget(self, action: #selector(bottomBtnClick), for: .touchUpInside) - button.isHidden = true - return button - }() -} - -extension NESearchServerCell { - @objc func bottomBtnClick(sender: UIButton) { - guard let serverId = serverModel?.serverId else { - return - } - let param = QChatApplyServerJoinParam(serverId: serverId) - - serverViewModel.applyServerJoin(parameter: param) { [self] error in - NELog.infoLog( - self.className, - desc: "CALLBACK applyServerJoin " + (error?.localizedDescription ?? "no error") - ) - if error == nil { - self.joinBtn.isHidden = true - self.rightContent.isHidden = false - if self.joinServerCallBack != nil { - joinServerCallBack!() - } - } else { - print("applyServerJoin failed,error = \(error!)") - } - } - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/ViewModel/CreateServerViewModel.swift b/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/ViewModel/CreateServerViewModel.swift deleted file mode 100644 index fe593914..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/ViewModel/CreateServerViewModel.swift +++ /dev/null @@ -1,254 +0,0 @@ -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -import NECoreIMKit -import UIKit -import NEQChatKit -import NIMSDK -import NECoreKit -import SDWebImageWebPCoder -import SDWebImageSVGKitPlugin - -@objcMembers -public class CreateServerViewModel: NSObject, QChatRepoMessageDelegate, AllChannelDataDelegate { - typealias ServerListRefresh = () -> Void - - var dataDic = WeakDictionary() - - var channelUnreadCountDic = [UInt64: Int]() - - var requestFlag = [UInt64: AllChannelData]() - - var channelDataDic = [UInt64: [UInt64: UInt]]() - - let repo = QChatRepo() - - var currentServerId: UInt64? - - var delegate: ViewModelDelegate? - - var updateServerList: ServerListRefresh? - - private let className = "CreateServerViewModel" - - override public init() { - super.init() - NELog.infoLog(ModuleName + " " + className, desc: #function) - repo.delegate = self - let webpCoder = SDImageWebPCoder() - SDImageCodersManager.shared.addCoder(webpCoder) - let svgCoder = SDImageSVGKCoder.shared - SDImageCodersManager.shared.addCoder(svgCoder) - } - - public func onUnReadChange(_ unreads: [NIMQChatUnreadInfo]?, - _ lastUnreads: [NIMQChatUnreadInfo]?) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", unreads.count:\(unreads?.count ?? 0)") - print("onUnReadChange: ", unreads as Any) - weak var weakSelf = self - var set = Set() - - unreads?.forEach { unread in - set.insert(unread.serverId) - if weakSelf?.channelDataDic[unread.serverId] != nil { - weakSelf?.channelDataDic[unread.serverId]?[unread.channelId] = unread.unreadCount - } else { - var channelDic = [UInt64: UInt]() - channelDic[unread.channelId] = unread.unreadCount - weakSelf?.channelDataDic[unread.serverId] = channelDic - } - } - - set.forEach { sid in - let hasUnread = checkServerExistUnread(sid) - print("hasUnread : ", hasUnread) - let model = weakSelf?.dataDic[sid] - print("server model : ", model?.name as Any) - model?.hasUnread = hasUnread - if let cSid = weakSelf?.currentServerId, cSid == sid { - weakSelf?.delegate?.dataDidChange() - } - } - - if let block = updateServerList { - block() - } - } - - func checkServerExistUnread(_ serverId: UInt64) -> Bool { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(serverId)") - if let channelDic = channelDataDic[serverId] { - for key in channelDic.keys { - if let unreadCount = channelDic[key], unreadCount > 0 { - return true - } - } - } - return false - } - - public lazy var dataArray: [(String, String)] = { - let array = [ - ("mine_create", localizable("qchat_mine_add")), - ("addOther_icon", localizable("qchat_join_otherServer")), - ] - return array - }() - - public func createServer(parameter: CreateServerParam, - _ completion: @escaping (NSError?, CreateServerResult?) -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", name:\(parameter.name ?? "nil")") - QChatServerProvider.shared.createServer(param: parameter) { error, serverResult in - completion(error, serverResult) - } - } - - public func getServers(parameter: QChatGetServersParam, - _ completion: @escaping (NSError?, QChatGetServersResult?) -> Void) { - NELog.infoLog( - ModuleName + " " + className, - desc: #function + ", serverIds.count:\(parameter.serverIds?.count ?? 0)" - ) - repo.getServers(parameter) { error, serverResult in - completion(error, serverResult) - } - } - - public func getServerList(parameter: GetServersByPageParam, - _ completion: @escaping (NSError?, GetServersByPageResult?) -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function) - QChatServerProvider.shared.getServerCount(param: parameter) { error, result in - completion(error, result) - } - } - - public func getServerMemberList(parameter: QChatGetServerMembersParam, - _ completion: @escaping (NSError?, - QChatGetServerMembersResult?) -> Void) { - NELog.infoLog( - ModuleName + " " + className, - desc: #function + ", serverAccIds.count:\(parameter.serverAccIds?.count ?? 0)" - ) - QChatServerProvider.shared.getServerMembers(param: parameter) { error, result in - completion(error, result) - } - } - - public func getServerMembersByPage(parameter: QChatGetServerMembersByPageParam, - _ completion: @escaping (NSError?, - QChatGetServerMembersResult?) - -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(parameter.serverId ?? 0)") - QChatServerProvider.shared.getServerMembersByPage(param: parameter) { error, result in - completion(error, result) - } -// repo.getServerMembersByPage(parameter, completion) - } - - public func applyServerJoin(parameter: QChatApplyServerJoinParam, - _ completion: @escaping (NSError?) -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(parameter.serverId)") - QChatServerProvider.shared.applyServerJoin(param: parameter) { error in - completion(error) - } - } - - public func inviteMembersToServer(serverId: UInt64, accids: [String], - _ completion: @escaping (NSError?) -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(serverId)") - let param = QChatInviteServerMembersParam(serverId: serverId, accids: accids) - repo.inviteMembersToServer(param) { error in - completion(error) - } - } - - public func getUnread(_ servers: [QChatServer]) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", servers.count:\(servers.count)") -// print("server model get unread servers : ", servers.count) - - if currentServerId == nil { - currentServerId = servers.first?.serverId - } - weak var weakSelf = self - servers.forEach { server in - if let sid = server.serverId { - weakSelf?.dataDic[sid] = server - } - weakSelf?.getAllChannel(server) - } - } - - func getAllChannel(_ server: QChatServer) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(server.serverId ?? 0)") - if let sid = server.serverId, requestFlag[sid] == nil { - let allChannelData = AllChannelData(sid: sid) - allChannelData.delegate = self - requestFlag[sid] = allChannelData - } - } - - func getChannelUnread(_ serverId: UInt64, _ channels: [ChatChannel]) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(serverId), channels.count:\(channels.count)") -// print("getChannelUnread channel count : ", channels.count) - var param = GetChannelUnreadInfosParam() - var targets = [ChannelIdInfo]() - - channels.forEach { channel in - var channelIdInfo = ChannelIdInfo() - channelIdInfo.serverId = serverId - channelIdInfo.channelId = channel.channelId - targets.append(channelIdInfo) - } - param.targets = targets -// weak var weakSelf = self - repo.getChannelUnReadInfo(param) { error, infos in - - print("get channel unread info : ", error as Any) - /* - infos?.forEach({ info in - if weakSelf?.channelDataDic[info.serverId] != nil { - weakSelf?.channelDataDic[info.serverId]?[info.channelId] = info.unreadCount - }else { - var channelDic = [UInt64: UInt]() - channelDic[info.channelId] = info.unreadCount - weakSelf?.channelDataDic[info.serverId] = channelDic - } - }) - if let last = infos?.last, let sid = weakSelf?.currentServerId { - if last.serverId == sid { - weakSelf?.delegate?.dataDidChange() - } - } - if let server = weakSelf?.dataDic[serverId], let block = weakSelf?.updateServerList, let hasUnread = weakSelf?.checkServerExistUnread(serverId){ - server.hasUnread = hasUnread - block() - if let cSid = weakSelf?.currentServerId, cSid == serverId { - weakSelf?.delegate?.dataDidChange() - } - }*/ - } - } - - func dataGetSuccess(_ serverId: UInt64, _ channels: [ChatChannel]) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(serverId)") - print("get unread channel success : ", channels.count) - requestFlag.removeValue(forKey: serverId) - getChannelUnread(serverId, channels) - } - - func dataGetError(_ serverId: UInt64, _ error: Error) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(serverId)") - requestFlag.removeValue(forKey: serverId) - print("get all channels error : ", error) - } - - func getChannelUnreadCount(_ serverId: UInt64, _ channelId: UInt64) -> UInt { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(serverId)") - if let channelDic = channelDataDic[serverId], let count = channelDic[channelId] { - return count - } - return 0 - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/ViewModel/MemberListViewModel.swift b/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/ViewModel/MemberListViewModel.swift deleted file mode 100644 index c423a8d9..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/QChatHomePage/ViewModel/MemberListViewModel.swift +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -import NEQChatKit -import NECoreIMKit - -@objcMembers -public class MemberListViewModel: NSObject { - let repo = QChatRepo() - public var memberInfomationArray: [QChatMember]? - weak var delegate: ViewModelDelegate? - private let className = "MemberListViewModel" - - override init() {} - - func requestServerMemebersByPage(param: QChatGetServerMembersByPageParam, - _ completion: @escaping (NSError?, [ServerMemeber]?) -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(param.serverId ?? 0)") - repo.getServerMembersByPage(param) { error, memberResult in - - if error == nil { - guard let memberArr = memberResult?.memberArray else { return } - var accidList = [String]() - var dic = [String: ServerMemeber]() - - for memberModel in memberArr { - accidList.append(memberModel.accid ?? "") - if let accid = memberModel.accid { - dic[accid] = memberModel - } - } - - let roleParam = QChatGetExistingAccidsInServerRoleParam( - serverId: param.serverId!, - accids: accidList - ) - self.repo.getExistingServerRolesByAccids(roleParam) { error, serverRolesDict in - serverRolesDict?.forEach { key, roleArray in - dic[key]?.roles = roleArray - } - var tempServerArray = [ServerMemeber]() - for var memberModel in memberArr { - if let accid = memberModel.accid, let dicMember = dic[accid] { - memberModel.roles = dicMember.roles - memberModel.imName = dicMember.imName - tempServerArray.append(memberModel) - } - } - completion(nil, tempServerArray) - } - - } else { - completion(error, nil) - print("getServerMembersByPage failed,error = \(error!)") - NELog.infoLog(ModuleName + " " + self.className, desc: #function + ", ❌CALLBACK FAILED, error:" + error!.localizedDescription) - } - } - } - - func getRoles() {} -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/Model/IdGroupModel.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/Model/IdGroupModel.swift deleted file mode 100644 index a0e3e62e..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/Model/IdGroupModel.swift +++ /dev/null @@ -1,30 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -import NECoreIMKit - -@objcMembers -public class IdGroupModel: NSObject { - var idName: String? - var subTitle: String? - var uid: Int? - var isSelect = false - var cornerType: CornerType = .none - var role: ServerRole? - var hasPermission = false - - override public init() {} - - public init(_ serverRole: ServerRole) { - role = serverRole - idName = serverRole.name - if let type = serverRole.type, type == .everyone { - subTitle = localizable("qchat_group_default_permission") - } else if let type = serverRole.type, type == .custom { - subTitle = "\(serverRole.memberCount ?? 0)人" - } - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/Model/PermissionCellModel.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/Model/PermissionCellModel.swift deleted file mode 100644 index 58c12a14..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/Model/PermissionCellModel.swift +++ /dev/null @@ -1,15 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation - -@objcMembers -public class PermissionCellModel: NSObject { - weak var permission: PermissionModel? - var permissionKey: String? - var showName: String? - var cornerType = CornerType.none - var hasPermission = false -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/Model/PermissionModel.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/Model/PermissionModel.swift deleted file mode 100644 index fc9ca6f3..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/Model/PermissionModel.swift +++ /dev/null @@ -1,108 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -import NECoreIMKit - -@objcMembers -public class PermissionModel: NSObject { - let commonPermission = [ - #keyPath(PermissionModel.managerServer), - #keyPath(PermissionModel.allChannelProperty), - #keyPath(PermissionModel.role), - ] - - let commonPermissionDic = [ - #keyPath(PermissionModel.managerServer): localizable("qchat_manager_server"), - #keyPath(PermissionModel.allChannelProperty): localizable("qchat_manager_channel"), - #keyPath(PermissionModel.role): localizable("qchat_manager_role"), - ] - - var allChannelProperty = ChatPermissionType.manageChannel.rawValue - - var role = ChatPermissionType.manageRole.rawValue - - var managerServer = ChatPermissionType.manageServer.rawValue - - let messagePermission = [#keyPath(PermissionModel.sendMessage)] - - let messagePermissionDic = - [#keyPath(PermissionModel.sendMessage): localizable("qchat_send_message")] - - var sendMessage = ChatPermissionType.sendMsg.rawValue - -// @objc var deleteOtherMemberMessage = ChatPermissionType.deleteOtherMsg.rawValue -// -// @objc var recallMessage = ChatPermissionType.revokeMsg.rawValue -// -// @objc var atAnyMember = ChatPermissionType.remindOther.rawValue -// -// @objc var atAllMember = ChatPermissionType.remindAll.rawValue - - /* - let messagePermission = [#keyPath(PermissionModel.sendMessage), - #keyPath(PermissionModel.deleteOtherMemberMessage), - #keyPath(PermissionModel.recallMessage), - #keyPath(PermissionModel.atAnyMember), - #keyPath(PermissionModel.atAllMember)] - - let messagePermissionDic = [#keyPath(PermissionModel.sendMessage):localizable("qchat_send_message"), - #keyPath(PermissionModel.deleteOtherMemberMessage):localizable("qchat_delete_message"), - #keyPath(PermissionModel.recallMessage):localizable("qchat_recall_message"), - #keyPath(PermissionModel.atAnyMember):localizable("qchat_at_any"), - #keyPath(PermissionModel.atAllMember):localizable("qchat_at_all")] - - @objc var sendMessage = ChatPermissionType.sendMsg.rawValue - - @objc var deleteOtherMemberMessage = ChatPermissionType.deleteOtherMsg.rawValue - - @objc var recallMessage = ChatPermissionType.revokeMsg.rawValue - - @objc var atAnyMember = ChatPermissionType.remindOther.rawValue - - @objc var atAllMember = ChatPermissionType.remindAll.rawValue - */ - - let memberPermission = [#keyPath(PermissionModel.modifyOwnServer), - #keyPath(PermissionModel.modifyOthersServer), - #keyPath(PermissionModel.inviteMember), - #keyPath(PermissionModel.kickout), - #keyPath(PermissionModel.managerBlackAndWhite)] - - let memberPermissionDic = [ - #keyPath(PermissionModel.modifyOwnServer): localizable("qchat_modify_own_server"), - #keyPath(PermissionModel.modifyOthersServer): localizable("qchat_modify_other_server"), - #keyPath(PermissionModel.inviteMember): localizable("qchat_invite_member"), - #keyPath(PermissionModel.kickout): localizable("qchat_kick_out"), - #keyPath(PermissionModel.managerBlackAndWhite): localizable("qchat_manager_channel_list"), - ] - - var modifyOwnServer = ChatPermissionType.manageServer.rawValue - - var modifyOthersServer = ChatPermissionType.modifyOthersInfoInServer.rawValue - - var inviteMember = ChatPermissionType.inviteToServer.rawValue - - var kickout = ChatPermissionType.kickOthersInServer.rawValue - - var managerBlackAndWhite = ChatPermissionType.manageBlackWhiteList.rawValue - - var changeMap = [String: Bool]() - - override init() { - super.init() - } - - func getChangePermission() -> [ChatPermissionType: Bool] { - var permissions = [ChatPermissionType: Bool]() - changeMap.forEach { (key: String, v: Bool) in - if let permissionKey = value(forKey: key) as? String, - let type = ChatPermissionType(rawValue: permissionKey) { - permissions[type] = v - } - } - return permissions - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/Model/SettingModel.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/Model/SettingModel.swift deleted file mode 100644 index 60193a48..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/Model/SettingModel.swift +++ /dev/null @@ -1,13 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation - -@objcMembers -public class SettingModel: NSObject { - var title: String? - var cornerType: CornerType = CornerType.bottomLeft.union(CornerType.bottomRight) - .union(CornerType.topLeft).union(CornerType.topRight) -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/Model/UserInfo.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/Model/UserInfo.swift deleted file mode 100644 index 7a319b6f..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/Model/UserInfo.swift +++ /dev/null @@ -1,50 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -import NECoreIMKit - -@objcMembers -class UserInfo: NSObject { - var nickName: String? - var cornerType: CornerType = .none - var color = UIColor.colorWithNumber(number: 0) - var select = false - var accid: String? - var serverId: UInt64? - var createTime: Double? - - var serverMember: ServerMemeber? - - var roleMember: RoleMember? - - override init() {} - - init(_ member: ServerMemeber) { - serverMember = member - if let n = member.nick, n.count > 0 { - nickName = n - } else { - nickName = member.accid - } - accid = member.accid - serverId = member.serverId - createTime = member.createTime - color = UIColor.colorWithString(string: accid) - } - - init(_ member: RoleMember) { - roleMember = member - if let n = member.nick, n.count > 0 { - nickName = n - } else { - nickName = member.accid - } - accid = member.accid - serverId = member.serverId - createTime = member.createTime - color = UIColor.colorWithString(string: accid) - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatDestructiveCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatDestructiveCell.swift deleted file mode 100644 index 38a54c94..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatDestructiveCell.swift +++ /dev/null @@ -1,46 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class QChatDestructiveCell: QChatCornerCell { - lazy var redTextLabel: UILabel = { - let label = UILabel() - label.textColor = .ne_redText - label.font = DefaultTextFont(16) - label.translatesAutoresizingMaskIntoConstraints = false - return label - }() - - override func awakeFromNib() { - super.awakeFromNib() - // Initialization code - } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - - // Configure the view for the selected state - setupUI() - } - - func setupUI() { - contentView.backgroundColor = .clear - backgroundColor = .clear - contentView.addSubview(redTextLabel) - NSLayoutConstraint.activate([ - redTextLabel.centerXAnchor.constraint(equalTo: contentView.centerXAnchor), - redTextLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), - ]) - } - - func changeDisableTextColor() { - redTextLabel.textColor = .ne_disableRedText - } - - func changeEnableTextColor() { - redTextLabel.textColor = .ne_redText - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatHeaderCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatHeaderCell.swift deleted file mode 100644 index 61ea3353..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatHeaderCell.swift +++ /dev/null @@ -1,69 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class QChatHeaderCell: QChatCornerCell { - var user: UserInfo? { - didSet { - if let name = user?.nickName { - headerView.setTitle(name) - nameLabel.text = name - } else if let aid = user?.accid { - headerView.setTitle(aid) - nameLabel.text = aid - } - headerView.backgroundColor = user?.color - } - } - - let headerView: NEUserHeaderView = { - let header = NEUserHeaderView(frame: .zero) - header.titleLabel.font = DefaultTextFont(20) - header.titleLabel.textColor = UIColor.white - header.layer.cornerRadius = 30 - header.translatesAutoresizingMaskIntoConstraints = false -// header.backgroundColor = UIColor.randomColor() - - return header - }() - - let nameLabel: UILabel = { - let label = UILabel() - label.textColor = .ne_darkText - label.font = DefaultTextFont(16) - label.translatesAutoresizingMaskIntoConstraints = false - return label - }() - - override func awakeFromNib() { - super.awakeFromNib() - // Initialization code - } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - - // Configure the view for the selected state - setupUI() - } - - func setupUI() { - contentView.addSubview(headerView) - NSLayoutConstraint.activate([ - headerView.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 36), - headerView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), - headerView.widthAnchor.constraint(equalToConstant: 60), - headerView.heightAnchor.constraint(equalToConstant: 60), - ]) - - contentView.addSubview(nameLabel) - NSLayoutConstraint.activate([ - nameLabel.leftAnchor.constraint(equalTo: headerView.rightAnchor, constant: 16), - nameLabel.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -36), - nameLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), - ]) - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatIdGroupCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatIdGroupCell.swift deleted file mode 100644 index e0415913..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatIdGroupCell.swift +++ /dev/null @@ -1,138 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class QChatIdGroupCell: QChatBaseCell { - lazy var headImage: UIImageView = { - let image = UIImageView() - image.translatesAutoresizingMaskIntoConstraints = false - image.image = UIImage.ne_imageNamed(name: "id_group_header") - return image - }() - - lazy var titleLabel: UILabel = { - let label = UILabel() - label.translatesAutoresizingMaskIntoConstraints = false - label.textColor = UIColor.ne_darkText - label.font = DefaultTextFont(14) - label.textAlignment = .left - return label - }() - - lazy var subTitleLabel: UILabel = { - let label = UILabel() - label.translatesAutoresizingMaskIntoConstraints = false - label.textColor = UIColor.ne_greyText - label.font = DefaultTextFont(12) - label.textAlignment = .left - return label - }() - - lazy var countHeadImage: UIImageView = { - let image = UIImageView() - image.translatesAutoresizingMaskIntoConstraints = false - image.image = UIImage.ne_imageNamed(name: "count_header") - return image - }() - - lazy var tailImage: UIImageView = { - let image = UIImageView() - image.translatesAutoresizingMaskIntoConstraints = false - image.highlightedImage = UIImage.ne_imageNamed(name: "lock") - image.image = UIImage.ne_imageNamed(name: "arrowRight") - return image - }() - - lazy var dividerLine: UIView = { - let line = UIView() - line.backgroundColor = .ne_greyLine - line.translatesAutoresizingMaskIntoConstraints = false - return line - }() - - var leftSpace: NSLayoutConstraint? - - var titleLeftSpace: NSLayoutConstraint? - - var countHeadWidth: NSLayoutConstraint? - - var headWidth: NSLayoutConstraint? - - var headHeight: NSLayoutConstraint? - - override func awakeFromNib() { - super.awakeFromNib() - // Initialization code - } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - - // Configure the view for the selected state - setupUI() - } - - func setupUI() { - contentView.addSubview(headImage) - leftSpace = headImage.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 24) - leftSpace?.isActive = true - - headWidth = headImage.widthAnchor.constraint(equalToConstant: 29) - headWidth?.isActive = true - headHeight = headImage.heightAnchor.constraint(equalToConstant: 33) - headHeight?.isActive = true - - NSLayoutConstraint.activate([ - headImage.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), - ]) - - contentView.addSubview(tailImage) - NSLayoutConstraint.activate([ - tailImage.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), - tailImage.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -20), - ]) - - contentView.addSubview(titleLabel) - titleLeftSpace = titleLabel.leftAnchor.constraint( - equalTo: headImage.rightAnchor, - constant: 15.5 - ) - titleLeftSpace?.isActive = true - NSLayoutConstraint.activate([ - titleLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 13.0), - titleLabel.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -36.0), - ]) - - contentView.addSubview(countHeadImage) - countHeadWidth = countHeadImage.widthAnchor.constraint(equalToConstant: 10) - countHeadWidth?.isActive = true - NSLayoutConstraint.activate([ - countHeadImage.leftAnchor.constraint(equalTo: titleLabel.leftAnchor), - countHeadImage.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 6), - countHeadImage.heightAnchor.constraint(equalToConstant: 10), - ]) - - contentView.addSubview(subTitleLabel) - NSLayoutConstraint.activate([ - subTitleLabel.leftAnchor.constraint(equalTo: countHeadImage.rightAnchor, constant: 6), - subTitleLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 4), - subTitleLabel.rightAnchor.constraint(equalTo: titleLabel.rightAnchor), - ]) - - contentView.addSubview(dividerLine) - NSLayoutConstraint.activate([ - dividerLine.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 20), - dividerLine.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -20), - dividerLine.bottomAnchor.constraint(equalTo: contentView.bottomAnchor), - dividerLine.heightAnchor.constraint(equalToConstant: 1), - ]) - } - - func configure(_ model: IdGroupModel) { - titleLabel.text = model.idName - subTitleLabel.text = model.subTitle - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatIdGroupMemberCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatIdGroupMemberCell.swift deleted file mode 100644 index dce6e98d..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatIdGroupMemberCell.swift +++ /dev/null @@ -1,98 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class QChatIdGroupMemberCell: QChatCornerCell { - lazy var headView: NEUserHeaderView = { - let view = NEUserHeaderView(frame: .zero) - view.titleLabel.textColor = .white - view.titleLabel.font = DefaultTextFont(11) - view.translatesAutoresizingMaskIntoConstraints = false - view.clipsToBounds = true - view.layer.cornerRadius = 16.0 - return view - }() - - lazy var tailorImage: UIImageView = { - let image = UIImageView() - image.image = UIImage.ne_imageNamed(name: "delete") - image.translatesAutoresizingMaskIntoConstraints = false - return image - }() - - lazy var nameLabel: UILabel = { - let label = UILabel() - label.translatesAutoresizingMaskIntoConstraints = false - label.textColor = .ne_darkText - label.font = DefaultTextFont(14) - return label - }() - - var user: UserInfo? { - didSet { - if let name = user?.nickName { - headView.setTitle(name) - } - headView.backgroundColor = user?.color - nameLabel.text = user?.nickName - } - } - - var leftSpace: NSLayoutConstraint? - - var rightSpace: NSLayoutConstraint? - - override func awakeFromNib() { - super.awakeFromNib() - // Initialization code - } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - - // Configure the view for the selected state - } - - override public init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - setupUI() - } - - required init?(coder: NSCoder) { - super.init(coder: coder) - } - - func setupUI() { - contentView.addSubview(headView) - - leftSpace = headView.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 36) - leftSpace?.isActive = true - NSLayoutConstraint.activate([ - headView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), - headView.widthAnchor.constraint(equalToConstant: 32), - headView.heightAnchor.constraint(equalToConstant: 32), - ]) - - contentView.addSubview(tailorImage) - rightSpace = tailorImage.rightAnchor.constraint( - equalTo: contentView.rightAnchor, - constant: -36 - ) - rightSpace?.isActive = true - NSLayoutConstraint.activate([ - tailorImage.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), - tailorImage.widthAnchor.constraint(equalToConstant: 16.0), - tailorImage.heightAnchor.constraint(equalToConstant: 16.0), - ]) - - contentView.addSubview(nameLabel) - NSLayoutConstraint.activate([ - nameLabel.leftAnchor.constraint(equalTo: headView.rightAnchor, constant: 12), - nameLabel.rightAnchor.constraint(equalTo: tailorImage.leftAnchor, constant: -10), - nameLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), - ]) - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatIdGroupSelectCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatIdGroupSelectCell.swift deleted file mode 100644 index 86514861..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatIdGroupSelectCell.swift +++ /dev/null @@ -1,67 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class QChatIdGroupSelectCell: QChatCornerCell { - var group: IdGroupModel? { - didSet { - if let select = group?.isSelect { - tailImage.isHighlighted = select - } - nameLabel.text = group?.idName - if let type = group?.cornerType { - cornerType = type - } - } - } - - let tailImage: UIImageView = { - let image = UIImageView() - image.image = UIImage.ne_imageNamed(name: "unselect") - image.highlightedImage = UIImage.ne_imageNamed(name: "select") - image.translatesAutoresizingMaskIntoConstraints = false - image.isHidden = true - return image - }() - - let nameLabel: UILabel = { - let label = UILabel() - label.textColor = .ne_darkText - label.font = DefaultTextFont(14) - label.translatesAutoresizingMaskIntoConstraints = false - return label - }() - - override func awakeFromNib() { - super.awakeFromNib() - // Initialization code - } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - - // Configure the view for the selected state - setupUI() - } - - func setupUI() { - contentView.addSubview(tailImage) - NSLayoutConstraint.activate([ - tailImage.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -36), - tailImage.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), - ]) - - contentView.addSubview(nameLabel) - NSLayoutConstraint.activate([ - nameLabel.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 36), - nameLabel.rightAnchor.constraint( - equalTo: contentView.rightAnchor, - constant: -(36 + 23) - ), - nameLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), - ]) - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatIdGroupSortButtonCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatIdGroupSortButtonCell.swift deleted file mode 100644 index 7629ddc4..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatIdGroupSortButtonCell.swift +++ /dev/null @@ -1,78 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class QChatIdGroupSortButtonCell: QChatBaseCell { - lazy var titleLabel: UILabel = { - let label = UILabel() - label.translatesAutoresizingMaskIntoConstraints = false - label.textColor = .ne_greyText - label.font = DefaultTextFont(12) - return label - }() - - lazy var sortImage: UIImageView = { - let image = UIImageView() - image.translatesAutoresizingMaskIntoConstraints = false - image.image = UIImage.ne_imageNamed(name: "id_group_sort") - return image - }() - - lazy var sortBtn: ExpandButton = { - let btn = ExpandButton() - btn.translatesAutoresizingMaskIntoConstraints = false - return btn - }() - - lazy var sortLabel: UILabel = { - let label = UILabel() - label.translatesAutoresizingMaskIntoConstraints = false - label.font = DefaultTextFont(12) - label.textColor = .ne_blueText - label.text = localizable("qchat_sort") - return label - }() - - override func awakeFromNib() { - super.awakeFromNib() - // Initialization code - } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - - // Configure the view for the selected state - setupUI() - } - - func setupUI() { - contentView.addSubview(titleLabel) - NSLayoutConstraint.activate([ - titleLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor), - titleLabel.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 20), - ]) - - contentView.addSubview(sortLabel) - NSLayoutConstraint.activate([ - sortLabel.centerYAnchor.constraint(equalTo: titleLabel.centerYAnchor), - sortLabel.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -20), - ]) - - contentView.addSubview(sortImage) - NSLayoutConstraint.activate([ - sortImage.centerYAnchor.constraint(equalTo: sortLabel.centerYAnchor), - sortImage.rightAnchor.constraint(equalTo: sortLabel.leftAnchor, constant: -6), - ]) - - contentView.addSubview(sortBtn) - NSLayoutConstraint.activate([ - sortBtn.rightAnchor.constraint(equalTo: contentView.rightAnchor), - sortBtn.bottomAnchor.constraint(equalTo: contentView.bottomAnchor), - sortBtn.topAnchor.constraint(equalTo: contentView.topAnchor), - sortBtn.leftAnchor.constraint(equalTo: sortImage.leftAnchor, constant: -10), - ]) - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatIdGroupTopCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatIdGroupTopCell.swift deleted file mode 100644 index 3e0c3bb2..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatIdGroupTopCell.swift +++ /dev/null @@ -1,30 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class QChatIdGroupTopCell: QChatIdGroupCell { - override func awakeFromNib() { - super.awakeFromNib() - // Initialization code - } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - - // Configure the view for the selected state - } - - override func setupUI() { - super.setupUI() - leftSpace?.constant = 20.0 - headImage.image = UIImage.ne_imageNamed(name: "member_header") - titleLeftSpace?.constant = 12.0 - countHeadWidth?.constant = 0 - countHeadImage.isHidden = true - headWidth?.constant = 36.0 - headHeight?.constant = 36.0 - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatMemberManagerCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatMemberManagerCell.swift deleted file mode 100644 index ec712139..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatMemberManagerCell.swift +++ /dev/null @@ -1,26 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class QChatMemberManagerCell: QChatIdGroupMemberCell { - override func awakeFromNib() { - super.awakeFromNib() - // Initialization code - } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - - // Configure the view for the selected state - } - - override func setupUI() { - super.setupUI() - contentView.backgroundColor = .white - leftSpace?.constant = 20 - rightSpace?.constant = -20 - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatPlainTextArrowCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatPlainTextArrowCell.swift deleted file mode 100644 index c5cd2e17..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatPlainTextArrowCell.swift +++ /dev/null @@ -1,27 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class QChatPlainTextArrowCell: QChatTextArrowCell { - override func awakeFromNib() { - super.awakeFromNib() - // Initialization code - } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - - // Configure the view for the selected state - setupUI() - } - - func setupUI() { - contentView.backgroundColor = .white - titleLeftMargin?.constant = 20 - detailRightMargin?.constant = -42 - rightImageMargin?.constant = -20 - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatSelectedCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatSelectedCell.swift deleted file mode 100644 index 434af2e1..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatSelectedCell.swift +++ /dev/null @@ -1,92 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class QChatSelectedCell: QChatBaseCell { - var user: UserInfo? { - didSet { - if let name = user?.nickName { - headerView.setTitle(name) - } - titleLabel.text = user?.nickName - headerView.backgroundColor = user?.color - if let value = user?.select { - checkBox.isHighlighted = value - } - } - } - - public lazy var titleLabel: UILabel = { - let label = UILabel() - label.textAlignment = .left - label.translatesAutoresizingMaskIntoConstraints = false - label.font = UIFont.systemFont(ofSize: 14.0) - label.textColor = .ne_darkText - return label - }() - - let headerView: NEUserHeaderView = { - let header = NEUserHeaderView(frame: .zero) - header.titleLabel.font = DefaultTextFont(14) - header.titleLabel.textColor = UIColor.white - header.layer.cornerRadius = 18 - header.translatesAutoresizingMaskIntoConstraints = false - return header - }() - - let checkBox: UIImageView = { - let image = UIImageView() - image.translatesAutoresizingMaskIntoConstraints = false - image.image = UIImage.ne_imageNamed(name: "unselect") - image.highlightedImage = UIImage.ne_imageNamed(name: "select") - return image - }() - - override func awakeFromNib() { - super.awakeFromNib() - // Initialization code - } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - - // Configure the view for the selected state - setupUI() - } - - func setupUI() { - contentView.addSubview(checkBox) - NSLayoutConstraint.activate([ - checkBox.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 20), - checkBox.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), - ]) - - contentView.addSubview(headerView) - NSLayoutConstraint.activate([ - headerView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), - headerView.leftAnchor.constraint(equalTo: checkBox.rightAnchor, constant: 12), - headerView.widthAnchor.constraint(equalToConstant: 36), - headerView.heightAnchor.constraint(equalToConstant: 36), - ]) - - contentView.addSubview(titleLabel) - NSLayoutConstraint.activate([ - titleLabel.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 98), - titleLabel.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -35), - titleLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), - ]) - } - - func setSelect() { - user?.select = true - checkBox.isHighlighted = true - } - - func setUnselect() { - user?.select = false - checkBox.isHighlighted = false - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatSortCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatSortCell.swift deleted file mode 100644 index 5b7d7fd5..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatSortCell.swift +++ /dev/null @@ -1,39 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class QChatSortCell: QChatIdGroupCell { - lazy var dotImage: UIImageView = { - let image = UIImageView() - image.translatesAutoresizingMaskIntoConstraints = false - image.image = UIImage.ne_imageNamed(name: "dot_image") - image.highlightedImage = UIImage.ne_imageNamed(name: "dot_image_disable") - return image - }() - - override func awakeFromNib() { - super.awakeFromNib() - // Initialization code - } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - - // Configure the view for the selected state - } - - override func setupUI() { - super.setupUI() -// self.leftSpace?.constant = 72 - tailImage.image = UIImage.ne_imageNamed(name: "delete") - tailImage.highlightedImage = UIImage.ne_imageNamed(name: "lock") -// contentView.addSubview(dotImage) -// NSLayoutConstraint.activate([ -// dotImage.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 31), -// dotImage.centerYAnchor.constraint(equalTo: contentView.centerYAnchor) -// ]) - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatSwitchCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatSwitchCell.swift deleted file mode 100644 index c639e2dc..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatSwitchCell.swift +++ /dev/null @@ -1,88 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -protocol QChatSwitchCellDelegate: AnyObject { - func didChangeSwitchValue(_ cell: QChatSwitchCell) -} - -class QChatSwitchCell: QChatCornerCell { - weak var delegate: QChatSwitchCellDelegate? - - var qSwitch: UISwitch = { - let q = UISwitch() - q.translatesAutoresizingMaskIntoConstraints = false - q.onTintColor = .ne_blueText - return q - }() - - var permissionLabel: UILabel = { - let label = UILabel() - label.translatesAutoresizingMaskIntoConstraints = false - label.textColor = .ne_darkText - label.font = DefaultTextFont(16) - return label - }() - - var model: PermissionCellModel? { - didSet { - permissionLabel.text = model?.showName - - if let type = model?.cornerType { - cornerType = type - } - if let value = model?.hasPermission { - qSwitch.isOn = value - } - } - } - - override func awakeFromNib() { - super.awakeFromNib() - // Initialization code - } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - - // Configure the view for the selected state - setupUI() - } - - func setupUI() { - contentView.addSubview(qSwitch) - NSLayoutConstraint.activate([ - qSwitch.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), - qSwitch.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -36), - ]) - qSwitch.addTarget(self, action: #selector(valueChange(_:)), for: .valueChanged) - - contentView.addSubview(permissionLabel) - NSLayoutConstraint.activate([ - permissionLabel.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 36), - permissionLabel.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -95), - permissionLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), - ]) - } - - @objc func valueChange(_ s: UISwitch) { - model?.hasPermission = s.isOn - delegate?.didChangeSwitchValue(self) - /* - if s.isOn == true { - if let key = model?.permissionKey { - print("add key : ", key) - model?.permission?.changeMap[key] = true - } - }else { - if let key = model?.permissionKey { - print("rm key : ", key) - model?.permission?.changeMap[key] = false - } - }*/ - print("change maps : ", model?.permission?.changeMap as Any) - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatUserUnCheckCell.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatUserUnCheckCell.swift deleted file mode 100644 index 223f91c0..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/View/QChatUserUnCheckCell.swift +++ /dev/null @@ -1,57 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit - -class QChatUserUnCheckCell: QChatBaseCollectionViewCell { - public var avatarImage = UIView() - public var nameTailLabel = UILabel() - - override init(frame: CGRect) { - super.init(frame: frame) - setupUI() - } - - required init?(coder: NSCoder) { - super.init(coder: coder) - } - - func setupUI() { - contentView.addSubview(avatarImage) - avatarImage.translatesAutoresizingMaskIntoConstraints = false - NSLayoutConstraint.activate([ - avatarImage.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), - avatarImage.centerXAnchor.constraint(equalTo: contentView.centerXAnchor), - avatarImage.widthAnchor.constraint(equalToConstant: 36), - avatarImage.heightAnchor.constraint(equalToConstant: 36), - ]) - avatarImage.layer.cornerRadius = 18.0 - avatarImage.clipsToBounds = true - - avatarImage.addSubview(nameTailLabel) - nameTailLabel.translatesAutoresizingMaskIntoConstraints = false - NSLayoutConstraint.activate([ - nameTailLabel.centerXAnchor.constraint(equalTo: avatarImage.centerXAnchor), - nameTailLabel.centerYAnchor.constraint(equalTo: avatarImage.centerYAnchor), - nameTailLabel.leftAnchor.constraint(equalTo: avatarImage.leftAnchor, constant: 1), - nameTailLabel.rightAnchor.constraint(equalTo: avatarImage.rightAnchor, constant: -1), - ]) - nameTailLabel.font = UIFont.systemFont(ofSize: 16.0) - nameTailLabel.textAlignment = .center - nameTailLabel.textColor = .white - - contentView.backgroundColor = .clear - } - - func configure(_ model: UserInfo) { - avatarImage.backgroundColor = model.color - // title - guard let name = model.nickName else { - return - } - nameTailLabel.text = name - .count > 2 ? String(name[name.index(name.endIndex, offsetBy: -2)...]) : name - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatCreateGroupViewController.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatCreateGroupViewController.swift deleted file mode 100644 index 3718b993..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatCreateGroupViewController.swift +++ /dev/null @@ -1,273 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NECoreIMKit - -typealias CreateCompletion = () -> Void - -public class QChatCreateGroupViewController: NEBaseTableViewController, - QChatMemberSelectControllerDelegate, UITableViewDataSource, UITableViewDelegate, - ViewModelDelegate, - QChatTextEditCellDelegate { - let viewModel = CreateGroupViewModel() - - var serverId: UInt64? - - var serverName = "" - - var completion: CreateCompletion? - - override public func viewDidLoad() { - super.viewDidLoad() - - // Do any additional setup after loading the view. - viewModel.delegate = self - setupUI() - } - - func setupUI() { - addRightAction(localizable("create"), #selector(createClick), self) - title = localizable("qchat_create_new_id_group") - setupTable() - tableView.delegate = self - tableView.backgroundColor = .ne_backcolor - - tableView.dataSource = self - tableView.register( - QChatTextArrowCell.self, - forCellReuseIdentifier: "\(QChatTextArrowCell.self)" - ) - tableView.register( - QChatTextEditCell.self, - forCellReuseIdentifier: "\(QChatTextEditCell.self)" - ) - tableView.register(QChatUnfoldCell.self, forCellReuseIdentifier: "\(QChatUnfoldCell.self)") - tableView.register( - QChatIdGroupMemberCell.self, - forCellReuseIdentifier: "\(QChatIdGroupMemberCell.self)" - ) - } - - // MAKR: objc 方法 - @objc func createClick() { - if serverName.count <= 0 { - view.makeToast(localizable("qchat_please_input_role_name")) - return - } - var param = ServerRoleParam() - param.serverId = serverId - param.type = .custom - param.name = serverName - weak var weakSelf = self - print("create role param : ", param) - - viewModel.repo.createRole(param) { error, role in - print("create role : ", error as Any, role) - if let err = error { - weakSelf?.dataDidError(err) - } else { - if let rid = role.roleId, let addMemebers = weakSelf?.viewModel.allUsers, - addMemebers.count > 0 { - weakSelf?.addMember(rid) - } else { - if let block = weakSelf?.completion { - block() - } - weakSelf?.navigationController?.popViewController(animated: true) - } - } - } - } - - func addMember(_ roleId: UInt64) { - weak var weakSelf = self - if viewModel.allUsers.count > 0 { - var accids = [String]() - viewModel.allUsers.forEach { user in - if let accid = user.serverMember?.accid { - accids.append(accid) - } - } - var param = AddServerRoleMemberParam() - param.accountArray = accids - param.serverId = serverId - param.roleId = roleId - viewModel.repo.addRoleMember(param) { error, sAccids, fAccids in - if let err = error { - weakSelf?.showToast(err.localizedDescription) - } - if let block = weakSelf?.completion { - block() - } - weakSelf?.navigationController?.popViewController(animated: true) - } - } - } - - // MARK: - - public func filterMembers(accid: [String]?, _ filterMembers: @escaping ([String]?) -> Void) { - var dic = [String: String]() - viewModel.allUsers.forEach { user in - if let aid = user.accid { - dic[aid] = aid - } - } - var retArray = [String]() - accid?.forEach { aid in - if dic[aid] != nil { - retArray.append(aid) - } - } - filterMembers(retArray) - - // filterMembers(accid) - } - - func textDidChange(_ textField: UITextField) { - if let text = textField.text { - serverName = text - } - print("text change: ", textField.text as Any) - } - - public func dataDidError(_ error: Error) { - UIApplication.shared.keyWindow?.endEditing(true) - view.makeToast(error.localizedDescription) - } - - public func dataDidChange() { - tableView.reloadData() - } - - public func numberOfSections(in tableView: UITableView) -> Int { - let count = 3 - // if viewModel.limitUsers.count < viewModel.allUsers.count { - // count = count + 1 - // } - return count - } - - public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - if section == 0 || section == 1 { - return 1 - } else if section == 2 { - return viewModel.allUsers.count - } else if section == 3 { - return 0 - } - return 0 - } - - public func tableView(_ tableView: UITableView, - cellForRowAt indexPath: IndexPath) -> UITableViewCell { - if indexPath.section == 0 { - let cell: QChatTextEditCell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatTextEditCell.self)", - for: indexPath - ) as! QChatTextEditCell - cell.textFied.placeholder = localizable("qchat_please_input_role_name") - cell.delegate = self - cell.limit = 20 - cell.cornerType = CornerType.bottomLeft.union(CornerType.bottomRight) - .union(CornerType.topLeft).union(CornerType.topRight) - return cell - } else if indexPath.section == 1 { - let cell: QChatTextArrowCell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatTextArrowCell.self)", - for: indexPath - ) as! QChatTextArrowCell - cell.titleLabel.text = localizable("add_member") - cell.cornerType = CornerType.bottomLeft.union(CornerType.bottomRight) - .union(CornerType.topLeft).union(CornerType.topRight) - return cell - } else if indexPath.section == 2 { - let cell: QChatIdGroupMemberCell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatIdGroupMemberCell.self)", - for: indexPath - ) as! QChatIdGroupMemberCell - let user = viewModel.allUsers[indexPath.row] - cell.cornerType = user.cornerType - cell.user = user - return cell - } else if indexPath.section == 3 { - let cell: QChatUnfoldCell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatUnfoldCell.self)", - for: indexPath - ) as! QChatUnfoldCell - cell.contentLabel.text = "更多(共\(viewModel.allUsers.count))人" - cell.cornerType = CornerType.bottomLeft.union(CornerType.bottomRight) - return cell - } - return UITableViewCell() - } - - public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - if indexPath.section == 1 { - let memberSelect = QChatMemberSelectController() - memberSelect.serverId = serverId - memberSelect.delegate = self - // memberSelect.selectType = .ServerMember - weak var weakSelf = self - memberSelect.completion = { datas in - if datas.count > 0 { - weakSelf?.viewModel.addMembers(datas) - } - } - navigationController?.pushViewController(memberSelect, animated: true) - - } else if indexPath.section == 2 { - // 编辑成员临时入口 - - // let user = viewModel.limitUsers[indexPath.row] - // let editMember = QChatEditMemberViewController() - // editMember.user = user - // navigationController?.pushViewController(editMember, animated: true) - - viewModel.removeData(indexPath.row) - } else if indexPath.section == 3 { - viewModel.loadAllData() - tableView.reloadData() - } - } - - public func tableView(_ tableView: UITableView, - heightForRowAt indexPath: IndexPath) -> CGFloat { - 50 - } - - public func tableView(_ tableView: UITableView, - heightForHeaderInSection section: Int) -> CGFloat { - if section == 0 || section == 1 { - return 40.0 - } else if section == 2 { - return 16 - } - return 0 - } - - public func tableView(_ tableView: UITableView, - viewForHeaderInSection section: Int) -> UIView? { - let header = QChatHeaderView() - if section == 0 { - header.titleLabel.text = localizable("qchat_group_name") - return header - } - - if section == 1 { - header.titleLabel.text = localizable("qchat_manager_member") - return header - } - - if section == 2 { - let space = UIView() - space.backgroundColor = .clear - return space - } - - return nil - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatEditMemberViewController.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatEditMemberViewController.swift deleted file mode 100644 index 88b64cec..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatEditMemberViewController.swift +++ /dev/null @@ -1,398 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NECoreKit -import NECoreIMKit - -// typealias EditMemberCompletion = (_ member: ServerMemeber) -> Void - -typealias EditMemberChange = () -> Void - -typealias EditMemberDelete = () -> Void - -public class QChatEditMemberViewController: NEBaseTableViewController, UITableViewDataSource, - UITableViewDelegate, ViewModelDelegate, QChatTextEditCellDelegate { - var user: UserInfo? - var editAble = false - var showAll = false - let viewModel = EditMemberViewModel() - private let tag = "QChatEditMemberViewController" - -// var completion: EditMemberCompletion? - var changeCompletion: EditMemberChange? - var deleteCompletion: EditMemberDelete? - var nickName = "" - - var didChange = false - - override public func viewDidLoad() { - super.viewDidLoad() - - // Do any additional setup after loading the view. - if let nick = user?.nickName { - nickName = nick - } -// else if let acid = user?.accid { -// nickName = acid -// } - viewModel.delegate = self - viewModel.getData(user?.serverId, user?.accid) - setupUI() - } - - func setupUI() { - setupTable() - if let name = user?.nickName { - title = name - } - addRightAction(localizable("qchat_edit"), #selector(rightBtnClick(_:)), self) - tableView.register( - QChatTextEditCell.self, - forCellReuseIdentifier: "\(QChatTextEditCell.self)" - ) - tableView.register(QChatHeaderCell.self, forCellReuseIdentifier: "\(QChatHeaderCell.self)") - tableView.register( - QChatDestructiveCell.self, - forCellReuseIdentifier: "\(QChatDestructiveCell.self)" - ) - tableView.register( - QChatIdGroupSelectCell.self, - forCellReuseIdentifier: "\(QChatIdGroupSelectCell.self)" - ) - tableView.register(QChatUnfoldCell.self, forCellReuseIdentifier: "\(QChatUnfoldCell.self)") - tableView.dataSource = self - tableView.delegate = self - tableView.backgroundColor = .ne_backcolor - -// let image = UIImage.ne_imageNamed(name: "backArrow")?.withRenderingMode(.alwaysOriginal) -// self.navigationItem.leftBarButtonItem = UIBarButtonItem(image: image, style: .plain, target: self, action: #selector(back)) - addLeftAction(UIImage.ne_imageNamed(name: "backArrow"), #selector(back), self) - } - - @objc func back() { - didChangeRole() - navigationController?.popViewController(animated: true) - } - - /* - // MARK: - Navigation - - // In a storyboard-based application, you will often want to do a little preparation before navigation - override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - // Get the new view controller using segue.destination. - // Pass the selected object to the new view controller. - } - */ - - // MARK: objc 方法 - - @objc func rightBtnClick(_ btn: ExpandButton) { - if btn.isSelected == true { - print("to save") - if nickName.count <= 0 { - showToast(localizable("nickName_not_empty")) - return - } - - guard let accid = user?.accid else { - showToast(localizable("accid_not_empty")) - return - } - - weak var weakSelf = self - - if IMKitEngine.instance.isMySelf(accid) == true { - viewModel.updateMyMember(user?.serverMember?.serverId, nickName) { error, member in - NELog.infoLog( - ModuleName + " " + self.tag, - desc: "CALLBACK updateMyMember " + (error?.localizedDescription ?? "no error") - ) - if let err = error { - weakSelf?.showToast(err.localizedDescription) - } else { - weakSelf?.navigationController?.popViewController(animated: true) - if let block = weakSelf?.changeCompletion { - block() - } - } - } - } else { - viewModel - .updateMember(user?.serverMember?.serverId, nickName, - user?.accid) { error, member in - NELog.infoLog( - ModuleName + " " + self.tag, - desc: "CALLBACK updateMember " + (error?.localizedDescription ?? "no error") - ) - if let err = error { - weakSelf?.showToast(err.localizedDescription) - } else { - weakSelf?.navigationController?.popViewController(animated: true) - if let block = weakSelf?.changeCompletion { - block() - } - } - } - } - - } else { - btn.isSelected = true - editAble = true - btn.setTitle(localizable("qchat_save"), for: .normal) - viewModel.showServerData() - } - } - - // MARK: UITableViewDataSource, UITableViewDelegate,ViewModelDelegate, QChatTextEditCellDelegate - - func textDidChange(_ textField: UITextField) { - print("edit mebmer name change : ", textField.text as Any) - if let text = textField.text { - nickName = text - } - } - - public func dataDidChange() { - tableView.reloadData() - } - - public func dataDidError(_ error: Error) { - showToast(error.localizedDescription) - } - - public func numberOfSections(in tableView: UITableView) -> Int { - 5 - } - - public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - if section == 0 || section == 1 { - return 1 - } else if section == 2 { - return showAll ? viewModel.allIdGroups.count : viewModel.limitIdGroups.count - } else if section == 3 { - if viewModel.limitIdGroups.count < viewModel.allIdGroups.count { - return 1 - } - } else if section == 4 { - return 1 - } - return 0 - } - - public func tableView(_ tableView: UITableView, - cellForRowAt indexPath: IndexPath) -> UITableViewCell { - if indexPath.section == 0 { - let cell: QChatHeaderCell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatHeaderCell.self)", - for: indexPath - ) as! QChatHeaderCell - cell.cornerType = CornerType.topLeft.union(CornerType.topRight) - .union(CornerType.bottomLeft).union(CornerType.bottomRight) - cell.user = user - return cell - } else if indexPath.section == 1 { - let cell: QChatTextEditCell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatTextEditCell.self)", - for: indexPath - ) as! QChatTextEditCell - cell.cornerType = CornerType.topLeft.union(CornerType.topRight) - .union(CornerType.bottomLeft).union(CornerType.bottomRight) - cell.delegate = self - cell.editTotast = localizable("modify_nickname") - cell.canEdit = editAble - if nickName.count > 0 { - cell.textFied.text = nickName - } else { - cell.textFied.text = nil - } - cell.textFied.placeholder = localizable("qcaht_edit_nickname") - return cell - } else if indexPath.section == 2 { - let cell: QChatIdGroupSelectCell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatIdGroupSelectCell.self)", - for: indexPath - ) as! QChatIdGroupSelectCell - let group = showAll ? viewModel.allIdGroups[indexPath.row] : viewModel - .limitIdGroups[indexPath.row] - cell.tailImage.isHidden = !editAble - if let type = group.role?.type, type == .everyone { - cell.tailImage.isHidden = true - } - let exist = viewModel.checkoutCurrentUserRole(group.role?.roleId) - print("checkoutCurrentUserRole name : \(group.idName ?? "") exist : \(exist)") - group.isSelect = exist - cell.group = group - return cell - } else if indexPath.section == 3 { - let cell: QChatUnfoldCell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatUnfoldCell.self)", - for: indexPath - ) as! QChatUnfoldCell - cell.contentLabel - .text = showAll ? "收起(共\(viewModel.allIdGroups.count)个)" : - "更多(共\(viewModel.allIdGroups.count)个)" - if showAll { - cell.changeToArrowUp() - } else { - cell.changeToArrowDown() - } - cell.cornerType = CornerType.bottomLeft.union(CornerType.bottomRight) - return cell - } else if indexPath.section == 4 { - let cell: QChatDestructiveCell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatDestructiveCell.self)", - for: indexPath - ) as! QChatDestructiveCell - if indexPath.row == 0 { - cell.cornerType = CornerType.topLeft.union(CornerType.topRight) - .union(CornerType.bottomLeft).union(CornerType.bottomRight) - cell.redTextLabel.text = "\(localizable("qchat_kick_out")) \(user?.nickName ?? "")" - if getKickDisable() { - cell.changeDisableTextColor() - } - } else if indexPath.row == 1 { - cell.cornerType = CornerType.bottomLeft.union(CornerType.bottomRight) - cell.redTextLabel.text = "\(localizable("qchat_prohibit")) \(user?.nickName ?? "")" - cell.changeEnableTextColor() - } - return cell - } - - return UITableViewCell() - } - - public func tableView(_ tableView: UITableView, - heightForRowAt indexPath: IndexPath) -> CGFloat { - if indexPath.section == 0 { - return 92 - } - return 50 - } - - public func tableView(_ tableView: UITableView, - viewForHeaderInSection section: Int) -> UIView? { - let header = QChatHeaderView() - if section == 1 { - header.titleLabel.text = localizable("qchat_nickname") - return header - } - - if section == 2, viewModel.allIdGroups.count > 0 { - header.titleLabel.text = localizable("qchat_id_group") - return header - } - return nil - } - - public func tableView(_ tableView: UITableView, - heightForHeaderInSection section: Int) -> CGFloat { - if section == 0 { - return 22 - } - - if section == 1 { - return 38 - } - - if section == 2, viewModel.allIdGroups.count > 0 { - return 38 - } - - if section == 4 { - return 20 - } - return 0 - } - - public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - if indexPath.section == 1 { - // showToast("请点击编辑后修改昵称") - } else if indexPath.section == 2 { - if editAble == false { - return - } - - let group = showAll == true ? viewModel.allIdGroups[indexPath.row] : viewModel - .limitIdGroups[indexPath.row] - - if let type = group.role?.type, type == .everyone { - return - } - let select = viewModel.checkoutCurrentUserRole(group.role?.roleId) - weak var weakSelf = self - if select == false { - view.makeToastActivity(.center) - viewModel.addMembers(user?.accid, user?.serverId, group.role?.roleId) { - NELog.infoLog(ModuleName + " " + self.className(), desc: #function + ", accid:\(self.user?.accid ?? "nil")") - weakSelf?.view.hideToastActivity() - weakSelf?.didChange = true - } - } else { - view.makeToastActivity(.center) - viewModel.remove(user?.accid, user?.serverId, group.role?.roleId) { - NELog.infoLog(ModuleName + " " + self.className(), desc: #function + ", accid:\(self.user?.accid ?? "nil")") - weakSelf?.view.hideToastActivity() - weakSelf?.didChange = true - } - } - } else if indexPath.section == 3 { - showAll = !showAll - tableView.reloadData() - } else if indexPath.section == 4 { - weak var weakSelf = self - if getKickDisable() == true { - return - } - showAlert(message: localizable("kick_currentMember")) { - weakSelf?.kickOutMember() - } - } - } - - func didChangeRole() { - if didChange == true { - if let block = changeCompletion { - block() - } - } - } - - func getKickDisable() -> Bool { - if let accid = user?.serverMember?.accid { - // if CoreKitEngine.instance.imAccid == accid { - // return true - // } - - if IMKitEngine.instance.imAccid == accid { - return true - } - if let type = user?.serverMember?.type, type == .owner { - return true - } - } - return false - } - - func kickOutMember() { - view.makeToastActivity(.center) - weak var weakSelf = self - viewModel.kickoutMember(user?.serverId, user?.accid) { error in - NELog.infoLog( - ModuleName + " " + self.tag, - desc: "CALLBACK kickoutMember " + (error?.localizedDescription ?? "no error") - ) - weakSelf?.view.hideToastActivity() - if let err = error { - weakSelf?.showToast(err.localizedDescription) - } else { - if let block = weakSelf?.deleteCompletion { - block() - } - weakSelf?.navigationController?.popViewController(animated: true) - } - } - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatIdGroupSortController.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatIdGroupSortController.swift deleted file mode 100644 index a982fbb2..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatIdGroupSortController.swift +++ /dev/null @@ -1,210 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NECoreIMKit - -// typealias SortCompletion = (_ array: NSMutableArray) -> Void - -typealias SortChange = () -> Void - -public class QChatIdGroupSortController: NEBaseTableViewController, UITableViewDelegate, - UITableViewDataSource, ViewModelDelegate { - var serverId: UInt64? - - var isOwer = false - - let viewmodel = IdGroupSortViewModel() - -// let dataArray = NSMutableArray() - - var didDelete = false - - var completion: SortChange? - - override public func viewDidLoad() { - super.viewDidLoad() - - // Do any additional setup after loading the view. - let image = UIImage.ne_imageNamed(name: "backArrow")?.withRenderingMode(.alwaysOriginal) - navigationItem.leftBarButtonItem = UIBarButtonItem( - image: image, - style: .plain, - target: self, - action: #selector(back) - ) - viewmodel.isOwner = isOwer - viewmodel.delegate = self - viewmodel.getData(serverId) - setupUI() - } - - func setupUI() { - setupTable() - title = localizable("qchat_id_group_sort") - addRightAction(localizable("qchat_save"), #selector(saveSort), self) - tableView.backgroundColor = .white - tableView.delegate = self - tableView.dataSource = self - tableView.register(QChatSortCell.self, forCellReuseIdentifier: "\(QChatSortCell.self)") - tableView.isEditing = true - tableView.allowsSelectionDuringEditing = true - } - - @objc func saveSort() { - view.makeToastActivity(.center) - weak var weakSelf = self - viewmodel.saveSort(serverId) { - NELog.infoLog(ModuleName + " " + self.className(), desc: #function + ", serverId:\(self.serverId ?? 0)") - weakSelf?.view.hideToastActivity() - if let block = weakSelf?.completion { - block() - } - print("save success") - weakSelf?.navigationController?.popViewController(animated: true) - } - } - - @objc func back() { - if didDelete == true, let block = completion { - block() - } - navigationController?.popViewController(animated: true) - } - - // MARK: UITableViewDelegate, UITableViewDataSource, ViewModelDelegate - - public func dataDidChange() { - tableView.reloadData() - } - - public func dataDidError(_ error: Error) { - view.hideToastActivity() - showToast(error.localizedDescription) - } - - public func numberOfSections(in tableView: UITableView) -> Int { - 1 - } - - public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - // if section == 0 { - // return viewmodel.lockData.count - // }else if section == 1 { - // return viewmodel.datas.count - // } - viewmodel.datas.count - } - - public func tableView(_ tableView: UITableView, - cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell: QChatSortCell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatSortCell.self)", - for: indexPath - ) as! QChatSortCell - // if indexPath.section == 0 { - // let model = viewmodel.lockData[indexPath.row] - // cell.configure(model) - // cell.tailImage.isHighlighted = true - // }else if indexPath.section == 1 { - // if let model = viewmodel.datas[indexPath.row] as? IdGroupModel { - // cell.configure(model) - // cell.tailImage.isHighlighted = !model.hasPermission - // } - // } - if let model = viewmodel.datas[indexPath.row] as? IdGroupModel { - cell.configure(model) - cell.tailImage.isHighlighted = !model.hasPermission - } - - return cell - } - - public func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, - to destinationIndexPath: IndexPath) { - print("source :", sourceIndexPath.row, " destionation :", destinationIndexPath.row) - - if sourceIndexPath.row > destinationIndexPath.row { - let src_model = viewmodel.datas.object(at: sourceIndexPath.row) - viewmodel.datas.remove(src_model) - viewmodel.datas.insert(src_model, at: destinationIndexPath.row) - } else { - let src_model = viewmodel.datas.object(at: sourceIndexPath.row) - viewmodel.datas.insert(src_model, at: destinationIndexPath.row + 1) - viewmodel.datas.removeObject(at: sourceIndexPath.row) - } - - viewmodel.datas.forEach { user in - if let u = user as? IdGroupModel { - print("change name : ", u.idName as Any) - print("change p: ", u.role?.priority as Any) - } - } - } - - public func tableView(_ tableView: UITableView, - heightForRowAt indexPath: IndexPath) -> CGFloat { - 60 - } - - public func tableView(_ tableView: UITableView, - shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool { - false - } - - public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - if let model = viewmodel.datas[indexPath.row] as? IdGroupModel { - weak var weakSelf = self - if model.hasPermission == true { - showAlert( - message: "\(localizable("sure_delete"))\(model.idName ?? localizable("current_identity"))?" - ) { - weakSelf?.view.makeToastActivity(.center) - weakSelf?.viewmodel.removeRole(weakSelf?.serverId, model.role?.roleId, model) { - NELog.infoLog(ModuleName + " " + self.className(), desc: #function + ", serverId:\(weakSelf?.serverId ?? 0)") - weakSelf?.didDelete = true - weakSelf?.view.hideToastActivity() - } - } - } - } - } - - public func tableView(_ tableView: UITableView, - targetIndexPathForMoveFromRowAt sourceIndexPath: IndexPath, - toProposedIndexPath proposedDestinationIndexPath: IndexPath) - -> IndexPath { - if isOwer == true { - return proposedDestinationIndexPath - } else { - if let model = viewmodel.datas[proposedDestinationIndexPath.row] as? IdGroupModel { - if model.hasPermission == true { - return proposedDestinationIndexPath - } - } - } - return sourceIndexPath - } - - public func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { - if let model = viewmodel.datas[indexPath.row] as? IdGroupModel { - return model.hasPermission - } - return true - } - - public func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool { - if let model = viewmodel.datas[indexPath.row] as? IdGroupModel { - return model.hasPermission - } - return true - } - - public func tableView(_ tableView: UITableView, - editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell - .EditingStyle { - UITableViewCell.EditingStyle.none - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatIdGroupViewController.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatIdGroupViewController.swift deleted file mode 100644 index 9ff02440..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatIdGroupViewController.swift +++ /dev/null @@ -1,246 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import MJRefresh - -public class QChatIdGroupViewController: NEBaseTableViewController, UITableViewDelegate, - UITableViewDataSource, ViewModelDelegate { - let viewModel = IdGroupViewModel() - var isOwner = false - var serverid: UInt64? - - override public func viewDidLoad() { - super.viewDidLoad() - - // Do any additional setup after loading the view. - viewModel.delegate = self - loadMoreData() - setupUI() - } - - func setupUI() { - NELog.infoLog(ModuleName + " " + className(), desc: "serverid : \(serverid ?? 0)") - title = localizable("qchat_id_group") - addRightAction(UIImage.ne_imageNamed(name: "sign_add"), #selector(addClick), self) - setupTable() - tableView.delegate = self - tableView.dataSource = self - tableView.register( - QChatIdGroupCell.self, - forCellReuseIdentifier: "\(QChatIdGroupCell.self)" - ) - tableView.register( - QChatIdGroupTopCell.self, - forCellReuseIdentifier: "\(QChatIdGroupTopCell.self)" - ) - tableView.register( - QChatIdGroupSortButtonCell.self, - forCellReuseIdentifier: "\(QChatIdGroupSortButtonCell.self)" - ) - let mjFooter = MJRefreshBackNormalFooter( - refreshingTarget: self, - refreshingAction: #selector(loadMoreData) - ) - mjFooter.stateLabel?.isHidden = true - tableView.mj_footer = mjFooter - } - - @objc func loadMoreData() { - if let sid = serverid { - viewModel.getRoles(sid, false, nil) - } else { - fatalError("serverid must not be nil") - } - } - - @objc func refreshData() { - weak var weakSelf = self - view.makeToastActivity(.center) - print("refresh data") - viewModel.getRoles(weakSelf?.serverid, true) { - weakSelf?.view.hideToastActivity() - weakSelf?.tableView.mj_footer?.state = .idle - weakSelf?.tableView.mj_footer?.isHidden = false - } - } - - /* - // MARK: - Navigation - - // In a storyboard-based application, you will often want to do a little preparation before navigation - override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - // Get the new view controller using segue.destination. - // Pass the selected object to the new view controller. - } - */ - - // MARK: UITableViewDelegate, UITableViewDataSource,ViewModelDelegate - - public func dataDidError(_ error: Error) { -// print("get roles error : ", error) - NELog.errorLog(ModuleName + " " + className(), desc: "error : \(error)") - view.makeToast(error.localizedDescription) - } - - public func dataDidChange() { - tableView.mj_footer?.endRefreshing() - tableView.reloadData() - } - - public func dataNoMore() { - tableView.mj_footer?.endRefreshingWithNoMoreData() - tableView.mj_footer?.isHidden = true - } - - public func numberOfSections(in tableView: UITableView) -> Int { - 3 - } - - public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - if section == 0 { - return viewModel.topDatas.count - } else if section == 1 { - if viewModel.datas.count > 0 { - return viewModel.sortBtnCellDatas.count - } - } else if section == 2 { - return viewModel.datas.count - } - return 0 - } - - public func tableView(_ tableView: UITableView, - cellForRowAt indexPath: IndexPath) -> UITableViewCell { - if indexPath.section == 0 { - let model = viewModel.topDatas[indexPath.row] - let cell: QChatIdGroupTopCell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatIdGroupTopCell.self)", - for: indexPath - ) as! QChatIdGroupTopCell - cell.configure(model) - return cell - } else if indexPath.section == 1 { - let model = viewModel.sortBtnCellDatas[indexPath.row] - let cell: QChatIdGroupSortButtonCell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatIdGroupSortButtonCell.self)", - for: indexPath - ) as! QChatIdGroupSortButtonCell - cell.titleLabel.text = model.idName - cell.sortBtn.addTarget(self, action: #selector(toSort), for: .touchUpInside) - return cell - } else if indexPath.section == 2 { - let model = viewModel.datas[indexPath.row] - let cell: QChatIdGroupCell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatIdGroupCell.self)", - for: indexPath - ) as! QChatIdGroupCell - cell.configure(model) - return cell - } - return UITableViewCell() - } - - public func tableView(_ tableView: UITableView, - heightForRowAt indexPath: IndexPath) -> CGFloat { - if indexPath.section == 0 { - return 68 - } else if indexPath.section == 1 { - return 30 - } else if indexPath.section == 2 { - return 60 - } - return 0 - } - - public func tableView(_ tableView: UITableView, - heightForHeaderInSection section: Int) -> CGFloat { - if section == 1 { - return 6 - } - return 0 - } - - public func tableView(_ tableView: UITableView, - viewForHeaderInSection section: Int) -> UIView? { - if section == 1 { - let view = UIView(frame: CGRect.zero) - view.backgroundColor = UIColor(hexString: "EFF1F4") - return view - } - return nil - } - - public func tableView(_ tableView: UITableView, - heightForFooterInSection section: Int) -> CGFloat { - 0 - } - - public func tableView(_ tableView: UITableView, - viewForFooterInSection section: Int) -> UIView? { - nil - } - - public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - if indexPath.section == 1 { - return - } - - if indexPath.section == 0 { - let model = viewModel.topDatas[indexPath.row] - toPermission(model) - } else if indexPath.section == 2 { - let model = viewModel.datas[indexPath.row] - toPermission(model) - } - } - - // MARK: objc 方法 - - @objc func addClick() { - let create = QChatCreateGroupViewController() - create.serverId = serverid - weak var weakSelf = self - create.completion = { - weakSelf?.refreshData() - } - navigationController?.pushViewController(create, animated: true) - } - - @objc func toSort() { - let sort = QChatIdGroupSortController() - sort.serverId = serverid - sort.isOwer = isOwner - weak var weakSelf = self - sort.completion = { - weakSelf?.refreshData() - // weakSelf?.viewModel.datas.removeAll() - // for index in 0.. Void - -public class QChatMemberManagerController: NEBaseTableViewController, UITableViewDelegate, - UITableViewDataSource, ViewModelDelegate, QChatMemberSelectControllerDelegate { - let viewmodel = MemberManagerViewModel() - - var memberCount = 0 - - var serverId: UInt64? - - var roleId: UInt64? - - var countChangeBlock: MemberCountChange? - - override public func viewDidLoad() { - super.viewDidLoad() - - // Do any additional setup after loading the view. - viewmodel.delegate = self - loadMoreData() - setupUI() - } - - func setupUI() { - title = localizable("qchat_manager_member") - view.backgroundColor = .white - setupTable() - tableView.delegate = self - tableView.dataSource = self - tableView.register( - QChatMemberManagerCell.self, - forCellReuseIdentifier: "\(QChatMemberManagerCell.self)" - ) - tableView.register( - QChatPlainTextArrowCell.self, - forCellReuseIdentifier: "\(QChatPlainTextArrowCell.self)" - ) - - let mjfooter = MJRefreshBackNormalFooter( - refreshingTarget: self, - refreshingAction: #selector(loadMoreData) - ) - mjfooter.stateLabel?.isHidden = true - tableView.mj_footer = mjfooter - } - - @objc func loadMoreData() { - if let rid = roleId, let sid = serverId { - viewmodel.getData(sid, rid) - } else { - fatalError("serverId or roleId is nil") - } - } - - /* - // MARK: - Navigation - - // In a storyboard-based application, you will often want to do a little preparation before navigation - override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - // Get the new view controller using segue.destination. - // Pass the selected object to the new view controller. - } - */ - - // MARK: UITableViewDelegate, UITableViewDataSource,ViewModelDelegate,QChatMemberSelectControllerDelegate - - public func filterMembers(accid: [String]?, _ filterMembers: @escaping ([String]?) -> Void) { - var param = GetExistingServerRoleMembersByAccidsParam() - param.serverId = serverId - param.accids = accid - param.roleId = roleId - print("param existing accid : ", accid as Any) - viewmodel.repo.getExistingServerRoleMembersByAccids(param) { error, accids in - NELog.infoLog(ModuleName + " " + self.className(), desc: #function + ", accids:\(accids)") -// print("getExistingServerRoleMembersByAccids : ", accids) - var dic = [String: String]() - var retAccids = [String]() - accids.forEach { aid in - dic[aid] = aid - } - accid?.forEach { aid in - if dic[aid] != nil { - retAccids.append(aid) - } - } - print("filter members : ", retAccids) - filterMembers(retAccids) - } - } - - public func dataDidChange() { - view.hideToastActivity() - tableView.mj_footer?.endRefreshing() - tableView.reloadData() - } - - public func dataNoMore() { - view.hideToastActivity() - tableView.mj_footer?.endRefreshingWithNoMoreData() - tableView.mj_footer?.isHidden = true - } - - public func dataDidError(_ error: Error) { - showToast(error.localizedDescription) - } - - public func numberOfSections(in tableView: UITableView) -> Int { - 2 - } - - public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - if section == 0 { - return 1 - } - if section == 1 { - return viewmodel.datas.count - } - return 0 - } - - public func tableView(_ tableView: UITableView, - cellForRowAt indexPath: IndexPath) -> UITableViewCell { - if indexPath.section == 0 { - let cell: QChatPlainTextArrowCell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatPlainTextArrowCell.self)", - for: indexPath - ) as! QChatPlainTextArrowCell - cell.titleLabel.text = localizable("add_member") - cell.detailLabel.text = "\(memberCount)" - return cell - } - - if indexPath.section == 1 { - let cell: QChatMemberManagerCell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatMemberManagerCell.self)", - for: indexPath - ) as! QChatMemberManagerCell - let user = viewmodel.datas[indexPath.row] - cell.user = user - return cell - } - - return UITableViewCell() - } - - public func tableView(_ tableView: UITableView, - heightForRowAt indexPath: IndexPath) -> CGFloat { - 50 - } - - public func tableView(_ tableView: UITableView, - heightForHeaderInSection section: Int) -> CGFloat { - 0 - } - - public func tableView(_ tableView: UITableView, - heightForFooterInSection section: Int) -> CGFloat { - 0 - } - - public func tableView(_ tableView: UITableView, - viewForHeaderInSection section: Int) -> UIView? { - nil - } - - public func tableView(_ tableView: UITableView, - viewForFooterInSection section: Int) -> UIView? { - nil - } - - public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - weak var weakSelf = self - if indexPath.section == 0 { - let memberSelect = QChatMemberSelectController() - memberSelect.delegate = self - memberSelect.serverId = serverId - memberSelect.completion = { users in - print("member manager select: ", users) - weakSelf?.view.makeToastActivity(.center) - weakSelf?.viewmodel - .addMembers(users, weakSelf?.serverId, weakSelf?.roleId) { successCount in - NELog.infoLog(ModuleName + " " + (weakSelf?.className() ?? "QChatMemberManagerController"), desc: "✅ CALLBACK SUCCESS") - // weakSelf?.view.hideToastActivity() - weakSelf?.showToast(localizable("qchat_add_success")) - if let block = weakSelf?.countChangeBlock, var count = weakSelf?.memberCount { - count += successCount - weakSelf?.memberCount = count - block(count) - } - } - } - navigationController?.pushViewController(memberSelect, animated: true) - } else { - let user = viewmodel.datas[indexPath.row] - showAlert(message: localizable("qchat_sure_delete_user")) { - if let rid = weakSelf?.roleId, let sid = weakSelf?.serverId { - weakSelf?.view.makeToastActivity(.center) - weakSelf?.viewmodel.remove(user, sid, rid) { - NELog.infoLog(ModuleName + " " + self.className(), desc: #function + ", serverId:\(sid)") - weakSelf?.view.hideToastActivity() - weakSelf?.viewmodel.datas.remove(at: indexPath.row) - weakSelf?.tableView.reloadData() - if var count = weakSelf?.memberCount, - let block = weakSelf?.countChangeBlock { - count -= 1 - weakSelf?.memberCount = count - block(count) - } - } - } - } - } - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatMemberSelectController.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatMemberSelectController.swift deleted file mode 100644 index 03ec8558..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatMemberSelectController.swift +++ /dev/null @@ -1,288 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import MJRefresh - -typealias SelectMemeberCompletion = ([UserInfo]) -> Void -typealias FilterMembersBlock = ([UserInfo]) -> [UserInfo]? - -public protocol QChatMemberSelectControllerDelegate: NSObjectProtocol { - func filterMembers(accid: [String]?, _ filterMembers: @escaping ([String]?) -> Void) -} - -// enum SelectType { -// case ServerMember -// case ChannelMember -// } - -public class QChatMemberSelectController: NEBaseTableViewController, MemberSelectViewModelDelegate, - UICollectionViewDelegate, UICollectionViewDataSource, - UICollectionViewDelegateFlowLayout, UITableViewDelegate, UITableViewDataSource, - ViewModelDelegate { - let viewmodel = MemberSelectViewModel() - var filterBlock: FilterMembersBlock? - var completion: SelectMemeberCompletion? - -// var selectType = SelectType.ServerMember - - var serverId: UInt64? - - var limit = 10 - - private let tag = "QChatMemberSelectController" - - public weak var delegate: QChatMemberSelectControllerDelegate? - - lazy var collection: UICollectionView = { - let layout = UICollectionViewFlowLayout() - layout.scrollDirection = .horizontal - layout.minimumLineSpacing = 0 - layout.minimumInteritemSpacing = 0 - let collect = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout) - collect.contentInset = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5) - return collect - }() - - var collectionHeight: NSLayoutConstraint? - - var selectArray = [UserInfo]() - - override public func viewDidLoad() { - super.viewDidLoad() - viewmodel.delegate = self - loadData() - setupUI() - } - - func setupUI() { - edgesForExtendedLayout = [] - addRightAction(localizable("qchat_sure"), #selector(sureClick), self) - title = localizable("qchat_select") - view.addSubview(collection) - collection.delegate = self - collection.dataSource = self - collection.allowsMultipleSelection = false - collection.translatesAutoresizingMaskIntoConstraints = false - collectionHeight = collection.heightAnchor.constraint(equalToConstant: 0) - collectionHeight?.isActive = true - collection.backgroundColor = UIColor(hexString: "F2F4F5") - NSLayoutConstraint.activate([ - collection.topAnchor.constraint(equalTo: view.topAnchor), - collection.leftAnchor.constraint(equalTo: view.leftAnchor), - collection.rightAnchor.constraint(equalTo: view.rightAnchor), - ]) - - collection.register( - QChatUserUnCheckCell.self, - forCellWithReuseIdentifier: "\(NSStringFromClass(QChatUserUnCheckCell.self))" - ) - - view.addSubview(tableView) - NSLayoutConstraint.activate([ - tableView.leftAnchor.constraint(equalTo: view.leftAnchor), - tableView.rightAnchor.constraint(equalTo: view.rightAnchor), - tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor), - tableView.topAnchor.constraint(equalTo: collection.bottomAnchor), - ]) - if #available(iOS 13.0, *) { - tableView.automaticallyAdjustsScrollIndicatorInsets = false - } else { - // Fallback on earlier versions - } - tableView.delegate = self - tableView.dataSource = self - tableView.register( - QChatSelectedCell.self, - forCellReuseIdentifier: "\(QChatSelectedCell.self)" - ) - - if #available(iOS 11.0,*) { - tableView.contentInsetAdjustmentBehavior = UIScrollView.ContentInsetAdjustmentBehavior - .never - } else { - automaticallyAdjustsScrollViewInsets = false - } - tableView.mj_footer = MJRefreshBackNormalFooter( - refreshingTarget: self, - refreshingAction: #selector(loadMoreData) - ) -// tableView.mj_header = MJRefreshNormalHeader(refreshingTarget: self, refreshingAction: #selector(loadData)) - } - - @objc func sureClick() { - if selectArray.count <= 0 { - view.makeToast(localizable("qchat_not_empty_select_memeber")) - return - } - if let block = completion { - block(selectArray) - } - navigationController?.popViewController(animated: true) - } - - @objc func loadData() { - viewmodel.loadFirst(serverId: serverId) { [weak self] error, users in - NELog.infoLog( - ModuleName + " " + (self?.tag ?? "QChatMemberSelectController"), - desc: "CALLBACK loadFirst " + (error?.localizedDescription ?? "no error") - ) - if error != nil { - self?.view.makeToast(error?.localizedDescription) - } else { - self?.tableView.reloadData() - self?.tableView.mj_footer?.resetNoMoreData() - self?.tableView.mj_header?.endRefreshing() - } - } - } - - @objc func loadMoreData() { - viewmodel.loadMore(serverId: serverId) { [weak self] error, users in - NELog.infoLog( - ModuleName + " " + (self?.tag ?? "QChatMemberSelectController"), - desc: "CALLBACK loadMore " + (error?.localizedDescription ?? "no error") - ) - if error != nil { - self?.view.makeToast(error?.localizedDescription) - } else { - if users?.count ?? 0 > 0 { - self?.tableView.reloadData() - self?.tableView.mj_footer?.endRefreshing() - } else { - self?.tableView.mj_footer?.endRefreshingWithNoMoreData() - } - } - } - } - - // MARK: - - public func dataDidError(_ error: Error) { - view.makeToast(error.localizedDescription) - } - - public func dataDidChange() { - tableView.reloadData() - } - - public func collectionView(_ collectionView: UICollectionView, - numberOfItemsInSection section: Int) -> Int { - selectArray.count - } - - public func collectionView(_ collectionView: UICollectionView, - cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { - let user = selectArray[indexPath.row] - let cell = collectionView.dequeueReusableCell( - withReuseIdentifier: "\(NSStringFromClass(QChatUserUnCheckCell.self))", - for: indexPath - ) as? QChatUserUnCheckCell - cell?.configure(user) - return cell ?? UICollectionViewCell() - } - - public func collectionView(_ collectionView: UICollectionView, - didSelectItemAt indexPath: IndexPath) { - let user = selectArray[indexPath.row] - didUnselectContact(user) - } - - public func collectionView(_ collectionView: UICollectionView, - layout collectionViewLayout: UICollectionViewLayout, - sizeForItemAt indexPath: IndexPath) -> CGSize { - CGSize(width: 46, height: 52) - } - - public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - viewmodel.datas.count - } - - public func tableView(_ tableView: UITableView, - cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell: QChatSelectedCell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatSelectedCell.self)", - for: indexPath - ) as! QChatSelectedCell - let user = viewmodel.datas[indexPath.row] - cell.user = user - return cell - } - - public func tableView(_ tableView: UITableView, - heightForRowAt indexPath: IndexPath) -> CGFloat { - 62 - } - - public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - let user = viewmodel.datas[indexPath.row] - let cell = tableView.cellForRow(at: indexPath) as? QChatSelectedCell - - if user.select == true { - cell?.setUnselect() - didUnselectContact(user) - } else { - if selectArray.count >= limit { - // view.makeToast("超出\(limit)人限制") - showToast( - "\(localizable("exceed"))\(limit)\(localizable("person"))\(localizable("limit"))" - ) - return - } - cell?.setSelect() - didSelectContact(user) - } - // tableView.reloadRows(at: [indexPath], with: .none) - } - - func didSelectContact(_ user: UserInfo) { - user.select = true - if selectArray.contains(where: { c in - user === c - }) == false { - selectArray.append(user) - if let height = collectionHeight?.constant, height <= 0 { - collectionHeight?.constant = 52 - } - } - collection.reloadData() - tableView.reloadData() - refreshSelectCount() - } - - func didUnselectContact(_ user: UserInfo) { - user.select = false - selectArray.removeAll { c in - user === c - } - if selectArray.count <= 0 { - collection.reloadData() - collectionHeight?.constant = 0 - } - collection.reloadData() - tableView.reloadData() - refreshSelectCount() - } - - func refreshSelectCount() { - if selectArray.count > 0 { - rightNavBtn.setTitle("\(localizable("qchat_sure"))(\(selectArray.count))", for: .normal) - } else { - rightNavBtn.setTitle(localizable("qchat_sure"), for: .normal) - } - } - - public func tableView(_ tableView: UITableView, - heightForHeaderInSection section: Int) -> CGFloat { - 0 - } - - // MARK: MemberSelectViewModelDelegate - - public func filterMembers(accid: [String]?, _ filterMembers: @escaping ([String]?) -> Void) { - // 查询需要筛选的用户 - delegate?.filterMembers(accid: accid, filterMembers) - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatPermissionViewController.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatPermissionViewController.swift deleted file mode 100644 index 9c4dd2f1..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatPermissionViewController.swift +++ /dev/null @@ -1,308 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NECoreIMKit - -typealias RoleUpdateCompletion = (_ role: ServerRole) -> Void -public class QChatPermissionViewController: NEBaseTableViewController, UITableViewDelegate, - UITableViewDataSource, QChatTextEditCellDelegate, ViewModelDelegate, QChatSwitchCellDelegate { - var idGroup: IdGroupModel? - - let viewmodel = PermissionViewModel() - - var serverName = "" - - var completion: RoleUpdateCompletion? - - override public func viewDidLoad() { - super.viewDidLoad() - - // Do any additional setup after loading the view. - viewmodel.delegate = self - if let name = idGroup?.role?.name { - serverName = name - } - if let serverRole = idGroup?.role { - viewmodel.getData(serverRole) - } else { - fatalError("permission server role is nil ") - } - setupUI() - } - - func setupUI() { - if let type = idGroup?.role?.type, type != .everyone { - addRightAction(localizable("qchat_save"), #selector(savePermission), self) - } - - setupTable() - title = idGroup?.idName - tableView.backgroundColor = .ne_backcolor - tableView.delegate = self - tableView.dataSource = self - tableView.register( - QChatTextEditCell.self, - forCellReuseIdentifier: "\(QChatTextEditCell.self)" - ) - tableView.register(QChatSwitchCell.self, forCellReuseIdentifier: "\(QChatSwitchCell.self)") - tableView.register( - QChatTextArrowCell.self, - forCellReuseIdentifier: "\(QChatTextArrowCell.self)" - ) - } - - /* - // MARK: - Navigation - - // In a storyboard-based application, you will often want to do a little preparation before navigation - override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - // Get the new view controller using segue.destination. - // Pass the selected object to the new view controller. - } - */ - - // MARK: UITableViewDelegate, UITableViewDataSource, QChatTextEditCellDelegate, ViewModelDelegate, QChatSwitchCellDelegate - - func didChangeSwitchValue(_ cell: QChatSwitchCell) { - print("did change switch value : ", cell) - if let key = cell.model?.permissionKey, - let value = cell.model?.permission?.value(forKey: key) as? String, - let type = ChatPermissionType(rawValue: value) { - updatePermission(type, cell.qSwitch.isOn) { success in - if success == false { - cell.qSwitch.isOn = !cell.qSwitch.isOn - } - } - } - } - - public func dataDidChange() { - tableView.reloadData() - } - - public func dataDidError(_ error: Error) { - showToast(error.localizedDescription) - } - - func textDidChange(_ textField: UITextField) { - if let text = textField.text { - serverName = text - } - } - - public func numberOfSections(in tableView: UITableView) -> Int { - 5 - } - - public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - if section == 0 { - return 1 - } - if section == 1 { - if let type = idGroup?.role?.type, type == .everyone { - return 0 - } - return 1 - } - if section == 2 { - return viewmodel.commons.count - } - if section == 3 { - return viewmodel.messages.count - } - if section == 4 { - return viewmodel.members.count - } - return 0 - } - - public func tableView(_ tableView: UITableView, - cellForRowAt indexPath: IndexPath) -> UITableViewCell { - if indexPath.section == 0 { - let cell: QChatTextEditCell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatTextEditCell.self)", - for: indexPath - ) as! QChatTextEditCell - if serverName.count > 0 { - cell.textFied.text = serverName - } else { - cell.textFied.text = nil - } - cell.textFied.placeholder = localizable("qchat_please_input_role_name") - cell.delegate = self - cell.limit = 20 - cell.cornerType = CornerType.topLeft.union(CornerType.topRight) - .union(CornerType.bottomLeft).union(CornerType.bottomRight) - return cell - } - - if indexPath.section == 1 { - let cell: QChatTextArrowCell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatTextArrowCell.self)", - for: indexPath - ) as! QChatTextArrowCell - cell.titleLabel.text = localizable("qchat_member") - cell.detailLabel.text = "\(idGroup?.role?.memberCount ?? 0)" - cell.cornerType = CornerType.topLeft.union(CornerType.topRight) - .union(CornerType.bottomLeft).union(CornerType.bottomRight) - return cell - } - - if indexPath.section == 2 || indexPath.section == 3 || indexPath.section == 4 { - let cell: QChatSwitchCell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatSwitchCell.self)", - for: indexPath - ) as! QChatSwitchCell - var model: PermissionCellModel? - if indexPath.section == 2 { - model = viewmodel.commons[indexPath.row] - } else if indexPath.section == 3 { - model = viewmodel.messages[indexPath.row] - } else if indexPath.section == 4 { - model = viewmodel.members[indexPath.row] - } - cell.delegate = self - cell.model = model - return cell - } - - return UITableViewCell() - } - - public func tableView(_ tableView: UITableView, - heightForRowAt indexPath: IndexPath) -> CGFloat { - 50 - } - - public func tableView(_ tableView: UITableView, - viewForHeaderInSection section: Int) -> UIView? { - let header = QChatHeaderView() - switch section { - case 0: - header.titleLabel.text = localizable("qchat_group_name") - case 1: - if let type = idGroup?.role?.type, type == .everyone { - return nil - } - header.titleLabel.text = localizable("qchat_manager_member") - case 2: - header.titleLabel.text = localizable("qchat_common_permission") - case 3: - header.titleLabel.text = localizable("qchat_message_permission") - case 4: - header.titleLabel.text = localizable("qchat_member_permission") - default: - break - } - return header - } - - public func tableView(_ tableView: UITableView, - heightForHeaderInSection section: Int) -> CGFloat { - if let type = idGroup?.role?.type, type == .everyone, section == 1 { - return 0 - } - return 40 - } - - public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - if indexPath.section == 1 { - let memberManager = QChatMemberManagerController() - memberManager.serverId = idGroup?.role?.serverId - memberManager.roleId = idGroup?.role?.roleId - memberManager.memberCount = idGroup?.role?.memberCount ?? 0 - weak var weakSelf = self - memberManager.countChangeBlock = { count in - weakSelf?.idGroup?.role?.memberCount = count - if let role = weakSelf?.idGroup?.role, let block = weakSelf?.completion { - block(role) - } - tableView.reloadData() - } - navigationController?.pushViewController(memberManager, animated: true) - } - } - - // MAKR: objc 方法 - @objc func savePermission() { - if serverName.count <= 0 { - showToast(localizable("qchat_please_input_role_name")) - return - } - var param = UpdateServerRoleParam() - param.serverId = idGroup?.role?.serverId - if let rid = idGroup?.role?.roleId { - param.roleId = UInt64(rid) - } - param.name = serverName - - /* 批量逻辑,暂时不用 - let permissions = viewmodel.permission.getChangePermission() - var commonds = [StatusInfo]() - - permissions.forEach { (type: ChatPermissionType, value: Bool) in - var info = StatusInfo() - info.permissionType = type - if value == true { - info.status = .Allow - }else { - info.status = .Deny - } - commonds.append(info) - } - if commonds.count > 0 { - print("commonds : ", commonds) - print("commonds count :", commonds.count) - param.commands = commonds - } */ - - weak var weakSelf = self - viewmodel.repo.updateRole(param) { error, role in - if let err = error { - weakSelf?.showToast(err.localizedDescription) - } else { - if let block = weakSelf?.completion { - block(role) - } - weakSelf?.showToastInWindow(localizable("update_channel_suscess")) - weakSelf?.navigationController?.popViewController(animated: true) - } - } - } -} - -extension QChatPermissionViewController { - func updatePermission(_ type: ChatPermissionType, _ open: Bool, - _ completion: @escaping (Bool) -> Void) { - var param = UpdateServerRoleParam() - param.serverId = idGroup?.role?.serverId - if let rid = idGroup?.role?.roleId { - param.roleId = UInt64(rid) - } - - var commonds = [StatusInfo]() - var info = StatusInfo() - info.permissionType = type - info.status = open == true ? .Allow : .Deny - commonds.append(info) - param.commands = commonds - - weak var weakSelf = self - view.makeToastActivity(.center) - viewmodel.repo.updateRole(param) { error, role in - weakSelf?.view.hideToastActivity() - if let err = error { - weakSelf?.showToast(err.localizedDescription) - completion(false) - } else { - if let block = weakSelf?.completion { - completion(true) - block(role) - } - } - } - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatServerSettingViewController.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatServerSettingViewController.swift deleted file mode 100644 index f65228bf..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewController/QChatServerSettingViewController.swift +++ /dev/null @@ -1,494 +0,0 @@ - -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import UIKit -import NECoreKit -import NECoreIMKit -import NIMSDK - -typealias SaveSuccessBlock = (_ server: QChatServer?) -> Void - -public class QChatServerSettingViewController: NEBaseTableViewController, UITableViewDelegate, - UITableViewDataSource, UITextFieldDelegate, UINavigationControllerDelegate { - let viewModel = SettingViewModel() - var server: QChatServer? - - var headerImageUrl: String? - - var headerImage: NEUserHeaderView? - - lazy var serverNameInput: UITextField = getInput() - - lazy var serverThemeInput: UITextField = getInput() - - var topicInput: UITextField? - - private let className = "QChatServerSettingViewController" - - lazy var serverName: UILabel = { - let label = UILabel() - label.translatesAutoresizingMaskIntoConstraints = false - label.font = UIFont.systemFont(ofSize: 16.0) - label.textColor = .ne_darkText - return label - }() - - override public func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - navigationController?.navigationBar.isHidden = false - } - - override public func viewDidLoad() { - super.viewDidLoad() - - // Do any additional setup after loading the view. - - NELog.infoLog(ModuleName + " " + className, desc: "server id : \(server?.serverId ?? 0)") - - setupUI() - addRightAction(localizable("save"), #selector(saveClick), self) - } - - func setupUI() { - title = localizable("qchat_setting") - view.backgroundColor = .ne_backcolor - setupTable() - tableView.bounces = false - tableView.tableHeaderView = headerView() - tableView.register( - QChatTextArrowCell.self, - forCellReuseIdentifier: "\(QChatTextArrowCell.self)" - ) - tableView.register( - QChatDestructiveCell.self, - forCellReuseIdentifier: "\(QChatDestructiveCell.self)" - ) - tableView.delegate = self - tableView.dataSource = self - } - - func headerView() -> UIView { - let headerBack = UIView() - headerBack.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: 334) - headerBack.backgroundColor = .clear - - let cornerView = UIView() - cornerView.translatesAutoresizingMaskIntoConstraints = false - headerBack.addSubview(cornerView) - NSLayoutConstraint.activate([ - cornerView.topAnchor.constraint(equalTo: headerBack.topAnchor, constant: 22), - cornerView.leftAnchor.constraint(equalTo: headerBack.leftAnchor, constant: 20), - cornerView.rightAnchor.constraint(equalTo: headerBack.rightAnchor, constant: -20), - cornerView.heightAnchor.constraint(equalToConstant: 98), - ]) - cornerView.clipsToBounds = true - cornerView.layer.cornerRadius = 8 - cornerView.backgroundColor = .white - - let header = NEUserHeaderView(frame: .zero) - header.translatesAutoresizingMaskIntoConstraints = false - cornerView.addSubview(header) - NSLayoutConstraint.activate([ - header.widthAnchor.constraint(equalToConstant: 60), - header.heightAnchor.constraint(equalToConstant: 60), - header.leftAnchor.constraint(equalTo: cornerView.leftAnchor, constant: 16), - header.topAnchor.constraint(equalTo: cornerView.topAnchor, constant: 16), - ]) - header.isUserInteractionEnabled = true - header.clipsToBounds = true - header.backgroundColor = UIColor.colorWithNumber(number: server?.serverId) - header.layer.cornerRadius = 30 - headerImage = header - if let icon = server?.icon { - header.sd_setImage(with: URL(string: icon), completed: nil) - } else { - if let name = server?.name { - header.setTitle(name) - } - } - - let cameraBtn = ExpandButton() - cornerView.addSubview(cameraBtn) - cameraBtn.translatesAutoresizingMaskIntoConstraints = false - cameraBtn.backgroundColor = .ne_backcolor - NSLayoutConstraint.activate([ - cameraBtn.leftAnchor.constraint(equalTo: cornerView.leftAnchor, constant: 58), - cameraBtn.topAnchor.constraint(equalTo: cornerView.topAnchor, constant: 58), - cameraBtn.widthAnchor.constraint(equalToConstant: 26), - cameraBtn.heightAnchor.constraint(equalToConstant: 26), - ]) - cameraBtn.layer.cornerRadius = 12 - cameraBtn.clipsToBounds = true - cameraBtn.layer.borderColor = UIColor.white.cgColor - cameraBtn.layer.borderWidth = 2 - cameraBtn.addTarget(self, action: #selector(cameraClick), for: .touchUpInside) - - let camera = UIImageView() - camera.translatesAutoresizingMaskIntoConstraints = false - cornerView.addSubview(camera) - camera.backgroundColor = .clear - camera.image = coreLoader.loadImage("camera") - NSLayoutConstraint.activate([ - camera.centerXAnchor.constraint(equalTo: cameraBtn.centerXAnchor), - camera.centerYAnchor.constraint(equalTo: cameraBtn.centerYAnchor, constant: -2), - ]) - - cornerView.addSubview(serverName) - NSLayoutConstraint.activate([ - serverName.leftAnchor.constraint(equalTo: header.rightAnchor, constant: 16), - serverName.rightAnchor.constraint(equalTo: cornerView.rightAnchor, constant: -16), - serverName.topAnchor.constraint(equalTo: cornerView.topAnchor, constant: 30), - ]) - serverName.text = server?.name - - let account = UILabel() - account.translatesAutoresizingMaskIntoConstraints = false - account.textColor = UIColor.ne_emptyTitleColor - account.font = UIFont.systemFont(ofSize: 12) - cornerView.addSubview(account) - NSLayoutConstraint.activate([ - account.leftAnchor.constraint(equalTo: serverName.leftAnchor), - account.rightAnchor.constraint(equalTo: serverName.rightAnchor), - account.topAnchor.constraint(equalTo: serverName.bottomAnchor, constant: 6), - ]) - account.text = "ID: \(server?.serverId ?? 0)" - - addInputView(headerBack, cornerView) - - return headerBack - } - - func addInputView(_ back: UIView, _ topView: UIView) { - let serverNameLabel = getTagLabel() - back.addSubview(serverNameLabel) - NSLayoutConstraint.activate([ - serverNameLabel.leftAnchor.constraint(equalTo: back.leftAnchor, constant: 33), - serverNameLabel.topAnchor.constraint(equalTo: topView.bottomAnchor, constant: 16.0), - ]) - serverNameLabel.text = localizable("qchat_server_name") - - back.addSubview(serverNameInput) - NSLayoutConstraint.activate([ - serverNameInput.leftAnchor.constraint(equalTo: back.leftAnchor, constant: 20), - serverNameInput.rightAnchor.constraint(equalTo: back.rightAnchor, constant: -20), - serverNameInput.topAnchor.constraint(equalTo: topView.bottomAnchor, constant: 38), - serverNameInput.heightAnchor.constraint(equalToConstant: 50), - ]) - serverNameInput.placeholder = localizable("enter_name") - serverNameInput.tag = 50 - if let name = server?.name { - serverNameInput.text = name - } - - let serverThemeLabel = getTagLabel() - back.addSubview(serverThemeLabel) - NSLayoutConstraint.activate([ - serverThemeLabel.leftAnchor.constraint(equalTo: serverNameLabel.leftAnchor), - serverThemeLabel.topAnchor.constraint( - equalTo: serverNameInput.bottomAnchor, - constant: 16 - ), - ]) - serverThemeLabel.text = localizable("qchat_server_theme") - - back.addSubview(serverThemeInput) - NSLayoutConstraint.activate([ - serverThemeInput.leftAnchor.constraint(equalTo: back.leftAnchor, constant: 20), - serverThemeInput.rightAnchor.constraint(equalTo: back.rightAnchor, constant: -20), - serverThemeInput.topAnchor.constraint( - equalTo: serverNameInput.bottomAnchor, - constant: 38 - ), - serverThemeInput.heightAnchor.constraint(equalToConstant: 50), - ]) - serverThemeInput.placeholder = localizable("qchat_please_input_topic") - if let custom = server?.custom, let dic = getDictionaryFromJSONString(custom), - let topic = dic["topic"] as? String { - serverThemeInput.text = topic - } - serverThemeInput.tag = 64 - - let permissionLabel = getTagLabel() - back.addSubview(permissionLabel) - NSLayoutConstraint.activate([ - permissionLabel.leftAnchor.constraint(equalTo: serverThemeLabel.leftAnchor), - permissionLabel.topAnchor.constraint( - equalTo: serverThemeInput.bottomAnchor, - constant: 16 - ), - ]) - permissionLabel.text = localizable("qchat_permisssion") - } - - func getTagLabel() -> UILabel { - let label = UILabel() - label.textColor = UIColor(hexString: "666666") - label.font = UIFont.systemFont(ofSize: 12.0) - label.translatesAutoresizingMaskIntoConstraints = false - label.textAlignment = .left - return label - } - - func getInput() -> UITextField { - let textField = UITextField() - textField.backgroundColor = .white - textField.clipsToBounds = true - textField.layer.cornerRadius = 8 - textField.font = UIFont.systemFont(ofSize: 16.0) - textField.translatesAutoresizingMaskIntoConstraints = false - let leftSpace = UIView(frame: CGRect(x: 0, y: 0, width: 20, height: 0)) - textField.leftView = leftSpace - textField.leftViewMode = .always - textField.delegate = self - return textField - } - - // MARK: action - - @objc func cameraClick() { - // print("camera click") - showBottomAlert(self) - } - - @objc func saveClick() { - print("save click") - - var name = "" - - if let currentName = serverNameInput.text, currentName.count > 0 { - name = currentName - } else if let originServerName = server?.name, originServerName.count > 0 { - name = originServerName - } - - if name.count <= 0 { - showToast(localizable("qchat_not_empty_servername")) - return - } - - if let icon = headerImageUrl { - server?.icon = icon - } - - var serverParam = UpdateServerParam(name: name, icon: headerImageUrl) - - guard let sid = server?.serverId else { - showToast(localizable("serverId_notbe_empty")) - return - } - serverParam.serverId = sid - - if let topic = serverThemeInput.text, topic.count > 0 { - serverParam.custom = getJSONStringFromDictionary(["topic": topic]) - } - weak var weakSelf = self - - view.makeToastActivity(.center) - print("update param : ", serverParam) - QChatServerProvider.shared.updateServer(serverParam) { error in - print("update finish : ", error as Any) - weakSelf?.view.hideToastActivity() - if let err = error { - weakSelf?.showToast(err.localizedDescription) - } else { - weakSelf?.navigationController?.popViewController(animated: true) - } - } - } - - func leaveServer() { - if let serverid = server?.serverId { - weak var weakSelf = self - view.makeToastActivity(.center) - viewModel.repo.leaveServer(serverid) { error in - weakSelf?.view.hideToastActivity() - if let err = error { - NELog.errorLog(ModuleName + " " + self.className, desc: "leave server error : \(err)") - weakSelf?.view.makeToast(err.localizedDescription) - } else { - weakSelf?.navigationController?.popViewController(animated: true) - } - } - } - } - - func deleteServer() { - if let serverid = server?.serverId { - weak var weakSelf = self - view.makeToastActivity(.center) - QChatServerProvider.shared.deleteServer(serverid) { error in - print("delete result : ", error as Any) - weakSelf?.view.hideToastActivity() - if let err = error { - weakSelf?.view.makeToast(err.localizedDescription) - } else { - weakSelf?.navigationController?.popViewController(animated: true) - } - } - } - } - - // MARK: UITableViewDelegate, UITableViewDataSource,UITextFieldDelegate - - public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, - replacementString string: String) -> Bool { - let l = textField.tag - let text = "\(textField.text ?? "")\(string)" - print("count : ", text.count) - if text.count > l { - return false - } - return true - } - - public func numberOfSections(in tableView: UITableView) -> Int { - 2 - } - - public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - print("count section : ", section) - if section == 0 { - return viewModel.permissions.count - } else if section == 1 { - return 1 - } - return 0 - } - - public func tableView(_ tableView: UITableView, - cellForRowAt indexPath: IndexPath) -> UITableViewCell { - if indexPath.section == 0 { - let textCell: QChatTextArrowCell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatTextArrowCell.self)", - for: indexPath - ) as! QChatTextArrowCell - let model = viewModel.permissions[indexPath.row] - textCell.titleLabel.text = model.title - textCell.backgroundColor = .clear - textCell.cornerType = model.cornerType - return textCell - } else if indexPath.section == 1 { - let destructiveCell: QChatDestructiveCell = tableView.dequeueReusableCell( - withIdentifier: "\(QChatDestructiveCell.self)", - for: indexPath - ) as! QChatDestructiveCell - - destructiveCell.redTextLabel - .text = isMyServer() ? localizable("qchat_delete_server") : - localizable("qchat_leave_server") - destructiveCell.cornerType = CornerType.bottomLeft.union(CornerType.bottomRight) - .union(CornerType.topLeft).union(CornerType.topRight) - return destructiveCell - } - - return UITableViewCell() - } - - public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - if indexPath.section == 0 { - if indexPath.row == 1 { - let idGroupController = QChatIdGroupViewController() - idGroupController.serverid = server?.serverId - if let owner = server?.owner, owner == IMKitEngine.instance.imAccid { - idGroupController.isOwner = true - } - navigationController?.pushViewController(idGroupController, animated: true) - - } else if indexPath.row == 0 { - let memberCtrl = MemberListViewController() - memberCtrl.serverId = server?.serverId - navigationController?.pushViewController(memberCtrl, animated: true) - } - - } else if indexPath.section == 1 { - print("click delete") - weak var weakSelf = self - if isMyServer() == true { - showAlert(message: localizable("sure_delete_server")) { - weakSelf?.deleteServer() - } - } else { - showAlert(message: localizable("sure_exit_server")) { - weakSelf?.leaveServer() - } - } - } - } - - public func tableView(_ tableView: UITableView, - heightForRowAt indexPath: IndexPath) -> CGFloat { - if indexPath.section == 0 { - return 48 - } else if indexPath.section == 1 { - return 40 - } - return 0 - } - - public func tableView(_ tableView: UITableView, - viewForHeaderInSection section: Int) -> UIView? { - if section == 1 { - return UIView(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: 24)) - } - return nil - } - - public func tableView(_ tableView: UITableView, - heightForHeaderInSection section: Int) -> CGFloat { - if section == 1 { - return 24 - } - return 0 - } - - public func tableView(_ tableView: UITableView, - heightForFooterInSection section: Int) -> CGFloat { - 0 - } - - func isMyServer() -> Bool { - if let owner = server?.owner { - let accid = IMKitEngine.instance.imAccid - if owner == accid { - return true - } - } - return false - } - - // UINavigationControllerDelegate - func imagePickerController(_ picker: UIImagePickerController, - didFinishPickingMediaWithInfo info: [UIImagePickerController - .InfoKey: Any]) { - let image: UIImage = info[UIImagePickerController.InfoKey.editedImage] as! UIImage - uploadHeadImage(image: image) - picker.dismiss(animated: true, completion: nil) - } - - public func uploadHeadImage(image: UIImage) { - view.makeToastActivity(.center) - if let imageData = image.jpegData(compressionQuality: 0.6) as NSData? { - let filePath = NSHomeDirectory().appending("/Documents/") - .appending(IMKitEngine.instance.imAccid) - let succcess = imageData.write(toFile: filePath, atomically: true) - weak var weakSelf = self - if succcess { - NIMSDK.shared().resourceManager - .upload(filePath, progress: nil) { urlString, error in - if error == nil { - // 显示设置的照片 - weakSelf?.headerImage?.image = image - weakSelf?.headerImageUrl = urlString - weakSelf?.headerImage?.titleLabel.isHidden = true - print("upload image success") - } else { - print("upload image failed,error = \(error!)") - } - weakSelf?.view.hideToastActivity() - } - } - } - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/CreateGroupViewModel.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/CreateGroupViewModel.swift deleted file mode 100644 index f3e82131..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/CreateGroupViewModel.swift +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -import NEQChatKit -import NECoreIMKit - -@objcMembers -public class CreateGroupViewModel: NSObject { -// var limit = 7 - -// var limitUsers = [UserInfo]() - var allUsers = [UserInfo]() - let repo = QChatRepo() - private let className = "CreateGroupViewModel" - - weak var delegate: ViewModelDelegate? - - override init() {} - - func loadAllData() { - NELog.infoLog(ModuleName + " " + className, desc: #function) -// limitUsers.removeAll() -// limitUsers.append(contentsOf: allUsers) - } - - private func addUser(_ user: UserInfo) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(user.serverId ?? 0)") - allUsers.append(user) -// if limitUsers.count <= limit { -// limitUsers.append(user) -// } - } - - func addNewUser(_ user: UserInfo) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(user.serverId ?? 0)") - addUser(user) - filterData() - } - - func filterData() { - NELog.infoLog(ModuleName + " " + className, desc: #function) - allUsers.forEach { user in - user.cornerType = .none - } - if allUsers.count == 1, let first = allUsers.first { - first.cornerType = CornerType.topLeft.union(CornerType.topRight).union(.bottomLeft) - .union(.bottomRight) - } - - if allUsers.count > 1, let first = allUsers.first, let last = allUsers.last { - first.cornerType = .topLeft.union(.topRight) - last.cornerType = .bottomLeft.union(.bottomRight) - } - - /* - if limitUsers.count < limit { - if let last = limitUsers.last { - if limitUsers.count == 1 { - last.cornerType = CornerType.topLeft.union(CornerType.topRight).union(CornerType.bottomLeft).union(CornerType.bottomRight) - }else { - last.cornerType = CornerType.bottomLeft.union(CornerType.bottomRight) - } - } - }else { - if let last = limitUsers.last { - last.cornerType = .none - } - } */ - - delegate?.dataDidChange() - } - - func removeData(_ index: Int) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", index:\(index)") - allUsers.remove(at: index) - filterData() - delegate?.dataDidChange() - } - - func addMembers(_ members: [UserInfo]) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", members.count:\(members.count)") - members.forEach { user in - if allUsers.contains(where: { lUser in - if let cid = lUser.serverMember?.accid, let mid = user.serverMember?.accid { - if cid == mid { - return true - } - } - return false - }) == false { - addUser(user) - } - } - filterData() - } - - func removeMember(_ member: UserInfo) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(member.serverId ?? 0)") - delegate?.dataDidChange() - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/EditMemberViewModel.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/EditMemberViewModel.swift deleted file mode 100644 index 706199b7..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/EditMemberViewModel.swift +++ /dev/null @@ -1,231 +0,0 @@ -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -import NECoreIMKit -import NEQChatKit - -@objcMembers -public class EditMemberViewModel: NSObject { - var limitIdGroups = [IdGroupModel]() - var allIdGroups = [IdGroupModel]() - - var serverRoles = [ServerRole]() - var userRoles = [ServerRole]() - - var userDic = [UInt64: IdGroupModel]() - var serverDic = [UInt64: IdGroupModel]() - - var delegate: ViewModelDelegate? - - let repo = QChatRepo() - - var limit = 5 - - private let className = "EditMemberViewModel" - - override init() {} - - func checkoutCurrentUserRole(_ roleId: UInt64?) -> Bool { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", roleId:\(roleId ?? 0)") - if let rid = roleId { - if userDic[rid] != nil { - return true - } - } - return false - } - - func showServerData() { - NELog.infoLog(ModuleName + " " + className, desc: #function) - limitIdGroups.removeAll() - allIdGroups.removeAll() - serverRoles.forEach { role in - if let roleId = role.roleId { - if let model = self.serverDic[roleId] { - self.allIdGroups.append(model) - } - } - } - allIdGroups.first?.cornerType = .topLeft.union(.topRight) - if allIdGroups.count > limit { - limitIdGroups.append(contentsOf: allIdGroups.prefix(limit)) - } else { - limitIdGroups.append(contentsOf: allIdGroups) - if let last = limitIdGroups.last { - last.cornerType = last.cornerType.union(.bottomLeft).union(.bottomRight) - } - } - delegate?.dataDidChange() - } - - func filterAllRoles() { - NELog.infoLog(ModuleName + " " + className, desc: #function) - let serverModels = getRoleModel(serverRoles, nil) - serverModels.forEach { idModel in - if let roleId = idModel.role?.roleId { - self.serverDic[roleId] = idModel - } - } - } - - func filterUserRoles() { - NELog.infoLog(ModuleName + " " + className, desc: #function) - allIdGroups.append(contentsOf: getRoleModel(userRoles, true)) - allIdGroups.first?.cornerType = .topLeft.union(.topRight) - if allIdGroups.count > limit { - limitIdGroups.append(contentsOf: allIdGroups.prefix(limit)) - } else { - limitIdGroups.append(contentsOf: allIdGroups) - if let last = limitIdGroups.last { - last.cornerType = last.cornerType.union(.bottomLeft).union(.bottomRight) - } - } - allIdGroups.forEach { idModel in - if let roleId = idModel.role?.roleId { - self.userDic[roleId] = idModel - } - } - delegate?.dataDidChange() - } - - func getData(_ serverId: UInt64?, _ accid: String?) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(serverId ?? 0)") - weak var weakSelf = self - - var accidParam = GetServerRolesByAccIdParam(serverId: serverId, accid: accid) - accidParam.limit = 200 - accidParam.timeTag = 0 - repo.getServerRolesByAccId(param: accidParam) { error, roles in - if let err = error { - weakSelf?.delegate?.dataDidError(err) - } else { - print("edit member member role : ", roles as Any) - if let datas = roles { - weakSelf?.userRoles.append(contentsOf: datas) - weakSelf?.delegate?.dataDidChange() - weakSelf?.filterUserRoles() - } - } - } - - var param = GetServerRoleParam() - param.limit = 200 - param.serverId = serverId - - repo.getRoles(param) { error, roles, sets in - if let err = error { - weakSelf?.delegate?.dataDidError(err) - } else { - print("edit member server roles : ", roles as Any) - if let datas = roles { - weakSelf?.serverRoles.append(contentsOf: datas) - weakSelf?.filterAllRoles() - } - } - } - } - - func getRoleModel(_ roles: [ServerRole]?, _ select: Bool?) -> [IdGroupModel] { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", roles.count:\(roles?.count ?? 0)") - var models = [IdGroupModel]() - roles?.forEach { role in - let model = IdGroupModel(role) - if let s = select { - model.isSelect = s - } - models.append(model) - } - return models - } - - func updateMyMember(_ serverId: UInt64?, _ nick: String?, - _ completion: @escaping (Error?, ServerMemeber) -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(serverId ?? 0)") - var param = UpdateMyMemberInfoParam() - param.serverId = serverId - param.nick = nick - repo.updateMyServerMember(param, completion) - } - - func updateMember(_ serverId: UInt64?, _ nick: String?, _ accid: String?, - _ completion: @escaping (Error?, ServerMemeber) -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(serverId ?? 0)") - var param = UpdateServerMemberInfoParam() - param.serverId = serverId - param.nick = nick - param.accid = accid - repo.updateServerMember(param, completion) - } - - func kickoutMember(_ serverId: UInt64?, _ accid: String?, - _ completion: @escaping (Error?) -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(serverId ?? 0)") - var param = KickServerMembersParam() - param.serverId = serverId - var accids = [String]() - if let acc = accid { - accids.append(acc) - param.accounts = accids - } - repo.kickoutServerMembers(param) { error in - completion(error) - } - } - - func addMembers(_ accid: String?, _ serverId: UInt64?, _ roleId: UInt64?, - _ completion: @escaping () -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", accid:\(accid ?? "nil")") - var param = AddServerRoleMemberParam() - param.serverId = serverId - param.roleId = roleId - var accids = [String]() - if let aid = accid { - accids.append(aid) - } - param.accountArray = accids - weak var weakSelf = self - - repo.addRoleMember(param) { error, successAccids, failedAccids in - print("add role member result : ", error as Any) - completion() - if let err = error { - weakSelf?.delegate?.dataDidError(err) - } else { - print("add members success accids : ", successAccids) - - if let rid = roleId, let model = weakSelf?.serverDic[rid] { - weakSelf?.userDic[rid] = model - } - weakSelf?.delegate?.dataDidChange() - } - } - } - - func remove(_ accid: String?, _ serverId: UInt64?, _ rid: UInt64?, - _ completion: @escaping () -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", accid:\(accid ?? "nil")") - var param = RemoveServerRoleMemberParam() - param.serverId = serverId - param.roleId = rid - weak var weakSelf = self - if let accid = accid { - param.accountArray = [accid] - repo.deleateRoleMember(param) { error, successAccids, failedAccids in - if let err = error { - weakSelf?.delegate?.dataDidError(err) - } else { - if let roleId = rid { - print("add role id : ", roleId) - weakSelf?.userDic.removeValue(forKey: roleId) - } - weakSelf?.delegate?.dataDidChange() - } - completion() - } - } else { - completion() - } - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/IdGroupSortViewModel.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/IdGroupSortViewModel.swift deleted file mode 100644 index 6e85e372..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/IdGroupSortViewModel.swift +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -import NEQChatKit -import NECoreIMKit -import AVFoundation - -@objcMembers -public class IdGroupSortViewModel: NSObject { - let repo = QChatRepo() - - var datas = NSMutableArray() - -// var lockData = [IdGroupModel]() - - weak var delegate: ViewModelDelegate? - - var isOwner = false - - private let className = "IdGroupSortViewModel" - - func getData(_ serverId: UInt64?) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(serverId ?? 0)") - var param = GetServerRoleParam() - param.limit = 200 - param.serverId = serverId - weak var weakSelf = self - - repo.getRoles(param) { error, roles, sets in - if let err = error { - weakSelf?.delegate?.dataDidError(err) - } else { - weakSelf?.filterData(roles, sets) - } - } - } - - func filterData(_ roles: [ServerRole]?, _ sets: Set?) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", roles.count:\(roles?.count ?? 0)") - weak var weakSelf = self - roles?.forEach { role in - if role.type == .everyone { - return - } - let model = IdGroupModel(role) - model.hasPermission = isOwner - if let rid = role.roleId, let s = sets, s.contains(NSNumber(value: rid)) == true { - isOwner = true - } - weakSelf?.datas.add(model) -// if model.hasPermission == true { -// weakSelf?.datas.add(model) -// }else { -// weakSelf?.lockData.append(model) -// } - } - weakSelf?.delegate?.dataDidChange() - } - - func removeRole(_ serverId: UInt64?, _ roleId: UInt64?, _ model: IdGroupModel, - _ completion: @escaping () -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(serverId ?? 0)") - var param = DeleteServerRoleParam() - param.serverId = serverId - param.roleId = roleId - weak var weakSelf = self - repo.deleteRoles(param) { error in - if let err = error { - weakSelf?.delegate?.dataDidError(err) - } else { - weakSelf?.datas.remove(model) - weakSelf?.delegate?.dataDidChange() - completion() - } - } - } - - func saveSort(_ serverId: UInt64?, _ completion: @escaping () -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(serverId ?? 0)") - var startIndex = 0 - - var startSort = false - var last: IdGroupModel? - var items = [UpdateServerRolePriorityItem]() - - var min: Int? - - datas.forEach { data in - - if let model = data as? IdGroupModel, model.hasPermission == true { - print("model p : ", model.role?.priority as Any) - if let m = min, let p = model.role?.priority { - if m > p { - min = p - } - } else { - min = model.role?.priority - } - } - } - - print("print min : ", min as Any) - - for index in 0 ..< datas.count { - if let m = datas[index] as? IdGroupModel, let r = m.role { - if startSort == false, m.hasPermission == true { - startSort = true - if let m = min { - startIndex = m - } - } - if startSort == false { - } else { - let item = UpdateServerRolePriorityItem(r, startIndex) - items.append(item) - startIndex += 1 - print("item priority : ", startIndex) - } - last = m - print("item name : ", m.idName as Any) - } - } - - var param = UpdateServerRolePrioritiesParam() - param.updateItems = items - param.serverId = serverId - weak var weakSelf = self - - if items.count <= 1 { - completion() - return - } - - repo.updateServerRolePriorities(param) { error in - if let err = error { - weakSelf?.delegate?.dataDidError(err) - } else { - completion() - } - } - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/IdGroupViewModel.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/IdGroupViewModel.swift deleted file mode 100644 index 6f8715fa..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/IdGroupViewModel.swift +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -import NEQChatKit -import NECoreIMKit - -typealias IdGroupViewModelBlock = () -> Void - -@objcMembers -public class IdGroupViewModel: NSObject { - let repo = QChatRepo() - var topDatas = [IdGroupModel]() - var datas = [IdGroupModel]() - var sortBtnCellDatas = [IdGroupModel]() // only one - weak var delegate: ViewModelDelegate? - - var limitCount = 20 - - private let className = "IdGroupViewModelBlock" - - override init() {} - - func getRoles(_ serverId: UInt64?, _ refresh: Bool = false, _ block: IdGroupViewModelBlock?) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(serverId ?? 0)") - var param = GetServerRoleParam() - param.serverId = serverId - param.limit = limitCount - if let last = datas.last, let pri = last.role?.priority, refresh == false { - param.priority = pri - } - weak var weakSelf = self - print("param : ", param) - - repo.getRoles(param) { error, roles, sets in - if let err = error { - weakSelf?.delegate?.dataDidError(err) - } else if let rs = roles { - print("get roles success : ", rs.count) - weakSelf?.parseData(rs, refresh) - } - if let completion = block { - completion() - } - } - } - - func parseData(_ roles: [ServerRole], _ refresh: Bool) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", roles.count:\(roles.count)") - var models = [IdGroupModel]() - roles.forEach { role in - print("get data proprity : ", role.priority as Any) - let model = IdGroupModel(role) - models.append(model) - } - filterData(models, refresh) - if roles.count < limitCount { - delegate?.dataNoMore?() - } - } - - func filterData(_ models: [IdGroupModel], _ refresh: Bool) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", models.count:\(models.count)") - if refresh == true { - topDatas.removeAll() - datas.removeAll() - sortBtnCellDatas.removeAll() - } - - if let first = models.first { - topDatas.append(first) - } - if models.count >= 2 { - datas.append(contentsOf: models.suffix(models.count - 1)) - } - - if datas.count > 0 { - if let first = sortBtnCellDatas.first { - first.idName = "身份组(\(datas.count))" - } else { - let data = IdGroupModel() - data.idName = "身份组(\(datas.count))" - sortBtnCellDatas.append(data) - } - } - delegate?.dataDidChange() - } - - func addRole(_ role: ServerRole) { - var models = [IdGroupModel]() - models.append(contentsOf: topDatas) - models.append(contentsOf: datas) - models.append(IdGroupModel(role)) - topDatas.removeAll() - datas.removeAll() - filterData(models, false) - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/MemberManagerViewModel.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/MemberManagerViewModel.swift deleted file mode 100644 index df6ffcb0..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/MemberManagerViewModel.swift +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -import NECoreIMKit -import NEQChatKit -import CoreMedia - -@objcMembers -public class MemberManagerViewModel: NSObject { - var datas = [UserInfo]() - - var delegate: ViewModelDelegate? - - let repo = QChatRepo() - - let limit = 20 - - private let className = "MemberManagerViewModel" - - override init() {} - - func getData(_ sid: UInt64?, _ rid: UInt64?, _ refresh: Bool = false) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", sid:\(sid ?? 0)") - var param = GetServerRoleMembersParam() - param.limit = limit - param.serverId = sid - param.roleId = rid - if let last = datas.last, let accid = last.accid, let createTime = last.createTime, - refresh == false { - param.accid = accid - param.timeTag = createTime - print("load more : ", param) - } else { - param.accid = "" - param.timeTag = 0 - print("first refresh : ", param) - } - weak var weakSelf = self - repo.getServerRoleMembers(param) { error, members in - if let err = error { - weakSelf?.delegate?.dataDidError(err) - } else { - if refresh == true { - weakSelf?.datas.removeAll() - } - members.forEach { member in - let user = UserInfo(member) - weakSelf?.datas.append(user) - } - weakSelf?.delegate?.dataDidChange() - if let count = weakSelf?.limit, members.count < count { - weakSelf?.delegate?.dataNoMore?() - } - } - } - } - - func addMembers(_ users: [UserInfo], _ serverId: UInt64?, _ roleId: UInt64?, - _ completion: @escaping (Int) -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", users.count:\(users.count)") - var param = AddServerRoleMemberParam() - param.serverId = serverId - param.roleId = roleId - var accids = [String]() - users.forEach { user in - if let accid = user.serverMember?.accid { - accids.append(accid) - } - } - param.accountArray = accids - weak var weakSelf = self - - repo.addRoleMember(param) { error, successAccids, failedAccids in - print("add role member result : ", error as Any) - if let err = error { - weakSelf?.delegate?.dataDidError(err) - } else { - weakSelf?.getData(serverId, roleId, true) - -// print("add members success accids : ", successAccids) -// var dic = [String: UserInfo]() -// users.forEach { user in -// print("for each role member : ", user.serverMember as Any) -// if let accid = user.serverMember?.accid { -// dic[accid] = user -// } -// } -// successAccids.forEach { accid in -// if let user = dic[accid] { -// print("add data user ", user) -// weakSelf?.datas.append(user) -// } -// } -// weakSelf?.delegate?.dataDidChange() - completion(successAccids.count) - } - } - } - - func remove(_ user: UserInfo, _ serverId: UInt64?, _ rid: UInt64?, - _ completion: @escaping () -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(user.serverId ?? 0)") - var param = RemoveServerRoleMemberParam() - param.serverId = serverId - param.roleId = rid - weak var weakSelf = self - if let accid = user.accid { - param.accountArray = [accid] - repo.deleateRoleMember(param) { error, successAccids, failedAccids in - if let err = error { - weakSelf?.delegate?.dataDidError(err) - } else { - completion() - } - } - } else {} - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/MemberSelectViewModel.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/MemberSelectViewModel.swift deleted file mode 100644 index 35667f5c..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/MemberSelectViewModel.swift +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -import NEQChatKit -import NECoreIMKit - -@objc -public protocol MemberSelectViewModelDelegate: NSObjectProtocol { - func filterMembers(accid: [String]?, _ filterMembers: @escaping ([String]?) -> Void) -} - -@objcMembers -public class MemberSelectViewModel: NSObject { - let repo = QChatRepo() - - var datas = [UserInfo]() - - weak var delegate: MemberSelectViewModelDelegate? - - var lastTimeTag: TimeInterval = 0 - - let pageSize = 50 - - private let className = "MemberSelectViewModel" - - override init() {} - - func loadFirst(serverId: UInt64?, completion: @escaping (NSError?, [UserInfo]?) -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(serverId ?? 0)") - lastTimeTag = 0 - datas.removeAll() - print("self?.datas:\(datas.count)") - getServerMebers(serverId) { [weak self] error, userInfos in - NELog.infoLog( - ModuleName + " " + (self?.className ?? "MemberSelectViewModel"), - desc: "CALLBACK getServerMebers " + (error?.localizedDescription ?? "no error") - ) - if error != nil { - completion(error as NSError?, userInfos) - } else { - if let userArray = userInfos, !userArray.isEmpty { -// 判断有没设置delegate - if let del = self?.delegate { - self?.lastTimeTag = userArray.last?.serverMember?.createTime ?? 0 - var accids = [String]() - for user in userArray { - if let accid = user.serverMember?.accid { - accids.append(accid) - } - } - del.filterMembers(accid: accids) { filterAccids in - if let filterIds = filterAccids { - var tmp = [UserInfo]() - for user in userArray { - if filterIds.contains(user.serverMember?.accid ?? "") { - } else { - tmp.append(user) - self?.datas.append(user) - } - } - completion(error as NSError?, tmp) - } else { - self?.datas = userArray - completion(error as NSError?, userArray) - } - } - } else { - // 未设置 - self?.datas = userArray - completion(error as NSError?, userArray) - } - - } else { - // 结果为空 - completion(error as NSError?, userInfos) - } - } - } - } - - func loadMore(serverId: UInt64?, completion: @escaping (NSError?, [UserInfo]?) -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(serverId ?? 0)") - getServerMebers(serverId) { [weak self] error, userInfos in - NELog.infoLog( - ModuleName + " " + (self?.className ?? "MemberSelectViewModel"), - desc: "CALLBACK getServerMebers " + (error?.localizedDescription ?? "no error") - ) - if error != nil { - completion(error as NSError?, userInfos) - } else { - if var userArray = userInfos, userArray.count > 0 { - if let del = self?.delegate { - self?.lastTimeTag = userArray.last?.serverMember?.createTime ?? 0 - var accids = [String]() - for user in userArray { - if let accid = user.serverMember?.accid { - accids.append(accid) - } - } - - del.filterMembers(accid: accids) { filterAccids in - var tmp = [UserInfo]() - for user in userArray { - if accids.contains(user.serverMember?.accid ?? "") { - } else { - tmp.append(user) - self?.datas.append(user) - } - } - completion(error as NSError?, tmp) - } - } else { - for u in userArray { - self?.datas.append(u) - } - completion(error as NSError?, userArray) - } - - } else { - // 结果为空 - completion(error as NSError?, userInfos) - } - } - } - } - - func getServerMebers(_ serverId: UInt64?, - completion: @escaping (NSError?, [UserInfo]?) -> Void) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(serverId ?? 0)") - var param = GetServerMembersByPageParam() - param.serverId = serverId - param.timeTag = lastTimeTag - param.limit = pageSize - repo.getServerMembers(param) { error, members in - var memberArray = [UserInfo]() - members.forEach { member in - memberArray.append(UserInfo(member)) - } - completion(error as NSError?, memberArray) - } - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/PermissionViewModel.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/PermissionViewModel.swift deleted file mode 100644 index cae71969..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/PermissionViewModel.swift +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -import NEQChatKit -import UIKit -import NECoreIMKit - -@objcMembers -public class PermissionViewModel: NSObject { - let permission = PermissionModel() - - var commons = [PermissionCellModel]() - - var messages = [PermissionCellModel]() - - var members = [PermissionCellModel]() - - let repo = QChatRepo() - - var delegate: ViewModelDelegate? - - var hasPermissionKey = [String: String]() - - private let className = "PermissionViewModel" - - override init() {} - - func getData(_ serverRole: ServerRole) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", serverId:\(serverRole.serverId ?? 0)") - weak var weakSelf = self -// print("get data authors : ", serverRole.auths as Any) - serverRole.auths?.forEach { info in - if info.status == .Allow { - if let key = info.permissionType?.rawValue { - weakSelf?.hasPermissionKey[key] = key - } - } - } - loadData(permission.commonPermission, permission.commonPermissionDic, &commons) - loadData(permission.messagePermission, permission.messagePermissionDic, &messages) - loadData(permission.memberPermission, permission.memberPermissionDic, &members) - -// delegate?.dataDidChange() - } - - func loadData(_ keys: [String], _ keyValues: [String: String], - _ datas: inout [PermissionCellModel]) { - NELog.infoLog(ModuleName + " " + className, desc: #function + ", keys.count:\(keys.count)") - for index in 0 ..< keys.count { - let model = PermissionCellModel() - model.permission = permission - let key = keys[index] - let name = keyValues[key] - model.showName = name - model.permissionKey = key - if let value = permission.value(forKey: key) as? String { - if hasPermissionKey[value] != nil { - model.hasPermission = true - } - } - datas.append(model) - if index == 0 { - model.cornerType = CornerType.topLeft.union(CornerType.topRight) - } - if index == keys.count - 1 { - model.cornerType = model.cornerType.union(.bottomLeft).union(.bottomRight) - } - } - } -} diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/SettingViewModel.swift b/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/SettingViewModel.swift deleted file mode 100644 index 62e919a3..00000000 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Server/ViewModel/SettingViewModel.swift +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be -// found in the LICENSE file. - -import Foundation -import NEQChatKit - -@objcMembers -public class SettingViewModel: NSObject { - let repo = QChatRepo() - var permissions = [SettingModel]() - override init() { - super.init() - NELog.infoLog(ModuleName + " " + className(), desc: #function) - let member = SettingModel() - member.title = localizable("qchat_member") - member.cornerType = CornerType.topLeft.union(CornerType.topRight) - permissions.append(member) - let idGroup = SettingModel() - idGroup.title = localizable("qchat_id_group") - idGroup.cornerType = CornerType.bottomLeft.union(CornerType.bottomRight) - permissions.append(idGroup) - } -} diff --git a/NEQChatUIKit/NEQChatUIKit.podspec b/NERtcCallUIKit/NERtcCallUIKit.podspec similarity index 54% rename from NEQChatUIKit/NEQChatUIKit.podspec rename to NERtcCallUIKit/NERtcCallUIKit.podspec index 8d6d7fd2..419b1958 100644 --- a/NEQChatUIKit/NEQChatUIKit.podspec +++ b/NERtcCallUIKit/NERtcCallUIKit.podspec @@ -1,5 +1,5 @@ # -# Be sure to run `pod lib lint NEQChatUIKit.podspec' to ensure this is a +# Be sure to run `pod lib lint NERtcCallUIKit.podspec' to ensure this is a # valid spec before submitting. # # Any lines starting with a # are optional, but their use is encouraged @@ -7,8 +7,8 @@ # Pod::Spec.new do |s| - s.name = 'NEQChatUIKit' - s.version = '9.3.0' + s.name = 'NERtcCallUIKit' + s.version = '1.8.2' s.summary = 'Netease XKit' # This description is used to generate tags and improve search results. @@ -20,30 +20,25 @@ Pod::Spec.new do |s| s.description = <<-DESC TODO: Add long description of the pod here. DESC + s.homepage = 'http://netease.im' - s.license = { :'type' => 'Copyright', :'text' => ' Copyright 2022 Netease '} - s.author = 'yunxin engineering department' + # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' + s.license = { :'type' => 'Copyright', :'text' => ' Copyright 2022 Netease ' } + s.author = "yunxin engineering department" s.source = { :git => 'ssh://git@g.hz.netease.com:22222/yunxin-app/xkit-ios.git', :tag => s.version.to_s } - s.pod_target_xcconfig = { - 'BUILD_LIBRARY_FOR_DISTRIBUTION' => 'YES' - } - s.user_target_xcconfig = { 'BUILD_LIBRARY_FOR_DISTRIBUTION' => 'YES' } - + # s.social_media_url = 'https://twitter.com/' + s.ios.deployment_target = '9.0' - s.swift_version = '5.0' - s.source_files = 'NEQChatUIKit/Classes/**/*' + s.source_files = 'NERtcCallUIKit/Classes/**/*' + s.resource = 'NERtcCallUIKit/Assets/**/*' -# s.resource_bundles = { -# 'NEQChatUIKit' => ['NEQChatUIKit/Assets/*.png'] -# } - s.resource = 'NEQChatUIKit/Assets/**/*' - s.dependency 'NECommonUIKit' - s.dependency 'NEQChatKit' - s.dependency 'SDWebImageWebPCoder' - s.dependency 'SDWebImageSVGKitPlugin' - s.dependency 'MJRefresh' - s.dependency 'NIMSDK_LITE' - s.dependency 'YXAlog_iOS' + s.dependency 'NERtcCallKit' + s.dependency 'NERtcSDK' + s.dependency 'AFNetworking' + s.dependency 'SDWebImage' + s.dependency 'Toast' + s.dependency 'NECoreKit' + s.dependency 'NECommonKit' end diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/.gitkeep b/NERtcCallUIKit/NERtcCallUIKit/Assets/.gitkeep similarity index 100% rename from NEQChatUIKit/NEQChatUIKit/Assets/.gitkeep rename to NERtcCallUIKit/NERtcCallUIKit/Assets/.gitkeep diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/Contents.json b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/Contents.json similarity index 100% rename from NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/Contents.json rename to NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/Contents.json diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/delete.imageset/Contents.json b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/avator.imageset/Contents.json similarity index 79% rename from NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/delete.imageset/Contents.json rename to NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/avator.imageset/Contents.json index 5c4d3b18..5ab63d7f 100644 --- a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Commom/delete.imageset/Contents.json +++ b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/avator.imageset/Contents.json @@ -5,12 +5,12 @@ "scale" : "1x" }, { - "filename" : "Frame@2x.png", + "filename" : "avatar@2x.png", "idiom" : "universal", "scale" : "2x" }, { - "filename" : "Frame@3x.png", + "filename" : "avatar@3x.png", "idiom" : "universal", "scale" : "3x" } diff --git a/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/avator.imageset/avatar@2x.png b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/avator.imageset/avatar@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..e685ba2a7af8fb6d33ccba8f874beeb0608043d3 GIT binary patch literal 2295 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 RlWzb3002ovPDHLkV1fzdKwtm> literal 0 HcmV?d00001 diff --git a/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/avator.imageset/avatar@3x.png b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/avator.imageset/avatar@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..5bd90639aee9e15e96009b8ac1ea5afc8e849061 GIT binary patch literal 3542 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 QApigX07*qoM6N<$fzND5zUJ3=P&b zp1ElRR}``3R#@alBPi`x&=vD0D@b2NVQCn*TapkuR_a}u#A{0B_$@b6#F}c zunbZ+A4^TBxr^0>CFBI_g%yYiQXE8fTq!Pf^RaXj>V)l1W~H#owTbdJln!dB3G)^z z$R#E>gPd8Z{(cS?VwJE+P+K7nn-_fq_PbM9>hMD4aT6-*ummfFMTvMxi)jcq+!dKw zTLhMAVX>e(l6iq;Qdk8Id66+?i)rPJChN!;nG@Dn?Ww~WdKxUKu++_MoX%R3pBZ7f zVGrW<{EqU{MlUy^4`ju?Br?FR+T<}a-ExLS)enNEtj^Ql5*c8qj>RsO8g-N0SBL3d zLvt+3rP!rX!=b~FNCK}a+1_sDLh2@97dCCXC z43dF|#({;xQLi7W#-bVu6dG%E4=^AGBCOHcQ>JoG`II%SEP2Gi0Q0WYh2;%@^(>f7 zASGTKL`kBA6rnd@lDKIwnSwfMzcBS6KAHR1X{1DI!eUWno3zE1im+Hzc95pH5*HSW z$}Z9pSE9mVQQ1iv;!3PQ>bJYhfUy@TrdIYQ(|(hPu)M;XTc={IN9|cjV1-cMbu5~u zF;6oOCMU>w@1FMgEa(H8Q1+&2xT2mT-1%I(x9EeugynZBIAC&y829gOY+?(Gl67$F zOP)E>&%9!+7K5R#csuP z!noG`-CV1yW3gK?o#^FS9UY6^is^+JA@1ljLhR^R>{d)Kx{VM!he9Ftf?>KKBo23K z2pnnmO|QysXWiNo04~1SKPey=*xI`+x;DX{;CnztM%W4Nge@J zy|Cecsm(c-7S^>JzhGRco2Y_orXM&2CV4a+lC^=&!m=!BzxR%NjA*_e>e}bWz8m^l zCIWKv$sy~6MMt#3vZVc}aiS=YbCJN9L@AGX+F4_ruuSc03Kl_b^^6$-MukG+!`mD% z$+0mUt`CKlg~7)+i~yrRBgpL|TfroR6#LhG89eYeK6PLbPu}$y;xZN?H)BHKv@XrR z?N~}yU>Q&J;aCLaTKzr;a~q-LS~y%2mMPC$6$YswN+12gC5Yq@LRW&vYr@h%1s0Kn zs0gZm@hCAFL`#nD3d_&0tXkQ8?;Up|DX0X&iF_iI@AeNV@El7?>y~w0UHw0jg50lH z<(>)07GFz#DAd*o>&ohNBnj2Tm;{hsIP`=iu^X0gHDO`>rEv~S|7fUI$FgsQGYRX$ zjgOE7)cKIqa}^x{;m~JkW8xk_jePw=g5q|XL@86DR5mT%=j!bQ!q@kfGjW7+u8^gX z-Lhoih%lgEVQ~md2XRa7klJF$I(O}S>?EE<$ssTujHVo^g?3;uZ^YzV zgOK7rDFyC>#k}?LUlEm8I0UAO)+Q9faww!l4To=Y%_?1tSs7so2bS~e3x5oKZIbmb zrah*XRkq%-h_^oeTj*<(>WW~xL&9=kIW#(ayYY|E*K>1U>NvS@EP`rMVR@qb2$*!q zjj$*o59?abk9~*xuTmyA!Xm=D7UfyIkRn}jC9G(!#S1CYBv-;BqU2hyeeK5_5>ukI zed@s}97;j!ES(Kyr3d6WK-)a$SLGnVdn)&RKFWP z&f-c0X&g(7I&w2}pA9A$B50GO>AYn@o z0VG6n7%I4as%{|)wD^?-_3W;1yXA}kdJR;RrOo257~%difmKFXL<;ru($+&?y&+-W zhPF|mS{2>YC@Y?6**!T8Ei)tM3j?{-uO2#z2eyuOyoLn!q#qjTxszUeJ8W)3pK!P1 z9<5DYMvjW4ouC`~r$=9omFrM%eYaITB-mF?B|qvk5k23r|GXZn#X6%jR;nj=l<1ME zzEddNiJU_rjhX_zTqjz?U$ET~iIN9d<-nV5LdbE&$pHV9nbL8|m37#DIcswoXK_p+%PzcEK&CoCa#;ltrZDEE5& zogWQcVC0r|2}{kb|9S&OnKz6J9b`^ZIBB*r)0P30>)A3nO=0lE>dAEp;pW8@O3#7m z2szlkcVAq~!IHlDv~!M4q9WRrsx~p1x#c}T+}g2p^_@-orFe?OlJvze}LMfBXp$ak&W?MTDKrK9Q@@jQfWS)iem-HZg8AdIn4mP?Ha5EYTw>0jmr z%?chVS_|E~evd9#&NaDgGSX}myhN%4KO$QcN_DM@r z{&S}Xiz~aNDJuW@(}l&AIkdUyFQq9eB6VRAqqRxe>iab?!$zAjz;ho|PtGD`1|lqi zil`cL-u#0On1N%W#(4oXnN*#s7XuR(v9mVeNXQzCYtZO3X6kJ+Zl^*V5-X5~f!^2_ zGiAVC5d*^*m7XyZ%HJHMsEC0&Rx5tqMM*txm6Q&&m+VVPR@0*}G+_}O8dHH>YRQDY z=LYRktqfII0bG(ujG?+zE13`$LGD$8m^UwJ986R);Zm(+MpywR_nIR2;_w)n%(zr5 znG+U4?ll5A#o@6lm(9)l#Wkpze!D%>Ad|uhaKob((-7hym;m$t8)lnOFJ&d{wIkEQ z3Sfb`SRtqYD})sg2uusHw;(wfiK&t0kk<*Tgw+Zq`R4C_IH#jXca$fjT)d{5b2bSo zz*=DixGRLTIFbVwbKQv!$r4g8UZ^fC!D6fzRx9oSQ(8<}A~Nm&r*7s>7xN&dR&ph* zR>;YOEbTQ8P%$^J0&h-|ZsxGwv-UqX+!Gz7I6b18i**YU@i^pGSR3&d)s7pX?S{l| zKR0Wg08i>~p<5oC+(_4;P)2x?K72(YO^VZdM^mwn$n&zYHJcD~P? zk2xRzp9M2J4C`g){O5VU&U+L=B&;qKvV6n8bXFV6Dzc-b)e0gjkCP>ptv^>e&+DjS z`B(LMwp{xgWis|Ee~*gM#E+TsJU{1BzBorPbc!G}qou;=9UPzx>4}W76IQGH`QeEk zp$eFlAXdoGdrIrGw`l&on?!S!e6d0h3WP8~t4f85Pf=!*B@P@>Zn$A{%g%A-ENfD; z63mPF;w(WR5JDeulQO4CZ{lWPj$hgderS}Eqv8b9sG~-kS%lI*2%!hkyj(_^=M9IB zU&tIKD|Ed`-*Z-xD$djVQ4VF9U?2#gOZDJcG6jD5as)MYmIsw)5J>kB!ag8)ZXu9v zAcS2=A1^~{7lP->j3IO6gM6__&=x}2M5^AMq+j9}=4DD(A1`QSLu#+3`6H-~iy?$H zPSvw&8!7cPA$&pOrmC4n7^_krLNqyt$hOpZ7)cYw`XDvVviR~{YDumMX5LTO?x?_2oXRS zvPcARXdy%ZAtHtz#G!-`0fdMdY7j$TwkBsnSh9NwAbKomwf(}Ta8D2pHH6irL(Wn( zfT*&H%oFEBygo)~A*?ONmH=WY8bsZdc`_TqTJ#;tvbBb@ArL@_gO#$Qo18{RAqXXe z8RvXJoDBi7vi2@ghbRPrhp@U}Rz>zS5`fNBeylXPn*tVSpAaLVkO0;g+WEnghXOl} z0}CMrVjw{R9jFPUIVv4m48%Z!1UgU?NC;~i^JWPkIe4H(zd`}Ct?fnFh zJl2qz{2*T}l8<~1A$CWD6!5)&=xcK{W7QNPfRJq5KUA-ik9-TE(+pKAG1rU(=uGAO z+_}w{<|vw>kV3vSOMR(?Xof-xt<<3SoV&;oDQA#|oBaOrA*HdJoBRLGG_?kgdtBmg=Ys2aKoVYLckN&=uW z_tnr{B}5ej=*4w4>^p?3tLe@X0QBIl8ulGR9uY+q1n7^eYS`C2A?5`ETQ$k`g&roC!h)f4D8AcG7nVp#Y(p)jZhC6qYL3&u_Aspj;^D1%ho#gPhLMu zKdqc3fCek&42w#S3*z<+AqVg!f<+{JJG0L^w~fx<{E*(fILp6E&V2x->08tzgk77X zYksu3U^4bF!GfLHtxf>DkpS*Gv!C9+{4;{o>p4KvwV`RWDG)5^CxBvn>8I)Y>%Y_2 zb0P71PFHlSgcy)nY|H9A?Rn@g$*u35{|}lvgOg5D&hh}wJ)H(-2|h zLnuvAoHJM@RZv3Yl~hFZ5z|cNI_=8VHiT%3-nL`FW@tMyu=CWtj}fF(rzUCp<|vw? z4!^2kBN^QB(zJ!x>ewW02_c%Iw>{o88SjVXBX{xi#orL5QTrxoO9;^vy>09290fs^ zx?!Luo!T`?TSBNbJx$=KuL})=4Ag84pwdF5DW&YD<_B9sXo+$JPC%sT7$j7~^x+hC z4`FQ!3r`ofNQxkJzF70>|=^J1H#E|HL3onk>%QLI}|x94_t8H{&|-J(p$mFm5~9TB z>i3)wW~=Mj&>U@W{^lhL8+L0;m27<-sT0DR2w;n=w{B3FuJQj5AxxJ$YOPNvgcy`* zCHshm>3iq@6Wb)F%#vE}YJEbRC0OLt^&u|RYP->Ly1ZHHo|C&gLZ_zENhR^^Z9DvtqIQ`&u z^bKJFLO1|F`i6TR`YQqu2;qRd_YEJzj@#gn5S9sClWOR7O{rWG4c8`2y$UL!2UBPE zds%SA)CAuM6w6PT4e(wn-TO+>aaT|N-AHFp)O)D^em@>MowWSJyXM4DBc;b4QypWO7 zHz!_25Yxn%tDHfF5c=esC%)_Xl4^3g6M~o?oWHADVV=-8=Wc%JR79`pK|~)h@vP)8 zbJzCIjcQWc2z>GGwf}MYcN>;}mc01%l9lw8dmnSIhY{u$iSo05-T-x8L?f( zKgTJL&1~pQDYH+>UicZ(;a(9l;p9M;O19pI?JQ(-C|MK`#!hXrj7}DpH?QJ3SKF`{ z+co;menMu0l6zyNNlW0XHO?T*6yN?f`9VUkheu$8c%$S)V~WGq>xAQTH~){e%uQj} zIRDrS`9r!sPgo}Kl~j)xPyC~Ap^*vwAo_{YufKS$~rI`YxM({DQ=T>ktct2vehfXUB_a2oXNj2NLI_HG((kEBB`Fn#@!*k^RijigX7r*li2XIFqd!NepmuU^2cy|7s z&>yYLcds2dU3T8DY^gB%|D>-F1WpDuo(*uLCt1gO{^lj;RzfQMNNIlhRrz|6vr49U zN(IC1J=q&%?y2O9m4y#Yo~Dqw!Yo1Hf)3)ao!}3EXXjp_tGMBXQG!r>`}9A1KIk zw*JNKlX|t8B?y%SvD$x1W)vleQxCpC&?=+Nd-eN`18LGPl))KXASPsfFL8?!`FN2J z8b7Y@m>^d!!I>eE zAb#b)|GL&sOjh$$<`HG>D^xY-Y*7d``h`O${lu+vyPPu?l0;V3V35XPIcJMPm}&e% zX7878d-!F(yOdyPWU~E-mw!%o^8~xBa8VS0pVCX{mmj}RC$ZqWav^{C&l(?S+47Lz z@L7VPljf<+C+_55NvMkQK{B><6{VeRGaug)LTd>9!U&PG*=5k?4Ze+kUorKI*{sUw z!_5!2gzye+W(XpsUKPK1?9ZJM)Hoi>@&R(Ja*EP!-pv1``LUJ|mh;65zhtunky9T* ztv6BQ6h`^kf13I;EbQ#Xe6ig8X!~vOjXFXQS<*z^$W<{eVU#NP%@hAXDQ9{5VW!<5 zv<)Ger121kFiHSrlPZjgwr`4xj-%gWrDsa~$2o%7*s?lLe?0zGp4P}ZC;1LrJ%D~} zh#Y^m#8VSbwEL5hj(EAET5_E2g zijMCO&bE)g`le7@R&Sz>&i*#R2U4ov+n0alTrLj#lP<9HWFBZYC?mSQCuou;hn%VL z_~^Po0%>c%%jl;xJuwQ}V*iEwp^oQtjdb~o{3h9Hix4J)Oc9*B_@UEWl?o~Q&U~4x zr1T%xEo|4{Uoh*TlWh)Vz(p$GTioo#wufz5o6*H?Pw4rY;~c}}Tkfn;%{qO_@ujQi zk!APS9$&VwMTLY|Hv5&^^EWTksq1H*03vwZ@dwt~_w$Dy==PkhmC*SnhW05%#H;;0v9A!G&lhL0s2jkI_KUUK=_`anrYi^l`e8XQeN{o>YQ7ee_W-^1 zGcD1m?@B084FP(xN~CJ;Lx6TVpEKBv z>q;n44FOv4yr3QE>Nf+0Q05J}gdQdUsGI3`Ua;9fAr!aB>?Euy1rU9&j%jD$5K8Lh z3=0BCH=dZM=|QWY7&wGN&ajXnSprBYKK{$+^M^c*k$4KBoMEBK;8LuRRs&5*H1iZf zQCr+yB7k&}T|QdLyqSg0iC!INC;&T-;j}0I?z9aB)G!I z^OF_lD%SoBB!mLf7LX7!8anNFKd@0?Arw4}yBGaKh%skzHXp}HV2=Qd! zy^ufr1qxW8m9Xv(vXdC7fjE)lmFK-TQwT!4lJe?OA)6unF5g{A0MYhqo{;}Sko~|$ zp;SU4{~$$XlIqu(1c)X+KFyP11yF<*LQy^K2`g$KvZO%lxR5W-QHVkfq2PbujEp!D zK(vH16538^eZpqrrO7G&*ufQmAqt!TdfldCP(ur$KoB7Uh8jRI)DQ{;5r$~!0Te?I zp+FE}2qFdt8S!#gMj zVs${*25cmV=qExaSGak%BZ>nsoy4xHpq~gGSUDR$>ixfVBHbr!M_%A1WH!_`kirSV zAe`oB9QuFl#JYdQ&C_ktPefHrHQ5t%`v>{r5sInU4{|tr*I2cSlzN^pXp<&V{buDN zL~*QsjS_RvqAI3}?Cd_2v*3e}sLFw=n0T`Gvv`Zl&bU{bpf#yo!mYqZ%eT-}^^Ft0q)#;r3I|vhYf6QJvFd45 z$AQ$&a6yx^7aUZ5s8z=tA5hQL`i=sxU8~!{)4F)w%pXM6>kS8zO9*5O1kWRc(1Us) z`9=I1ABj1BXq3|Nn%4Vxv!vB5g69oF=p&i#For{^?U(qaouFzcMVw#f`tAiBGCQY8 z9VIeH(Z}--LKq+kCF#tgWb7tOHd_m3T@+t?+i<5Wl}>3jXU+Ui!oGxbnjnNB8Z8w@ zmk~`!FzqdqB~6c#Q!N*TQv~_G*rqSanuvpDf5lBp4w`xI20w=8Wq1(6h>&gn`OO%$ zq_fsgmWTCMa41%gQ$Zyx%DGk5Chlmb?<1kA-{^NI8z?s=amzF cc0yeI29Qn#1ViEM?*IS*07*qoM6N<$f})`2wg3PC literal 0 HcmV?d00001 diff --git a/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_camera_off.imageset/Contents.json b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_camera_off.imageset/Contents.json new file mode 100644 index 00000000..fdc2dc0c --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_camera_off.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "yx-tv-video-off-white@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "yx-tv-video-off-white@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_camera_off.imageset/yx-tv-video-off-white@2x.png b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_camera_off.imageset/yx-tv-video-off-white@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d91357f9482f21f6c46fca37e9a4b70a466bef06 GIT binary patch literal 611 zcmV-p0-XJcP)+lL^D9+4^MbWGI?Qx)u0)mrM_^v z*4kzvp~?fEELI?=>Pmo0IAO1F^+tZU^4Mn@fih2eNUXV9lOM41J0AZ+15h%d1rP8m z#~~!}?5}bTHu%{qt`OcoS~hSlp+P(d-pH0LdxGyfaCIO*;MptNP4ZFy!G|dLxL;xu zXL1r+qVxO5h>VJ;t_=`UV$s%6MhP`Y>e_h>D^Wq>J*US#c}F)~i$X%;eMA58-imIy z9#q1Jck36a?q~}sk&|UpmuO3SD2dGVMwl=6JS zavteY4!}s-^0fz=DP`+?VQDjKNo_&@xY(xBY$bgQlAL+(XgfveOij|xXUfU<{X$LN;+bC0A^jrxae)lmw~juI!7Z|P)C~WatjQ5s2X3i(CV*#J zmhy0@TxTF@Ne;-LS6ecSc#NR-gQYI%VaPHBZMkgtbYp8%8tRgl)TdD^C!f38m6rM( zrkfSXn?KZJN|qhhvXs=yn_eTWym37nNs>2MvTTOjcS{gRUXtVurqqfC(nkn}}%tDfnAdtNzUqK*i zNg)J*Y$b&f1hSMAQV_^aQfNUSD@kJr0@+9!OAyFH(wKrk@{-0D1d^5%Ll8(-QY=9r zNl7sUf!LCcPkolB93s(vOYw-`jv?YsiYGMP=IB>$BPY z7V`gmY>}z)+1IZ_t;u7j=t#Iqs;QAgKA2ubSWxp?6ihnriU`by1nLDnB)yvUe-Gi; zb%k^|wM;UCOkznmwMoJc+e^@t)bVA7c6$n?1nwra-@AOg>MNt$* dQ4~cPiT@XNWRXzyliL6Q002ovPDHLkV1lZDa6kY6 literal 0 HcmV?d00001 diff --git a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/add.imageset/Contents.json b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_camera_on.imageset/Contents.json similarity index 78% rename from NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/add.imageset/Contents.json rename to NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_camera_on.imageset/Contents.json index 53a2c560..211a7bbc 100644 --- a/NEQChatUIKit/NEQChatUIKit/Assets/NEKitQChatUI.xcassets/Chat/add.imageset/Contents.json +++ b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_camera_on.imageset/Contents.json @@ -5,12 +5,12 @@ "scale" : "1x" }, { - "filename" : "Frame@2x-4.png", + "filename" : "shooting@2x.png", "idiom" : "universal", "scale" : "2x" }, { - "filename" : "Frame@3x-4.png", + "filename" : "shooting@3x.png", "idiom" : "universal", "scale" : "3x" } diff --git a/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_camera_on.imageset/shooting@2x.png b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_camera_on.imageset/shooting@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..010147adbf852f758c90cc8060e6c79225e69453 GIT binary patch literal 423 zcmV;Y0a*TtP)IhDtPM{;`1UiBn=mxrhIDy^3Zg9S%SCDf3N2N(2KX_ifi;_o^ zLPMk|ilQhZ#{7P<*2Y*88jjQ$^Ps-C#G$+8;SJ5H5B^U$`9QM{`R<@6ltk_Wdol6i zlHWH4Ig`){muJY`wPZs4$rsd?k=!LNIZ_;*6x_vxr*M*+9JN4t-xN zDU`1t5^?hJuaS+|d^U9PzgriZ+@r;WI%54e(gZg9%_+O_pW&{eD2k$tl`pEUW2A(- Rhid=;002ovPDHLkV1j9(vFHE* literal 0 HcmV?d00001 diff --git a/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_camera_on.imageset/shooting@3x.png b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_camera_on.imageset/shooting@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..cdd7488e2651cfc46ea565fca257028b039975c5 GIT binary patch literal 609 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@ZgvM!oCO|{#S9FJ79h;%I?XTvD9BhG zC*n0xtY>O7o<}^6K(+s@4|@XT*F{fTA#G{)XX47&+t@7y=45wxnctV# zX~46DvBu6-_s`A}HPwyx&8Hb$k#n`Xv-8Q{@Y?T>Zu~WSDsbhO{e(t70bcdH_m(Sb zOe|3O$F1+$@9O*UQ|5I;bs;(4j9l3#pVa;+9b3`8w7q73q(`Ub&D{-VzkFA&lz1ef z{iJ&Gx7mSH&wo`?xS!7zuIc?DIA`(wB|**?lsO(|2+#9oUf922p~;ogsr$ItQW6~4 z@Dgnon2q%RM>z3kv{g-GYvR-BT4b8lGQB@2SiefZX;wmUYm}$!-pot?{I;A@{F)`| z?4g~bmva6r*X^q9XMXQ1QLl_Iy7p0#EhH=Rd+kf1t#`^}bl88ay`X00q$Tsa@9fqm z;c?tY|Fz6)QJmbhMSo$5N@n~ol#g-RTIB!dTcG{^^NK4ZhNiw`TfA= z`3mzZOER7xDeb?vu3FnY=!=Gv*3V>)s`Mi(w@kO|Tj2X`t5>p`5*RGHP|GNH&3UJP T8e11IMKE}}`njxgN@xNAI7#^E literal 0 HcmV?d00001 diff --git a/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_cancel.imageset/Contents.json b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_cancel.imageset/Contents.json new file mode 100644 index 00000000..0b27130f --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_cancel.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "拒绝@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "拒绝@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_cancel.imageset/\346\213\222\347\273\235@2x.png" "b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_cancel.imageset/\346\213\222\347\273\235@2x.png" new file mode 100644 index 0000000000000000000000000000000000000000..b8c6562b0b425222bb1fa94c3d16d3537eb45340 GIT binary patch literal 5331 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 SVE*rC1T76+^=ehC@c#iTa zt&*1wg4=xL)KCH$fF&Kx##V9&Y3oDUeW6Gl0L0c8lo^8Cc&20LpE_+v$&5gD2(CNj z%R8q>N~pT~CkKSsJ6!aXGN`s6q=b-ib57B=?ozEiOaa09aLseNbkRvwyE0-R#JhAS zYc|z=nGp~ON48Wz^|b;+Ah^y>>STww3IL4(A>M1sX)f!B-nX6x8ahU&c4u84MGXMa z5pqxF6_;O;{{ETut|gaU+vOe{mEZXCN?|f1aRz~rz%vT>NcM+%<94>(-r0y=n2>z2 z(9RpBG$-3!(XW|ZNSgz(OMNPcU**|^+dccZUXyr$q9M2}05(ci5dbK~NGv(+>~_0* ziJSn3mr(?Sl+#S<|7b80iYoe&az_wK;94%8QA4cCN&lSw>8lq7k<<&xiNS&jLL_&i z(ix0|&t}E0x1d0XEbD;mw!SHFUJQZAx{%4dSW-_suha>G$i5QG!V@&PLm-NT5}git zpUinc%y3gI7D9(OVI+P->W~|v!B6pEP8L1P3wWuuM|l^-VKkG35+x)ykB|jBw3d#? e?Lq6!P3j-Q)`2#iXuy8}0000mKAm)koat^$+q&J!|H~5F;-0|+2 zPUV0lpL?bmb0hl)N14YtOS(~(o2{gSpif2FSxVXolHTfFQGRqu{QfK6eq&Dss1ARi zw`z6sE+7fzU#TGS*?#d>%S-qC+6R9QP3@1SY9HWBXtH7oxfmB zQcrwVjH>HJE0Uz0S<#48eJ940B<;k|Z)8y)o`XJ6Js;UwWe`svVZBdHW)x z1PcNwCGou=ry-+~q6C4tNQxE&rX&f$CwfYB2r_(8v7iJ5G_)IE!|fQDcF|}i7JBaa zDcApVU90NF#CYu~hBxvJD80QKY7&=eNH0mls^eaW)Dd1d|HHh3_`|-CUrq>PNP2L5 zmM?z4b>D@~Hb_}>VzAV3uVjeRiLa5)8Nij4+G5XdS?9<`05NG(C-5o>}# zh$Lqe+{4Cm{-hQK<%0^M3MMH6)FK3j)E|JJh^(UK_HhTUvGBA zx*(84lI!ujZO21X5Cl?7^0i-+69iI9QfCOJBnT8)pVaOlrzQxbkmQ=yK8dZSC0gr|FeIOZ>7T0?1Y#wvyUO|m#ilmLCREZ#SMAxAbKOKH z)Lv-1Xx9StCg8k_7c8t*9*9?x3)Silv0PI;h&^&F>-|*T7mv>?i=t4HEPv6EX`yCA z`?;(~McF7x#dHQL-QDrjTT6G!IF>0@{f6v^7XJZ#!#Rq~-3^)m00003Frod4Pb(X3Cad^17L!d3Cad76Tk+}29ybeOblm~cUw12ogROu%h`D; z`dD#dhp0m^^N>yvE^)DYu@5o3hwnseOgSJIE?m+aAkjbceG@Zu47dx4Eg2voMgiPy zry^9ja7zIu62f*O0+mY}0Y2t*gNVaS3cR6Q+6wUT?;@d=)CRmmx$G(+h_w(Kf%9b~ z++D~Ua6K#&F+rZs05l@H ztg1c0&pjQH_k0!0jQRnE3%kSv#GWYiiiLUsAzWr<@dX48+cMl&3PE1 zpu_D-OyzLzo9?A`siBc0=C4OMeh7K60ZHOHP>~ybLmkc z7(cWQGdd(V{($W*fa~2l1j}9hFySp_l@RB+yVKy}^OgceS&~;tG|DQ$cc^@qoa;YZ jP*$n`$c*>BrvHF1>>QeJO5xoK5{v;s~l59^tdNnMp{Zr4Zi3jF8B6- z3^jz0F|0W538jFh)5y9p)Bruci_3M6^?@R?NGJX};!;v~6u{Q!YnaHjPyo>cl62zD zluP6GC4ia7-s3U~6{%AK(y8?n)ALRP&NHHy!dCZAF$F3DMLMI{Sa)zei*tl`HNg92oc@I{FME^1SpFclYXk!)=Ls+1Z!%rfr2mE|> z75|kRE#n|V^&;mrB9$AtMB?a}@#fIuztUifKnIi_x4I1mVKi> zYP5*76A!>%a6!*p2KcW;QIY~_s(d3X(!O;}aj?Jmp(xs0d`UHeq>=-|?TLV*2t{FU zA#Sn)2`thT%_GT$^jZfFUlHdA@Ga#dX@LYCw~WCq=rQ67*dEg?d4Uv^YCX^vjmbSV zB7PsU5J($slrHd>n32bPD4bw6wfzaZpA+Vve z%p-#AeC1f-Fw5Za+TkZYrOQv!GI@ctk_PN@rPHfbl*ms$k`_qC@vZSWb@<8#rR7*Y zk`+k1XK7msu-k=BXH?M#zLH*#GnAW@E;8^dfPF@e)C-87r^);zBgoEIcNCu84y)Q8 z6{qjj@ zrzo#h&TRyNmd+_FIAlFf3HAvQM~JgdN`;!(W*BOLHN;u#{~N7fo28whhNw6u;9T9N zmggetrk$Y%Bq7c+cKx(7)Bru7k2?!i#4d<3l9sNM%QnrIsm!Q*N{{`X%NH=q_(ar4 z4P7?3OL%=?*T`S8g2Z`IJZWdB0d_u4y0fpf%~=Oq-P;*zh_o*%$R928Uy|4({&ujd oz1_6UyR64fQ<&#uQ<1mCUy&}hswFwye*gdg07*qoM6N<$g7xJCO#lD@ literal 0 HcmV?d00001 diff --git a/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_switch_audio.imageset/Contents.json b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_switch_audio.imageset/Contents.json new file mode 100644 index 00000000..8127486a --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_switch_audio.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "切换语音2@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "切换语音2@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_switch_audio.imageset/\345\210\207\346\215\242\350\257\255\351\237\2632@2x.png" "b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_switch_audio.imageset/\345\210\207\346\215\242\350\257\255\351\237\2632@2x.png" new file mode 100644 index 0000000000000000000000000000000000000000..af1e5bfe026e611ec34aeedff97ae44f10a7c495 GIT binary patch literal 812 zcmV+{1JnG8P)Mc{K~#7F?O2O( z+b|4;dL1C$fZ4#=K;0l4B$>c%7l=k^7pOHs;tA~Q0(HAU3 zPVWwvSb6~Y2=FJO5hF&7cr7rq*qOE5nxUb=2{^Y_bAv}~moy~U4rkVu{69956~zBQ zZx>I&@66iWU`orC(}h<~J{B|-M1)9LUC~Rxtt69Np$i@Tp4I6aoHLwyv z2|hA;XWr=EMtDn3oaD!d2vZ&v;zsy0=-8J;F84Y&Tp1y#LR`mgfR6~70KS%u){J)% zQgjjGM0~PVal!~Qo*N?Kn)<|nLi}CX?_5q;bcmnSHx3kXlhQeEN~#KY{jX9jLVhbk zGLVf&g;xf=jlApi*x@=kxAq6TzOc3cLfG1m;2GL;g!h-8w`qPN)BV~TM$?Nqz(w=CCv%jkc__6x{1(aluBx{ghp&Dz>fSJ zyhD>1#V|^{aaaMjtfO|5I`{Z9g~K@mPqN%xRBA{De36$J5{Ly96wk1 zu{#B-alu02mO#Wr3w{j(*BtrEz|EbaN)g;5ViWrDK4T#sV! zIOKF9@cv5bFZKG0cB1ABIPa7%^hRyTw1F-yR(vkt<3700004y^o@O`M9zNBp>0?U&w#QjLZN@zScQsK1YTtTZ9_lwlQ5vHtWa)}QY4%x z{Vmay%-cVNVlpNhV#TFb09V)-l0Vwq@*g8-J|79R3Fe7aBeM#H`f_0giVwE;LjN(e z4eGC6vruk=2PnU##NrSa$$uvFkD+ZE5K7x_Xwf7^B#U$ko1g)qQo)ZUnxrLn0h^*O zq0m+wrb_=8Lf@aTNsK~`jY3sUz?d&NUtXHRrl~_HTr&YXk#3~E8>y2pufTis*Bi21 zrTGB}r-!cQVIL#GM*=dxg=c$@p#|Iok02i`TiFfdT&R~MN|C6174n0uSMZEgd=4_w zFX~xiB4NIhK7)lY>%v0u#xwOiANjk&6X6*PEQz#VyGWS7a!<)lpnjeT&!maQAoEvx zSer<0NpW4#gXWMXqvbZJ+P4;wFh8E)rO@PIRYvw1nn4`*S|YjVxgu-&CUi#jhLZL~ zXcI$qq?}d#s08yf8-9gX5okho3AV`K#QKf|`lYm!qCr}wkrqgBYzuCovEX2x{_V=pKQ)d?tD2A2=vyw& zmJrA*j`MS2@R1tFq-|2~gmKKbG(O7h-Ow)35aqp+#m^-eLH#amAoSJFr0f?0Xghvo z&J{m>gO3~Iu$E6KeTbI=mc<%@kXi;%n{(6!iopol?)Foqf2CZu>gW_}5Xc}>h9wW(QGP2i+BsC^T(<0F5A|hc zz7BT&iVnuiLKjRj^NdT&MV4Il)-s4b%A`;d%p-HQB2WSqKso7tG4z$n5dEVG)RT1v z6>+|MPO!=wV)S1ESdM$8C{jh9JL)S=9?Yk`Zqh7xY7rjwTx7eHL^+DS!j|F$)!wqE zDAL|&F>E2YSZ1?2qG*V_8%4*8Kz)lNttw7nOK~Fggt`5(I+B)}c~A8a!NuEfip5bB zTOADrk(#*uXcb(1h&pz{+&R(2xkW2ZP-uIgoH1_&Zi-wcB#@tNUwbY*3p*#cqf2dF zmM;Qgq1|`rFv}uMgm&72eRsg(O1tttZ70FJPFlXj7~+;z*sXwF|KB=+Kp+qZ1OkCT bpe6nRjmo;7OX8|W00000NkvXXu0mjfS~Mu8 literal 0 HcmV?d00001 diff --git a/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_switch_camera.imageset/Contents.json b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_switch_camera.imageset/Contents.json new file mode 100644 index 00000000..89ecb081 --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_switch_camera.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "翻转@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "翻转@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_switch_camera.imageset/\347\277\273\350\275\254@2x.png" "b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_switch_camera.imageset/\347\277\273\350\275\254@2x.png" new file mode 100644 index 0000000000000000000000000000000000000000..9e037707cf34f923da25af0e418dd901b7c5917e GIT binary patch literal 2719 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 Z{{t&dr@(zoVOjtH002ovPDHLkV1mux?(qNs literal 0 HcmV?d00001 diff --git "a/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_switch_camera.imageset/\347\277\273\350\275\254@3x.png" "b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_switch_camera.imageset/\347\277\273\350\275\254@3x.png" new file mode 100644 index 0000000000000000000000000000000000000000..1517a5f1d03faef596d0ca959177c3f6c0e0fea1 GIT binary patch literal 4183 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 literal 0 HcmV?d00001 diff --git "a/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_voice_on.imageset/\347\274\226\347\273\204 8@3x.png" "b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/call_voice_on.imageset/\347\274\226\347\273\204 8@3x.png" new file mode 100644 index 0000000000000000000000000000000000000000..76e205dc5ad5c835c6d58f74c4455c56153b759a GIT binary patch literal 935 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 UqF!Bj=l?SdbgpYxYTm>B58Cq{hX4Qo literal 0 HcmV?d00001 diff --git a/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/micro_phone.imageset/Contents.json b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/micro_phone.imageset/Contents.json new file mode 100644 index 00000000..2981b974 --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/micro_phone.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "micro_phone@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "micro_phone@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/micro_phone.imageset/micro_phone@2x.png b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/micro_phone.imageset/micro_phone@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..6c130c79ec6ebffdb3e023ab001a78709c02ec4b GIT binary patch literal 2691 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 xw6CiDSKd=-@|eWe$5!1e~9y#a$a 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 literal 0 HcmV?d00001 diff --git a/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/micro_phone_mute.imageset/micro_phone_mute@3x.png b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/micro_phone_mute.imageset/micro_phone_mute@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..20b5f473db4656590b5087936e95672c4b21f569 GIT binary patch literal 5236 zcmV-)6pQPLP)jLeQ5ZZgS|mGUZ51-b5EetPH$K@!VN|-YujHzDkNOK4oK7F7^L>OBn zh0+*8hEHFq3}c!?$neDnhN+)QO6H7d2qE@sPL=E$AH_>53OGp)A(tAGqbb)CDXAgE zkaN1k>#7B^m)QAY(n5&PA$*+oC0F8xs7VUpb&@T-aOjzQiRu-T5JL8T>6M6H@dAmr zjB0nPcCk#KO|=2I2^_BbB?g` zNyRWM-5@a=p2n>wMDb;&YL!A%487u5$@Yfr5)*L>A$Gmg3x}U%55Lo+a*vNn48&nL zichy&h1E}T55<~KMDyXP?mZ#qee)%IZYPmjn6_k8J1FN)CD)G5Aw z6ha1&!lG3WbqOH@NMX|^h&qIj0i>vC5yYrN$N*B*A`fDeA!Gna7m)@rst_`Oq?^cs z7)1ziCB$SQ(hq`&eWsyaARKlGaV7L^LZq*ZgnVDcFhgi;#^zQu(p^Ti|C5k5eTNl7 z<7#+r#-=zxE;5omNGkB-GQtYsT-AmNQGDR)ixCpSv5H}Y5LM7W2vPiC1cw8p+9W_h zhme&}iaYd%fnEaDUxI^Ak%>YSe;CaLcDi3sJt4-^sD!c*LrD;5p(dyhVhB1)h>`;x z3-aRo{4j_R)~Yr|h>{2ML+qwGDL(RhPKa?c_k>cC%@CjGhkl1J&-d#_h!Z&*$UITs|d<~kp4Lx^6GJ7b8f zx$X_!hLF7=QE9Gn;wFShID0{&(p>e1ZbCRoh{!3&y`j?(q6cI}l*l>9y`j?(axO^Z zo}&#dPD04tF+}Cbh=VIEoP;nVL{tt0@VZiOauUMvLPX{A9KzAUWeFlL&>PwoXi9}} zj1ZAmwuMc*yXLYWqq(cEzPfVi)Tz~%U3S?Z)4lS^`>QMIql zUa$)x?yk!PdQBjFOO`B|J9_kJSECaIa?P4G>lZIx+$a;r$_Cz*1Df=BN7l`sG~C2whQ?)NHXnBNUm} zUVCk7&;bOsym9HvFTXrfC~QT$XUsy#Wr+waT)1$qgyfc6ZkdVdt5BGV^3~tu4HZIV z!+h?$@4kDev$OMQ3@cxG@3}qhrU8*)D+F1@VnH-Z=E}#~+s*vIb$)s8Q?*!-aX_*`IlS2rm`#59Kh-UC1f^%;+Z{Ga$ ziWMuC;_#{nPXI`&DkrzgrZV6cxUR15ro!i^OqpVN`kHP*#D_@!xi>gJXXVP3j|lk+ zA>_W%0H|MH)AMEq4jgEE0j*9!tf{HFvhX<^lgQrCS3}qnYDkwLR#sMCX!iVw5hDf( z`G(a|O|fd49;}XPj6qBV7G`wu?6c3-ncWwHK}C@-k zwtD#R;Uho$>@&L{zUWsFe^rDcgAkq;^4-CM2fM9ayXKl}ih_0WVL zYKUnXj)sPYk%iASHa2#gIdjJJmpkYnntfo{?GMF&Q^+?6VV6)KPAF#2Uv<@0MZ-J< z;pow$Z5IEkz=K$5+_-V32Y|J=w;vMnQx|)}03A}yo}V&hN}bvBUwrY!Zm|(&5O2Tz z_6cUs|NQgMCxm>(!c2g^{q|ea5Z2Vxj5I6GJn_U6f3q5r8o~;q>aE9`J>T5i+#=+s z(+FXYP#~Ur?zuf?&*PfH1q&7w%?mLk-L`GpRw*HjAnsJmp5L`=7l)(%>cQVYeXdae za6Cl*)#(PcgwZl)%$OH?dwYw%=h(4hPpSp`k{8aZ`B~evY13Y4X=y3yJyr3idfmEp z|1osvP}}>AY}~kU!|d6!O&9Jz`skxMcieHu*-hb{ot-}o8#e6ELVjxEa5P|6^E?F8 z>hPrd?z`{5dwP0GE(7@0Bidbkv1!w$vjJ5-^?o70on{CFW;f4UvSf+ra1a4ny?XUu z#DNfl*!$RHk8!J;|GF+v|G;m-bwYtqs}z5~=bn2mQ;LR{YG_ye%P+sQsOeYHy4(8o z>)Wol;);&(s@9z1m6!iD2M_~3(G9UUEi&wuT}fdk!Ne);7dH3ywg zQBh%ezKtpr)lQx~x!+rFy;W3rdGpOTTQ0ot!nTzwR~``Z+t=gytG{`cR1mr@X>8*aFvdeWpxBQLt>qP}3OC4^tqlE{h8n>Qb_+uz9` zYU69w8jTR5R6au}aH_}qlj@}!tX|)@Z(sAgdGlVknj`v!LDWK{YF`_3LhgzW$%79* zxB{*xz8RltNjJGS0`f?g20JFmJnL$Y&23W=LFK)^cS{{8#+sYUtb_uhN&aIX4UG+9%X*uiRX{t8uX z9XoE^xLRZHD%TOUa!|ERc#t1LR7a-@g$hd-xCNQnZPZG^cDR!#PoC)R?(PfK#TQ@P zcOfo@vsT~3AZnwpD1!(2A;e$YJwlOC!^H-*2KYy@So`x6gQ$fKsvW_D{24#SsJyl? zBKO{V@77tfX8pOjxp}7q3_EMKZ{Kctz%Z+(fx}$zi1CLD3SPubA$j}kh+wnztFOMg z2b;RDz4qE_wFvKMuISc}KmNGyrI%iMSB2=9+3P?2@I&{mUAvmqyt1y;rf;ha=wz#1 zwX+-L3qQtqfv-j$c;JDNk38~7!EzaZ@&3v&zd!B8lQjuc}GW7sGhm{ zop;_@YB$GhYHDhnG-=W*Avc|aF*O%Qw4@cH${ix)QvIfeP)s{AL+wqhI=(w<$fwtM$(U*~ApS)+e&ClL8MT$-*Fbm;6;i5g6z?$IW zk3ZflAquWl34%_-H^+P%R^ z2zhxEQTfguV`0U~S$g;v@QQmP_fU{&E%hcRAw+@Zpb(K;wgnl3(^F-+TtVbslan_& z4dGGYas`naxN_dnf!c1)SLbpCk#qm+^o?#p$lj3187xa2ar$PrcN$@DNK~5RUJ%@d zki8+1J@kUEj{PX-o?Gk`J{`y_iqqVr*Q%wMGp<%SSF zVXF|4!O`v*GhXh)jE$+>Q%aQW1s&~`^G4|_^+Zt3Mhlx`@-v`U%0^n`#bEO@Vb zN;51;l-&!0*ASvN{8Wh2%k`2(A+I3>E?H1owMZFD5{3K-A$%$<(oni!8s=#jYVcB+ z$%kR-@2ZUwqIAIOfG;CJzj{JIk%q%kN&{bpp$0!g2%idvrIc*G4MPon4Mz}-JtnbM z%x}p}6equ__JL}F+~Xst5CWGiC@H>F?T`c{$PhxiaDGVfhN)Gv1SqIEVLsohNkk#R z9j|;{jxZB+PiSaW?GM7cJ5hX~5c9EQr&WOpD}*f6P@EWrm{2PGVTBOziGn%eSRv9E zu98OpPfAF_3?Xz$_R}RJM0)z0gnWKd*dc_D+*clpLAnXN5^5%j5Q0%HWe`ahO%g&S z)J#+%1O}0G5m^8s$`AsBNKuP4fDm;EfkC9GL>@rUA%wsnQrNTzAm|c8U=S%R+5`}E z3L!9v6f~^@2)cz35Jc>*;U!SyC+vjTF4?Q&wbD=YRjt|_;ihl$4tqg2i>6oe=-3k) zx>fr@vRm93L@F1qhQMCX4$+j(Ap{IdarFh}h?PR*&SBLyNRh3 z>In_#4RId;{BP$0Qe?pJ^M6G1`Jb6Mh7d5$Z0b=nTcx% z4JbRKdWsNM3#ARJpPM9mY)Wj!aZYFjhe*{6=Za~7-fy>Pxcj9XNeUq#fCyr(P*NR` z>^U%rxz|b3LTF&Gm^`R_{#6oqkaSW*XsFLMiZ9%Bc5kjF@&>d?4W$8zCt zCG>WwA9C7Z2%SNXh&kg};oPwlBY3TmZ5{6J8Mj)$lts?KwFeLYNpx6&{ u^RGDQ%6kq6WcB18pU%CO=&KXr;{O3Iy+Qi%7;p;!0000$e1C57bX*(jF%Uw8jX$d!5E1TeQRTk%IJ&1 zh!3sC+a&d+cu6CT<0TpuBY_w}CsJ#wHb6!(ZJ@Ds|2b#V&0+6z*4ekS*V^ANS>13r zLMlJM^{sE+vMAg{w3er}?D)qK!^hc%_n0vdf4(++jy9;Z{`j+xLP{2ehrD>35`X4s z?LG1qT`~yP8-IpEHkHLfq$#ABNCo7*M4~{pXIlFq{!~&l)x?5CQHlu_Avr+z3BkH4 zCYutdAeJuEEDBCkvWqTR2T2~uWEBenL8K_f#8MH61;M&WLSz#QLVXZ#vPUOT^eEOw zzmG%%k1S##UnFDV2Ix>zifIe`}}sA7e&%d-RIf@FacEQn&w)mkaBP@+I8 zU9i9qB(c!#{gu=m<#`Q8k>5~2qE}GFLLSB4o;$R~TSm#WSRAFi0a2@kG8nzyq0E6? z>Tg>6BQb7+$X~3rH(L9VGC(H8!vAzR#k#+DiSY{jZl_ah`48lJLq6hnSBS2!hGNTB z82|9SYxFZ>L8hfzn@Eh`pqGeJY-;Fd@&UiZLVpjbc+{6U@OM8)YeVEi-sOi_$fYWX z2@2EW&u8QzUW-*0Z%nYz%R8RQ<)v6GRj~0?F0aI5spP;jxx5gIrIHIzW;YCQigcvd$wwb;&0O^NMzpcXWNF z#HbDehpjZnu2^-%$$A*TBEdyu13O(IERGTr7W9afR`E35h^6mLX2J#X>9o4Ubj7M6 zCXA%rC8pCA;{1d;#Do<@Ea6e2XvE?!kO6QYTjY(RVj)^_b)A7!b4A`LA{Iw0#)wcN zFCrF8#TY@46_z8! zWMUN%!z2e{nMN%uvAAxKxHeC_=C^DWDlFaMetKfu{rqb`^-i&)Y{tD2gcj}l*7wrpA5 zxpU|KPK+NECca=MmNH2@%jFwm@~p&VGmuKUh*eQhG5#+aW?!2%YgSQtd3n~!lP5hr zV1M1Zb<@_aUHj*^Z{Pm%`0-<3PR$Dt@CYkRM~ym--49Iv`Xe9tXg zw$wu^d_Hd6xc4cXM2(*q#lmP%>e`i`a?PAMb9`G{+sF8x#DEAH{4t89#O)A%$W>ik zou^6lX=!OG*ULr|)ju$brOas1OSyLL+*zdMYoAV-FoDmiAInH^Qc^77gK5nEpFgJi(;{3E${C~%*$_*) zh_z?Wo)R}I<6g-1{Q2`fv)571P$=h$KrH1pP2}e0y0*f=ZMn8>+xD&1`?qf0s>-57 zHN|opH|0W-e&E1?FU`J&E>V%F^`2W-o+yu-a_!o+>z+0;Y&HAZ#*G_QsPN}NtQ=y5 z5RvO=4H97e`t>blBF>mGqX;DllACOfSZR_AK!2Fc_~r_g!*`gPL{9`okSll>Z*2uCcNxUmxT=+UF5VrgBW^!F37SPpP17owY4 zo|Ti6BmIU97Rw<{r@n7iYUu3jY$pZah~*)6Caw=2JlIO|Gr$qc zW73i9?%lgLjvqfReSSr%iuLf}!#)ZSqH;AfG^lcB>JWD6;QYv1QjC``U+xat!5ztV z|6r+%LOXR@AQo0PtR=<3sB8cJ{dKvyxx#WyoH%ikQyCF?lI`9J$!X4C=|@G@lY)nW z*x~BctE(z2D{Zgh#Je$KvfWhDwdV%ycF~d|1)dRO3FK&QZvMjVF-9SgYs4WI zD-AYp-h4w7;B&iqR|w=983Y=|>LDg2$h(l#<6JAUf#PzRiZwtyAuR;tnml>(XI9(f zQz0VPnKNf(+iDMYMk0CQ3ep~8gmF?#O(oZY1q(_@E=HwNES5tOi>c{sgh(b=R#w(q zl8aHRUK8&t#MI6QT6>omVcOf0NZ~wNxzyBA}KYQZDiSC697h-k8 zsLLczpFZ89VJnZz0O$rsokL-ECp0b|noEqY;9l$6+S=hupKji~*}i)9YMEA&B3fNG zzF;O6?n6;^f|T)wuP9;m#%%l7Gvb;SBTgTgObJ@;E9@bL5u?NGMJutoi02NO)F5d$ z-2-VQ7A6xriD8msnKC8YV&6dwlbklIFC-HSQA_r%-i&v^4a+IOREL7J5yP01)QwbP zSte&ps7V^FfXFdMFq21!jFFT***laPr7O;Vu2sE zmaVmXVpIfG0NZoLPH(2b59X6<)B}0dU2=evhy_qM#TKO~@llhi0I85yIXY<9saOE{ z7DkD4h*1GZ^?!1R8)5<6+z!*D#K;V$Y7GSyL!gZ;D7h(aHOAb7d3V0gXHo$##R4o>F!59>;I&u)a-r76 z^NPXXzvRPa7a=E9r5%}CV)&A$c2i!D1M3s z^lkh2xx6aEAJFZg`}6gZO~1tg`ouLP`xEhbr(S_YdRR||B>fHfjGsA{8OXQli1RMD z!9o6rQW-n9KNAtli18dQE=f2?k5bnt_IH~xG99suAZlUM7^n-vB_iWd%1DsJ(kaqf z8FBY03ZfKNdj{&Dyda7NAeAl{V-AGsjJLq;m>eE($NJgpz!2if$s9GkWDNjh+cC^-BBb)c|BTtND}Tkmsu&xsWrIYxTofYplEqC~DiS8K%z$9o@h2pU(C=MnPW)-rrRtGpDE_hjM1xTM d6ynRfTjQd002ovPDHLkV1iE3%-a9} literal 0 HcmV?d00001 diff --git a/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/speaker_off.imageset/speaker_off@3x.png b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/speaker_off.imageset/speaker_off@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..5943ab7d413f002faff50d39c9dc353fccccbb10 GIT binary patch literal 4624 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 Bqgem| literal 0 HcmV?d00001 diff --git a/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/switch_video.imageset/switch_video@3x.png b/NERtcCallUIKit/NERtcCallUIKit/Assets/NERtcCallUIKit.xcassets/switch_video.imageset/switch_video@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..d1ef4bf5e543b38d787791762e05b9aa98c2a1ee GIT binary patch literal 4983 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 BXGQ=3 literal 0 HcmV?d00001 diff --git a/NERtcCallUIKit/NERtcCallUIKit/Assets/en.lproj/Localizable.strings b/NERtcCallUIKit/NERtcCallUIKit/Assets/en.lproj/Localizable.strings new file mode 100644 index 00000000..9ab47fd7 --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Assets/en.lproj/Localizable.strings @@ -0,0 +1,37 @@ + +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + + +"switch_to_audio"="Switch to audio"; +"switch_to_video"="Switch to video"; +"accept_failed"="Answer Failed"; +"network_error"="Network error, try later"; +"switch_error"="Switch Error"; +"remote_cancel"="Cancelled by the opposite"; +"remote_busy"="Busy-line"; +"remote_timeout"="No Responding"; +"remote_reject"="Reject"; +"other_client_accept"="Accept by other client"; +"other_client_reject"="Reject by other client"; + +"permission"="Permission Require"; +"reject"="Reject"; +"agree"="Agree"; +"audio_to_video"="Opposite requests to switch to video, have to turn on your camera"; +"video_to_audio"="Opposite requests to switch to audio, will turn off your camera directly"; +"reject_tip"="Request Denied"; + +"invite_audio_call"="Invite for audio call"; +"invite_video_call"="Invite for video call"; + +"waitting_remote_response"="Waiting for response"; +"call_cancel"="Cancel"; +"call_reject"="Reject"; +"call_accept"="Accept"; +"call_micro_phone"="Microphone"; +"call_speaker"="Speaker"; +"waitting_remote_accept"="Waitting to connect"; +"calling"="Calling"; +"cancel_failed"="The invitation has been accepted and cannot be canceled"; diff --git a/NERtcCallUIKit/NERtcCallUIKit/Assets/zh-Hans.lproj/Localizable.strings b/NERtcCallUIKit/NERtcCallUIKit/Assets/zh-Hans.lproj/Localizable.strings new file mode 100644 index 00000000..bbac656f --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Assets/zh-Hans.lproj/Localizable.strings @@ -0,0 +1,36 @@ + +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +"switch_to_audio"="切换到语音通话"; +"switch_to_video"="切换到视频通话"; +"accept_failed"="接听失败"; +"network_error"="网络连接异常,请稍后再试"; +"switch_error"="切换失败"; +"remote_cancel"="对方取消"; +"remote_busy"="对方占线"; +"remote_timeout"="对方超时未响应"; +"remote_reject"="对方已经拒绝"; +"other_client_accept"="已被其他端接受"; +"other_client_reject"="已被其他端拒绝"; + +"permission"="权限请求"; +"reject"="拒绝"; +"agree"="同意"; +"audio_to_video"="对方请求将音频转为视频,需要打开您的摄像头。"; +"video_to_audio"="对方请求将视频转为音频,将直接关闭您的摄像头。"; +"reject_tip"="对方拒绝了您请求"; + +"invite_audio_call"="邀请您音频通话"; +"invite_video_call"="邀请您视频通话"; + +"waitting_remote_response"="正在等待对方响应..."; +"call_cancel"="取消"; +"call_reject"="拒绝"; +"call_accept"="接听"; +"call_micro_phone"="麦克风"; +"call_speaker"="扬声器"; +"waitting_remote_accept"="等待对方接听……"; +"calling"="正在呼叫"; +"cancel_failed"="邀请已接受无法取消"; diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/.gitkeep b/NERtcCallUIKit/NERtcCallUIKit/Classes/.gitkeep similarity index 100% rename from NEQChatUIKit/NEQChatUIKit/Classes/.gitkeep rename to NERtcCallUIKit/NERtcCallUIKit/Classes/.gitkeep diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEAudioCallingController.h b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEAudioCallingController.h new file mode 100644 index 00000000..db1682db --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEAudioCallingController.h @@ -0,0 +1,13 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import "NECallUIStateController.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface NEAudioCallingController : NECallUIStateController + +@end + +NS_ASSUME_NONNULL_END diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEAudioCallingController.m b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEAudioCallingController.m new file mode 100644 index 00000000..5e2a907a --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEAudioCallingController.m @@ -0,0 +1,54 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import "NEAudioCallingController.h" + +@interface NEAudioCallingController () + +@end + +@implementation NEAudioCallingController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. +} + +- (void)setupUI { + [super setupUI]; + [self setupCenterRemoteAvator]; + + /// 取消按钮 + [self.view addSubview:self.cancelBtn]; + [NSLayoutConstraint activateConstraints:@[ + [self.cancelBtn.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor], + [self.cancelBtn.widthAnchor constraintEqualToConstant:self.buttonSize.width], + [self.cancelBtn.heightAnchor constraintEqualToConstant:self.buttonSize.height], + [self.cancelBtn.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor + constant:-80 * self.factor] + ]]; + + [self.view addSubview:self.microphoneBtn]; + [NSLayoutConstraint activateConstraints:@[ + [self.microphoneBtn.centerYAnchor constraintEqualToAnchor:self.cancelBtn.centerYAnchor], + [self.microphoneBtn.centerXAnchor + constraintEqualToAnchor:self.view.centerXAnchor + constant:-self.view.frame.size.width / 4.0 - 20], + [self.microphoneBtn.widthAnchor constraintEqualToConstant:self.buttonSize.width], + [self.microphoneBtn.heightAnchor constraintEqualToConstant:self.buttonSize.height] + ]]; + + [self.view addSubview:self.speakerBtn]; + [NSLayoutConstraint activateConstraints:@[ + [self.speakerBtn.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor + constant:self.view.frame.size.width / 4.0 + 20], + [self.speakerBtn.centerYAnchor constraintEqualToAnchor:self.cancelBtn.centerYAnchor], + [self.speakerBtn.heightAnchor constraintEqualToConstant:self.buttonSize.height], + [self.speakerBtn.widthAnchor constraintEqualToConstant:self.buttonSize.width] + ]]; + + [self setupAudioCallingUI]; +} + +@end diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEAudioInCallController.h b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEAudioInCallController.h new file mode 100644 index 00000000..b19cddf0 --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEAudioInCallController.h @@ -0,0 +1,13 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import "NECallUIStateController.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface NEAudioInCallController : NECallUIStateController + +@end + +NS_ASSUME_NONNULL_END diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEAudioInCallController.m b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEAudioInCallController.m new file mode 100644 index 00000000..b91a66ab --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEAudioInCallController.m @@ -0,0 +1,24 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import "NEAudioInCallController.h" + +@interface NEAudioInCallController () + +@end + +@implementation NEAudioInCallController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. +} + +- (void)setupUI { + [super setupUI]; + [self setupCenterRemoteAvator]; + [self setupAudioInCallUI]; +} + +@end diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NECallUIStateController.h b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NECallUIStateController.h new file mode 100644 index 00000000..8fbc58c5 --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NECallUIStateController.h @@ -0,0 +1,83 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import +#import "NECallParam.h" +#import "NECustomButton.h" +#import "NERtcCallUIConfig.h" +#import "NEVideoOperationView.h" +#import "NEVideoView.h" +@class NECallViewController; +NS_ASSUME_NONNULL_BEGIN + +@interface NECallUIStateController : UIViewController + +@property(strong, nonatomic) NEVideoView *smallVideoView; +@property(strong, nonatomic) NEVideoView *bigVideoView; +@property(strong, nonatomic) UIImageView *remoteAvatorView; +@property(strong, nonatomic) UIImageView *remoteBigAvatorView; +@property(strong, nonatomic) UILabel *titleLabel; +@property(strong, nonatomic) UILabel *centerTitleLabel; +@property(strong, nonatomic) UILabel *subTitleLabel; +@property(strong, nonatomic) UILabel *centerSubtitleLabel; + +/// 取消呼叫 +@property(strong, nonatomic) NECustomButton *cancelBtn; +/// 拒绝接听 +@property(strong, nonatomic) NECustomButton *rejectBtn; +/// 接听 +@property(strong, nonatomic) NECustomButton *acceptBtn; +/// 麦克风 +@property(strong, nonatomic) NECustomButton *microphoneBtn; +/// 扬声器 +@property(strong, nonatomic) NECustomButton *speakerBtn; + +@property(strong, nonatomic) NEVideoOperationView *operationView; + +// YES 主叫 NO 被叫 +@property(nonatomic, assign) BOOL isCaller; + +@property(nonatomic, weak) NECallParam *callParam; + +@property(nonatomic, weak) NECallUIConfig *config; + +@property(nonatomic, assign) CGFloat statusHeight; + +@property(assign, nonatomic) CGFloat radius; + +@property(assign, nonatomic) CGFloat titleFontSize; + +@property(assign, nonatomic) CGFloat subTitleFontSize; + +@property(assign, nonatomic) CGFloat factor; + +@property(assign, nonatomic) CGSize buttonSize; + +@property(nonatomic, assign) NERtcCallType callType; + +@property(nonatomic, weak) NECallViewController *mainController; + +@property(nonatomic, strong) NSBundle *bundle; + +- (void)setupUI; + +- (void)setupCenterRemoteAvator; + +- (void)setupVideoCallingUI; + +- (void)setupAudioCallingUI; + +- (void)setupCalledUI; + +- (void)setupAudioInCallUI; + +- (NSString *)getInviteText; + +- (void)refreshUI; + +- (void)refreshVideoView; + +@end + +NS_ASSUME_NONNULL_END diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NECallUIStateController.m b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NECallUIStateController.m new file mode 100644 index 00000000..e7b18d40 --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NECallUIStateController.m @@ -0,0 +1,410 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import "NECallUIStateController.h" +#import +#import +#import +#import "NECallViewController.h" + +@interface NECallUIStateController () + +@property(nonatomic, weak) UIView *parentView; + +@end + +@implementation NECallUIStateController + +- (instancetype)init { + self = [super init]; + if (self) { + self.factor = 1; + self.radius = 4.0; + self.titleFontSize = 20.0; + self.subTitleFontSize = 14.0; + self.buttonSize = CGSizeMake(75, 103); + self.bundle = [NSBundle bundleForClass:self.class]; + } + return self; +} + +//- (void)loadView { +// NSLog(@"state view load parent view %@",self.parentView); +// self.view = self.parentView; +//} + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + self.view.backgroundColor = [UIColor clearColor]; + if (self.view.frame.size.height < 600) { + self.factor = 0.5; + } + self.statusHeight = [[UIApplication sharedApplication] statusBarFrame].size.height; + [self setupUI]; +} + +/* +#pragma mark - Navigation + +// In a storyboard-based application, you will often want to do a little preparation before +navigation +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. +} +*/ + +#pragma mark lazy init + +- (NEVideoView *)bigVideoView { + if (!_bigVideoView) { + _bigVideoView = [[NEVideoView alloc] init]; + _bigVideoView.backgroundColor = [UIColor darkGrayColor]; + _bigVideoView.translatesAutoresizingMaskIntoConstraints = NO; + } + return _bigVideoView; +} + +- (NEVideoView *)smallVideoView { + if (!_smallVideoView) { + _smallVideoView = [[NEVideoView alloc] init]; + _smallVideoView.backgroundColor = [UIColor darkGrayColor]; + UITapGestureRecognizer *tap = + [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(switchVideoView:)]; + [_smallVideoView addGestureRecognizer:tap]; + _smallVideoView.translatesAutoresizingMaskIntoConstraints = NO; + } + return _smallVideoView; +} + +- (void)switchVideoView:(UITapGestureRecognizer *)tap { + self.mainController.showMyBigView = !self.mainController.showMyBigView; + [self refreshVideoView]; + // TODO: 代码整理 + // [self changeDefaultImage:self.operationView.cameraBtn.selected]; +} + +- (UIImageView *)remoteAvatorView { + if (!_remoteAvatorView) { + _remoteAvatorView = [[UIImageView alloc] init]; + _remoteAvatorView.image = [UIImage imageNamed:@"avator" + inBundle:self.bundle + compatibleWithTraitCollection:nil]; + _remoteAvatorView.translatesAutoresizingMaskIntoConstraints = NO; + } + return _remoteAvatorView; +} + +- (UILabel *)titleLabel { + if (!_titleLabel) { + _titleLabel = [[UILabel alloc] init]; + _titleLabel.font = [UIFont boldSystemFontOfSize:self.titleFontSize]; + _titleLabel.textColor = [UIColor whiteColor]; + _titleLabel.textAlignment = NSTextAlignmentRight; + _titleLabel.translatesAutoresizingMaskIntoConstraints = NO; + } + return _titleLabel; +} + +- (UILabel *)subTitleLabel { + if (!_subTitleLabel) { + _subTitleLabel = [[UILabel alloc] init]; + _subTitleLabel.font = [UIFont boldSystemFontOfSize:self.subTitleFontSize]; + _subTitleLabel.textColor = [UIColor whiteColor]; + _subTitleLabel.text = [self localizableWithKey:@"waitting_remote_response"]; + _subTitleLabel.textAlignment = NSTextAlignmentRight; + _subTitleLabel.translatesAutoresizingMaskIntoConstraints = NO; + } + return _subTitleLabel; +} + +- (NECustomButton *)cancelBtn { + if (!_cancelBtn) { + _cancelBtn = [[NECustomButton alloc] init]; + _cancelBtn.titleLabel.text = [self localizableWithKey:@"call_cancel"]; + _cancelBtn.imageView.image = [UIImage imageNamed:@"call_cancel" + inBundle:self.bundle + compatibleWithTraitCollection:nil]; + _cancelBtn.maskBtn.accessibilityIdentifier = @"cancel_btn"; + [_cancelBtn.maskBtn addTarget:self.mainController + action:@selector(cancelEvent:) + forControlEvents:UIControlEventTouchUpInside]; + } + return _cancelBtn; +} + +- (NECustomButton *)rejectBtn { + if (!_rejectBtn) { + _rejectBtn = [[NECustomButton alloc] init]; + _rejectBtn.titleLabel.text = [self localizableWithKey:@"call_reject"]; + _rejectBtn.imageView.image = [UIImage imageNamed:@"call_cancel" + inBundle:self.bundle + compatibleWithTraitCollection:nil]; + _rejectBtn.maskBtn.accessibilityIdentifier = @"reject_btn"; + [_rejectBtn.maskBtn addTarget:self.mainController + action:@selector(rejectEvent:) + forControlEvents:UIControlEventTouchUpInside]; + } + return _rejectBtn; +} + +- (NECustomButton *)acceptBtn { + if (!_acceptBtn) { + _acceptBtn = [[NECustomButton alloc] init]; + _acceptBtn.titleLabel.text = [self localizableWithKey:@"call_accept"]; + _acceptBtn.imageView.image = [UIImage imageNamed:@"call_accept" + inBundle:self.bundle + compatibleWithTraitCollection:nil]; + _acceptBtn.imageView.contentMode = UIViewContentModeCenter; + _acceptBtn.maskBtn.accessibilityIdentifier = @"accept_btn"; + [_acceptBtn.maskBtn addTarget:self.mainController + action:@selector(acceptEvent:) + forControlEvents:UIControlEventTouchUpInside]; + } + return _acceptBtn; +} + +- (NECustomButton *)microphoneBtn { + if (nil == _microphoneBtn) { + _microphoneBtn = [[NECustomButton alloc] init]; + _microphoneBtn.titleLabel.text = [self localizableWithKey:@"call_micro_phone"]; + _microphoneBtn.imageView.image = [UIImage imageNamed:@"micro_phone" + inBundle:self.bundle + compatibleWithTraitCollection:nil]; + _microphoneBtn.imageView.highlightedImage = [UIImage imageNamed:@"micro_phone_mute" + inBundle:self.bundle + compatibleWithTraitCollection:nil]; + _microphoneBtn.imageView.contentMode = UIViewContentModeCenter; + _microphoneBtn.maskBtn.accessibilityIdentifier = @"micro_phone"; + [_microphoneBtn.maskBtn addTarget:self.mainController + action:@selector(microphoneBtnClick:) + forControlEvents:UIControlEventTouchUpInside]; + } + return _microphoneBtn; +} + +- (NECustomButton *)speakerBtn { + if (nil == _speakerBtn) { + _speakerBtn = [[NECustomButton alloc] init]; + _speakerBtn.titleLabel.text = [self localizableWithKey:@"call_speaker"]; + _speakerBtn.imageView.image = [UIImage imageNamed:@"speaker_off" + inBundle:self.bundle + compatibleWithTraitCollection:nil]; + _speakerBtn.imageView.highlightedImage = [UIImage imageNamed:@"speaker_on" + inBundle:self.bundle + compatibleWithTraitCollection:nil]; + _speakerBtn.imageView.contentMode = UIViewContentModeCenter; + _speakerBtn.maskBtn.accessibilityIdentifier = @"speaker"; + [_speakerBtn.maskBtn addTarget:self.mainController + action:@selector(speakerBtnClick:) + forControlEvents:UIControlEventTouchUpInside]; + } + return _speakerBtn; +} + +- (UILabel *)centerSubtitleLabel { + if (nil == _centerSubtitleLabel) { + _centerSubtitleLabel = [[UILabel alloc] init]; + _centerSubtitleLabel.textColor = [UIColor whiteColor]; + _centerSubtitleLabel.font = [UIFont systemFontOfSize:self.subTitleFontSize]; + _centerSubtitleLabel.text = [self localizableWithKey:@"waitting_remote_accept"]; + _centerSubtitleLabel.textAlignment = NSTextAlignmentCenter; + _centerSubtitleLabel.translatesAutoresizingMaskIntoConstraints = NO; + } + return _centerSubtitleLabel; +} + +- (UILabel *)centerTitleLabel { + if (nil == _centerTitleLabel) { + _centerTitleLabel = [[UILabel alloc] init]; + _centerTitleLabel.textColor = [UIColor whiteColor]; + _centerTitleLabel.font = [UIFont systemFontOfSize:self.titleFontSize]; + _centerTitleLabel.textAlignment = NSTextAlignmentCenter; + _centerTitleLabel.translatesAutoresizingMaskIntoConstraints = NO; + } + return _centerTitleLabel; +} + +- (UIImageView *)remoteBigAvatorView { + if (nil == _remoteBigAvatorView) { + _remoteBigAvatorView = [[UIImageView alloc] init]; + _remoteBigAvatorView.image = [UIImage imageNamed:@"avator" + inBundle:self.bundle + compatibleWithTraitCollection:nil]; + _remoteBigAvatorView.clipsToBounds = YES; + _remoteBigAvatorView.layer.cornerRadius = self.radius; + _remoteBigAvatorView.translatesAutoresizingMaskIntoConstraints = NO; + } + return _remoteBigAvatorView; +} + +#pragma mark - publick + +- (void)setupCenterRemoteAvator { + [self.view addSubview:self.centerSubtitleLabel]; + + [NSLayoutConstraint activateConstraints:@[ + [self.centerSubtitleLabel.leftAnchor constraintEqualToAnchor:self.view.leftAnchor], + [self.centerSubtitleLabel.rightAnchor constraintEqualToAnchor:self.view.rightAnchor], + [self.centerSubtitleLabel.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor + constant:-(233 * self.factor + 163)], + [self.centerSubtitleLabel.heightAnchor constraintEqualToConstant:self.titleFontSize + 2] + ]]; + + [self.view addSubview:self.centerTitleLabel]; + [NSLayoutConstraint activateConstraints:@[ + [self.centerTitleLabel.bottomAnchor constraintEqualToAnchor:self.centerSubtitleLabel.topAnchor + constant:-10 * self.factor], + [self.centerTitleLabel.rightAnchor constraintEqualToAnchor:self.view.rightAnchor], + [self.centerTitleLabel.leftAnchor constraintEqualToAnchor:self.view.leftAnchor], + [self.centerTitleLabel.heightAnchor constraintEqualToConstant:self.titleFontSize + 2] + + ]]; + + [self.view addSubview:self.remoteBigAvatorView]; + [NSLayoutConstraint activateConstraints:@[ + [self.remoteBigAvatorView.heightAnchor constraintEqualToConstant:90], + [self.remoteBigAvatorView.widthAnchor constraintEqualToConstant:90], + [self.remoteBigAvatorView.bottomAnchor constraintEqualToAnchor:self.centerTitleLabel.topAnchor + constant:-10 * self.factor], + [self.remoteBigAvatorView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor] + ]]; + + if (self.callParam.remoteAvatar.length <= 0) { + UIView *cover = [self getDefaultHeaderView:self.callParam.remoteUserAccid + font:[UIFont systemFontOfSize:self.titleFontSize] + showName:self.callParam.remoteShowName]; + [self.remoteBigAvatorView addSubview:cover]; + [NSLayoutConstraint activateConstraints:@[ + [cover.leftAnchor constraintEqualToAnchor:self.remoteBigAvatorView.leftAnchor], + [cover.rightAnchor constraintEqualToAnchor:self.remoteBigAvatorView.rightAnchor], + [cover.topAnchor constraintEqualToAnchor:self.remoteBigAvatorView.topAnchor], + [cover.bottomAnchor constraintEqualToAnchor:self.remoteBigAvatorView.bottomAnchor] + ]]; + } +} + +- (void)setupUI { +} + +- (void)refreshUI { +} + +- (void)setupVideoCallingUI { + self.titleLabel.text = [NSString stringWithFormat:@"%@ %@", [self localizableWithKey:@"calling"], + self.callParam.remoteShowName]; + self.subTitleLabel.text = [self localizableWithKey:@"waitting_remote_accept"]; + + if (self.callParam.remoteAvatar.length <= 0) { + UIView *cover = [self getDefaultHeaderView:self.callParam.remoteUserAccid + font:[UIFont systemFontOfSize:self.titleFontSize] + showName:self.callParam.remoteShowName]; + [self.remoteAvatorView addSubview:cover]; + [NSLayoutConstraint activateConstraints:@[ + [cover.leftAnchor constraintEqualToAnchor:self.remoteAvatorView.leftAnchor], + [cover.rightAnchor constraintEqualToAnchor:self.remoteAvatorView.rightAnchor], + [cover.topAnchor constraintEqualToAnchor:self.remoteAvatorView.topAnchor], + [cover.bottomAnchor constraintEqualToAnchor:self.remoteAvatorView.bottomAnchor] + ]]; + } else { + [self.remoteAvatorView sd_setImageWithURL:[NSURL URLWithString:self.callParam.remoteAvatar] + placeholderImage:[UIImage imageNamed:@"avator" + inBundle:self.bundle + compatibleWithTraitCollection:nil]]; + } +} + +- (void)setupAudioCallingUI { + self.centerTitleLabel.text = + [NSString stringWithFormat:@"%@ %@", [self localizableWithKey:@"calling"], + self.callParam.remoteShowName]; + self.centerSubtitleLabel.text = [self localizableWithKey:@"waitting_remote_accept"]; + if (self.callParam.remoteAvatar.length <= 0) { + UIView *cover = [self getDefaultHeaderView:self.callParam.remoteUserAccid + font:[UIFont systemFontOfSize:self.titleFontSize] + showName:self.callParam.remoteShowName]; + [self.remoteBigAvatorView addSubview:cover]; + [NSLayoutConstraint activateConstraints:@[ + [cover.leftAnchor constraintEqualToAnchor:self.remoteBigAvatorView.leftAnchor], + [cover.rightAnchor constraintEqualToAnchor:self.remoteBigAvatorView.rightAnchor], + [cover.topAnchor constraintEqualToAnchor:self.remoteBigAvatorView.topAnchor], + [cover.bottomAnchor constraintEqualToAnchor:self.remoteBigAvatorView.bottomAnchor] + ]]; + } else { + [self.remoteBigAvatorView sd_setImageWithURL:[NSURL URLWithString:self.callParam.remoteAvatar] + placeholderImage:[UIImage imageNamed:@"avator" + inBundle:self.bundle + compatibleWithTraitCollection:nil]]; + } +} + +- (void)setupAudioInCallUI { + [self.remoteBigAvatorView sd_setImageWithURL:[NSURL URLWithString:self.callParam.remoteAvatar] + placeholderImage:[UIImage imageNamed:@"avator" + inBundle:self.bundle + compatibleWithTraitCollection:nil]]; + self.centerTitleLabel.text = [NSString stringWithFormat:@"%@", self.callParam.remoteShowName]; + self.centerSubtitleLabel.hidden = YES; +} + +- (void)setupCalledUI { + self.centerTitleLabel.text = [NSString stringWithFormat:@"%@", self.callParam.remoteShowName]; +} + +- (NSString *)getInviteText { + return (self.callType == NERtcCallTypeAudio ? [self localizableWithKey:@"invite_audio_call"] + : [self localizableWithKey:@"invite_video_call"]); +} + +- (void)refreshVideoView { + if (self.mainController.showMyBigView) { + [[NERtcCallKit sharedInstance] setupLocalView:self.bigVideoView.videoView]; + [[NERtcCallKit sharedInstance] setupRemoteView:self.smallVideoView.videoView + forUser:self.callParam.remoteUserAccid]; + NSLog(@"show my big view"); + self.smallVideoView.maskView.hidden = self.mainController.remoteCameraAvailable; + self.bigVideoView.maskView.hidden = !self.operationView.cameraBtn.selected; + self.bigVideoView.userID = self.callParam.currentUserAccid; + self.smallVideoView.userID = self.callParam.remoteUserAccid; + } else { + [[NERtcCallKit sharedInstance] setupLocalView:self.smallVideoView.videoView]; + [[NERtcCallKit sharedInstance] setupRemoteView:self.bigVideoView.videoView + forUser:self.callParam.remoteUserAccid]; + NSLog(@"show my small view"); + self.bigVideoView.maskView.hidden = self.mainController.remoteCameraAvailable; + self.smallVideoView.maskView.hidden = !self.operationView.cameraBtn.selected; + self.bigVideoView.userID = self.callParam.remoteUserAccid; + self.smallVideoView.userID = self.callParam.currentUserAccid; + } +} + +- (UIView *)getDefaultHeaderView:(NSString *)accid + font:(UIFont *)font + showName:(NSString *)showName { + UIView *headerView = [[UIView alloc] init]; + headerView.backgroundColor = [UIColor colorWithStringWithString:accid]; + headerView.translatesAutoresizingMaskIntoConstraints = NO; + NSString *show = showName.length > 0 ? showName : accid; + if (show.length >= 2) { + UILabel *label = [[UILabel alloc] init]; + label.translatesAutoresizingMaskIntoConstraints = NO; + [headerView addSubview:label]; + label.textColor = [UIColor whiteColor]; + label.font = font; + label.text = [show substringWithRange:NSMakeRange(show.length - 2, 2)]; + [NSLayoutConstraint activateConstraints:@[ + [label.centerYAnchor constraintEqualToAnchor:headerView.centerYAnchor], + [label.centerXAnchor constraintEqualToAnchor:headerView.centerXAnchor] + ]]; + } + return headerView; +} + +- (NSString *)localizableWithKey:(NSString *)key { + return [self.bundle localizedStringForKey:key value:nil table:@"Localizable"]; + ; +} + +@end diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NECallViewController.h b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NECallViewController.h new file mode 100644 index 00000000..e8ecfa51 --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NECallViewController.h @@ -0,0 +1,36 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import +#import +#import "NECallParam.h" +#import "NERtcCallUIConfig.h" + +NS_ASSUME_NONNULL_BEGIN + +extern NSString *const kCallKitDismissNoti; + +@interface NECallViewController : UIViewController + +@property(nonatomic, assign) NERtcCallStatus status; + +@property(nonatomic, assign) NERtcCallType callType; + +@property(nonatomic, strong) NECallParam *callParam; + +@property(nonatomic, strong) NSMutableDictionary *uiConfigDic; + +@property(nonatomic, strong) NECallUIConfig *config; + +// 当前用户视频显示位置 +@property(nonatomic, assign) BOOL showMyBigView; + +@property(nonatomic, assign) BOOL remoteCameraAvailable; + +// 主叫 +@property(nonatomic, assign) BOOL isCaller; + +@end + +NS_ASSUME_NONNULL_END diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NECallViewController.m b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NECallViewController.m new file mode 100644 index 00000000..4dd9cb47 --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NECallViewController.m @@ -0,0 +1,1183 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import "NECallViewController.h" +#import +#import +#import +#import "NECallUIStateController.h" +#import "NECustomButton.h" +#import "NEExpandButton.h" +#import "NERtcCallUIKit.h" +#import "NEVideoOperationView.h" +#import "NEVideoView.h" +#import "NetManager.h" +#import "SettingManager.h" + +NSString *const kCallKitDismissNoti = @"kCallKitDismissNoti"; + +NSString *const kCallKitShowNoti = @"kCallKitShowNoti"; + +@interface NECallViewController () + +@property(nonatomic, strong) UIButton *switchCameraBtn; + +@property(strong, nonatomic) NEVideoOperationView *operationView; + +/// 音视频转换 +@property(strong, nonatomic) NECustomButton *mediaSwitchBtn; + +@property(strong, nonatomic) UILabel *timerLabel; + +@property(strong, nonatomic) NSTimer *timer; + +@property(strong, nonatomic) UIImageView *blurImage; + +@property(strong, nonatomic) UIToolbar *toolBar; + +@property(assign, nonatomic) int timerCount; + +@property(nonatomic, assign) BOOL isPstn; // 当前呼叫是否已进入pstn流程,默认 NO + +@property(nonatomic, strong) UIView *bannerView; + +@property(nonatomic, weak) UIAlertController *alert; + +@property(nonatomic, strong) UILabel *cnameLabel; + +@property(nonatomic, assign) BOOL isRemoteMute; + +@property(assign, nonatomic) CGFloat factor; + +/// 通话状态视图 +@property(nonatomic, strong) NEAudioCallingController *audioCallingController; + +@property(nonatomic, strong) NEAudioInCallController *audioInCallController; + +@property(nonatomic, strong) NEVideoCallingController *videoCallingController; + +@property(nonatomic, strong) NEVideoInCallController *videoInCallController; + +@property(nonatomic, strong) NECalledViewController *calledController; + +@property(nonatomic, weak) NECallUIStateController *stateUIController; + +@property(nonatomic, strong) NSBundle *bundle; + +@end + +@implementation NECallViewController + +- (instancetype)init { + self = [super init]; + if (self) { + self.timerCount = 0; + self.factor = 1.0; + self.bundle = [NSBundle bundleForClass:self.class]; + } + return self; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + [[NSNotificationCenter defaultCenter] postNotificationName:kCallKitShowNoti object:nil]; + [[NERtcEngine sharedEngine] setParameters:@{kNERtcKeyVideoStartWithBackCamera : @NO}]; + if (self.callType == NERtcCallTypeVideo) { + self.remoteCameraAvailable = YES; + } + [self setupUI]; + // [self setupCenterRemoteAvator]; + [self setupSDK]; + [self updateUIonStatus:self.status]; + if (self.isCaller == NO && [NERtcCallKit sharedInstance].callStatus == NERtcCallStatusIdle) { + __weak typeof(self) weakSelf = self; + dispatch_async(dispatch_get_main_queue(), ^{ + [weakSelf onCallEnd]; + }); + } + + [self.view addSubview:self.bannerView]; + [NSLayoutConstraint activateConstraints:@[ + [self.bannerView.topAnchor constraintEqualToAnchor:self.view.topAnchor constant:80], + [self.bannerView.leftAnchor constraintEqualToAnchor:self.view.leftAnchor constant:20], + [self.bannerView.rightAnchor constraintEqualToAnchor:self.view.rightAnchor constant:-20], + [self.bannerView.heightAnchor constraintEqualToConstant:40] + ]]; +} + +- (void)viewDidDisappear:(BOOL)animated { + [super viewDidDisappear:animated]; + [[NERtcCallKit sharedInstance] setupLocalView:nil]; +} + +#pragma mark - SDK +- (void)setupSDK { + [[NERtcCallKit sharedInstance] addDelegate:self]; + [[NERtcCallKit sharedInstance] enableLocalVideo:YES]; + + __weak typeof(self) weakSelf = self; + if (self.status == NERtcCallStatusCalling) { + [[NERtcCallKit sharedInstance] + call:self.callParam.remoteUserAccid + type:self.callType ? self.callType : NERtcCallTypeVideo + attachment:self.callParam.attachment + globalExtra:self.callParam.extra + withToken:self.callParam.token + channelName:self.callParam.channelName + completion:^(NSError *_Nullable error) { + NSLog(@"call error code : %@", error); + + if (weakSelf.callType == NERtcCallTypeVideo) { + if ([[SettingManager shareInstance] isGlobalInit] == YES) { + dispatch_async(dispatch_get_main_queue(), ^{ + [[NERtcCallKit sharedInstance] + setupLocalView:weakSelf.videoCallingController.bigVideoView.videoView]; + }); + } + self.videoCallingController.bigVideoView.userID = weakSelf.callParam.currentUserAccid; + } + + if (error) { + /// 对方离线时 通过APNS推送 UI不弹框提示 + if (error.code == 10202 || error.code == 10201) { + return; + } else { + [weakSelf onCallEnd]; + } + [UIApplication.sharedApplication.keyWindow makeToast:error.localizedDescription]; + } + }]; + } +} + +- (void)setCallType:(NERtcCallType)callType { + NSLog(@"set current call type : %lu", (unsigned long)callType); + _callType = callType; +} + +#pragma mark - UI +- (void)setupUI { + if (self.view.frame.size.height < 600) { + self.factor = 0.5; + } + + CGSize buttonSize = CGSizeMake(75, 103); + CGFloat statusHeight = [[UIApplication sharedApplication] statusBarFrame].size.height; + + self.blurImage = [[UIImageView alloc] init]; + self.blurImage.translatesAutoresizingMaskIntoConstraints = NO; + [self.view addSubview:self.blurImage]; + [NSLayoutConstraint activateConstraints:@[ + [self.blurImage.leftAnchor constraintEqualToAnchor:self.view.leftAnchor], + [self.blurImage.rightAnchor constraintEqualToAnchor:self.view.rightAnchor], + [self.blurImage.topAnchor constraintEqualToAnchor:self.view.topAnchor], + [self.blurImage.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor] + ]]; + + if (self.callParam.remoteAvatar.length <= 0) { + UIView *cover = [self getDefaultHeaderView:self.callParam.remoteUserAccid + font:[UIFont systemFontOfSize:200] + showName:self.callParam.remoteShowName]; + [self.blurImage addSubview:cover]; + [NSLayoutConstraint activateConstraints:@[ + [cover.leftAnchor constraintEqualToAnchor:self.blurImage.leftAnchor], + [cover.rightAnchor constraintEqualToAnchor:self.blurImage.rightAnchor], + [cover.topAnchor constraintEqualToAnchor:self.blurImage.topAnchor], + [cover.bottomAnchor constraintEqualToAnchor:self.blurImage.bottomAnchor] + ]]; + } + + self.toolBar = [[UIToolbar alloc] initWithFrame:self.view.bounds]; + self.toolBar.barStyle = UIBarStyleBlackOpaque; + [self.blurImage addSubview:self.toolBar]; + + [self setupChildController]; + + [self.view addSubview:self.switchCameraBtn]; + [NSLayoutConstraint activateConstraints:@[ + [self.switchCameraBtn.topAnchor constraintEqualToAnchor:self.view.topAnchor + constant:statusHeight + 20], + [self.switchCameraBtn.leftAnchor constraintEqualToAnchor:self.view.leftAnchor constant:20], + [self.switchCameraBtn.heightAnchor constraintEqualToConstant:30], + [self.switchCameraBtn.widthAnchor constraintEqualToConstant:30] + ]]; + + [self.view addSubview:self.operationView]; + [NSLayoutConstraint activateConstraints:@[ + [self.operationView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor], + [self.operationView.heightAnchor constraintEqualToConstant:60], + [self.operationView.widthAnchor constraintEqualToConstant:self.view.frame.size.width * 0.8], + [self.operationView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor + constant:-50.0 * self.factor] + ]]; + + /// 未接通状态下的音视频切换按钮 + self.mediaSwitchBtn = [[NECustomButton alloc] init]; + self.mediaSwitchBtn.maskBtn.accessibilityIdentifier = @"inCallSwitch"; + + [self.view addSubview:self.mediaSwitchBtn]; + [NSLayoutConstraint activateConstraints:@[ + [self.mediaSwitchBtn.centerXAnchor constraintEqualToAnchor:self.operationView.centerXAnchor], + [self.mediaSwitchBtn.bottomAnchor constraintEqualToAnchor:self.operationView.topAnchor + constant:-150 * self.factor], + [self.mediaSwitchBtn.heightAnchor constraintEqualToConstant:buttonSize.height], + [self.mediaSwitchBtn.widthAnchor constraintEqualToConstant:buttonSize.width] + ]]; + self.mediaSwitchBtn.hidden = YES; + + [self.mediaSwitchBtn.maskBtn addTarget:self + action:@selector(mediaClick:) + forControlEvents:UIControlEventTouchUpInside]; + + [self.view addSubview:self.timerLabel]; + [NSLayoutConstraint activateConstraints:@[ + [self.timerLabel.centerYAnchor constraintEqualToAnchor:self.switchCameraBtn.centerYAnchor], + [self.timerLabel.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor] + ]]; +} + +#pragma mark - inner function + +- (void)setCallingTypeSwith:(BOOL)show { + if (show == YES && self.config.showCallingSwitchCallType == YES) { + self.mediaSwitchBtn.hidden = NO; + } else { + self.mediaSwitchBtn.hidden = YES; + } +} + +- (void)setupChildController { + if (self.isCaller == YES) { + [self addChildViewController:self.videoCallingController]; + [self.view addSubview:self.videoCallingController.view]; + [self addChildViewController:self.audioCallingController]; + [self.view addSubview:self.audioCallingController.view]; + } else { + [self addChildViewController:self.calledController]; + [self.view addSubview:self.calledController.view]; + } + + [self addChildViewController:self.audioInCallController]; + [self.view addSubview:self.audioInCallController.view]; + [self addChildViewController:self.videoInCallController]; + [self.view addSubview:self.videoInCallController.view]; +} + +- (void)setSwitchAudioStyle { + self.mediaSwitchBtn.imageView.image = [UIImage imageNamed:@"switch_audio" + inBundle:self.bundle + compatibleWithTraitCollection:nil]; + self.mediaSwitchBtn.titleLabel.text = [self localizableWithKey:@"switch_to_audio"]; + self.mediaSwitchBtn.tag = NERtcCallTypeAudio; + [self showVideoView]; + [self setUrl:self.callParam.remoteAvatar withPlaceholder:@"avator"]; + [self.stateUIController refreshUI]; +} + +- (void)setSwitchVideoStyle { + self.mediaSwitchBtn.imageView.image = [UIImage imageNamed:@"switch_video" + inBundle:self.bundle + compatibleWithTraitCollection:nil]; + self.mediaSwitchBtn.titleLabel.text = [self localizableWithKey:@"switch_to_video"]; + self.mediaSwitchBtn.tag = NERtcCallTypeVideo; + [self hideVideoView]; + [self setUrl:self.callParam.remoteAvatar withPlaceholder:@"avator"]; + [self.stateUIController refreshUI]; +} + +- (void)updateUIonStatus:(NERtcCallStatus)status { + switch (status) { + case NERtcCallStatusCalling: { + [self setCallingTypeSwith:YES]; + self.operationView.hidden = YES; + self.stateUIController.view.hidden = YES; + if (self.callType == NERtcCallTypeVideo) { + self.stateUIController = self.videoCallingController; + [self.videoCallingController refreshUI]; + [self setSwitchAudioStyle]; + } else { + self.stateUIController = self.audioCallingController; + [self setSwitchVideoStyle]; + } + self.stateUIController.view.hidden = NO; + + } break; + case NERtcCallStatusCalled: { + [self setCallingTypeSwith:YES]; + self.operationView.hidden = YES; + self.stateUIController.view.hidden = YES; + self.stateUIController = self.calledController; + self.stateUIController.view.hidden = NO; + [self.calledController refreshUI]; + if (self.callType == NERtcCallTypeVideo) { + self.mediaSwitchBtn.imageView.image = [UIImage imageNamed:@"switch_audio" + inBundle:self.bundle + compatibleWithTraitCollection:nil]; + self.mediaSwitchBtn.titleLabel.text = [self localizableWithKey:@"switch_to_audio"]; + [self setSwitchAudioStyle]; + } else { + self.mediaSwitchBtn.imageView.image = [UIImage imageNamed:@"switch_video" + inBundle:self.bundle + compatibleWithTraitCollection:nil]; + self.mediaSwitchBtn.titleLabel.text = [self localizableWithKey:@"switch_to_video"]; + [self setSwitchVideoStyle]; + } + __weak typeof(self) weakSelf = self; + [self.calledController.remoteBigAvatorView + sd_setImageWithURL:[NSURL URLWithString:self.callParam.remoteAvatar] + completed:^(UIImage *_Nullable image, NSError *_Nullable error, + SDImageCacheType cacheType, NSURL *_Nullable imageURL) { + if (image == nil) { + image = [UIImage imageNamed:@"avator" + inBundle:self.bundle + compatibleWithTraitCollection:nil]; + } + if (weakSelf.isCaller == false && weakSelf.callType == NERtcCallTypeVideo) { + [weakSelf.blurImage setHidden:NO]; + } + weakSelf.blurImage.image = image; + }]; + + } break; + case NERtcCallStatusInCall: { + [self setCallingTypeSwith:NO]; + self.operationView.hidden = NO; + self.stateUIController.view.hidden = YES; + if (self.callType == NERtcCallTypeVideo) { + self.stateUIController = self.videoInCallController; + self.switchCameraBtn.hidden = NO; + [self.videoInCallController refreshUI]; + } else { + [self.operationView changeAudioStyle]; + self.stateUIController = self.audioInCallController; + } + self.stateUIController.view.hidden = NO; + + } break; + default: + break; + } + self.status = status; +} + +- (void)showVideoView { + if (self.status == NERtcCallStatusCalling) { + [[NERtcCallKit sharedInstance] + setupLocalView:self.videoCallingController.bigVideoView.videoView]; + } + if (self.status == NERtcCallStatusInCall) { + [[NERtcCallKit sharedInstance] + setupLocalView:self.videoInCallController.smallVideoView.videoView]; + [[NERtcCallKit sharedInstance] setupRemoteView:self.videoInCallController.bigVideoView.videoView + forUser:self.callParam.remoteUserAccid]; + } + + [[NERtcCallKit sharedInstance] muteLocalAudio:NO]; + [[NERtcCallKit sharedInstance] muteLocalVideo:NO]; + self.operationView.microPhone.selected = NO; + self.operationView.cameraBtn.selected = NO; + + self.operationView.speakerBtn.selected = NO; + self.operationView.microPhone.selected = NO; + NSError *error; + [[NERtcCallKit sharedInstance] setLoudSpeakerMode:YES error:&error]; + [[NERtcEngine sharedEngine] muteLocalAudio:NO]; +} + +- (void)hideVideoView { + [[NERtcCallKit sharedInstance] setupLocalView:nil]; + [[NERtcCallKit sharedInstance] setupRemoteView:nil forUser:nil]; + self.operationView.speakerBtn.selected = YES; + self.operationView.microPhone.selected = NO; + NSError *error; + [[NERtcCallKit sharedInstance] setLoudSpeakerMode:NO error:&error]; + [[NERtcEngine sharedEngine] muteLocalAudio:NO]; +} + +#pragma mark - event + +- (void)closeEvent:(UIButton *)button { + [[NERtcCallKit sharedInstance] hangup:^(NSError *_Nullable error){ + + }]; +} + +- (void)cancelEvent:(UIButton *)button { + __weak typeof(self) weakSelf = self; + NSLog(@"cancel rtc"); + if ([[NetManager shareInstance] isClose] == YES) { + [self destroy]; + } + [[NERtcCallKit sharedInstance] cancel:^(NSError *_Nullable error) { + NSLog(@"cancel error %@", error); + button.enabled = YES; + if (error.code == 20016) { + [UIApplication.sharedApplication.keyWindow + makeToast:[self localizableWithKey:@"cancel_failed"]]; + } else { + [weakSelf destroy]; + } + }]; +} +- (void)rejectEvent:(UIButton *)button { + if ([[NetManager shareInstance] isClose] == YES) { + [self destroy]; + } + self.calledController.acceptBtn.userInteractionEnabled = NO; + __weak typeof(self) weakSelf = self; + + if ([[SettingManager shareInstance] rejectBusyCode] == YES) { + [[NERtcCallKit sharedInstance] rejectWithReason:TerminalCodeBusy + withCompletion:^(NSError *_Nullable error) { + weakSelf.calledController.acceptBtn.userInteractionEnabled = + YES; + [weakSelf destroy]; + }]; + } else { + [[NERtcCallKit sharedInstance] reject:^(NSError *_Nullable error) { + weakSelf.calledController.acceptBtn.userInteractionEnabled = YES; + [weakSelf destroy]; + }]; + } +} +- (void)acceptEvent:(UIButton *)button { + if ([[NetManager shareInstance] isClose] == YES) { + [self.view makeToast:[self localizableWithKey:@"network_error"]]; + return; + } + + self.calledController.rejectBtn.userInteractionEnabled = NO; + self.calledController.acceptBtn.userInteractionEnabled = NO; + __weak typeof(self) weakSelf = self; + + [[NERtcCallKit sharedInstance] + acceptWithToken:[[SettingManager shareInstance] customToken] + withCompletion:^(NSError *_Nullable error) { + weakSelf.calledController.rejectBtn.userInteractionEnabled = YES; + weakSelf.calledController.acceptBtn.userInteractionEnabled = YES; + if (error) { + if (error.code != 10420) { + [UIApplication.sharedApplication.keyWindow + makeToast:[NSString stringWithFormat:@"%@ %@", + [self localizableWithKey:@"accept_failed"], + error.localizedDescription]]; + } + + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), + dispatch_get_main_queue(), ^{ + [weakSelf destroy]; + }); + } else { + [[NERtcCallKit sharedInstance] memberOfAccid:@"" + completion:^(NIMSignalingMemberInfo *_Nullable info){ + + }]; + [weakSelf updateUIonStatus:NERtcCallStatusInCall]; + [weakSelf startTimer]; + } + }]; +} +- (void)switchCameraBtn:(UIButton *)button { + [[NERtcCallKit sharedInstance] switchCamera]; + button.selected = !button.selected; + if (button.isSelected == YES) { + [[NERtcEngine sharedEngine] setParameters:@{kNERtcKeyVideoStartWithBackCamera : @YES}]; + } else { + [[NERtcEngine sharedEngine] setParameters:@{kNERtcKeyVideoStartWithBackCamera : @NO}]; + } +} +- (void)microPhoneClick:(UIButton *)button { + button.selected = !button.selected; + [[NERtcCallKit sharedInstance] muteLocalAudio:button.selected]; +} +- (void)cameraBtnClick:(UIButton *)button { + button.selected = !button.selected; + NSLog(@"mute video select : %d", button.selected); + if ([[SettingManager shareInstance] useEnableLocalMute] == YES) { + NSLog(@"enableLocalVideo: %d", !button.selected); + [[NERtcCallKit sharedInstance] enableLocalVideo:!button.selected]; + } else { + [[NERtcCallKit sharedInstance] muteLocalVideo:button.selected]; + } + [self changeDefaultImage:button.selected]; + [self cameraAvailble:!button.selected userId:self.callParam.currentUserAccid]; +} +- (void)hangupBtnClick:(UIButton *)button { + [[NERtcCallKit sharedInstance] hangup:^(NSError *_Nullable error){ + + }]; + + [self destroy]; +} +- (void)microphoneBtnClick:(UIButton *)button { + NSLog(@"micro phone btn click : %d", button.imageView.highlighted); + self.audioCallingController.microphoneBtn.imageView.highlighted = + !self.audioCallingController.microphoneBtn.imageView.highlighted; + [[NERtcCallKit sharedInstance] + muteLocalAudio:self.audioCallingController.microphoneBtn.imageView.highlighted]; + _operationView.microPhone.selected = + self.audioCallingController.microphoneBtn.imageView.highlighted; +} +- (void)speakerBtnClick:(UIButton *)button { + NSLog(@"speaker btn click : %d", self.audioCallingController.speakerBtn.imageView.highlighted); + NSError *error = nil; + + [[NERtcCallKit sharedInstance] + setLoudSpeakerMode:!self.audioCallingController.speakerBtn.imageView.highlighted + error:&error]; + if (error == nil) { + self.audioCallingController.speakerBtn.imageView.highlighted = + !self.audioCallingController.speakerBtn.imageView.highlighted; + _operationView.speakerBtn.selected = + !self.audioCallingController.speakerBtn.imageView.highlighted; + } else { + [self.view makeToast:error.description]; + } +} + +- (void)operationSwitchClick:(UIButton *)btn { + if ([[NetManager shareInstance] isClose] == YES) { + [self.view makeToast:[self localizableWithKey:@"network_error"]]; + return; + } + __weak typeof(self) weakSelf = self; + btn.enabled = NO; + NERtcCallType type = + self.callType == NERtcCallTypeVideo ? NERtcCallTypeAudio : NERtcCallTypeVideo; + [[NERtcCallKit sharedInstance] + switchCallType:type + withState:NERtcSwitchStateInvite + completion:^(NSError *_Nullable error) { + // weakSelf.mediaSwitchBtn.enabled = YES; + btn.enabled = YES; + if (error == nil) { + NSLog(@"切换成功 : %lu", type); + NSLog(@"switch : %d", btn.selected); + if (type == NERtcCallTypeVideo && [SettingManager.shareInstance isVideoConfirm]) { + [weakSelf showBannerView]; + } else if (type == NERtcCallTypeAudio && + [SettingManager.shareInstance isAudioConfirm]) { + [weakSelf showBannerView]; + } + } else { + [weakSelf.view + makeToast:[NSString stringWithFormat:@"%@: %@", + [self localizableWithKey:@"switch_error"], + error]]; + } + }]; +} + +- (void)operationSpeakerClick:(UIButton *)btn { + NSError *error = nil; + BOOL use; + [[NERtcEngine sharedEngine] getLoudspeakerMode:&use]; + NSLog(@"get loud speaker %d", use); + [[NERtcCallKit sharedInstance] setLoudSpeakerMode:btn.selected error:&error]; + if (error == nil) { + btn.selected = !btn.selected; + } else { + [self.view makeToast:error.description]; + } +} + +- (void)mediaClick:(UIButton *)btn { + if ([[NetManager shareInstance] isClose] == YES) { + [self.view makeToast:[self localizableWithKey:@"network_error"]]; + return; + } + __weak typeof(self) weakSelf = self; + self.mediaSwitchBtn.maskBtn.enabled = NO; + NERtcCallType type = + weakSelf.callType == NERtcCallTypeVideo ? NERtcCallTypeAudio : NERtcCallTypeVideo; + [[NERtcCallKit sharedInstance] + switchCallType:type + withState:NERtcSwitchStateInvite + completion:^(NSError *_Nullable error) { + weakSelf.mediaSwitchBtn.maskBtn.enabled = YES; + if (error == nil) { + if (type == NERtcCallTypeVideo && [SettingManager.shareInstance isVideoConfirm]) { + [weakSelf showBannerView]; + } else if (type == NERtcCallTypeAudio && + [SettingManager.shareInstance isAudioConfirm]) { + [weakSelf showBannerView]; + } + } else { + [weakSelf.view + makeToast:[NSString stringWithFormat:@"%@ : %@", + [self localizableWithKey:@"switch_error"], + error]]; + } + }]; +} + +#pragma mark - NERtcVideoCallDelegate + +- (void)onDisconnect:(NSError *)reason { + [self destroy]; +} +- (void)onUserEnter:(NSString *)userID { + [self updateUIonStatus:NERtcCallStatusInCall]; + [self startTimer]; + if ([[SettingManager shareInstance] incallShowCName] == YES && + [self.cnameLabel superview] == nil) { + [self.view addSubview:self.cnameLabel]; + self.cnameLabel.text = + [NSString stringWithFormat:@"cname: %@", [[SettingManager shareInstance] getRtcCName]]; + [NSLayoutConstraint activateConstraints:@[ + [self.cnameLabel.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor], + [self.cnameLabel.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor] + ]]; + } +} +- (void)onUserCancel:(NSString *)userID { + [[NERtcCallKit sharedInstance] hangup:^(NSError *_Nullable error){ + }]; + [UIApplication.sharedApplication.keyWindow makeToast:[self localizableWithKey:@"remote_cancel"]]; + [self destroy]; +} +- (void)onCameraAvailable:(BOOL)available userID:(NSString *)userID { + self.isRemoteMute = !available; + [self cameraAvailble:available userId:userID]; +} +- (void)onVideoMuted:(BOOL)muted userID:(NSString *)userID { + self.isRemoteMute = muted; + [self cameraAvailble:!muted userId:userID]; +} +- (void)onUserLeave:(NSString *)userID { + NSLog(@"onUserLeave"); + [self destroy]; +} +- (void)onUserDisconnect:(NSString *)userID { + NSLog(@"onUserDiconnect"); + [self destroy]; +} +- (void)onCallingTimeOut { + if ([[NetManager shareInstance] isClose] == YES) { + [self destroy]; + return; + } + [UIApplication.sharedApplication.keyWindow makeToast:[self localizableWithKey:@"remote_timeout"]]; + [self destroy]; +} +- (void)onUserBusy:(NSString *)userID { + [UIApplication.sharedApplication.keyWindow makeToast:[self localizableWithKey:@"remote_busy"]]; + [self destroy]; +} +- (void)onCallEnd { + [self destroy]; +} +- (void)onUserReject:(NSString *)userID { + [UIApplication.sharedApplication.keyWindow makeToast:[self localizableWithKey:@"remote_reject"]]; + [self destroy]; +} + +- (void)onOtherClientAccept { + [UIApplication.sharedApplication.keyWindow + makeToast:[self localizableWithKey:@"other_client_accept"]]; + [self destroy]; +} + +- (void)onOtherClientReject { + [UIApplication.sharedApplication.keyWindow + makeToast:[self localizableWithKey:@"other_client_reject"]]; + [self destroy]; +} + +- (void)onCallTypeChange:(NERtcCallType)callType withState:(NERtcSwitchState)state { + NSLog(@"onCallTypeChange: %lu withState: %lu", (unsigned long)callType, (unsigned long)state); + switch (state) { + case NERtcSwitchStateAgree: + [self hideBannerView]; + [self onCallTypeChange:callType]; + break; + case NERtcSwitchStateInvite: { + if (self.alert != nil) { + NSLog(@"alert is showing"); + return; + } + UIAlertController *alert = [UIAlertController + alertControllerWithTitle:[self localizableWithKey:@"permission"] + message:callType == NERtcCallTypeVideo + ? [self localizableWithKey:@"audio_to_video"] + : [self localizableWithKey:@"video_to_audio"] + preferredStyle:UIAlertControllerStyleAlert]; + self.alert = alert; + UIAlertAction *rejectAction = + [UIAlertAction actionWithTitle:[self localizableWithKey:@"reject"] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *_Nonnull action) { + [[NERtcCallKit sharedInstance] + switchCallType:callType + withState:NERtcSwitchStateReject + completion:^(NSError *_Nullable error) { + if (error) { + [UIApplication.sharedApplication.keyWindow + makeToast:error.localizedDescription]; + } + }]; + }]; + __weak typeof(self) weakSelf = self; + UIAlertAction *agreeAction = + [UIAlertAction actionWithTitle:[self localizableWithKey:@"agree"] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *_Nonnull action) { + [[NERtcCallKit sharedInstance] + switchCallType:callType + withState:NERtcSwitchStateAgree + completion:^(NSError *_Nullable error) { + [weakSelf onCallTypeChange:callType]; + if (error) { + [UIApplication.sharedApplication.keyWindow + makeToast:error.localizedDescription]; + } + }]; + }]; + + [alert addAction:rejectAction]; + [alert addAction:agreeAction]; + [self presentViewController:alert animated:YES completion:nil]; + + NSLog(@"NERtcSwitchStateInvite : %ld", callType); + + } + + break; + case NERtcSwitchStateReject: + [self hideBannerView]; + [UIApplication.sharedApplication.keyWindow makeToast:[self localizableWithKey:@"reject_tip"]]; + break; + default: + break; + } + NSLog(@"onCallTypeChange : %lu with state : %lu", callType, state); +} + +- (void)onCallTypeChange:(NERtcCallType)callType { + NSLog(@"onCallTypeChange:"); + if (self.callType == callType) { + return; + } + self.callType = callType; + [self updateUIonStatus:self.status]; + + if (self.status == NERtcCallStatusInCall) { + switch (callType) { + case NERtcCallTypeAudio: + NSLog(@"NERtcCallTypeAudio"); + [self.operationView changeAudioStyle]; + [self hideVideoView]; + break; + case NERtcCallTypeVideo: + NSLog(@"NERtcCallTypeVideo"); + [self.operationView changeVideoStyle]; + [self showVideoView]; + break; + default: + break; + } + return; + } + + switch (callType) { + case NERtcCallTypeAudio: + [self.operationView changeAudioStyle]; + [self setSwitchVideoStyle]; + break; + case NERtcCallTypeVideo: + [self.operationView changeVideoStyle]; + [self setSwitchAudioStyle]; + break; + default: + break; + } +} + +- (void)onError:(NSError *)error { + NSLog(@"call kit on error : %@", error); +} + +- (void)onAudioAvailable:(BOOL)available userID:(NSString *)userID { + NSLog(@"onAudioAvailable"); +} + +#pragma mark - private mothed +- (void)cameraAvailble:(BOOL)available userId:(NSString *)userId { + if ([self.videoInCallController.bigVideoView.userID isEqualToString:userId]) { + self.videoInCallController.bigVideoView.maskView.hidden = available; + self.remoteCameraAvailable = available; + } + if ([self.videoInCallController.smallVideoView.userID isEqualToString:userId]) { + self.videoInCallController.smallVideoView.maskView.hidden = available; + self.remoteCameraAvailable = available; + } +} + +- (void)setUrl:(NSString *)url withPlaceholder:(NSString *)holder { + __weak typeof(self) weakSelf = self; + UIImageView *remoteAvatorView = nil; + if (self.callType == NERtcCallTypeVideo) { + remoteAvatorView = self.videoCallingController.remoteAvatorView; + } else { + remoteAvatorView = self.calledController.remoteBigAvatorView; + } + [remoteAvatorView + sd_setImageWithURL:[NSURL URLWithString:url] + completed:^(UIImage *_Nullable image, NSError *_Nullable error, + SDImageCacheType cacheType, NSURL *_Nullable imageURL) { + if (image == nil) { + image = [UIImage imageNamed:holder + inBundle:self.bundle + compatibleWithTraitCollection:nil]; + } + if (weakSelf.isCaller == false && weakSelf.callType == NERtcCallTypeVideo) { + [weakSelf.blurImage setHidden:NO]; + } + weakSelf.blurImage.image = image; + }]; +} + +- (void)startTimer { + if (self.timer != nil) { + return; + } + if (self.timerLabel.hidden == YES) { + self.timerLabel.hidden = NO; + } + self.timer = [NSTimer scheduledTimerWithTimeInterval:1 + target:self + selector:@selector(figureTimer) + userInfo:nil + repeats:YES]; +} + +- (void)figureTimer { + self.timerCount++; + self.timerLabel.text = [self timeFormatted:self.timerCount]; +} + +- (NSString *)timeFormatted:(int)totalSeconds { + if (totalSeconds < 3600) { + int seconds = totalSeconds % 60; + int minutes = (totalSeconds / 60) % 60; + return [NSString stringWithFormat:@"%02d:%02d", minutes, seconds]; + } + int seconds = totalSeconds % 60; + int minutes = (totalSeconds / 60) % 60; + int hours = totalSeconds / 3600; + return [NSString stringWithFormat:@"%02d:%02d:%02d", hours, minutes, seconds]; +} + +- (NSString *)getInviteText { + return (self.callType == NERtcCallTypeAudio ? [self localizableWithKey:@"invite_audio_call"] + : [self localizableWithKey:@"invite_video_call"]); +} + +- (void)hideBannerView { + self.bannerView.hidden = YES; +} + +- (void)showBannerView { + self.bannerView.hidden = NO; +} + +#pragma mark - destroy +- (void)destroy { + if (self.alert != nil) { + [self.alert dismissViewControllerAnimated:NO completion:nil]; + } + [[NSNotificationCenter defaultCenter] postNotificationName:kCallKitDismissNoti object:nil]; + [[NERtcCallKit sharedInstance] removeDelegate:self]; + + if (self.timer != nil) { + [self.timer invalidate]; + self.timer = nil; + } +} + +#pragma mark - property + +- (UILabel *)cnameLabel { + if (_cnameLabel == nil) { + _cnameLabel = [[UILabel alloc] init]; + _cnameLabel.textColor = [UIColor redColor]; + _cnameLabel.font = [UIFont systemFontOfSize:14]; + _cnameLabel.translatesAutoresizingMaskIntoConstraints = NO; + } + return _cnameLabel; +} + +- (UIView *)bannerView { + if (!_bannerView) { + _bannerView = [[UIView alloc] init]; + _bannerView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.7]; + _bannerView.clipsToBounds = YES; + _bannerView.layer.cornerRadius = 4.0; + _bannerView.hidden = YES; + _bannerView.translatesAutoresizingMaskIntoConstraints = NO; + + NEExpandButton *closeBtn = [NEExpandButton buttonWithType:UIButtonTypeCustom]; + [_bannerView addSubview:closeBtn]; + closeBtn.translatesAutoresizingMaskIntoConstraints = NO; + closeBtn.backgroundColor = [UIColor clearColor]; + [closeBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + [closeBtn setTitle:@"X" forState:UIControlStateNormal]; + [closeBtn addTarget:self + action:@selector(hideBannerView) + forControlEvents:UIControlEventTouchUpInside]; + + [NSLayoutConstraint activateConstraints:@[ + [closeBtn.topAnchor constraintEqualToAnchor:_bannerView.topAnchor], + [closeBtn.bottomAnchor constraintEqualToAnchor:_bannerView.bottomAnchor], + [closeBtn.rightAnchor constraintEqualToAnchor:_bannerView.rightAnchor], + [closeBtn.widthAnchor constraintEqualToConstant:40] + ]]; + + UILabel *label = [[UILabel alloc] init]; + label.translatesAutoresizingMaskIntoConstraints = NO; + [_bannerView addSubview:label]; + label.textColor = [UIColor whiteColor]; + [NSLayoutConstraint activateConstraints:@[ + [label.leftAnchor constraintEqualToAnchor:self.bannerView.leftAnchor constant:10], + [label.topAnchor constraintEqualToAnchor:self.bannerView.topAnchor], + [label.rightAnchor constraintEqualToAnchor:closeBtn.leftAnchor constant:-10] + ]]; + + label.adjustsFontSizeToFitWidth = YES; + label.text = [self localizableWithKey:@"waitting_remote_response"]; + } + return _bannerView; +} + +- (UIButton *)switchCameraBtn { + if (!_switchCameraBtn) { + _switchCameraBtn = [[UIButton alloc] init]; + [_switchCameraBtn setImage:[UIImage imageNamed:@"call_switch_camera" + inBundle:self.bundle + compatibleWithTraitCollection:nil] + forState:UIControlStateNormal]; + [_switchCameraBtn addTarget:self + action:@selector(switchCameraBtn:) + forControlEvents:UIControlEventTouchUpInside]; + _switchCameraBtn.translatesAutoresizingMaskIntoConstraints = NO; + _switchCameraBtn.hidden = YES; + } + return _switchCameraBtn; +} + +- (NEVideoOperationView *)operationView { + if (!_operationView) { + _operationView = [[NEVideoOperationView alloc] init]; + _operationView.translatesAutoresizingMaskIntoConstraints = NO; + _operationView.layer.cornerRadius = 30; + [_operationView.microPhone addTarget:self + action:@selector(microPhoneClick:) + forControlEvents:UIControlEventTouchUpInside]; + [_operationView.cameraBtn addTarget:self + action:@selector(cameraBtnClick:) + forControlEvents:UIControlEventTouchUpInside]; + [_operationView.hangupBtn addTarget:self + action:@selector(hangupBtnClick:) + forControlEvents:UIControlEventTouchUpInside]; + [_operationView.mediaBtn addTarget:self + action:@selector(operationSwitchClick:) + forControlEvents:UIControlEventTouchUpInside]; + [_operationView.speakerBtn addTarget:self + action:@selector(operationSpeakerClick:) + forControlEvents:UIControlEventTouchUpInside]; + } + return _operationView; +} + +- (UILabel *)timerLabel { + if (nil == _timerLabel) { + _timerLabel = [[UILabel alloc] init]; + _timerLabel.textColor = [UIColor whiteColor]; + _timerLabel.font = [UIFont systemFontOfSize:14.0]; + _timerLabel.textAlignment = NSTextAlignmentCenter; + _timerLabel.translatesAutoresizingMaskIntoConstraints = NO; + } + return _timerLabel; +} + +- (void)dealloc { + [[NERtcCallKit sharedInstance] removeDelegate:self]; +} + +- (void)hideViews:(NSArray *)views { + for (UIView *view in views) { + [view setHidden:YES]; + } +} + +- (void)showViews:(NSArray *)views { + for (UIView *view in views) { + [view setHidden:NO]; + } +} + +- (void)changeDefaultImage:(BOOL)mute { + // TODO: 代码整理 + /* + UIImage *image = [[SettingManager shareInstance] muteDefaultImage]; + if (image != nil) { + if (mute == YES) { + if (self.showMyBigView) { + self.bigVideoView.imageView.image = image; + self.bigVideoView.imageView.hidden = NO; + [self changeRemoteMute:self.isRemoteMute videoView:self.smallVideoView]; + } else { + self.smallVideoView.imageView.image = image; + self.smallVideoView.imageView.hidden = NO; + [self changeRemoteMute:self.isRemoteMute videoView:self.bigVideoView]; + } + } else { + if (self.showMyBigView) { + self.bigVideoView.imageView.image = nil; + self.bigVideoView.imageView.hidden = YES; + self.smallVideoView.imageView.hidden = YES; + [self changeRemoteMute:self.isRemoteMute videoView:self.smallVideoView]; + } else { + self.smallVideoView.imageView.image = nil; + self.smallVideoView.imageView.hidden = YES; + [self changeRemoteMute:self.isRemoteMute videoView:self.bigVideoView]; + } + } + } */ +} + +- (void)changeRemoteMute:(BOOL)mute videoView:(NEVideoView *)remoteVideo { + UIImage *defaultImage = [[SettingManager shareInstance] remoteDefaultImage]; + if (mute == true && defaultImage != nil) { + remoteVideo.imageView.hidden = NO; + remoteVideo.imageView.image = defaultImage; + } else { + remoteVideo.imageView.hidden = YES; + } +} + +- (NEAudioCallingController *)audioCallingController { + if (nil == _audioCallingController) { + _audioCallingController = + (NEAudioCallingController *)[self getCallStateInstanceWithClassKey:kAudioCalling]; + } + if (nil == _audioCallingController) { + _audioCallingController = [[NEAudioCallingController alloc] init]; + _audioCallingController.isCaller = self.isCaller; + _audioCallingController.callParam = self.callParam; + _audioCallingController.callType = self.callType; + _audioCallingController.mainController = self; + _audioCallingController.view.hidden = YES; + } + + return _audioCallingController; +} + +- (NEAudioInCallController *)audioInCallController { + if (nil == _audioInCallController) { + _audioInCallController = + (NEAudioInCallController *)[self getCallStateInstanceWithClassKey:kAudioInCall]; + } + if (nil == _audioInCallController) { + _audioInCallController = [[NEAudioInCallController alloc] init]; + _audioInCallController.isCaller = self.isCaller; + _audioInCallController.callParam = self.callParam; + _audioInCallController.callType = self.callType; + _audioInCallController.mainController = self; + _audioInCallController.view.hidden = YES; + } + return _audioInCallController; +} + +- (NEVideoCallingController *)videoCallingController { + if (nil == _videoCallingController) { + _videoCallingController = + (NEVideoCallingController *)[self getCallStateInstanceWithClassKey:kVideoCalling]; + } + if (nil == _videoCallingController) { + _videoCallingController = [[NEVideoCallingController alloc] init]; + _videoCallingController.isCaller = self.isCaller; + _videoCallingController.callParam = self.callParam; + _videoCallingController.callType = self.callType; + _videoCallingController.mainController = self; + _videoCallingController.view.hidden = YES; + } + return _videoCallingController; +} + +- (NEVideoInCallController *)videoInCallController { + if (nil == _videoInCallController) { + _videoInCallController = + (NEVideoInCallController *)[self getCallStateInstanceWithClassKey:kVideoInCall]; + } + if (nil == _videoInCallController) { + _videoInCallController = [[NEVideoInCallController alloc] init]; + _videoInCallController.isCaller = self.isCaller; + _videoInCallController.callParam = self.callParam; + _videoInCallController.callType = self.callType; + _videoInCallController.mainController = self; + _videoInCallController.view.hidden = YES; + } + return _videoInCallController; +} + +- (NECalledViewController *)calledController { + if (nil == _calledController) { + _calledController = + (NECalledViewController *)[self getCallStateInstanceWithClassKey:kCalledState]; + } + if (nil == _calledController) { + _calledController = [[NECalledViewController alloc] init]; + _calledController.isCaller = self.isCaller; + _calledController.callParam = self.callParam; + _calledController.callType = self.callType; + _calledController.mainController = self; + _calledController.view.hidden = YES; + } + return _calledController; +} + +#pragma mark - common fuction + +- (NECallUIStateController *)getCallStateInstanceWithClassKey:(NSString *)key { + Class cls = [self.uiConfigDic objectForKey:key]; + if (nil != cls) { + NECallUIStateController *controller = [[cls alloc] init]; + controller.isCaller = self.isCaller; + controller.callParam = self.callParam; + controller.callType = self.callType; + controller.mainController = self; + controller.view.hidden = YES; + return controller; + } + return nil; +} + +- (UIView *)getDefaultHeaderView:(NSString *)accid + font:(UIFont *)font + showName:(NSString *)showName { + UIView *headerView = [[UIView alloc] init]; + headerView.backgroundColor = [UIColor colorWithStringWithString:accid]; + headerView.translatesAutoresizingMaskIntoConstraints = NO; + NSString *show = showName.length > 0 ? showName : accid; + if (show.length >= 2) { + UILabel *label = [[UILabel alloc] init]; + label.translatesAutoresizingMaskIntoConstraints = NO; + [headerView addSubview:label]; + label.textColor = [UIColor whiteColor]; + label.font = font; + label.text = [show substringWithRange:NSMakeRange(show.length - 2, 2)]; + [NSLayoutConstraint activateConstraints:@[ + [label.centerYAnchor constraintEqualToAnchor:headerView.centerYAnchor], + [label.centerXAnchor constraintEqualToAnchor:headerView.centerXAnchor] + ]]; + } + return headerView; +} + +- (NSString *)localizableWithKey:(NSString *)key { + return [self.bundle localizedStringForKey:key value:nil table:@"Localizable"]; + ; +} +@end diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NECalledViewController.h b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NECalledViewController.h new file mode 100644 index 00000000..72cbca29 --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NECalledViewController.h @@ -0,0 +1,13 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import "NECallUIStateController.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface NECalledViewController : NECallUIStateController + +@end + +NS_ASSUME_NONNULL_END diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NECalledViewController.m b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NECalledViewController.m new file mode 100644 index 00000000..81a49ddb --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NECalledViewController.m @@ -0,0 +1,64 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import "NECalledViewController.h" + +@interface NECalledViewController () + +@end + +@implementation NECalledViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. +} + +- (void)setupUI { + [super setupUI]; + /// 接听和拒接按钮 + [self.view addSubview:self.rejectBtn]; + [NSLayoutConstraint activateConstraints:@[ + [self.rejectBtn.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor + constant:-self.view.frame.size.width / 4.0], + [self.rejectBtn.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor + constant:-80 * self.factor], + [self.rejectBtn.widthAnchor constraintEqualToConstant:self.buttonSize.width], + [self.rejectBtn.heightAnchor constraintEqualToConstant:self.buttonSize.height] + ]]; + + [self.view addSubview:self.acceptBtn]; + [NSLayoutConstraint activateConstraints:@[ + [self.acceptBtn.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor + constant:self.view.frame.size.width / 4.0], + [self.acceptBtn.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor + constant:-80 * self.factor], + [self.acceptBtn.widthAnchor constraintEqualToConstant:self.buttonSize.width], + [self.acceptBtn.heightAnchor constraintEqualToConstant:self.buttonSize.height] + ]]; + + [self setupCenterRemoteAvator]; + + [self refreshUI]; +} + +- (void)refreshUI { + self.centerTitleLabel.text = self.callParam.remoteShowName.length > 0 + ? self.callParam.remoteShowName + : self.callParam.remoteUserAccid; + self.centerSubtitleLabel.text = [self getInviteText]; +} + +/* +#pragma mark - Navigation + +// In a storyboard-based application, you will often want to do a little preparation before +navigation +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. +} +*/ + +@end diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEVideoCallingController.h b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEVideoCallingController.h new file mode 100644 index 00000000..4609b176 --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEVideoCallingController.h @@ -0,0 +1,13 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import "NECallUIStateController.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface NEVideoCallingController : NECallUIStateController + +@end + +NS_ASSUME_NONNULL_END diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEVideoCallingController.m b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEVideoCallingController.m new file mode 100644 index 00000000..9501ad54 --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEVideoCallingController.m @@ -0,0 +1,84 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import "NEVideoCallingController.h" + +@interface NEVideoCallingController () + +@end + +@implementation NEVideoCallingController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. +} + +- (void)setupUI { + [super setupUI]; + + [self.view addSubview:self.bigVideoView]; + [NSLayoutConstraint activateConstraints:@[ + [self.bigVideoView.leftAnchor constraintEqualToAnchor:self.view.leftAnchor], + [self.bigVideoView.rightAnchor constraintEqualToAnchor:self.view.rightAnchor], + [self.bigVideoView.topAnchor constraintEqualToAnchor:self.view.topAnchor], + [self.bigVideoView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor] + ]]; + + // [self.view addSubview:self.smallVideoView]; + // [NSLayoutConstraint activateConstraints:@[ + // [self.smallVideoView.topAnchor constraintEqualToAnchor:self.view.topAnchor + // constant:self.statusHeight + 20], + // [self.smallVideoView.rightAnchor constraintEqualToAnchor:self.view.rightAnchor + // constant:-20], [self.smallVideoView.heightAnchor constraintEqualToConstant:160], + // [self.smallVideoView.widthAnchor constraintEqualToConstant:90] + // ]]; + // + // self.smallVideoView.clipsToBounds = YES; + // self.smallVideoView.layer.cornerRadius = self.radius; + // self.smallVideoView.hidden = YES; + + [self.view addSubview:self.remoteAvatorView]; + [NSLayoutConstraint activateConstraints:@[ + [self.remoteAvatorView.topAnchor constraintEqualToAnchor:self.view.topAnchor + constant:self.statusHeight + 20], + [self.remoteAvatorView.rightAnchor constraintEqualToAnchor:self.view.rightAnchor constant:-20], + [self.remoteAvatorView.heightAnchor constraintEqualToConstant:60], + [self.remoteAvatorView.widthAnchor constraintEqualToConstant:60] + ]]; + + self.remoteAvatorView.clipsToBounds = YES; + self.remoteAvatorView.layer.cornerRadius = self.radius; + + [self.view addSubview:self.titleLabel]; + [NSLayoutConstraint activateConstraints:@[ + [self.titleLabel.topAnchor constraintEqualToAnchor:self.remoteAvatorView.topAnchor constant:5], + [self.titleLabel.rightAnchor constraintEqualToAnchor:self.remoteAvatorView.leftAnchor + constant:-8], + [self.titleLabel.leftAnchor constraintEqualToAnchor:self.view.leftAnchor constant:20], + [self.titleLabel.heightAnchor constraintEqualToConstant:25] + ]]; + + [self.view addSubview:self.subTitleLabel]; + [NSLayoutConstraint activateConstraints:@[ + [self.subTitleLabel.topAnchor constraintEqualToAnchor:self.titleLabel.bottomAnchor], + [self.subTitleLabel.rightAnchor constraintEqualToAnchor:self.titleLabel.rightAnchor], + [self.subTitleLabel.leftAnchor constraintEqualToAnchor:self.titleLabel.leftAnchor], + [self.subTitleLabel.heightAnchor constraintEqualToConstant:20] + ]]; + + /// 取消按钮 + [self.view addSubview:self.cancelBtn]; + [NSLayoutConstraint activateConstraints:@[ + [self.cancelBtn.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor], + [self.cancelBtn.widthAnchor constraintEqualToConstant:self.buttonSize.width], + [self.cancelBtn.heightAnchor constraintEqualToConstant:self.buttonSize.height], + [self.cancelBtn.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor + constant:-80 * self.factor] + ]]; + + [self setupVideoCallingUI]; +} + +@end diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEVideoInCallController.h b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEVideoInCallController.h new file mode 100644 index 00000000..b3b944cc --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEVideoInCallController.h @@ -0,0 +1,13 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import "NECallUIStateController.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface NEVideoInCallController : NECallUIStateController + +@end + +NS_ASSUME_NONNULL_END diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEVideoInCallController.m b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEVideoInCallController.m new file mode 100644 index 00000000..618160b6 --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/Controller/NEVideoInCallController.m @@ -0,0 +1,56 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import "NEVideoInCallController.h" + +@interface NEVideoInCallController () + +@end + +@implementation NEVideoInCallController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. +} + +- (void)setupUI { + [super setupUI]; + [self.view addSubview:self.bigVideoView]; + [NSLayoutConstraint activateConstraints:@[ + [self.bigVideoView.leftAnchor constraintEqualToAnchor:self.view.leftAnchor], + [self.bigVideoView.rightAnchor constraintEqualToAnchor:self.view.rightAnchor], + [self.bigVideoView.topAnchor constraintEqualToAnchor:self.view.topAnchor], + [self.bigVideoView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor] + ]]; + + [self.view addSubview:self.smallVideoView]; + [NSLayoutConstraint activateConstraints:@[ + [self.smallVideoView.topAnchor constraintEqualToAnchor:self.view.topAnchor + constant:self.statusHeight + 20], + [self.smallVideoView.rightAnchor constraintEqualToAnchor:self.view.rightAnchor constant:-20], + [self.smallVideoView.heightAnchor constraintEqualToConstant:160], + [self.smallVideoView.widthAnchor constraintEqualToConstant:90] + ]]; + + self.smallVideoView.clipsToBounds = YES; + self.smallVideoView.layer.cornerRadius = self.radius; +} + +- (void)refreshUI { + [self refreshVideoView]; +} + +/* +#pragma mark - Navigation + +// In a storyboard-based application, you will often want to do a little preparation before +navigation +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. +} +*/ + +@end diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/Manager/NetManager.h b/NERtcCallUIKit/NERtcCallUIKit/Classes/Manager/NetManager.h new file mode 100644 index 00000000..4cb79720 --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/Manager/NetManager.h @@ -0,0 +1,17 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NetManager : NSObject + +@property(nonatomic, assign) BOOL isClose; + ++ (id)shareInstance; + +@end + +NS_ASSUME_NONNULL_END diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/Manager/NetManager.m b/NERtcCallUIKit/NERtcCallUIKit/Classes/Manager/NetManager.m new file mode 100644 index 00000000..fdf3009c --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/Manager/NetManager.m @@ -0,0 +1,59 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import "NetManager.h" +#import "AFNetworking.h" + +@implementation NetManager + ++ (id)shareInstance { + static NetManager *shareInstance = nil; + static dispatch_once_t once_token; + dispatch_once(&once_token, ^{ + if (!shareInstance) { + shareInstance = [[self alloc] init]; + } + }); + return shareInstance; +} + +- (instancetype)init { + self = [super init]; + if (self) { + [self monitorNetworkState]; + } + return self; +} + +#pragma mark - 监测网络状态 +- (void)monitorNetworkState { + AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager]; + [manager startMonitoring]; + self.isClose = [manager isReachable] ? NO : YES; + NSLog(@"net work close state : %d", self.isClose); + [manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { + switch (status) { + case AFNetworkReachabilityStatusNotReachable: + NSLog(@"没有网络"); + self.isClose = YES; + break; + case AFNetworkReachabilityStatusUnknown: + NSLog(@"未知"); + self.isClose = YES; + break; + case AFNetworkReachabilityStatusReachableViaWiFi: + NSLog(@"WiFi"); + self.isClose = NO; + break; + case AFNetworkReachabilityStatusReachableViaWWAN: + NSLog(@"3G|4G"); + self.isClose = NO; + break; + default: + break; + } + }]; +} + +@end diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/Manager/SettingManager.h b/NERtcCallUIKit/NERtcCallUIKit/Classes/Manager/SettingManager.h new file mode 100644 index 00000000..67e510d0 --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/Manager/SettingManager.h @@ -0,0 +1,71 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface SettingManager : NSObject + +@property(nonatomic, assign, readonly) NSInteger timeout; + +@property(nonatomic, assign, readonly) BOOL supportAutoJoinWhenCalled; + +@property(nonatomic, assign, readonly) BOOL rejectBusyCode; + +@property(nonatomic, assign, readonly) BOOL openCustomTokenAndChannelName; + +@property(nonatomic, assign) uint64_t customUid; + +@property(nonatomic, strong) NSString *customChannelName; + +@property(nonatomic, strong) NSString *customToken; + +@property(nonatomic, strong) NSString *globalExtra; + +@property(nonatomic, assign) BOOL isAudioConfirm; + +@property(nonatomic, assign) BOOL isJoinRtcWhenCall; + +@property(nonatomic, assign) BOOL isVideoConfirm; + +@property(nonatomic, assign, readonly) bool incallShowCName; + +@property(nonatomic, strong, nullable) UIImage *muteDefaultImage; + +@property(nonatomic, strong, nullable) UIImage *remoteDefaultImage; + +@property(nonatomic, assign) BOOL isGroupPush; + +@property(nonatomic, strong) NSString *customPushContent; + +@property(nonatomic, assign, readonly) BOOL isGlobalInit; + +@property(nonatomic, assign, readonly) BOOL useEnableLocalMute; + ++ (id)shareInstance; + +- (void)setTimeoutWithSecond:(NSInteger)second; + +- (void)setAutoJoin:(BOOL)autoJoin; + +- (void)setBusyCode:(BOOL)open; + +- (void)setCallKitUid:(uint64_t)uid; + +- (void)setShowCName:(BOOL)show; + +- (NSString *)getRtcCName; + +- (uint64_t)getCallKitUid; + +- (void)setEnableLocal:(BOOL)enable; + +- (void)setIsGlobalInit:(BOOL)isGlobalInit + withApnsCer:(NSString *)apnsCer + withAppkey:(NSString *)appkey; + +@end + +NS_ASSUME_NONNULL_END diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/Manager/SettingManager.m b/NERtcCallUIKit/NERtcCallUIKit/Classes/Manager/SettingManager.m new file mode 100644 index 00000000..40f2bcf4 --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/Manager/SettingManager.m @@ -0,0 +1,157 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import "SettingManager.h" +#import +NSString *const kYXOTOTimeOut = @"kYXOTOTimeOut"; + +NSString *const kShowCName = @"kShowCName"; + +@interface SettingManager () + +@property(nonatomic, assign, readwrite) NSInteger timeout; + +@property(nonatomic, assign, readwrite) BOOL supportAutoJoinWhenCalled; + +@property(nonatomic, assign, readwrite) BOOL rejectBusyCode; + +@property(nonatomic, assign, readwrite) BOOL openCustomTokenAndChannelName; + +@property(nonatomic, assign, readwrite) bool incallShowCName; + +@property(nonatomic, assign, readwrite) BOOL useEnableLocalMute; + +@property(nonatomic, assign, readwrite) BOOL isGlobalInit; + +@end + +@implementation SettingManager + ++ (id)shareInstance { + static SettingManager *shareInstance = nil; + static dispatch_once_t once_token; + dispatch_once(&once_token, ^{ + if (!shareInstance) { + shareInstance = [[self alloc] init]; + } + }); + return shareInstance; +} + +- (void)setCallKitUid:(uint64_t)uid { + [[NERtcCallKit sharedInstance] setValue:[NSNumber numberWithUnsignedLongLong:uid] + forKeyPath:@"context.currentUserUid"]; + + // if ([[NERtcCallKit sharedInstance] respondsToSelector:@selector(changeStatusIdle)]) { + // [[NERtcCallKit sharedInstance] changeStatusIdle]; + // } +} + +- (uint64_t)getCallKitUid { + return [[[NERtcCallKit sharedInstance] valueForKeyPath:@"context.currentUserUid"] + unsignedLongLongValue]; +} + +- (void)setAutoJoin:(BOOL)autoJoin { + [[NERtcCallKit sharedInstance] setValue:[NSNumber numberWithBool:autoJoin] + forKeyPath:@"context.supportAutoJoinWhenCalled"]; + self.supportAutoJoinWhenCalled = autoJoin; +} + +- (void)setBusyCode:(BOOL)open { + self.rejectBusyCode = open; +} + +- (instancetype)init { + self = [super init]; + if (self) { + self.isGroupPush = YES; + self.supportAutoJoinWhenCalled = [[[NERtcCallKit sharedInstance] + valueForKeyPath:@"context.supportAutoJoinWhenCalled"] boolValue]; + self.rejectBusyCode = NO; + NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults]; + NSNumber *showCname = [userDefault objectForKey:kShowCName]; + if (showCname != nil) { + self.incallShowCName = [showCname boolValue]; + } + NSLog(@"current accid : %@", NIMSDK.sharedSDK.loginManager.currentAccount); + } + return self; +} + +- (void)setTimeoutWithSecond:(NSInteger)second { + [[NERtcCallKit sharedInstance] setTimeOutSeconds:second]; +} + +- (NSInteger)timeout { + return [[NERtcCallKit sharedInstance] timeOutSeconds]; +} + +- (BOOL)isGlobalInit { + return ![[[NERtcCallKit sharedInstance] valueForKeyPath:@"context.globalInit"] boolValue]; +} + +- (void)setIsGlobalInit:(BOOL)isGlobalInit + withApnsCer:(NSString *)apnsCer + withAppkey:(NSString *)appkey { + [[NERtcCallKit sharedInstance] setValue:[NSNumber numberWithBool:!isGlobalInit] + forKeyPath:@"context.globalInit"]; + if (isGlobalInit == NO) { + NERtcCallOptions *option = [NERtcCallOptions new]; + option.APNSCerName = apnsCer; + option.disableRecord = NO; + option.joinRtcWhenCall = [self isJoinRtcWhenCall]; + option.globalInit = YES; + NERtcCallKit *callkit = [NERtcCallKit sharedInstance]; + option.supportAutoJoinWhenCalled = self.supportAutoJoinWhenCalled; + [callkit setupAppKey:appkey options:option]; + } else { + [NERtcEngine destroyEngine]; + } +} + +- (BOOL)isJoinRtcWhenCall { + return [[[NERtcCallKit sharedInstance] valueForKeyPath:@"context.joinRtcWhenCall"] boolValue]; +} + +- (void)setIsJoinRtcWhenCall:(BOOL)isJoinRtcWhenCall { + [[NERtcCallKit sharedInstance] setValue:[NSNumber numberWithBool:isJoinRtcWhenCall] + forKeyPath:@"context.joinRtcWhenCall"]; +} + +- (BOOL)isAudioConfirm { + return [[[NERtcCallKit sharedInstance] valueForKeyPath:@"context.confirmAudio"] boolValue]; +} + +- (void)setIsAudioConfirm:(BOOL)isAudioConfirm { + [[NERtcCallKit sharedInstance] setValue:[NSNumber numberWithBool:isAudioConfirm] + forKeyPath:@"context.confirmAudio"]; +} + +- (BOOL)isVideoConfirm { + return [[[NERtcCallKit sharedInstance] valueForKeyPath:@"context.confirmVideo"] boolValue]; +} + +- (void)setIsVideoConfirm:(BOOL)isVideoConfirm { + [[NERtcCallKit sharedInstance] setValue:[NSNumber numberWithBool:isVideoConfirm] + forKeyPath:@"context.confirmVideo"]; +} + +- (NSString *)getRtcCName { + return [[NERtcCallKit sharedInstance] valueForKeyPath:@"context.channelInfo.channelName"]; +} + +- (void)setShowCName:(BOOL)show { + self.incallShowCName = show; + NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults]; + [userDefault setObject:[NSNumber numberWithBool:show] forKey:kShowCName]; + [userDefault synchronize]; +} + +// 1.5.6 add +- (void)setEnableLocal:(BOOL)enable { + self.useEnableLocalMute = enable; +} + +@end diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/Model/NECallParam.h b/NERtcCallUIKit/NERtcCallUIKit/Classes/Model/NECallParam.h new file mode 100644 index 00000000..ace9ddb5 --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/Model/NECallParam.h @@ -0,0 +1,32 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NECallParam : NSObject + +#pragma mark - 必要参数 +// 被叫accid +@property(nonatomic, strong) NSString *remoteUserAccid; +// 主叫accid +@property(nonatomic, strong) NSString *currentUserAccid; +// 通话页面被叫显示名称 +@property(nonatomic, strong) NSString *remoteShowName; +// 被叫头像链接 +@property(nonatomic, strong) NSString *remoteAvatar; +// 呼叫类型 +@property(assign, nonatomic) NERtcCallType callType; + +#pragma mark - 可选自定义参数 +@property(nonatomic, strong) NSString *token; +@property(nonatomic, strong) NSString *extra; +@property(nonatomic, strong) NSString *channelName; +@property(nonatomic, strong) NSString *attachment; + +@end + +NS_ASSUME_NONNULL_END diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatBaseCollectionViewCell.swift b/NERtcCallUIKit/NERtcCallUIKit/Classes/Model/NECallParam.m similarity index 68% rename from NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatBaseCollectionViewCell.swift rename to NERtcCallUIKit/NERtcCallUIKit/Classes/Model/NECallParam.m index c64290c5..3d6e0ec0 100644 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatBaseCollectionViewCell.swift +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/Model/NECallParam.m @@ -1,8 +1,9 @@ - // Copyright (c) 2022 NetEase, Inc. All rights reserved. // Use of this source code is governed by a MIT license that can be // found in the LICENSE file. -import UIKit +#import "NECallParam.h" + +@implementation NECallParam -class QChatBaseCollectionViewCell: UICollectionViewCell {} +@end diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/NERtcCallUIConfig.h b/NERtcCallUIKit/NERtcCallUIKit/Classes/NERtcCallUIConfig.h new file mode 100644 index 00000000..624b5a2e --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/NERtcCallUIConfig.h @@ -0,0 +1,46 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NECallUIConfig : NSObject + +/// 是否禁止音频通话转视频通话,默认NO,支持转换 +@property(nonatomic, assign) BOOL audioToVideoDisable; + +/// 是否禁止音频通话转视频通话,默认NO,支持转换 +@property(nonatomic, assign) BOOL videoToAudioDisable; + +/// 收到呼叫时是否禁止弹出被叫页面,默认NO,弹出被叫页面,用户可以通过此配置禁止组件弹出,自己通过继承以及监听被叫回调实现相关功能 +@property(nonatomic, assign) BOOL disableShowCalleeView; + +/// 是否初始化路由配置,默认NO,不进行路由初始化配置 +@property(nonatomic, assign) BOOL isInitRouter; + +/// 通话前音视频切换按钮是否显示,默认NO,不显示,开启此配置前需要开启 NERtcCallOptions 中 +/// supportAutoJoinWhenCalled 属性 +@property(nonatomic, assign) BOOL showCallingSwitchCallType; + +/// 被叫显示昵称字段还是手机号字段,默认显示昵称 +@property(nonatomic, assign) BOOL calleeShowPhone; + +@end + +@interface NERtcCallUIConfig : NSObject + +/// 透传 NERtcCallKit 初始化配置,如果不需要UI组件内部初始化 NERtcCallKit 则不传此参数即可 +@property(nonatomic, strong) NERtcCallOptions *option; + +/// appkey +@property(nonatomic, strong) NSString *appKey; + +/// UI 配置 +@property(nonatomic, strong) NECallUIConfig *uiConfig; + +@end + +NS_ASSUME_NONNULL_END diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/NERtcCallUIConfig.m b/NERtcCallUIKit/NERtcCallUIKit/Classes/NERtcCallUIConfig.m new file mode 100644 index 00000000..068e1aea --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/NERtcCallUIConfig.m @@ -0,0 +1,20 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import "NERtcCallUIConfig.h" + +@implementation NECallUIConfig + +@end + +@implementation NERtcCallUIConfig + +- (NECallUIConfig *)uiConfig { + if (nil == _uiConfig) { + _uiConfig = [[NECallUIConfig alloc] init]; + } + return _uiConfig; +} + +@end diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/NERtcCallUIKit.h b/NERtcCallUIKit/NERtcCallUIKit/Classes/NERtcCallUIKit.h new file mode 100644 index 00000000..49f2ba70 --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/NERtcCallUIKit.h @@ -0,0 +1,57 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#ifndef NERtcCallUIKit_h +#define NERtcCallUIKit_h + +#import "NECallParam.h" +#import "NECallViewController.h" +#import "NECustomButton.h" +#import "NEExpandButton.h" +#import "NERtcCallUIConfig.h" +#import "NEVideoOperationView.h" +#import "NEVideoView.h" +#import "NetManager.h" +#import "SettingManager.h" + +#import "NEAudioCallingController.h" +#import "NEAudioInCallController.h" +#import "NECalledViewController.h" +#import "NEVideoCallingController.h" +#import "NEVideoInCallController.h" + +// 音频呼叫中UI状态 +extern NSString *_Nonnull kAudioCalling; +// 视频呼叫中UI状态 +extern NSString *_Nonnull kVideoCalling; +// 音频通话中UI状态 +extern NSString *_Nonnull kAudioInCall; +// 视频通话中UI状态 +extern NSString *_Nonnull kVideoInCall; +// 被叫UI状态(音频&视频) +extern NSString *_Nonnull kCalledState; + +#endif /* NERtcCallUIKit_h */ + +NS_ASSUME_NONNULL_BEGIN + +@interface NERtcCallUIKit : NSObject + +/// UI状态配置类,如果用户需要自定义某个状态的UI,需要继承通话状态类,通过对应key值覆盖对应Class +@property(nonatomic, strong, readonly) NSMutableDictionary *uiConfigDic; + ++ (instancetype)sharedInstance; + +/// 初始化,所有功能需要先初始化 +/// @param config 初始化参数 +- (void)setupWithConfig:(NERtcCallUIConfig *)config; + +- (void)callWithParam:(NECallParam *)callParam withCallType:(NERtcCallType)callType; + +/// 版本号 ++ (NSString *)version; + +@end + +NS_ASSUME_NONNULL_END diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/NERtcCallUIKit.m b/NERtcCallUIKit/NERtcCallUIKit/Classes/NERtcCallUIKit.m new file mode 100644 index 00000000..8edb6e21 --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/NERtcCallUIKit.m @@ -0,0 +1,230 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import "NERtcCallUIKit.h" +#import +#import +#import +#import "NetManager.h" + +NSString *kAudioCalling = @"kAudioCalling"; + +NSString *kVideoCalling = @"kVideoCalling"; + +NSString *kAudioInCall = @"kAudioInCall"; + +NSString *kVideoInCall = @"kVideoInCall"; + +NSString *kCalledState = @"kCalledState"; + +NSString *kMouldName = @"NERtcCallUIKit"; + +@interface NERtcCallUIKit () + +@property(nonatomic, strong) NERtcCallUIConfig *config; + +@property(nonatomic, strong) UIWindow *keywindow; + +@property(nonatomic, strong, readwrite) NSMutableDictionary *uiConfigDic; + +@property(nonatomic, strong) NSBundle *bundle; + +@end + +@implementation NERtcCallUIKit + ++ (instancetype)sharedInstance { + static dispatch_once_t onceToken; + static NERtcCallUIKit *instance; + dispatch_once(&onceToken, ^{ + instance = [[self alloc] init]; + }); + return instance; +} + +- (NSString *)serviceName { + return kMouldName; +} + +- (NSString *)versionName { + return [NERtcCallUIKit version]; +} + +- (NSString *)appKey { + return self.config.appKey; +} + +- (void)setupWithConfig:(NERtcCallUIConfig *)config { + if (nil != config.option && config.appKey != nil) { + [[NERtcCallKit sharedInstance] setupAppKey:config.appKey options:config.option]; + } + [[XKit instance] registerService:self]; + self.config = config; +} + +- (instancetype)init { + self = [super init]; + if (self) { + [NetManager shareInstance]; + [[NERtcCallKit sharedInstance] addDelegate:self]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(didDismiss:) + name:kCallKitDismissNoti + object:nil]; + self.uiConfigDic = [[NSMutableDictionary alloc] init]; + [self.uiConfigDic setObject:NEAudioCallingController.class forKey:kAudioCalling]; + [self.uiConfigDic setObject:NEAudioInCallController.class forKey:kAudioInCall]; + [self.uiConfigDic setObject:NEVideoCallingController.class forKey:kVideoCalling]; + [self.uiConfigDic setObject:NEVideoInCallController.class forKey:kVideoInCall]; + [self registerRouter]; + [NERtcCallKit sharedInstance].recordHandler = ^(NIMMessage *message) { + if ([[NetManager shareInstance] isClose] == YES) { + NIMRtcCallRecordObject *object = (NIMRtcCallRecordObject *)message.messageObject; + object.callStatus = NIMRtcCallStatusCanceled; + } + }; + self.bundle = [NSBundle bundleForClass:self.class]; + } + return self; +} + +- (NSString *)localizableWithKey:(NSString *)key { + return [self.bundle localizedStringForKey:key value:nil table:@"Localizable"]; +} + +- (void)registerRouter { + [[Router shared] register:@"imkit://callkit.page" + closure:^(NSDictionary *_Nonnull param) { + if ([[NetManager shareInstance] isClose] == YES) { + [UIApplication.sharedApplication.keyWindow + makeToast:[self localizableWithKey:@"network_error"]]; + return; + } + NECallParam *callParam = [[NECallParam alloc] init]; + callParam.currentUserAccid = [param objectForKey:@"currentUserAccid"]; + callParam.remoteUserAccid = [param objectForKey:@"remoteUserAccid"]; + callParam.remoteShowName = [param objectForKey:@"remoteShowName"]; + callParam.remoteAvatar = [param objectForKey:@"remoteAvatar"]; + NSNumber *type = [param objectForKey:@"type"]; + NERtcCallType callType = NERtcCallTypeAudio; + if (type.intValue == 1) { + callType = NERtcCallTypeAudio; + } else if (type.intValue == 2) { + callType = NERtcCallTypeVideo; + } + [self callWithParam:callParam withCallType:callType]; + }]; +} + +- (void)callWithParam:(NECallParam *)callParam withCallType:(NERtcCallType)callType { + NECallViewController *callVC = [[NECallViewController alloc] init]; + if (callParam.remoteShowName.length <= 0) { + callParam.remoteShowName = callParam.remoteUserAccid; + } + callVC.isCaller = YES; + callVC.callType = callType; + callVC.status = NERtcCallStatusCalling; + callVC.callParam = callParam; + callVC.uiConfigDic = self.uiConfigDic; + callVC.config = self.config.uiConfig; + [self showCallView:callVC]; +} + +- (void)onInvited:(NSString *)invitor + userIDs:(NSArray *)userIDs + isFromGroup:(BOOL)isFromGroup + groupID:(NSString *)groupID + type:(NERtcCallType)type + attachment:(NSString *)attachment { + if (self.config.uiConfig.disableShowCalleeView == YES) { + return; + } + + [NIMSDK.sharedSDK.userManager + fetchUserInfos:@[ invitor ] + completion:^(NSArray *_Nullable users, NSError *_Nullable error) { + if (error) { + [UIApplication.sharedApplication.keyWindow makeToast:error.description]; + return; + } else { + NIMUser *imUser = users.firstObject; + NECallViewController *callVC = [[NECallViewController alloc] init]; + NECallParam *callParam = [[NECallParam alloc] init]; + callParam.remoteUserAccid = imUser.userId; + callParam.remoteShowName = self.config.uiConfig.calleeShowPhone == YES + ? imUser.userInfo.mobile + : imUser.userInfo.nickName; + callParam.remoteAvatar = imUser.userInfo.avatarUrl; + callParam.currentUserAccid = NIMSDK.sharedSDK.loginManager.currentAccount; + callVC.callParam = callParam; + callVC.isCaller = NO; + callVC.status = NERtcCallStatusCalled; + callVC.callType = type; + callVC.uiConfigDic = self.uiConfigDic; + callVC.config = self.config.uiConfig; + [self showCallView:callVC]; + } + }]; +} + +- (void)showCalled:(NIMUser *)imUser + callType:(NERtcCallType)type + attachment:(NSString *)attachment { + NECallViewController *callVC = [[NECallViewController alloc] init]; + NECallParam *callParam = [[NECallParam alloc] init]; + callParam.remoteUserAccid = imUser.userId; + callParam.remoteShowName = imUser.userInfo.mobile; + callParam.remoteAvatar = imUser.userInfo.avatarUrl; + callParam.currentUserAccid = NIMSDK.sharedSDK.loginManager.currentAccount; + callVC.callParam = callParam; + callVC.isCaller = NO; + callVC.status = NERtcCallStatusCalled; + callVC.callType = type; + callVC.uiConfigDic = self.uiConfigDic; + callVC.config = self.config.uiConfig; + [self showCallView:callVC]; +} + +- (void)showCallView:(UIViewController *)callVC { + UINavigationController *nav = [self getKeyWindowNav]; + UINavigationController *callNav = + [[UINavigationController alloc] initWithRootViewController:callVC]; + callNav.modalPresentationStyle = UIModalPresentationFullScreen; + [callNav.navigationBar setHidden:YES]; + [nav presentViewController:callNav animated:YES completion:nil]; +} + +- (UINavigationController *)getKeyWindowNav { + UIWindow *window = [[UIWindow alloc] init]; + window.frame = [[UIScreen mainScreen] bounds]; + window.windowLevel = UIWindowLevelStatusBar - 1; + UIViewController *root = [[UIViewController alloc] init]; + root.view.backgroundColor = [UIColor clearColor]; + UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:root]; + nav.navigationBar.tintColor = [UIColor clearColor]; + nav.view.backgroundColor = [UIColor clearColor]; + [nav.navigationBar setHidden:YES]; + self.keywindow = window; + window.rootViewController = nav; + window.backgroundColor = [UIColor clearColor]; + [window makeKeyAndVisible]; + return nav; +} + +- (void)didDismiss:(NSNotification *)noti { + UINavigationController *nav = (UINavigationController *)self.keywindow.rootViewController; + __weak typeof(self) weakSelf = self; + [nav dismissViewControllerAnimated:YES + completion:^{ + NSLog(@"self window %@", weakSelf.keywindow); + [weakSelf.keywindow resignKeyWindow]; + weakSelf.keywindow = nil; + }]; +} + ++ (NSString *)version { + return @"1.8.2"; +} + +@end diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/View/NECustomButton.h b/NERtcCallUIKit/NERtcCallUIKit/Classes/View/NECustomButton.h new file mode 100644 index 00000000..4971da31 --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/View/NECustomButton.h @@ -0,0 +1,15 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NECustomButton : UIView +@property(strong, nonatomic) UIImageView *imageView; +@property(strong, nonatomic) UILabel *titleLabel; +@property(strong, nonatomic) UIButton *maskBtn; +@end + +NS_ASSUME_NONNULL_END diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/View/NECustomButton.m b/NERtcCallUIKit/NERtcCallUIKit/Classes/View/NECustomButton.m new file mode 100644 index 00000000..929bcd11 --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/View/NECustomButton.m @@ -0,0 +1,70 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import "NECustomButton.h" + +@implementation NECustomButton +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + [self addSubview:self.imageView]; + [self addSubview:self.titleLabel]; + [self addSubview:self.maskBtn]; + + [NSLayoutConstraint activateConstraints:@[ + [self.imageView.topAnchor constraintEqualToAnchor:self.topAnchor], + [self.imageView.leftAnchor constraintEqualToAnchor:self.leftAnchor], + [self.imageView.rightAnchor constraintEqualToAnchor:self.rightAnchor], + [self.imageView.widthAnchor constraintEqualToConstant:75], + [self.imageView.heightAnchor constraintEqualToConstant:75], + ]]; + + [NSLayoutConstraint activateConstraints:@[ + [self.titleLabel.leftAnchor constraintEqualToAnchor:self.leftAnchor constant:-40], + [self.titleLabel.rightAnchor constraintEqualToAnchor:self.rightAnchor constant:40], + [self.titleLabel.topAnchor constraintEqualToAnchor:self.imageView.bottomAnchor constant:8], + [self.titleLabel.bottomAnchor constraintEqualToAnchor:self.bottomAnchor constant:0] + ]]; + + [NSLayoutConstraint activateConstraints:@[ + [self.maskBtn.leftAnchor constraintEqualToAnchor:self.leftAnchor], + [self.maskBtn.rightAnchor constraintEqualToAnchor:self.rightAnchor], + [self.maskBtn.topAnchor constraintEqualToAnchor:self.topAnchor], + [self.maskBtn.bottomAnchor constraintEqualToAnchor:self.bottomAnchor] + ]]; + + self.translatesAutoresizingMaskIntoConstraints = NO; + } + return self; +} + +- (UIImageView *)imageView { + if (!_imageView) { + _imageView = [[UIImageView alloc] init]; + _imageView.userInteractionEnabled = NO; + _imageView.translatesAutoresizingMaskIntoConstraints = NO; + _imageView.contentMode = UIViewContentModeCenter; + } + return _imageView; +} +- (UILabel *)titleLabel { + if (!_titleLabel) { + _titleLabel = [[UILabel alloc] init]; + _titleLabel.font = [UIFont systemFontOfSize:14]; + _titleLabel.textColor = [UIColor whiteColor]; + _titleLabel.textAlignment = NSTextAlignmentCenter; + _titleLabel.translatesAutoresizingMaskIntoConstraints = NO; + } + return _titleLabel; +} + +- (UIButton *)maskBtn { + if (!_maskBtn) { + _maskBtn = [[UIButton alloc] init]; + _maskBtn.backgroundColor = [UIColor clearColor]; + _maskBtn.translatesAutoresizingMaskIntoConstraints = NO; + } + return _maskBtn; +} +@end diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/View/NEExpandButton.h b/NERtcCallUIKit/NERtcCallUIKit/Classes/View/NEExpandButton.h new file mode 100644 index 00000000..4be819ea --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/View/NEExpandButton.h @@ -0,0 +1,13 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NEExpandButton : UIButton + +@end + +NS_ASSUME_NONNULL_END diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/View/NEExpandButton.m b/NERtcCallUIKit/NERtcCallUIKit/Classes/View/NEExpandButton.m new file mode 100644 index 00000000..64071d2c --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/View/NEExpandButton.m @@ -0,0 +1,18 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import "NEExpandButton.h" + +@implementation NEExpandButton + +- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { + CGRect bounds = self.bounds; + // 若原热区小于44x44,则放大热区,否则保持原大小不变 + CGFloat widthDelta = MAX(44.0 - bounds.size.width, 0); + CGFloat heightDelta = MAX(44.0 - bounds.size.height, 0); + bounds = CGRectInset(bounds, -0.5 * widthDelta, -0.5 * heightDelta); + return CGRectContainsPoint(bounds, point); +} + +@end diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/View/NEVideoOperationView.h b/NERtcCallUIKit/NERtcCallUIKit/Classes/View/NEVideoOperationView.h new file mode 100644 index 00000000..8604c52f --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/View/NEVideoOperationView.h @@ -0,0 +1,24 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NEVideoOperationView : UIView +@property(strong, nonatomic) UIButton *microPhone; +@property(strong, nonatomic) UIButton *cameraBtn; +@property(strong, nonatomic) UIButton *hangupBtn; +@property(strong, nonatomic) UIButton *speakerBtn; +@property(strong, nonatomic) UIButton *mediaBtn; + +- (void)changeAudioStyle; +- (void)changeVideoStyle; +- (void)hideMediaSwitch; + +- (void)setGroupStyle; + +@end + +NS_ASSUME_NONNULL_END diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/View/NEVideoOperationView.m b/NERtcCallUIKit/NERtcCallUIKit/Classes/View/NEVideoOperationView.m new file mode 100644 index 00000000..86562072 --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/View/NEVideoOperationView.m @@ -0,0 +1,146 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import "NEVideoOperationView.h" + +@interface NEVideoOperationView () + +@property(nonatomic, strong) UIStackView *stack; + +@property(nonatomic, strong) NSBundle *bundle; + +@end + +@implementation NEVideoOperationView +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + self.bundle = [NSBundle bundleForClass:self.class]; + [self setupUI]; + } + return self; +} +- (void)setupUI { + self.backgroundColor = [UIColor colorWithRed:39 / 255.0 + green:48 / 255.0 + blue:48 / 255.0 + alpha:1.0]; + UIStackView *stackView = [[UIStackView alloc] initWithArrangedSubviews:@[ + self.microPhone, self.cameraBtn, self.speakerBtn, self.mediaBtn, self.hangupBtn + ]]; + stackView.distribution = + UIStackViewDistributionEqualCentering; // UIStackViewDistributionFillEqually; + + [self addSubview:stackView]; + stackView.translatesAutoresizingMaskIntoConstraints = NO; + [NSLayoutConstraint activateConstraints:@[ + [stackView.leftAnchor constraintEqualToAnchor:self.leftAnchor constant:20], + [stackView.rightAnchor constraintEqualToAnchor:self.rightAnchor constant:-20], + [stackView.topAnchor constraintEqualToAnchor:self.topAnchor constant:0], + [stackView.bottomAnchor constraintEqualToAnchor:self.bottomAnchor constant:0], + + ]]; + // [stackView mas_makeConstraints:^(MASConstraintMaker *make) { + // make.edges.mas_equalTo(UIEdgeInsetsMake(0, 20, 0, 20)); + // }]; + self.stack = stackView; +} +- (UIButton *)microPhone { + if (!_microPhone) { + _microPhone = [UIButton buttonWithType:UIButtonTypeCustom]; + [_microPhone setImage:[UIImage imageNamed:@"call_voice_on" + inBundle:self.bundle + compatibleWithTraitCollection:nil] + forState:UIControlStateNormal]; + [_microPhone setImage:[UIImage imageNamed:@"call_voice_off" + inBundle:self.bundle + compatibleWithTraitCollection:nil] + forState:UIControlStateSelected]; + _microPhone.accessibilityIdentifier = @"op_micro_phone"; + } + return _microPhone; +} +- (UIButton *)cameraBtn { + if (!_cameraBtn) { + _cameraBtn = [UIButton buttonWithType:UIButtonTypeCustom]; + [_cameraBtn setImage:[UIImage imageNamed:@"call_camera_on" + inBundle:self.bundle + compatibleWithTraitCollection:nil] + forState:UIControlStateNormal]; + [_cameraBtn setImage:[UIImage imageNamed:@"call_camera_off" + inBundle:self.bundle + compatibleWithTraitCollection:nil] + forState:UIControlStateSelected]; + _cameraBtn.accessibilityIdentifier = @"op_video_mute"; + } + return _cameraBtn; +} +- (UIButton *)hangupBtn { + if (!_hangupBtn) { + _hangupBtn = [UIButton buttonWithType:UIButtonTypeCustom]; + [_hangupBtn setImage:[UIImage imageNamed:@"hangup" + inBundle:self.bundle + compatibleWithTraitCollection:nil] + forState:UIControlStateNormal]; + _hangupBtn.accessibilityIdentifier = @"op_hangup"; + } + return _hangupBtn; +} +- (UIButton *)speakerBtn { + if (nil == _speakerBtn) { + _speakerBtn = [UIButton buttonWithType:UIButtonTypeCustom]; + [_speakerBtn setImage:[UIImage imageNamed:@"call_speaker_off" + inBundle:self.bundle + compatibleWithTraitCollection:nil] + forState:UIControlStateSelected]; + [_speakerBtn setImage:[UIImage imageNamed:@"call_speaker_on" + inBundle:self.bundle + compatibleWithTraitCollection:nil] + forState:UIControlStateNormal]; + _speakerBtn.accessibilityIdentifier = @"op_speaker"; + } + return _speakerBtn; +} +- (UIButton *)mediaBtn { + if (nil == _mediaBtn) { + _mediaBtn = [UIButton buttonWithType:UIButtonTypeCustom]; + [_mediaBtn setImage:[UIImage imageNamed:@"call_switch_audio" + inBundle:self.bundle + compatibleWithTraitCollection:nil] + forState:UIControlStateNormal]; + [_mediaBtn setImage:[UIImage imageNamed:@"call_switch_video" + inBundle:self.bundle + compatibleWithTraitCollection:nil] + forState:UIControlStateSelected]; + _mediaBtn.accessibilityIdentifier = @"switch_media_btn"; + } + return _mediaBtn; +} + +- (void)changeAudioStyle { + [self.stack removeArrangedSubview:self.cameraBtn]; + [self.cameraBtn removeFromSuperview]; + self.mediaBtn.selected = YES; +} + +- (void)changeVideoStyle { + [self.stack insertArrangedSubview:self.cameraBtn atIndex:1]; + self.mediaBtn.selected = NO; +} + +- (void)hideMediaSwitch { + [self.stack removeArrangedSubview:self.mediaBtn]; + [self.mediaBtn removeFromSuperview]; + [self.stack removeArrangedSubview:self.cameraBtn]; + [self.cameraBtn removeFromSuperview]; +} + +- (void)setGroupStyle { + [self.stack removeArrangedSubview:self.mediaBtn]; + [self.stack removeArrangedSubview:self.speakerBtn]; + [self.mediaBtn removeFromSuperview]; + [self.speakerBtn removeFromSuperview]; +} + +@end diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/View/NEVideoView.h b/NERtcCallUIKit/NERtcCallUIKit/Classes/View/NEVideoView.h new file mode 100644 index 00000000..a33bfeae --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/View/NEVideoView.h @@ -0,0 +1,18 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NEVideoView : UIView +@property(strong, nonatomic) NSString *userID; +@property(strong, nonatomic) UIView *videoView; +@property(strong, nonatomic) UILabel *titleLabel; +@property(strong, nonatomic) UIView *maskView; +@property(strong, nonatomic) UIImageView *imageView; + +@end + +NS_ASSUME_NONNULL_END diff --git a/NERtcCallUIKit/NERtcCallUIKit/Classes/View/NEVideoView.m b/NERtcCallUIKit/NERtcCallUIKit/Classes/View/NEVideoView.m new file mode 100644 index 00000000..25d6e1b9 --- /dev/null +++ b/NERtcCallUIKit/NERtcCallUIKit/Classes/View/NEVideoView.m @@ -0,0 +1,80 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +#import "NEVideoView.h" + +@implementation NEVideoView +- (instancetype)init { + self = [super init]; + if (self) { + [self addSubview:self.videoView]; + [NSLayoutConstraint activateConstraints:@[ + [self.videoView.leftAnchor constraintEqualToAnchor:self.leftAnchor], + [self.videoView.rightAnchor constraintEqualToAnchor:self.rightAnchor], + [self.videoView.topAnchor constraintEqualToAnchor:self.topAnchor], + [self.videoView.bottomAnchor constraintEqualToAnchor:self.bottomAnchor] + ]]; + [self addSubview:self.maskView]; + [NSLayoutConstraint activateConstraints:@[ + [self.maskView.leftAnchor constraintEqualToAnchor:self.leftAnchor], + [self.maskView.rightAnchor constraintEqualToAnchor:self.rightAnchor], + [self.maskView.topAnchor constraintEqualToAnchor:self.topAnchor], + [self.maskView.bottomAnchor constraintEqualToAnchor:self.bottomAnchor] + ]]; + [self addSubview:self.titleLabel]; + [NSLayoutConstraint activateConstraints:@[ + [self.titleLabel.leftAnchor constraintEqualToAnchor:self.leftAnchor constant:10], + [self.titleLabel.rightAnchor constraintEqualToAnchor:self.rightAnchor constant:-10], + [self.titleLabel.topAnchor constraintEqualToAnchor:self.topAnchor constant:10], + [self.titleLabel.bottomAnchor constraintEqualToAnchor:self.bottomAnchor constant:-10] + ]]; + [self addSubview:self.imageView]; + [NSLayoutConstraint activateConstraints:@[ + [self.imageView.leftAnchor constraintEqualToAnchor:self.leftAnchor], + [self.imageView.rightAnchor constraintEqualToAnchor:self.rightAnchor], + [self.imageView.topAnchor constraintEqualToAnchor:self.topAnchor], + [self.imageView.bottomAnchor constraintEqualToAnchor:self.bottomAnchor] + ]]; + } + return self; +} +- (UIView *)videoView { + if (!_videoView) { + _videoView = [[UIView alloc] init]; + _videoView.translatesAutoresizingMaskIntoConstraints = NO; + } + return _videoView; +} +- (UIView *)maskView { + if (!_maskView) { + _maskView = [[UIView alloc] init]; + _maskView.backgroundColor = [UIColor darkGrayColor]; + _maskView.hidden = YES; + _maskView.translatesAutoresizingMaskIntoConstraints = NO; + } + return _maskView; +} + +- (UILabel *)titleLabel { + if (!_titleLabel) { + _titleLabel = [[UILabel alloc] init]; + _titleLabel.textColor = [UIColor whiteColor]; + _titleLabel.font = [UIFont systemFontOfSize:20]; + _titleLabel.numberOfLines = 0; + _titleLabel.textAlignment = NSTextAlignmentCenter; + _titleLabel.translatesAutoresizingMaskIntoConstraints = NO; + } + return _titleLabel; +} + +- (UIImageView *)imageView { + if (_imageView == nil) { + _imageView = [[UIImageView alloc] init]; + _imageView.userInteractionEnabled = YES; + _imageView.contentMode = UIViewContentModeScaleAspectFill; + _imageView.translatesAutoresizingMaskIntoConstraints = NO; + } + return _imageView; +} +@end diff --git a/NETeamUIKit/NETeamUIKit.podspec b/NETeamUIKit/NETeamUIKit.podspec index 4f1f43cd..d23b9064 100644 --- a/NETeamUIKit/NETeamUIKit.podspec +++ b/NETeamUIKit/NETeamUIKit.podspec @@ -8,7 +8,7 @@ Pod::Spec.new do |s| s.name = 'NETeamUIKit' - s.version = '9.3.0' + s.version = '9.2.10' s.summary = 'Netease XKit' # This description is used to generate tags and improve search results. @@ -27,9 +27,9 @@ TODO: Add long description of the pod here. s.source = { :git => 'https://github.com/netease/NEKitGroupUI.git', :tag => s.version.to_s } # s.social_media_url = 'https://twitter.com/' s.pod_target_xcconfig = { + 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64', 'BUILD_LIBRARY_FOR_DISTRIBUTION' => 'YES' } - s.user_target_xcconfig = { 'BUILD_LIBRARY_FOR_DISTRIBUTION' => 'YES' } s.ios.deployment_target = '9.0' s.swift_version = '5.0' @@ -45,6 +45,6 @@ TODO: Add long description of the pod here. s.dependency 'NECommonUIKit' s.dependency 'NETeamKit' s.dependency 'NIMSDK_LITE' - s.dependency 'YXAlog_iOS' + s.dependency 'YXAlog' end diff --git a/NETeamUIKit/NETeamUIKit/Assets/en.lproj/Localizable.strings b/NETeamUIKit/NETeamUIKit/Assets/en.lproj/Localizable.strings index ec826c22..7fecc69e 100644 --- a/NETeamUIKit/NETeamUIKit/Assets/en.lproj/Localizable.strings +++ b/NETeamUIKit/NETeamUIKit/Assets/en.lproj/Localizable.strings @@ -33,7 +33,7 @@ "save"="Save"; "historical_record"="History"; "search"="Search"; -"no_search_results"="No content"; +"no_search_results"="No History"; "discuss_info"="Temp Group Info"; "group_info"="Group Info"; "discuss_introduce"="Temp Group Introduce"; @@ -48,3 +48,4 @@ "discuss_name"="Temp Group Name"; "discuss_intro"="Temp Group Introduce"; "invite_has_send"="Invitation sent"; +"space_not_support"="All Spaces are not supported"; diff --git a/NETeamUIKit/NETeamUIKit/Assets/zh-Hans.lproj/Localizable.strings b/NETeamUIKit/NETeamUIKit/Assets/zh-Hans.lproj/Localizable.strings index a2f371d5..5834a476 100644 --- a/NETeamUIKit/NETeamUIKit/Assets/zh-Hans.lproj/Localizable.strings +++ b/NETeamUIKit/NETeamUIKit/Assets/zh-Hans.lproj/Localizable.strings @@ -33,7 +33,7 @@ "save"="保存"; "historical_record"="历史记录"; "search"="搜索"; -"no_search_results"="暂无搜索结果"; +"no_search_results"="暂无聊天记录"; "discuss_info"="讨论组信息"; "group_info"="群信息"; "discuss_introduce"="讨论组介绍"; @@ -48,3 +48,4 @@ "discuss_name"="讨论组名称"; "discuss_intro"="讨论组介绍"; "invite_has_send"="邀请已发送"; +"space_not_support"="不支持全空格"; diff --git a/NETeamUIKit/NETeamUIKit/Classes/Setting/Model/SettingCellModel.swift b/NETeamUIKit/NETeamUIKit/Classes/Setting/Model/SettingCellModel.swift index 5963d485..dbaa8807 100644 --- a/NETeamUIKit/NETeamUIKit/Classes/Setting/Model/SettingCellModel.swift +++ b/NETeamUIKit/NETeamUIKit/Classes/Setting/Model/SettingCellModel.swift @@ -24,6 +24,7 @@ public class SettingCellModel: NSObject { public var type = SettingCellType.SettingArrowCell.rawValue public var swichChange: SwitchChangeCompletion? public var rowHeight: CGFloat = 49 + public var titleWidth: CGFloat = 32 public var cornerType = CornerType.none public var headerUrl: String? public var cellClick: CellClick? diff --git a/NETeamUIKit/NETeamUIKit/Classes/Setting/TeamIntroduceViewController.swift b/NETeamUIKit/NETeamUIKit/Classes/Setting/TeamIntroduceViewController.swift index cd08085f..fd2364ae 100644 --- a/NETeamUIKit/NETeamUIKit/Classes/Setting/TeamIntroduceViewController.swift +++ b/NETeamUIKit/NETeamUIKit/Classes/Setting/TeamIntroduceViewController.swift @@ -15,7 +15,7 @@ public class TeamIntroduceViewController: NEBaseViewController, UITextViewDelega // var block: SaveCompletion? var team: NIMTeam? - + let textLimit = 100 let repo = TeamRepo() lazy var textView: UITextView = { @@ -96,9 +96,9 @@ public class TeamIntroduceViewController: NEBaseViewController, UITextViewDelega ]) if let intr = team?.intro { - countLabel.text = "\(intr.count)/100" + countLabel.text = "\(intr.count)/\(textLimit)" } else { - countLabel.text = "0/100" + countLabel.text = "0/\(textLimit)" } if changePermission() == false { @@ -161,28 +161,17 @@ public class TeamIntroduceViewController: NEBaseViewController, UITextViewDelega // MARK: UITextViewDelegate - public func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, - replacementText text: String) -> Bool { - let currentText = textView.text ?? "" - guard let stringRange = Range(range, in: currentText) else { return false } - let updatedText = currentText.replacingCharacters(in: stringRange, with: text) - return updatedText.count <= 100 - } - public func textViewDidChange(_ textView: UITextView) { + if let _ = textView.markedTextRange { + return + } if var text = textView.text { - if let lang = textView.textInputMode?.primaryLanguage, lang == "zh-Hans", - let selectRange = textView.markedTextRange { - let position = textView.position(from: selectRange.start, offset: 0) - if position == nil { - if text.count > 30 { - text = String(text.prefix(30)) - textView.text = String(text.prefix(30)) - } - countLabel.text = "\(text.count)/100" + if let lang = textView.textInputMode?.primaryLanguage, lang == "zh-Hans" { + if text.count > textLimit { + text = String(text.prefix(textLimit)) + textView.text = String(text) } - } else { - countLabel.text = "\(text.count)/100" + countLabel.text = "\(text.count)/\(textLimit)" } } } diff --git a/NETeamUIKit/NETeamUIKit/Classes/Setting/TeamNameViewController.swift b/NETeamUIKit/NETeamUIKit/Classes/Setting/TeamNameViewController.swift index 9943340d..dd81c52e 100644 --- a/NETeamUIKit/NETeamUIKit/Classes/Setting/TeamNameViewController.swift +++ b/NETeamUIKit/NETeamUIKit/Classes/Setting/TeamNameViewController.swift @@ -20,6 +20,7 @@ public class TeamNameViewController: NEBaseViewController, UITextFieldDelegate { var type = ChangeType.TeamName var teamMember: NIMTeamMember? var repo = TeamRepo() + let textLimit = 30 lazy var countLabel: UILabel = { let label = UILabel() @@ -108,7 +109,7 @@ public class TeamNameViewController: NEBaseViewController, UITextFieldDelegate { name = n } - countLabel.text = "\(name.count)/30" + countLabel.text = "\(name.count)/\(textLimit)" textField.text = name if name.count <= 0, type != .NickName { @@ -162,24 +163,32 @@ public class TeamNameViewController: NEBaseViewController, UITextFieldDelegate { // MARK: objc 方法 func textFieldChange() { + if let _ = textField.markedTextRange { + return + } if var text = textField.text { - if let lang = textField.textInputMode?.primaryLanguage, lang == "zh-Hans", - let selectRange = textField.markedTextRange { - let position = textField.position(from: selectRange.start, offset: 0) - if position == nil { - if text.count > 30 { - text = String(text.prefix(30)) - textField.text = String(text.prefix(30)) - } - figureTextCount(text) + if let lang = textField.textInputMode?.primaryLanguage, lang == "zh-Hans" { + if text.count > textLimit { + text = String(text.prefix(textLimit)) + textField.text = String(text) } - } else { figureTextCount(text) } } } func saveName() { + if let text = textField.text, + !text.isEmpty { + let trimText = text.trimmingCharacters(in: .whitespaces) + if trimText.isEmpty { + view.makeToast(localizable("space_not_support"), duration: 2, position: .center) + textField.text = trimText + figureTextCount(trimText) + return + } + } + weak var weakSelf = self textField.resignFirstResponder() if type == .TeamName, let tid = team?.teamId { @@ -208,21 +217,11 @@ public class TeamNameViewController: NEBaseViewController, UITextFieldDelegate { } } } - - // MAKR: UITextFieldDelegate - public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, - replacementString string: String) -> Bool { - if let text = (textField.text as NSString?)?.replacingCharacters(in: range, with: string), - text.count > 30 { - return false - } - return true - } } extension TeamNameViewController { func figureTextCount(_ text: String) { - countLabel.text = "\(text.count)/30" + countLabel.text = "\(text.count)/\(textLimit)" if type == .NickName { return } diff --git a/NETeamUIKit/NETeamUIKit/Classes/Setting/TeamSettingViewController.swift b/NETeamUIKit/NETeamUIKit/Classes/Setting/TeamSettingViewController.swift index 64ee7e73..9d177b4d 100644 --- a/NETeamUIKit/NETeamUIKit/Classes/Setting/TeamSettingViewController.swift +++ b/NETeamUIKit/NETeamUIKit/Classes/Setting/TeamSettingViewController.swift @@ -8,16 +8,26 @@ import NECommonUIKit import NECoreIMKit import NIMSDK +@objc +public enum TeamSettingType: Int { + case Discuss = 0 + case Senior = 1 +} + @objcMembers public class TeamSettingViewController: NEBaseViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UITableViewDataSource, UITableViewDelegate { - let viewmodel = TeamSettingViewModel() + public let viewmodel = TeamSettingViewModel() - var teamId: String? + public var teamId: String? var addBtnWidth: NSLayoutConstraint? + public var teamSettingType: TeamSettingType = .Discuss + + public var isSeniorDiscuss = false // 是否是高级群扩展的讨论组 + private let className = "TeamSettingViewController" public var cellClassDic = [ @@ -104,6 +114,7 @@ public class TeamSettingViewController: NEBaseViewController, UICollectionViewDe override public func viewDidLoad() { super.viewDidLoad() + title = localizable("setting") weak var weakSelf = self viewmodel.delegate = self @@ -116,6 +127,18 @@ public class TeamSettingViewController: NEBaseViewController, UICollectionViewDe if let err = error { weakSelf?.showToast(err.localizedDescription) } else { + if let type = weakSelf?.viewmodel.teamInfoModel?.team?.type { + if type == .normal { + weakSelf?.teamSettingType = .Discuss + } else if type == .advanced { + if let custom = weakSelf?.viewmodel.teamInfoModel?.team?.clientCustomInfo, custom.contains(discussTeamKey) { + weakSelf?.teamSettingType = .Discuss + weakSelf?.isSeniorDiscuss = true + } else { + weakSelf?.teamSettingType = .Senior + } + } + } weakSelf?.contentTable.tableHeaderView = weakSelf?.getHeaderView() weakSelf?.contentTable.tableFooterView = weakSelf?.getFooterView() weakSelf?.contentTable.reloadData() @@ -216,7 +239,7 @@ public class TeamSettingViewController: NEBaseViewController, UICollectionViewDe memberLabel.topAnchor.constraint(equalTo: line.bottomAnchor, constant: 12), ]) - if let type = viewmodel.teamInfoModel?.team?.type, type == .advanced { + if teamSettingType == .Senior { memberLabel.text = localizable("group_memmber") } else { memberLabel.text = localizable("discuss_mebmer") @@ -305,9 +328,9 @@ public class TeamSettingViewController: NEBaseViewController, UICollectionViewDe } func getBottomText() -> String? { - if let type = viewmodel.teamInfoModel?.team?.type, type == .normal { + if teamSettingType == .Discuss { return localizable("leave_discuss") - } else if let type = viewmodel.teamInfoModel?.team?.type, type == .advanced { + } else if teamSettingType == .Senior { return viewmodel.isOwner() ? localizable("dismiss_team") : localizable("leave_team") } return nil @@ -366,23 +389,54 @@ public class TeamSettingViewController: NEBaseViewController, UICollectionViewDe func removeTeamForMyself() { weak var weakSelf = self - if viewmodel.isOwner(), let type = viewmodel.teamInfoModel?.team?.type, type == .advanced { - showAlert(message: localizable("dissolute_team_chat")) { - weakSelf?.dismissTeam() + if teamSettingType == .Senior { + showAlert(message: viewmodel.isOwner() ? localizable("dissolute_team_chat") : localizable("quit_team_chat")) { + if weakSelf?.viewmodel.isOwner() == true { + weakSelf?.dismissTeam() + } else { + weakSelf?.leaveTeam() + } } - } else { - if let type = viewmodel.teamInfoModel?.team?.type { - if type == .advanced { - showAlert(message: localizable("quit_team_chat")) { - weakSelf?.leveaTeam() - } - } else if type == .normal { - showAlert(message: localizable("quit_discuss_chat")) { - weakSelf?.leveaTeam() - } + } else if teamSettingType == .Discuss { + showAlert(message: localizable("quit_discuss_chat")) { + weakSelf?.leaveDiscuss() + } + } + /* + if viewmodel.isOwner(), let type = viewmodel.teamInfoModel?.team?.type, type == .advanced { + showAlert(message: localizable("dissolute_team_chat")) { + weakSelf?.dismissTeam() + } + } else { + if let type = viewmodel.teamInfoModel?.team?.type { + if let custom = viewmodel.teamInfoModel?.team?.clientCustomInfo, type == .normal || (type == .advanced && custom.contains(discussTeamKey)) { + showAlert(message: localizable("quit_discuss_chat")) { + weakSelf?.leveaTeam() + } + }else if type == .advanced { + showAlert(message: localizable("quit_team_chat")) { + weakSelf?.leveaTeam() + } + } + } + } */ + } + + func leaveDiscuss() { + weak var weakSelf = self + if isSeniorDiscuss == true, viewmodel.isOwner() { + view.makeToastActivity(.center) + viewmodel.transferTeamOwner { error in + weakSelf?.view.hideToastActivity() + if let err = error { + weakSelf?.showToast(err.localizedDescription) + return } + weakSelf?.navigationController?.popViewController(animated: true) } + return } + leaveTeam() } func toInfoView() { @@ -394,7 +448,7 @@ public class TeamSettingViewController: NEBaseViewController, UICollectionViewDe func toMemberList() { let memberController = TeamMembersController() memberController.datas = viewmodel.teamInfoModel?.users - if let type = viewmodel.teamInfoModel?.team?.type, type == .advanced { + if teamSettingType == .Senior { memberController.isSenior = true } memberController.ownerId = viewmodel.teamInfoModel?.team?.owner @@ -585,20 +639,28 @@ extension TeamSettingViewController { } } - func leveaTeam() { + func leaveTeam() { if let tid = teamId { - weak var weakSelf = self view.makeToastActivity(.center) - viewmodel.quitTeam(tid) { error in + viewmodel.quitTeam(tid) { [weak self] error in NELog.infoLog( - ModuleName + " " + self.className, + ModuleName + " " + (self?.className ?? "TeamSettingViewController"), desc: "CALLBACK quitTeam " + (error?.localizedDescription ?? "no error") ) - weakSelf?.view.hideToastActivity() + self?.view.hideToastActivity() if let err = error { - weakSelf?.showToast(err.localizedDescription) + self?.showToast(err.localizedDescription) } else { - weakSelf?.navigationController?.popViewController(animated: true) + let session = NIMSession(tid, type: .team) + if let stickInfo = self?.viewmodel.getTopSessionInfo(session) { + self?.viewmodel.removeStickTop(params: stickInfo) { err, _ in + NELog.infoLog( + ModuleName + " " + (self?.className ?? "TeamSettingViewController"), + desc: "CALLBACK removeStickTop " + (error?.localizedDescription ?? "no error") + ) + } + } + self?.navigationController?.popViewController(animated: true) } } } @@ -612,6 +674,8 @@ extension TeamSettingViewController: TeamSettingViewModelDelegate { func didNeedRefreshUI() { contentTable.reloadData() + refreshMemberCount() + userinfoCollection.reloadData() } func didChangeInviteModeClick(_ model: SettingCellModel) { diff --git a/NETeamUIKit/NETeamUIKit/Classes/Setting/View/TeamSettingSubtitleCell.swift b/NETeamUIKit/NETeamUIKit/Classes/Setting/View/TeamSettingSubtitleCell.swift index 21ea2341..4ae2cc12 100644 --- a/NETeamUIKit/NETeamUIKit/Classes/Setting/View/TeamSettingSubtitleCell.swift +++ b/NETeamUIKit/NETeamUIKit/Classes/Setting/View/TeamSettingSubtitleCell.swift @@ -7,6 +7,8 @@ import UIKit @objcMembers public class TeamSettingSubtitleCell: BaseTeamSettingCell { + var titleWidthAnchor: NSLayoutConstraint? + override public func awakeFromNib() { super.awakeFromNib() // Initialization code @@ -36,26 +38,30 @@ public class TeamSettingSubtitleCell: BaseTeamSettingCell { NSLayoutConstraint.activate([ titleLabel.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 36), titleLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 16), - titleLabel.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -84), + titleLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), ]) + titleWidthAnchor = titleLabel.widthAnchor.constraint(equalToConstant: 0) + titleWidthAnchor?.isActive = true NSLayoutConstraint.activate([ arrow.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), arrow.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -36), + arrow.widthAnchor.constraint(equalToConstant: 7), ]) NSLayoutConstraint.activate([ + subTitleLabel.leftAnchor.constraint(equalTo: titleLabel.rightAnchor, constant: 10), subTitleLabel.rightAnchor.constraint(equalTo: arrow.leftAnchor, constant: -10), subTitleLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), - subTitleLabel.widthAnchor.constraint(equalToConstant: 200), ]) - - titleLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true } override public func configure(_ anyModel: Any) { super.configure(anyModel) - subTitleLabel.text = model?.subTitle + if let m = anyModel as? SettingCellModel { + titleWidthAnchor?.constant = m.titleWidth + subTitleLabel.text = m.subTitle + } } lazy var subTitleLabel: UILabel = { diff --git a/NETeamUIKit/NETeamUIKit/Classes/Setting/ViewModel/TeamInfoViewModel.swift b/NETeamUIKit/NETeamUIKit/Classes/Setting/ViewModel/TeamInfoViewModel.swift index 639af2b4..8e8a0519 100644 --- a/NETeamUIKit/NETeamUIKit/Classes/Setting/ViewModel/TeamInfoViewModel.swift +++ b/NETeamUIKit/NETeamUIKit/Classes/Setting/ViewModel/TeamInfoViewModel.swift @@ -5,6 +5,7 @@ import Foundation import NETeamKit import NIMSDK +import NECoreIMKit @objcMembers public class TeamInfoViewModel: NSObject { @@ -27,7 +28,7 @@ public class TeamInfoViewModel: NSObject { intrCell.type = SettingCellType.SettingArrowCell.rawValue intrCell.cornerType = .bottomLeft.union(.bottomRight) - if let type = team?.type, type == .normal { + if let type = team?.type, type == .normal || (type == .advanced && team?.clientCustomInfo?.contains(discussTeamKey) == true) { headerCell.cellName = localizable("discuss_avatar") nameCell.cellName = localizable("discuss_name") intrCell.cellName = localizable("discuss_intro") diff --git a/NETeamUIKit/NETeamUIKit/Classes/Setting/ViewModel/TeamSettingViewModel.swift b/NETeamUIKit/NETeamUIKit/Classes/Setting/ViewModel/TeamSettingViewModel.swift index e863632b..9dcfb20c 100644 --- a/NETeamUIKit/NETeamUIKit/Classes/Setting/ViewModel/TeamSettingViewModel.swift +++ b/NETeamUIKit/NETeamUIKit/Classes/Setting/ViewModel/TeamSettingViewModel.swift @@ -6,6 +6,7 @@ import Foundation import NETeamKit import NIMSDK import UIKit +import NECoreIMKit protocol TeamSettingViewModelDelegate: NSObjectProtocol { func didClickChangeNick() @@ -17,22 +18,31 @@ protocol TeamSettingViewModelDelegate: NSObjectProtocol { } @objcMembers -public class TeamSettingViewModel: NSObject { - var sectionData = [SettingSectionModel]() +public class TeamSettingViewModel: NSObject, NIMTeamManagerDelegate { + public var sectionData = [SettingSectionModel]() - var searchResultInfos: [HistoryMessageModel]? + public var searchResultInfos: [HistoryMessageModel]? - var teamInfoModel: TeamInfoModel? + public var teamInfoModel: TeamInfoModel? - let repo = TeamRepo() + public let repo = TeamRepo() - var memberInTeam: NIMTeamMember? + public var memberInTeam: NIMTeamMember? weak var delegate: TeamSettingViewModelDelegate? private let className = "TeamSettingViewModel" - override public init() {} + private var usersDic = [String: TeamMemberInfoModel]() + + override public init() { + super.init() + NIMSDK.shared().teamManager.add(self) + } + + deinit { + NIMSDK.shared().teamManager.remove(self) + } func getData() { NELog.infoLog(ModuleName + " " + className, desc: #function) @@ -40,6 +50,9 @@ public class TeamSettingViewModel: NSObject { sectionData.append(getTwoSection()) print("current team type : ", teamInfoModel?.team?.type.rawValue as Any) if let type = teamInfoModel?.team?.type, type == .advanced { + if teamInfoModel?.team?.clientCustomInfo?.contains(discussTeamKey) == true { + return + } sectionData.append(getThreeSection()) sectionData.append(getFourSection()) } @@ -153,6 +166,7 @@ public class TeamSettingViewModel: NSObject { return model } + // 群昵称/群禁言 private func getThreeSection() -> SettingSectionModel { NELog.infoLog(ModuleName + " " + className, desc: #function) let model = SettingSectionModel() @@ -289,9 +303,16 @@ public class TeamSettingViewModel: NSObject { repo.fetchTeamInfo(teamId) { error, teamInfo in weakSelf?.teamInfoModel = teamInfo print("get team info user: ", teamInfo?.users as Any) + teamInfo?.users.forEach { member in + print("team meber accid : ", member.nimUser?.userId as Any) + } print("get team info team: ", teamInfo?.team as Any) print("get team info error: ", error as Any) - + teamInfo?.users.forEach { model in + if let id = model.nimUser?.userId as? String { + weakSelf?.usersDic[id] = model + } + } if error == nil { weakSelf?.getData() weakSelf?.getCurrentMember(IMKitEngine.instance.imAccid, teamId) @@ -310,6 +331,18 @@ public class TeamSettingViewModel: NSObject { repo.quitTeam(teamId, completion) } + public func getTopSessionInfo(_ session: NIMSession) -> NIMStickTopSessionInfo { + NELog.infoLog(ModuleName + " " + className, desc: #function + ", teamId:\(session.sessionId)") + return repo.getTopSessionInfo(session) + } + + public func removeStickTop(params: NIMStickTopSessionInfo, + _ completion: @escaping (NSError?, NIMStickTopSessionInfo?) + -> Void) { + NELog.infoLog(ModuleName + " " + className, desc: #function + ", teamId:\(params.session.sessionId)") + repo.removeStickTop(params: params, completion) + } + @discardableResult func getCurrentMember(_ userId: String, _ teamId: String?) -> NIMTeamMember? { NELog.infoLog(ModuleName + " " + className, desc: #function + ", userId:\(userId)") @@ -329,6 +362,38 @@ public class TeamSettingViewModel: NSObject { return false } + private func sampleMemberId(arr: [TeamMemberInfoModel], owner: String) -> String? { + var index = arc4random_uniform(UInt32(arr.count)) + while arr[Int(index)].teamMember?.userId == owner { + index = arc4random_uniform(UInt32(arr.count)) + } + return arr[Int(index)].teamMember?.userId + } + + func transferTeamOwner(_ completion: @escaping (Error?) -> Void) { + if isOwner() == false { + completion(NSError(domain: "imuikit", code: -1, userInfo: [NSLocalizedDescriptionKey: "not team manager"])) + return + } + + guard let members = teamInfoModel?.users, let teamId = teamInfoModel?.team?.teamId else { + completion(NSError(domain: "imuikit", code: -1, userInfo: [NSLocalizedDescriptionKey: "team info error"])) + return + } + + var userId = NIMSDK.shared().loginManager.currentAccount() + if members.count == 1 { + dismissTeam(teamId, completion) + return + } else if let sampleOwnerId = sampleMemberId(arr: members, owner: userId) { + userId = sampleOwnerId + } + + NIMSDK.shared().teamManager.transferManager(withTeam: teamId, newOwnerId: userId, isLeave: true) { error in + completion(error) + } + } + public func updateInfoMode(_ mode: NIMTeamUpdateInfoMode, _ teamId: String, _ completion: @escaping (Error?) -> Void) { NELog.infoLog(ModuleName + " " + className, desc: #function + ", mode:\(mode.rawValue)") @@ -362,4 +427,24 @@ public class TeamSettingViewModel: NSObject { } } } + + public func onTeamMemberRemoved(_ team: NIMTeam, withMembers memberIDs: [String]?) { + if let accids = memberIDs { + weak var weakSelf = self + accids.forEach { accid in + if let model = weakSelf?.usersDic[accid] { + if let index = weakSelf?.teamInfoModel?.users.firstIndex(of: model) { + weakSelf?.teamInfoModel?.users.remove(at: index) + } + } + } + delegate?.didNeedRefreshUI() + } + } + + public func onTeamMemberChanged(_ team: NIMTeam) {} + + public func onTeamUpdated(_ team: NIMTeam) { + teamInfoModel?.team = team + } } diff --git a/NETeamUIKit/NETeamUIKit/Classes/TeamRouter.swift b/NETeamUIKit/NETeamUIKit/Classes/TeamRouter.swift index f60840b4..7103bd9a 100644 --- a/NETeamUIKit/NETeamUIKit/Classes/TeamRouter.swift +++ b/NETeamUIKit/NETeamUIKit/Classes/TeamRouter.swift @@ -33,9 +33,21 @@ public class TeamRouter: NSObject { if name.count > 30 { name = String(name.prefix(30)) } + let iconUrl = (param["url"] as? String) ?? iconUrls[Int(arc4random()) % iconUrls.count] - repo.createNormalTeam(name, iconUrl, accids) { error, teamid, failedIds in + + let option = NIMCreateTeamOption() + option.type = .advanced + option.avatarUrl = iconUrl + option.name = name + option.joinMode = .noAuth + option.inviteMode = .all + option.beInviteMode = .noAuth + option.updateInfoMode = .all + option.updateClientCustomMode = .all + + repo.createAdvanceTeam(accids, option) { error, teamid, failedIds in var result = [String: Any]() if let err = error { result["code"] = err.code @@ -44,6 +56,13 @@ public class TeamRouter: NSObject { result["code"] = 0 result["msg"] = "ok" result["teamId"] = teamid + if let tid = teamid { + repo.updateTeamCustomInfo(discussTeamKey, tid) { error in + if let err = error { + print(#function + "error: \(err.localizedDescription)") + } + } + } } Router.shared.use(TeamCreateDiscussResult, parameters: result, closure: nil) } @@ -57,9 +76,16 @@ public class TeamRouter: NSObject { if name.count > 30 { name = String(name.prefix(30)) } + let iconUrl = (param["url"] as? String) ?? iconUrls[Int(arc4random()) % iconUrls.count] - repo.createAdvanceTeam(name, iconUrl, accids) { error, teamid, failedIds in + + let option = NIMCreateTeamOption() + option.type = .advanced + option.avatarUrl = iconUrl + option.name = name + + repo.createAdvanceTeam(accids, option) { error, teamid, failedIds in var result = [String: Any]() if let err = error { result["code"] = err.code diff --git a/Podfile b/Podfile index 97b5f636..bc5d2bc6 100644 --- a/Podfile +++ b/Podfile @@ -10,37 +10,39 @@ target 'app' do pod 'YXLogin', '1.0.0' #可选UI库 - pod 'NEContactUIKit', '9.3.0' - pod 'NEQChatUIKit', '9.3.0' - pod 'NEConversationUIKit', '9.3.1' - pod 'NEChatUIKit', '9.3.0' - pod 'NETeamUIKit', '9.3.0' +# pod 'NEContactUIKit', '9.4.0' +# pod 'NEConversationUIKit', '9.4.0' +# pod 'NEChatUIKit', '9.4.0' +# pod 'NETeamUIKit', '9.4.0' #可选Kit库(和UIKit对应) - pod 'NEContactKit', '9.3.0' - pod 'NEQChatKit', '9.3.0' - pod 'NEConversationKit', '9.3.0' - pod 'NEChatKit', '9.3.0' - pod 'NETeamKit', '9.3.0' + pod 'NEContactKit', '9.4.0' + pod 'NEConversationKit', '9.4.0' + pod 'NEChatKit', '9.4.0' + pod 'NETeamKit', '9.4.0' #基础kit库 - pod 'NECommonUIKit', '9.3.0' - pod 'NECommonKit', '9.3.0' - pod 'NECoreIMKit', '9.3.0' - pod 'NECoreKit', '9.3.0' + pod 'NECommonUIKit', '9.4.0' + pod 'NECommonKit', '9.4.0' + pod 'NECoreIMKit', '9.4.0' + pod 'NECoreKit', '9.4.0' #扩展库 - pod 'NEMapKit', '9.3.1' - +# pod 'NEMapKit', '9.4.0' + + #呼叫组件,音视频通话能力,需要开通 音视频2.0,可选,聊天一面会根据依赖初始化自动显示音视频通话入口 +# pod 'NERtcCallUIKit', '1.8.2' + pod 'NERtcCallKit', '1.8.2' + pod 'NERtcSDK', '4.6.29' # 如果需要查看UI部分源码请注释掉以上在线依赖,打开下面的本地依赖 -# pod 'NEQChatUIKit', :path => 'NEQChatUIKit/NEQChatUIKit.podspec' -# pod 'NEContactUIKit', :path => 'NEContactUIKit/NEContactUIKit.podspec' -# pod 'NEConversationUIKit', :path => 'NEConversationUIKit/NEConversationUIKit.podspec' -# pod 'NETeamUIKit', :path => 'NETeamUIKit/NETeamUIKit.podspec' -# pod 'NEChatUIKit', :path => 'NEChatUIKit/NEChatUIKit.podspec' -# pod 'NEMapKit', :path => 'NEMapKit/NEMapKit.podspec' + pod 'NEContactUIKit', :path => 'NEContactUIKit/NEContactUIKit.podspec' + pod 'NEConversationUIKit', :path => 'NEConversationUIKit/NEConversationUIKit.podspec' + pod 'NETeamUIKit', :path => 'NETeamUIKit/NETeamUIKit.podspec' + pod 'NEChatUIKit', :path => 'NEChatUIKit/NEChatUIKit.podspec' + pod 'NEMapKit', :path => 'NEMapKit/NEMapKit.podspec' + pod 'NERtcCallUIKit', :path => 'NERtcCallUIKit/NERtcCallUIKit.podspec' end diff --git a/app.xcodeproj/project.pbxproj b/app.xcodeproj/project.pbxproj index f04b2571..b6c28802 100644 --- a/app.xcodeproj/project.pbxproj +++ b/app.xcodeproj/project.pbxproj @@ -7,30 +7,34 @@ objects = { /* Begin PBXBuildFile section */ - 398D733F290692FC00662649 /* MineSettingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398D732C290692FC00662649 /* MineSettingViewModel.swift */; }; - 398D7340290692FC00662649 /* PersonInfoViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398D732D290692FC00662649 /* PersonInfoViewModel.swift */; }; - 398D7341290692FC00662649 /* MessageRemindViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398D732E290692FC00662649 /* MessageRemindViewModel.swift */; }; - 398D7342290692FC00662649 /* IntroduceViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398D732F290692FC00662649 /* IntroduceViewModel.swift */; }; - 398D7343290692FC00662649 /* MeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398D7331290692FC00662649 /* MeViewController.swift */; }; - 398D7344290692FC00662649 /* NEAboutWebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398D7332290692FC00662649 /* NEAboutWebViewController.swift */; }; - 398D7346290692FC00662649 /* InputPersonInfoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398D7334290692FC00662649 /* InputPersonInfoController.swift */; }; - 398D7347290692FC00662649 /* MessageRemindViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398D7335290692FC00662649 /* MessageRemindViewController.swift */; }; - 398D7349290692FC00662649 /* PersonInfoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398D7337290692FC00662649 /* PersonInfoViewController.swift */; }; - 398D734A290692FC00662649 /* IntroduceBrandViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398D7338290692FC00662649 /* IntroduceBrandViewController.swift */; }; - 398D734B290692FC00662649 /* MineTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398D733A290692FC00662649 /* MineTableViewCell.swift */; }; - 398D734C290692FC00662649 /* BirthdayDatePickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398D733B290692FC00662649 /* BirthdayDatePickerView.swift */; }; - 398D734E290692FC00662649 /* VersionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398D733D290692FC00662649 /* VersionCell.swift */; }; - 398D73512906940C00662649 /* MineSettingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398D73502906940C00662649 /* MineSettingViewController.swift */; }; - 39A36F8128002CFF009B07A9 /* NETabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39A36F8028002CFF009B07A9 /* NETabBarController.swift */; }; 39E9E27728D87E9800A11820 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 39E9E27528D87E9800A11820 /* Localizable.strings */; }; - 39F793C827E20434007F63FF /* NENavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39F793C727E20434007F63FF /* NENavigationController.swift */; }; - 4B3B9BDF277AFEE50091A74E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B3B9BDE277AFEE50091A74E /* AppDelegate.swift */; }; - 4B3B9BE3277AFEE50091A74E /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B3B9BE2277AFEE50091A74E /* ViewController.swift */; }; 4B3B9BE6277AFEE50091A74E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4B3B9BE4277AFEE50091A74E /* Main.storyboard */; }; 4B3B9BE8277AFEE70091A74E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4B3B9BE7277AFEE70091A74E /* Assets.xcassets */; }; 4B3B9BEB277AFEE70091A74E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4B3B9BE9277AFEE70091A74E /* LaunchScreen.storyboard */; }; 8D94D1BFC1723D94D352756A /* Pods_app.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D8ECED9A11CC9DB62207FC66 /* Pods_app.framework */; }; 9EA2014127BE4B4800F8BBD0 /* AppKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA2014027BE4B4800F8BBD0 /* AppKey.swift */; }; + DDFAAE8029BACE0B00834C08 /* NodeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFAAE6229BACE0B00834C08 /* NodeViewModel.swift */; }; + DDFAAE8129BACE0B00834C08 /* MineSettingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFAAE6329BACE0B00834C08 /* MineSettingViewModel.swift */; }; + DDFAAE8229BACE0B00834C08 /* PersonInfoViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFAAE6429BACE0B00834C08 /* PersonInfoViewModel.swift */; }; + DDFAAE8329BACE0B00834C08 /* MessageRemindViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFAAE6529BACE0B00834C08 /* MessageRemindViewModel.swift */; }; + DDFAAE8429BACE0B00834C08 /* IntroduceViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFAAE6629BACE0B00834C08 /* IntroduceViewModel.swift */; }; + DDFAAE8529BACE0B00834C08 /* MeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFAAE6829BACE0B00834C08 /* MeViewController.swift */; }; + DDFAAE8629BACE0B00834C08 /* NEAboutWebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFAAE6929BACE0B00834C08 /* NEAboutWebViewController.swift */; }; + DDFAAE8829BACE0B00834C08 /* InputPersonInfoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFAAE6B29BACE0B00834C08 /* InputPersonInfoController.swift */; }; + DDFAAE8929BACE0B00834C08 /* MineSettingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFAAE6C29BACE0B00834C08 /* MineSettingViewController.swift */; }; + DDFAAE8A29BACE0B00834C08 /* MessageRemindViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFAAE6D29BACE0B00834C08 /* MessageRemindViewController.swift */; }; + DDFAAE8B29BACE0B00834C08 /* NENodeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFAAE6E29BACE0B00834C08 /* NENodeViewController.swift */; }; + DDFAAE8C29BACE0B00834C08 /* PersonInfoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFAAE6F29BACE0B00834C08 /* PersonInfoViewController.swift */; }; + DDFAAE8D29BACE0C00834C08 /* IntroduceBrandViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFAAE7029BACE0B00834C08 /* IntroduceBrandViewController.swift */; }; + DDFAAE8E29BACE0C00834C08 /* MineTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFAAE7229BACE0B00834C08 /* MineTableViewCell.swift */; }; + DDFAAE8F29BACE0C00834C08 /* BirthdayDatePickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFAAE7329BACE0B00834C08 /* BirthdayDatePickerView.swift */; }; + DDFAAE9029BACE0C00834C08 /* NodeSelectCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFAAE7429BACE0B00834C08 /* NodeSelectCell.swift */; }; + DDFAAE9129BACE0C00834C08 /* VersionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFAAE7529BACE0B00834C08 /* VersionCell.swift */; }; + DDFAAE9329BACE0C00834C08 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFAAE7929BACE0B00834C08 /* ViewController.swift */; }; + DDFAAE9529BACE0C00834C08 /* NENavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFAAE7B29BACE0B00834C08 /* NENavigationController.swift */; }; + DDFAAE9729BACE0C00834C08 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFAAE7D29BACE0B00834C08 /* AppDelegate.swift */; }; + DDFAAE9829BACE0C00834C08 /* NETabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFAAE7E29BACE0B00834C08 /* NETabBarController.swift */; }; + DDFAAE9F29BAFD1500834C08 /* NEUserHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFAAE9E29BAFD1500834C08 /* NEUserHeaderView.swift */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -52,27 +56,9 @@ 01B0A28E2816CF41009065C5 /* app.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = app.entitlements; sourceTree = ""; }; 01C0FC0F27BE754400C32949 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Main.strings"; sourceTree = ""; }; 01C0FC1027BE754500C32949 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/LaunchScreen.strings"; sourceTree = ""; }; - 398D732C290692FC00662649 /* MineSettingViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MineSettingViewModel.swift; sourceTree = ""; }; - 398D732D290692FC00662649 /* PersonInfoViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PersonInfoViewModel.swift; sourceTree = ""; }; - 398D732E290692FC00662649 /* MessageRemindViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageRemindViewModel.swift; sourceTree = ""; }; - 398D732F290692FC00662649 /* IntroduceViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntroduceViewModel.swift; sourceTree = ""; }; - 398D7331290692FC00662649 /* MeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MeViewController.swift; sourceTree = ""; }; - 398D7332290692FC00662649 /* NEAboutWebViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NEAboutWebViewController.swift; sourceTree = ""; }; - 398D7334290692FC00662649 /* InputPersonInfoController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputPersonInfoController.swift; sourceTree = ""; }; - 398D7335290692FC00662649 /* MessageRemindViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageRemindViewController.swift; sourceTree = ""; }; - 398D7337290692FC00662649 /* PersonInfoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PersonInfoViewController.swift; sourceTree = ""; }; - 398D7338290692FC00662649 /* IntroduceBrandViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntroduceBrandViewController.swift; sourceTree = ""; }; - 398D733A290692FC00662649 /* MineTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MineTableViewCell.swift; sourceTree = ""; }; - 398D733B290692FC00662649 /* BirthdayDatePickerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BirthdayDatePickerView.swift; sourceTree = ""; }; - 398D733D290692FC00662649 /* VersionCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VersionCell.swift; sourceTree = ""; }; - 398D73502906940C00662649 /* MineSettingViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MineSettingViewController.swift; sourceTree = ""; }; - 39A36F8028002CFF009B07A9 /* NETabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NETabBarController.swift; sourceTree = ""; }; 39E9E27628D87E9800A11820 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; 39E9E27828D87EA000A11820 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; - 39F793C727E20434007F63FF /* NENavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NENavigationController.swift; sourceTree = ""; }; 4B3B9BDB277AFEE50091A74E /* app.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = app.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 4B3B9BDE277AFEE50091A74E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 4B3B9BE2277AFEE50091A74E /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 4B3B9BE5277AFEE50091A74E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 4B3B9BE7277AFEE70091A74E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 4B3B9BEA277AFEE70091A74E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; @@ -80,6 +66,29 @@ A9E4316D70F3EF2E6BD5E5CB /* Pods-app.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app.release.xcconfig"; path = "Target Support Files/Pods-app/Pods-app.release.xcconfig"; sourceTree = ""; }; B831F1EC5F2E309A7BB5582D /* Pods-app.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app.debug.xcconfig"; path = "Target Support Files/Pods-app/Pods-app.debug.xcconfig"; sourceTree = ""; }; D8ECED9A11CC9DB62207FC66 /* Pods_app.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_app.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + DDFAAE6229BACE0B00834C08 /* NodeViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NodeViewModel.swift; sourceTree = ""; }; + DDFAAE6329BACE0B00834C08 /* MineSettingViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MineSettingViewModel.swift; sourceTree = ""; }; + DDFAAE6429BACE0B00834C08 /* PersonInfoViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PersonInfoViewModel.swift; sourceTree = ""; }; + DDFAAE6529BACE0B00834C08 /* MessageRemindViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageRemindViewModel.swift; sourceTree = ""; }; + DDFAAE6629BACE0B00834C08 /* IntroduceViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntroduceViewModel.swift; sourceTree = ""; }; + DDFAAE6829BACE0B00834C08 /* MeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MeViewController.swift; sourceTree = ""; }; + DDFAAE6929BACE0B00834C08 /* NEAboutWebViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NEAboutWebViewController.swift; sourceTree = ""; }; + DDFAAE6B29BACE0B00834C08 /* InputPersonInfoController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputPersonInfoController.swift; sourceTree = ""; }; + DDFAAE6C29BACE0B00834C08 /* MineSettingViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MineSettingViewController.swift; sourceTree = ""; }; + DDFAAE6D29BACE0B00834C08 /* MessageRemindViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageRemindViewController.swift; sourceTree = ""; }; + DDFAAE6E29BACE0B00834C08 /* NENodeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NENodeViewController.swift; sourceTree = ""; }; + DDFAAE6F29BACE0B00834C08 /* PersonInfoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PersonInfoViewController.swift; sourceTree = ""; }; + DDFAAE7029BACE0B00834C08 /* IntroduceBrandViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntroduceBrandViewController.swift; sourceTree = ""; }; + DDFAAE7229BACE0B00834C08 /* MineTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MineTableViewCell.swift; sourceTree = ""; }; + DDFAAE7329BACE0B00834C08 /* BirthdayDatePickerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BirthdayDatePickerView.swift; sourceTree = ""; }; + DDFAAE7429BACE0B00834C08 /* NodeSelectCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NodeSelectCell.swift; sourceTree = ""; }; + DDFAAE7529BACE0B00834C08 /* VersionCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VersionCell.swift; sourceTree = ""; }; + DDFAAE7929BACE0B00834C08 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + DDFAAE7B29BACE0B00834C08 /* NENavigationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NENavigationController.swift; sourceTree = ""; }; + DDFAAE7D29BACE0B00834C08 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + DDFAAE7E29BACE0B00834C08 /* NETabBarController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NETabBarController.swift; sourceTree = ""; }; + DDFAAE9A29BAECF100834C08 /* app-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "app-Bridging-Header.h"; sourceTree = ""; }; + DDFAAE9E29BAFD1500834C08 /* NEUserHeaderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NEUserHeaderView.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -102,102 +111,107 @@ name = Frameworks; sourceTree = ""; }; - 398D7329290692FC00662649 /* Mine */ = { + 4B3B9BD2277AFEE50091A74E = { isa = PBXGroup; children = ( - 398D732A290692FC00662649 /* ViewModel */, - 398D7330290692FC00662649 /* Controller */, - 398D7339290692FC00662649 /* View */, + 4B3B9BDD277AFEE50091A74E /* app */, + 4B3B9BDC277AFEE50091A74E /* Products */, + BF083551FB71DB2F668919FB /* Pods */, + 345791C57A67E47F5C6B3317 /* Frameworks */, ); - path = Mine; sourceTree = ""; }; - 398D732A290692FC00662649 /* ViewModel */ = { + 4B3B9BDC277AFEE50091A74E /* Products */ = { isa = PBXGroup; children = ( - 398D732C290692FC00662649 /* MineSettingViewModel.swift */, - 398D732D290692FC00662649 /* PersonInfoViewModel.swift */, - 398D732E290692FC00662649 /* MessageRemindViewModel.swift */, - 398D732F290692FC00662649 /* IntroduceViewModel.swift */, + 4B3B9BDB277AFEE50091A74E /* app.app */, ); - path = ViewModel; + name = Products; sourceTree = ""; }; - 398D7330290692FC00662649 /* Controller */ = { + 4B3B9BDD277AFEE50091A74E /* app */ = { isa = PBXGroup; children = ( - 398D73502906940C00662649 /* MineSettingViewController.swift */, - 398D7331290692FC00662649 /* MeViewController.swift */, - 398D7332290692FC00662649 /* NEAboutWebViewController.swift */, - 398D7334290692FC00662649 /* InputPersonInfoController.swift */, - 398D7335290692FC00662649 /* MessageRemindViewController.swift */, - 398D7337290692FC00662649 /* PersonInfoViewController.swift */, - 398D7338290692FC00662649 /* IntroduceBrandViewController.swift */, + DDFAAE7829BACE0B00834C08 /* Main */, + DDFAAE6029BACE0B00834C08 /* Mine */, + 01B0A28E2816CF41009065C5 /* app.entitlements */, + 9EA2014027BE4B4800F8BBD0 /* AppKey.swift */, + 39E9E27528D87E9800A11820 /* Localizable.strings */, + 4B3B9BE4277AFEE50091A74E /* Main.storyboard */, + 4B3B9BE7277AFEE70091A74E /* Assets.xcassets */, + 4B3B9BE9277AFEE70091A74E /* LaunchScreen.storyboard */, + DDFAAE9A29BAECF100834C08 /* app-Bridging-Header.h */, ); - path = Controller; + path = app; sourceTree = ""; }; - 398D7339290692FC00662649 /* View */ = { + BF083551FB71DB2F668919FB /* Pods */ = { isa = PBXGroup; children = ( - 398D733A290692FC00662649 /* MineTableViewCell.swift */, - 398D733B290692FC00662649 /* BirthdayDatePickerView.swift */, - 398D733D290692FC00662649 /* VersionCell.swift */, + B831F1EC5F2E309A7BB5582D /* Pods-app.debug.xcconfig */, + A9E4316D70F3EF2E6BD5E5CB /* Pods-app.release.xcconfig */, ); - path = View; + path = Pods; sourceTree = ""; }; - 398D734F2906931E00662649 /* Main */ = { + DDFAAE6029BACE0B00834C08 /* Mine */ = { isa = PBXGroup; children = ( - 39F793C727E20434007F63FF /* NENavigationController.swift */, - 39A36F8028002CFF009B07A9 /* NETabBarController.swift */, - 4B3B9BDE277AFEE50091A74E /* AppDelegate.swift */, + DDFAAE6129BACE0B00834C08 /* ViewModel */, + DDFAAE6729BACE0B00834C08 /* Controller */, + DDFAAE7129BACE0B00834C08 /* View */, ); - path = Main; + path = Mine; sourceTree = ""; }; - 4B3B9BD2277AFEE50091A74E = { + DDFAAE6129BACE0B00834C08 /* ViewModel */ = { isa = PBXGroup; children = ( - 4B3B9BDD277AFEE50091A74E /* app */, - 4B3B9BDC277AFEE50091A74E /* Products */, - BF083551FB71DB2F668919FB /* Pods */, - 345791C57A67E47F5C6B3317 /* Frameworks */, + DDFAAE6229BACE0B00834C08 /* NodeViewModel.swift */, + DDFAAE6329BACE0B00834C08 /* MineSettingViewModel.swift */, + DDFAAE6429BACE0B00834C08 /* PersonInfoViewModel.swift */, + DDFAAE6529BACE0B00834C08 /* MessageRemindViewModel.swift */, + DDFAAE6629BACE0B00834C08 /* IntroduceViewModel.swift */, ); + path = ViewModel; sourceTree = ""; }; - 4B3B9BDC277AFEE50091A74E /* Products */ = { + DDFAAE6729BACE0B00834C08 /* Controller */ = { isa = PBXGroup; children = ( - 4B3B9BDB277AFEE50091A74E /* app.app */, + DDFAAE6829BACE0B00834C08 /* MeViewController.swift */, + DDFAAE6929BACE0B00834C08 /* NEAboutWebViewController.swift */, + DDFAAE6B29BACE0B00834C08 /* InputPersonInfoController.swift */, + DDFAAE6C29BACE0B00834C08 /* MineSettingViewController.swift */, + DDFAAE6D29BACE0B00834C08 /* MessageRemindViewController.swift */, + DDFAAE6E29BACE0B00834C08 /* NENodeViewController.swift */, + DDFAAE6F29BACE0B00834C08 /* PersonInfoViewController.swift */, + DDFAAE7029BACE0B00834C08 /* IntroduceBrandViewController.swift */, ); - name = Products; + path = Controller; sourceTree = ""; }; - 4B3B9BDD277AFEE50091A74E /* app */ = { + DDFAAE7129BACE0B00834C08 /* View */ = { isa = PBXGroup; children = ( - 398D734F2906931E00662649 /* Main */, - 398D7329290692FC00662649 /* Mine */, - 01B0A28E2816CF41009065C5 /* app.entitlements */, - 9EA2014027BE4B4800F8BBD0 /* AppKey.swift */, - 4B3B9BE2277AFEE50091A74E /* ViewController.swift */, - 39E9E27528D87E9800A11820 /* Localizable.strings */, - 4B3B9BE4277AFEE50091A74E /* Main.storyboard */, - 4B3B9BE7277AFEE70091A74E /* Assets.xcassets */, - 4B3B9BE9277AFEE70091A74E /* LaunchScreen.storyboard */, + DDFAAE9E29BAFD1500834C08 /* NEUserHeaderView.swift */, + DDFAAE7229BACE0B00834C08 /* MineTableViewCell.swift */, + DDFAAE7329BACE0B00834C08 /* BirthdayDatePickerView.swift */, + DDFAAE7429BACE0B00834C08 /* NodeSelectCell.swift */, + DDFAAE7529BACE0B00834C08 /* VersionCell.swift */, ); - path = app; + path = View; sourceTree = ""; }; - BF083551FB71DB2F668919FB /* Pods */ = { + DDFAAE7829BACE0B00834C08 /* Main */ = { isa = PBXGroup; children = ( - B831F1EC5F2E309A7BB5582D /* Pods-app.debug.xcconfig */, - A9E4316D70F3EF2E6BD5E5CB /* Pods-app.release.xcconfig */, + DDFAAE7929BACE0B00834C08 /* ViewController.swift */, + DDFAAE7B29BACE0B00834C08 /* NENavigationController.swift */, + DDFAAE7D29BACE0B00834C08 /* AppDelegate.swift */, + DDFAAE7E29BACE0B00834C08 /* NETabBarController.swift */, ); - path = Pods; + path = Main; sourceTree = ""; }; /* End PBXGroup section */ @@ -237,6 +251,7 @@ TargetAttributes = { 4B3B9BDA277AFEE50091A74E = { CreatedOnToolsVersion = 13.0; + LastSwiftMigration = 1410; }; }; }; @@ -337,25 +352,29 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 39F793C827E20434007F63FF /* NENavigationController.swift in Sources */, - 398D7346290692FC00662649 /* InputPersonInfoController.swift in Sources */, - 398D7343290692FC00662649 /* MeViewController.swift in Sources */, - 398D7349290692FC00662649 /* PersonInfoViewController.swift in Sources */, - 398D734A290692FC00662649 /* IntroduceBrandViewController.swift in Sources */, - 398D733F290692FC00662649 /* MineSettingViewModel.swift in Sources */, + DDFAAE8129BACE0B00834C08 /* MineSettingViewModel.swift in Sources */, + DDFAAE8A29BACE0B00834C08 /* MessageRemindViewController.swift in Sources */, + DDFAAE8529BACE0B00834C08 /* MeViewController.swift in Sources */, + DDFAAE8929BACE0B00834C08 /* MineSettingViewController.swift in Sources */, + DDFAAE8D29BACE0C00834C08 /* IntroduceBrandViewController.swift in Sources */, + DDFAAE8029BACE0B00834C08 /* NodeViewModel.swift in Sources */, + DDFAAE9829BACE0C00834C08 /* NETabBarController.swift in Sources */, + DDFAAE8C29BACE0B00834C08 /* PersonInfoViewController.swift in Sources */, + DDFAAE8F29BACE0C00834C08 /* BirthdayDatePickerView.swift in Sources */, + DDFAAE8B29BACE0B00834C08 /* NENodeViewController.swift in Sources */, 9EA2014127BE4B4800F8BBD0 /* AppKey.swift in Sources */, - 398D7340290692FC00662649 /* PersonInfoViewModel.swift in Sources */, - 4B3B9BE3277AFEE50091A74E /* ViewController.swift in Sources */, - 398D734C290692FC00662649 /* BirthdayDatePickerView.swift in Sources */, - 39A36F8128002CFF009B07A9 /* NETabBarController.swift in Sources */, - 398D7342290692FC00662649 /* IntroduceViewModel.swift in Sources */, - 398D7344290692FC00662649 /* NEAboutWebViewController.swift in Sources */, - 398D7347290692FC00662649 /* MessageRemindViewController.swift in Sources */, - 4B3B9BDF277AFEE50091A74E /* AppDelegate.swift in Sources */, - 398D734E290692FC00662649 /* VersionCell.swift in Sources */, - 398D7341290692FC00662649 /* MessageRemindViewModel.swift in Sources */, - 398D73512906940C00662649 /* MineSettingViewController.swift in Sources */, - 398D734B290692FC00662649 /* MineTableViewCell.swift in Sources */, + DDFAAE8829BACE0B00834C08 /* InputPersonInfoController.swift in Sources */, + DDFAAE9729BACE0C00834C08 /* AppDelegate.swift in Sources */, + DDFAAE8629BACE0B00834C08 /* NEAboutWebViewController.swift in Sources */, + DDFAAE9129BACE0C00834C08 /* VersionCell.swift in Sources */, + DDFAAE8229BACE0B00834C08 /* PersonInfoViewModel.swift in Sources */, + DDFAAE8429BACE0B00834C08 /* IntroduceViewModel.swift in Sources */, + DDFAAE9F29BAFD1500834C08 /* NEUserHeaderView.swift in Sources */, + DDFAAE8E29BACE0C00834C08 /* MineTableViewCell.swift in Sources */, + DDFAAE9329BACE0C00834C08 /* ViewController.swift in Sources */, + DDFAAE8329BACE0B00834C08 /* MessageRemindViewModel.swift in Sources */, + DDFAAE9029BACE0C00834C08 /* NodeSelectCell.swift in Sources */, + DDFAAE9529BACE0C00834C08 /* NENavigationController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -520,6 +539,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = app/app.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; @@ -554,7 +574,8 @@ PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_OBJC_BRIDGING_HEADER = "app/app-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -566,6 +587,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = app/app.entitlements; CODE_SIGN_IDENTITY = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; @@ -600,7 +622,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = inHouseYunxin; SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_OBJC_BRIDGING_HEADER = "app/app-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; diff --git a/app/Main/AppDelegate.swift b/app/Main/AppDelegate.swift index 5280ff4b..83b7336f 100644 --- a/app/Main/AppDelegate.swift +++ b/app/Main/AppDelegate.swift @@ -1,45 +1,56 @@ -// Copyright (c) 2022 NetEase, Inc. All rights reserved. -// Use of this source code is governed by a MIT license that can be found in the LICENSE file. +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. import UIKit import NEContactUIKit import YXLogin import NECoreKit import NIMSDK -import NEQChatUIKit import NECoreIMKit import NEConversationUIKit import NETeamUIKit import NEChatUIKit import NEMapKit +import NERtcCallKit +import NERtcCallUIKit @main class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate { public var window: UIWindow? + private var tabbarCtrl = UITabBarController() func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + window?.backgroundColor = .white setupInit() NotificationCenter.default.addObserver(self, selector: #selector(refreshRoot), name: Notification.Name("logout"), object: nil) registerAPNS() return true } + func setupInit(){ + // init let option = NIMSDKOption() option.appKey = AppKey.appKey option.apnsCername = AppKey.pushCerName IMKitClient.instance.setupCoreKitIM(option) - NEKeyboardManager.shared.enable = true NEKeyboardManager.shared.shouldResignOnTouchOutside = true - - //login action - startLogin(account: <#imAccid#>, token: <#imToken#>) - + + weak var weakSelf = self + IMKitClient.instance.loginIM("<#accid#>", "<#token#>") { error in + if let err = error { + print("NEKitCore login error : ", err) + }else { + ChatRouter.setupInit() + weakSelf?.initializePage() + } + } } @objc func refreshRoot(){ @@ -79,46 +90,47 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD NELog.infoLog("app delegate : ", desc: error.localizedDescription) } - func startLogin(account:String,token:String){ - weak var weakSelf = self - IMKitClient.instance.loginIM(account, token) { error in - if let err = error { - print("NEKitCore login error : ", err) - }else { - ChatRouter.setupInit() - let param = QChatLoginParam(account,token) - IMKitClient.instance.loginQchat(param) { error, response in - if let err = error { - print("qchatLogin failed, error : ", err) - }else { - weakSelf?.setupTabbar() - } - } - } - } - } - - - func setupTabbar() { + func initializePage() { self.window?.rootViewController = NETabBarController() loadService() } - //路由注册 +// regist router func loadService() { + //TODO: service ContactRouter.register() ChatRouter.register() TeamRouter.register() ConversationRouter.register() + + //地图map初始化 + NEMapClient.shared().setupMapClient(withAppkey: AppKey.gaodeMapAppkey) + + /* 聊天面板外部扩展示例 + let item = NEMoreItemModel() + item.customDelegate = self + item.action = #selector(testLog) + item.customImage = UIImage(named: "chatSelect") + NEChatUIKitClient.instance.moreAction.append(item) + */ + + //呼叫组件初始化 + let option = NERtcCallOptions() + option.apnsCerName = AppKey.pushCerName + option.isDisableLog = true + let uiConfig = NERtcCallUIConfig() + uiConfig.option = option + uiConfig.appKey = AppKey.appKey + uiConfig.uiConfig.showCallingSwitchCallType = option.supportAutoJoinWhenCalled + NERtcCallKit.sharedInstance().timeOutSeconds = 30 + NERtcCallUIKit.sharedInstance().setup(with: uiConfig) + Router.shared.register(MeSettingRouter) { param in if let nav = param["nav"] as? UINavigationController { let me = PersonInfoViewController() nav.pushViewController(me, animated: true) } } - - //地图map初始化 - NEMapClient.shared().setupMapClient(withAppkey: AppKey.gaodeMapAppkey) } func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { diff --git a/app/Main/NENavigationController.swift b/app/Main/NENavigationController.swift index 803b1104..9d3a996b 100644 --- a/app/Main/NENavigationController.swift +++ b/app/Main/NENavigationController.swift @@ -31,4 +31,11 @@ class NENavigationController: UINavigationController { } super.pushViewController(viewController, animated: true) } + + override func popToViewController(_ viewController: UIViewController, animated: Bool) -> [UIViewController]? { + if children.count > 0 { + viewController.hidesBottomBarWhenPushed = true + } + return super.popToViewController(viewController, animated: animated) + } } diff --git a/app/Main/NETabBarController.swift b/app/Main/NETabBarController.swift index d6947b0b..ba6c56a8 100644 --- a/app/Main/NETabBarController.swift +++ b/app/Main/NETabBarController.swift @@ -6,7 +6,6 @@ import UIKit import NIMSDK import NECoreKit -import NEQChatUIKit import NECoreIMKit import NEConversationUIKit import NETeamUIKit @@ -37,16 +36,6 @@ class NETabBarController: UITabBarController { ) let chatNav = NENavigationController(rootViewController: chat) - // qchat - let qchat = QChatHomeViewController() - qchat.view.backgroundColor = UIColor(hexString: "#e9eff5") - qchat.tabBarItem = UITabBarItem( - title: NSLocalizedString("qchat", comment: ""), - image: UIImage(named: "qchat_tabbar_icon"), - selectedImage: UIImage(named: "qchat_tabbar_icon")?.withRenderingMode(.alwaysOriginal) - ) - let qChatNav = NENavigationController(rootViewController: qchat) - // Contacts let contactVC = ContactsViewController() contactVC.tabBarItem = UITabBarItem( @@ -68,14 +57,14 @@ class NETabBarController: UITabBarController { let meNav = NENavigationController(rootViewController: meVC) tabBar.backgroundColor = .white - viewControllers = [chatNav, qChatNav, contactsNav, meNav] + viewControllers = [chatNav, contactsNav, meNav] selectedIndex = 0 } func setUpSessionBadgeValue() { - sessionUnreadCount = ConversationRepo().getMsgUnreadCount(notify: true) + sessionUnreadCount = ConversationProvider.shared.allUnreadCount(notify: true) if sessionUnreadCount > 0 { - tabBar.showBadgOn(index: 0) + tabBar.showBadgOn(index: 0, tabbarItemNums: 3) } else { tabBar.hideBadg(on: 0) } @@ -84,9 +73,9 @@ class NETabBarController: UITabBarController { func setUpContactBadgeValue() { contactUnreadCount = NIMSDK.shared().systemNotificationManager.allUnreadCount() if contactUnreadCount > 0 { - tabBar.showBadgOn(index: 2) + tabBar.showBadgOn(index: 1, tabbarItemNums: 3) } else { - tabBar.hideBadg(on: 2) + tabBar.hideBadg(on: 1) } } diff --git a/app/ViewController.swift b/app/Main/ViewController.swift similarity index 100% rename from app/ViewController.swift rename to app/Main/ViewController.swift diff --git a/app/Mine/Controller/InputPersonInfoController.swift b/app/Mine/Controller/InputPersonInfoController.swift index 47c54f9c..de711202 100644 --- a/app/Mine/Controller/InputPersonInfoController.swift +++ b/app/Mine/Controller/InputPersonInfoController.swift @@ -43,12 +43,21 @@ class InputPersonInfoController: NEBaseViewController, UITextFieldDelegate { textfieldBgView.heightAnchor.constraint(equalToConstant: 50), ]) } else { - NSLayoutConstraint.activate([ - textfieldBgView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20.0), - textfieldBgView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -20), - textfieldBgView.topAnchor.constraint(equalTo: view.topAnchor, constant: 12), - textfieldBgView.heightAnchor.constraint(equalToConstant: 50), - ]) + if #available(iOS 10.0, *) { + NSLayoutConstraint.activate([ + textfieldBgView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20.0), + textfieldBgView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -20), + textfieldBgView.topAnchor.constraint(equalTo: view.topAnchor, constant: 12), + textfieldBgView.heightAnchor.constraint(equalToConstant: 50), + ]) + } else { + NSLayoutConstraint.activate([ + textfieldBgView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20.0), + textfieldBgView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -20), + textfieldBgView.topAnchor.constraint(equalTo: view.topAnchor, constant: 12 + kNavigationHeight + KStatusBarHeight), + textfieldBgView.heightAnchor.constraint(equalToConstant: 50), + ]) + } } textfieldBgView.addSubview(textField) @@ -69,7 +78,7 @@ class InputPersonInfoController: NEBaseViewController, UITextFieldDelegate { weak var weakSelf = self if let block = callBack { block(textField.text ?? "") - weakSelf?.navigationController?.popViewController(animated: true) +// weakSelf?.navigationController?.popViewController(animated: true) } } @@ -100,6 +109,7 @@ class InputPersonInfoController: NEBaseViewController, UITextFieldDelegate { text.delegate = self text.clearButtonMode = .always text.becomeFirstResponder() + text.addTarget(self, action: #selector(textFieldChange), for: .editingChanged) return text }() @@ -112,15 +122,15 @@ class InputPersonInfoController: NEBaseViewController, UITextFieldDelegate { return backView }() - // MARK: UITextFieldDelegate - - func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, - replacementString string: String) -> Bool { - if let text = (textField.text as NSString?)?.replacingCharacters(in: range, with: string), - text.count > limitNumberCount { - showToast("最多只能输入\(limitNumberCount)个字符哦") - return false + @objc + func textFieldChange() { + guard let _ = textField.markedTextRange else { + if let text = textField.text, + text.count > limitNumberCount { + textField.text = String(text.prefix(limitNumberCount)) + showToast(String(format: NSLocalizedString("text_count_limit", comment: ""), limitNumberCount)) + } + return } - return true } } diff --git a/app/Mine/Controller/IntroduceBrandViewController.swift b/app/Mine/Controller/IntroduceBrandViewController.swift index cd2dd54f..66ad1621 100644 --- a/app/Mine/Controller/IntroduceBrandViewController.swift +++ b/app/Mine/Controller/IntroduceBrandViewController.swift @@ -1,4 +1,3 @@ - // Copyright (c) 2022 NetEase, Inc. All rights reserved. // Use of this source code is governed by a MIT license that can be // found in the LICENSE file. @@ -25,7 +24,7 @@ class IntroduceBrandViewController: NEBaseViewController, UITableViewDelegate, func setupSubviews() { view.addSubview(headImage) - view.addSubview(headLable) + view.addSubview(headLabel) view.addSubview(tableView) @@ -37,12 +36,11 @@ class IntroduceBrandViewController: NEBaseViewController, UITableViewDelegate, ), headImage.widthAnchor.constraint(equalToConstant: 72), headImage.heightAnchor.constraint(equalToConstant: 53), - ]) NSLayoutConstraint.activate([ - headLable.centerXAnchor.constraint(equalTo: headImage.centerXAnchor), - headLable.topAnchor.constraint(equalTo: headImage.bottomAnchor, constant: 10), + headLabel.centerXAnchor.constraint(equalTo: headImage.centerXAnchor), + headLabel.topAnchor.constraint(equalTo: headImage.bottomAnchor, constant: 10), ]) NSLayoutConstraint.activate([ @@ -61,7 +59,7 @@ class IntroduceBrandViewController: NEBaseViewController, UITableViewDelegate, return image }() - private lazy var headLable: UILabel = { + private lazy var headLabel: UILabel = { let label = UILabel() label.translatesAutoresizingMaskIntoConstraints = false label.text = NSLocalizedString("brand_des", comment: "") diff --git a/app/Mine/Controller/MeViewController.swift b/app/Mine/Controller/MeViewController.swift index dbca3e46..7e103ffc 100644 --- a/app/Mine/Controller/MeViewController.swift +++ b/app/Mine/Controller/MeViewController.swift @@ -8,7 +8,6 @@ import YXLogin import NECoreKit import NIMSDK import NECoreIMKit -import NEQChatUIKit class MeViewController: UIViewController { private let mineData = [ @@ -59,7 +58,7 @@ class MeViewController: UIViewController { header.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20), header.topAnchor.constraint( equalTo: self.view.safeAreaLayoutGuide.topAnchor, - constant: 20 + constant: 32 ), header.widthAnchor.constraint(equalToConstant: 60), header.heightAnchor.constraint(equalToConstant: 60), @@ -68,7 +67,7 @@ class MeViewController: UIViewController { // Fallback on earlier versions NSLayoutConstraint.activate([ header.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20), - header.topAnchor.constraint(equalTo: view.topAnchor, constant: 20), + header.topAnchor.constraint(equalTo: view.topAnchor, constant: 32), header.widthAnchor.constraint(equalToConstant: 60), header.heightAnchor.constraint(equalToConstant: 60), ]) @@ -130,7 +129,7 @@ class MeViewController: UIViewController { } func updateUserInfo() { - let user = userProvider.getUserInfo(userId: IMKitClient.instance.imAccid) + let user = userProvider.getUserInfo(userId: IMKitEngine.instance.imAccid) idLabel.text = "\(NSLocalizedString("account", comment: "")):\(user?.userId ?? "")" nameLabel.text = user?.userInfo?.nickName header.configHeadData(headUrl: user?.userInfo?.avatarUrl, name: user?.showName() ?? "") diff --git a/app/Mine/Controller/MineSettingViewController.swift b/app/Mine/Controller/MineSettingViewController.swift index 6f7b5e2d..6268af24 100644 --- a/app/Mine/Controller/MineSettingViewController.swift +++ b/app/Mine/Controller/MineSettingViewController.swift @@ -89,18 +89,9 @@ class MineSettingViewController: NEBaseViewController, UITableViewDataSource, UI return footer } - @objc func loginOutAction(){ - NIMSDK.shared().loginManager.logout { error in - NIMSDK.shared().qchatManager.logout { chatError in - if error != nil { - self.view.makeToast(error?.localizedDescription) - }else { - print("logout success") - NotificationCenter.default.post(name: Notification.Name("logout"), object: nil) - } - } - } - } + @objc func loginOutAction() { + view.makeToast("demo not support logout") + } // MARK: UITableViewDataSource, UITableViewDelegate diff --git a/app/Mine/Controller/NENodeViewController.swift b/app/Mine/Controller/NENodeViewController.swift new file mode 100644 index 00000000..b053108e --- /dev/null +++ b/app/Mine/Controller/NENodeViewController.swift @@ -0,0 +1,123 @@ + +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +import UIKit +import NECoreKit +import NETeamUIKit + +class NENodeViewController: NEBaseViewController, UITableViewDataSource, UITableViewDelegate { + private var viewModel = NodeViewModel() + // 记录默认选中的cell + private var selectIndex = 0 + + override func viewDidLoad() { + super.viewDidLoad() + viewModel.getData() + setupUI() + } + + func setupUI() { + title = NSLocalizedString("node_select", comment: "") + view.addSubview(tableView) + NSLayoutConstraint.activate([ + tableView.leftAnchor.constraint(equalTo: view.leftAnchor), + tableView.rightAnchor.constraint(equalTo: view.rightAnchor), + tableView.topAnchor.constraint(equalTo: view.topAnchor), + tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor), + ]) + + tableView.register( + NodeSelectCell.self, + forCellReuseIdentifier: "\(NSStringFromClass(NodeSelectCell.self))" + ) + } + + private func showAlert(_ isDomestic: Bool) { + let alertController = UIAlertController( + title: NSLocalizedString("change_node", comment: ""), + message: NSLocalizedString("restart_take_effect", comment: ""), + preferredStyle: .alert + ) + + let cancelAction = UIAlertAction(title: NSLocalizedString("cancel", comment: ""), style: .default) { action in + } + alertController.addAction(cancelAction) + let sureAction = UIAlertAction(title: NSLocalizedString("restart", comment: ""), style: .default) { action in + // 设置节点 + IMKitClient.instance.repo.setNodeValue(isDomestic) + exit(0) + } + alertController.addAction(sureAction) + present(alertController, animated: true, completion: nil) + } + + lazy var tableView: UITableView = { + let table = UITableView() + table.translatesAutoresizingMaskIntoConstraints = false + table.backgroundColor = UIColor(hexString: "0xF1F1F6") + table.dataSource = self + table.delegate = self + table.separatorColor = .clear + table.separatorStyle = .none + table.sectionHeaderHeight = 12.0 + if #available(iOS 15.0, *) { + table.sectionHeaderTopPadding = 0.0 + } + return table + }() + + // MARK: UITableViewDataSource, UITableViewDelegate + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + if viewModel.sectionData.count > section { + let model = viewModel.sectionData[section] + return model.cellModels.count + } + return 0 + } + + func numberOfSections(in tableView: UITableView) -> Int { + viewModel.sectionData.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let model = viewModel.sectionData[indexPath.section].cellModels[indexPath.row] + let cell = tableView.dequeueReusableCell( + withIdentifier: "\(NSStringFromClass(NodeSelectCell.self))", + for: indexPath + ) as! NodeSelectCell + cell.configure(model) + return cell + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + if indexPath.row == 0 { + showAlert(true) + } else { + showAlert(false) + } + } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + let model = viewModel.sectionData[indexPath.section].cellModels[indexPath.row] + return model.rowHeight + } + + func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { + if viewModel.sectionData.count > section { + let model = viewModel.sectionData[section] + if model.cellModels.count > 0 { + return 12.0 + } + } + return 0 + } + + func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { + let header = UIView() + header.backgroundColor = UIColor(hexString: "0xF1F1F6") + return header + } +} diff --git a/app/Mine/Controller/PersonInfoViewController.swift b/app/Mine/Controller/PersonInfoViewController.swift index 3aef86f4..bcbac4e4 100644 --- a/app/Mine/Controller/PersonInfoViewController.swift +++ b/app/Mine/Controller/PersonInfoViewController.swift @@ -1,4 +1,3 @@ - // Copyright (c) 2022 NetEase, Inc. All rights reserved. // Use of this source code is governed by a MIT license that can be // found in the LICENSE file. @@ -9,6 +8,7 @@ import NETeamUIKit import NEChatUIKit import NIMSDK +@objcMembers class PersonInfoViewController: NEBaseViewController, NIMUserManagerDelegate, UINavigationControllerDelegate, PersonInfoViewModelDelegate, UITableViewDelegate, UITableViewDataSource { @@ -69,8 +69,8 @@ class PersonInfoViewController: NEBaseViewController, NIMUserManagerDelegate, second.setValue(UIColor(hexString: "0x333333"), forKey: "_titleTextColor") let cancel = UIAlertAction(title: NSLocalizedString("cancel", comment: ""), - style: .cancel) { action in - } + style: .cancel) + cancel.setValue(UIColor(hexString: "0x333333"), forKey: "_titleTextColor") alert.addAction(first) @@ -130,7 +130,7 @@ class PersonInfoViewController: NEBaseViewController, NIMUserManagerDelegate, // MARK: NIMUserManagerDelegate func onUserInfoChanged(_ user: NIMUser) { - if user.userId == IMKitClient.instance.imAccid { + if user.userId == IMKitEngine.instance.imAccid { viewModel.getData() tableView.reloadData() } @@ -151,7 +151,7 @@ class PersonInfoViewController: NEBaseViewController, NIMUserManagerDelegate, weak var weakSelf = self if let imageData = image.jpegData(compressionQuality: 0.6) as NSData? { let filePath = NSHomeDirectory().appending("/Documents/") - .appending(IMKitClient.instance.imAccid) + .appending(IMKitEngine.instance.imAccid) let succcess = imageData.write(toFile: filePath, atomically: true) if succcess { NIMSDK.shared().resourceManager @@ -190,7 +190,9 @@ class PersonInfoViewController: NEBaseViewController, NIMUserManagerDelegate, ctrl.callBack = { editText in weakSelf?.viewModel.updateNickName(name: editText) { error in if error != nil { - weakSelf?.showToast(NSLocalizedString("setting_nickname_failure", comment: "")) + weakSelf?.showToastInWindow(NSLocalizedString("setting_nickname_failure", comment: "")) + } else { + weakSelf?.navigationController?.popViewController(animated: true) } } } @@ -225,7 +227,9 @@ class PersonInfoViewController: NEBaseViewController, NIMUserManagerDelegate, ctrl.callBack = { editText in weakSelf?.viewModel.updateMobile(mobile: editText) { error in if error != nil { - weakSelf?.showToast(NSLocalizedString("change_phone_failure", comment: "")) + weakSelf?.showToastInWindow(NSLocalizedString("change_phone_failure", comment: "")) + } else { + weakSelf?.navigationController?.popViewController(animated: true) } } } @@ -240,7 +244,9 @@ class PersonInfoViewController: NEBaseViewController, NIMUserManagerDelegate, ctrl.callBack = { editText in weakSelf?.viewModel.updateEmail(email: editText) { error in if error != nil { - weakSelf?.showToast(NSLocalizedString("change_email_failure", comment: "")) + weakSelf?.showToastInWindow(NSLocalizedString("change_email_failure", comment: "")) + } else { + weakSelf?.navigationController?.popViewController(animated: true) } } } @@ -255,7 +261,9 @@ class PersonInfoViewController: NEBaseViewController, NIMUserManagerDelegate, ctrl.callBack = { editText in weakSelf?.viewModel.updateSign(sign: editText) { error in if error != nil { - weakSelf?.showToast(NSLocalizedString("change_sign_failure", comment: "")) + weakSelf?.showToastInWindow(NSLocalizedString("change_sign_failure", comment: "")) + } else { + weakSelf?.navigationController?.popViewController(animated: true) } } } diff --git a/app/Mine/View/BirthdayDatePickerView.swift b/app/Mine/View/BirthdayDatePickerView.swift index d5b773b5..8e6b376f 100644 --- a/app/Mine/View/BirthdayDatePickerView.swift +++ b/app/Mine/View/BirthdayDatePickerView.swift @@ -27,6 +27,11 @@ public class BirthdayDatePickerView: UIView { // 将日期选择器区域设置为中文,则选择器日期显示为中文 datePicker.locale = Locale(identifier: "zh_CN") datePicker.datePickerMode = .date + datePicker.maximumDate = Date() + if #available(iOS 13.4, *) { + datePicker.preferredDatePickerStyle = .wheels + } + // 注意:action里面的方法名后面需要加个冒号“:” datePicker.addTarget(self, action: #selector(dateChanged), for: .valueChanged) diff --git a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatHeaderView.swift b/app/Mine/View/NEUserHeaderView.swift similarity index 50% rename from NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatHeaderView.swift rename to app/Mine/View/NEUserHeaderView.swift index 2b56daa1..19ce8eb2 100644 --- a/NEQChatUIKit/NEQChatUIKit/Classes/Base/BaseView/QChatHeaderView.swift +++ b/app/Mine/View/NEUserHeaderView.swift @@ -5,24 +5,16 @@ import UIKit -public class QChatHeaderView: UIView { +public class NEUserHeaderView: UIImageView { public lazy var titleLabel: UILabel = { let label = UILabel() - label.font = DefaultTextFont(12) - label.textColor = .ne_greyText + label.font = UIFont.systemFont(ofSize: 12) + label.textColor = .white label.translatesAutoresizingMaskIntoConstraints = false return label }() - /* - // Only override draw() if you perform custom drawing. - // An empty implementation adversely affects performance during animation. - override func draw(_ rect: CGRect) { - // Drawing code - } - */ - - override init(frame: CGRect) { + override public init(frame: CGRect) { super.init(frame: frame) setupUI() } @@ -32,15 +24,29 @@ public class QChatHeaderView: UIView { } func setupUI() { + contentMode = .scaleAspectFill + isUserInteractionEnabled = true clipsToBounds = false addSubview(titleLabel) NSLayoutConstraint.activate([ - titleLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -8), - titleLabel.leftAnchor.constraint(equalTo: leftAnchor, constant: 33), + titleLabel.centerYAnchor + .constraint(equalTo: centerYAnchor), + titleLabel.centerXAnchor.constraint(equalTo: centerXAnchor), ]) backgroundColor = .clear } + public func configHeadData(headUrl: String?, name: String) { + if let avatar = headUrl, !avatar.isEmpty { + setTitle("") + sd_setImage(with: URL(string: avatar), completed: nil) + } else { + setTitle(name) + sd_setImage(with: nil, completed: nil) + backgroundColor = UIColor.colorWithString(string: name) + } + } + public func setTitle(_ name: String) { titleLabel.text = name .count > 2 ? String(name[name.index(name.endIndex, offsetBy: -2)...]) : name diff --git a/app/Mine/View/NodeSelectCell.swift b/app/Mine/View/NodeSelectCell.swift new file mode 100644 index 00000000..cef006f9 --- /dev/null +++ b/app/Mine/View/NodeSelectCell.swift @@ -0,0 +1,67 @@ + +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +import UIKit +import NETeamUIKit + +class NodeSelectCell: CornerCell { + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + selectionStyle = .none + setupUI() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + public func configure(_ cellModel: SettingCellModel) { + cornerType = cellModel.cornerType + stateImg.isHighlighted = cellModel.switchOpen ? true : false + titleLabel.text = cellModel.subTitle + } + + func setupUI() { + contentView.addSubview(titleLabel) + contentView.addSubview(stateImg) + + NSLayoutConstraint.activate([ + stateImg.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), + stateImg.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 30), + ]) + + NSLayoutConstraint.activate([ + titleLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), + titleLabel.leftAnchor.constraint(equalTo: stateImg.rightAnchor, constant: 10), + ]) + } + + lazy var titleLabel: UILabel = { + let label = UILabel() + label.textColor = UIColor.ne_darkText + label.font = NEConstant.defaultTextFont(14.0) + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + lazy var stateImg: UIImageView = { + let img = UIImageView() + img.image = UIImage(named: "unselect") + img.highlightedImage = UIImage(named: "select") + img.translatesAutoresizingMaskIntoConstraints = false + return img + }() +} diff --git a/app/Mine/ViewModel/MineSettingViewModel.swift b/app/Mine/ViewModel/MineSettingViewModel.swift index 1c069e23..0b20346f 100644 --- a/app/Mine/ViewModel/MineSettingViewModel.swift +++ b/app/Mine/ViewModel/MineSettingViewModel.swift @@ -55,10 +55,10 @@ public class MineSettingViewModel: NSObject { receiverModel.type = SettingCellType.SettingSwitchCell.rawValue receiverModel.cornerType = .topLeft.union(.topRight) // receiverModel.switchOpen = CoreKitEngine.instance.repo.getHandSetMode() - receiverModel.switchOpen = IMKitClient.instance.repo.getHandsetMode() + receiverModel.switchOpen = IMKitEngine.instance.repo.getHandsetMode() receiverModel.swichChange = { isOpen in - IMKitClient.instance.repo.setHandsetMode(isOpen) + IMKitEngine.instance.repo.setHandsetMode(isOpen) } // //过滤通知 // let filterNotify = SettingCellModel() @@ -74,10 +74,10 @@ public class MineSettingViewModel: NSObject { // let deleteFriend = SettingCellModel() // deleteFriend.cellName = NSLocalizedString("delete_friend", comment: "") // deleteFriend.type = SettingCellType.SettingSwitchCell.rawValue -// deleteFriend.switchOpen = IMKitClient.instance.repo.getDeleteFriendAlias() +// deleteFriend.switchOpen = IMKitEngine.instance.repo.getDeleteFriendAlias() // // deleteFriend.swichChange = { isOpen in -// IMKitClient.instance.repo.setDeleteFriendAlias(isOpen) +// IMKitEngine.instance.repo.setDeleteFriendAlias(isOpen) // } // 消息已读未读功能 @@ -86,9 +86,9 @@ public class MineSettingViewModel: NSObject { hasRead.type = SettingCellType.SettingSwitchCell.rawValue hasRead.cornerType = .bottomLeft.union(.bottomRight) // hasRead.switchOpen = true - hasRead.switchOpen = IMKitClient.instance.repo.getShowReadStatus() + hasRead.switchOpen = IMKitEngine.instance.repo.getShowReadStatus() hasRead.swichChange = { isOpen in - IMKitClient.instance.repo.setShowReadStatus(isOpen) + IMKitEngine.instance.repo.setShowReadStatus(isOpen) } model.cellModels.append(contentsOf: [receiverModel, hasRead]) return model diff --git a/app/Mine/ViewModel/NodeViewModel.swift b/app/Mine/ViewModel/NodeViewModel.swift new file mode 100644 index 00000000..cd36dfc7 --- /dev/null +++ b/app/Mine/ViewModel/NodeViewModel.swift @@ -0,0 +1,35 @@ + +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be +// found in the LICENSE file. + +import UIKit +import NETeamUIKit + +class NodeViewModel: NSObject { + var sectionData = [SettingSectionModel]() + + public func getData() { + sectionData.append(getSection()) + } + + private func getSection() -> SettingSectionModel { + let model = SettingSectionModel() + // 国内节点配置 + let home = SettingCellModel() + home.subTitle = NSLocalizedString("domestic_node", comment: "") + home.cornerType = .topLeft.union(.topRight) + home.rowHeight = 44.0 + home.switchOpen = IMKitClient.instance.repo.getNodeValue() == true ? true : false + + // 海外节点配置 + let overseas = SettingCellModel() + overseas.subTitle = NSLocalizedString("overseas_node", comment: "") + overseas.cornerType = .bottomLeft.union(.bottomRight) + overseas.switchOpen = IMKitClient.instance.repo.getNodeValue() == true ? false : true + overseas.rowHeight = 44.0 + + model.cellModels.append(contentsOf: [home, overseas]) + return model + } +} diff --git a/app/Mine/ViewModel/PersonInfoViewModel.swift b/app/Mine/ViewModel/PersonInfoViewModel.swift index 30aecd18..d607a482 100644 --- a/app/Mine/ViewModel/PersonInfoViewModel.swift +++ b/app/Mine/ViewModel/PersonInfoViewModel.swift @@ -29,7 +29,7 @@ public class PersonInfoViewModel: NSObject { func getData() { sectionData.removeAll() - userInfo = userProvider.getUserInfo(userId: IMKitClient.instance.imAccid) + userInfo = userProvider.getUserInfo(userId: IMKitEngine.instance.imAccid) sectionData.append(getFirstSection()) sectionData.append(getSecondSection()) } @@ -145,6 +145,7 @@ public class PersonInfoViewModel: NSObject { signItem.cellName = NSLocalizedString("individuality_sign", comment: "") signItem.subTitle = mineInfo.userInfo?.sign signItem.rowHeight = 46.0 + signItem.titleWidth = 64 signItem.cornerType = .topLeft.union(.topRight).union(.bottomLeft).union(.bottomRight) weak var weakSelf = self signItem.cellClick = { diff --git a/app/app-Bridging-Header.h b/app/app-Bridging-Header.h new file mode 100644 index 00000000..5323061e --- /dev/null +++ b/app/app-Bridging-Header.h @@ -0,0 +1,2 @@ +// Copyright (c) 2022 NetEase, Inc. All rights reserved. +// Use of this source code is governed by a MIT license that can be found in the LICENSE file. From a051665092e267cc5da49de02964414696ec105e Mon Sep 17 00:00:00 2001 From: chenyu Date: Fri, 10 Mar 2023 16:08:01 +0800 Subject: [PATCH 2/2] import online --- Podfile | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Podfile b/Podfile index bc5d2bc6..56b9fe0f 100644 --- a/Podfile +++ b/Podfile @@ -10,10 +10,10 @@ target 'app' do pod 'YXLogin', '1.0.0' #可选UI库 -# pod 'NEContactUIKit', '9.4.0' -# pod 'NEConversationUIKit', '9.4.0' -# pod 'NEChatUIKit', '9.4.0' -# pod 'NETeamUIKit', '9.4.0' + pod 'NEContactUIKit', '9.4.0' + pod 'NEConversationUIKit', '9.4.0' + pod 'NEChatUIKit', '9.4.0' + pod 'NETeamUIKit', '9.4.0' #可选Kit库(和UIKit对应) @@ -32,17 +32,17 @@ target 'app' do # pod 'NEMapKit', '9.4.0' #呼叫组件,音视频通话能力,需要开通 音视频2.0,可选,聊天一面会根据依赖初始化自动显示音视频通话入口 -# pod 'NERtcCallUIKit', '1.8.2' + pod 'NERtcCallUIKit', '1.8.2' pod 'NERtcCallKit', '1.8.2' pod 'NERtcSDK', '4.6.29' # 如果需要查看UI部分源码请注释掉以上在线依赖,打开下面的本地依赖 - pod 'NEContactUIKit', :path => 'NEContactUIKit/NEContactUIKit.podspec' - pod 'NEConversationUIKit', :path => 'NEConversationUIKit/NEConversationUIKit.podspec' - pod 'NETeamUIKit', :path => 'NETeamUIKit/NETeamUIKit.podspec' - pod 'NEChatUIKit', :path => 'NEChatUIKit/NEChatUIKit.podspec' - pod 'NEMapKit', :path => 'NEMapKit/NEMapKit.podspec' - pod 'NERtcCallUIKit', :path => 'NERtcCallUIKit/NERtcCallUIKit.podspec' +# pod 'NEContactUIKit', :path => 'NEContactUIKit/NEContactUIKit.podspec' +# pod 'NEConversationUIKit', :path => 'NEConversationUIKit/NEConversationUIKit.podspec' +# pod 'NETeamUIKit', :path => 'NETeamUIKit/NETeamUIKit.podspec' +# pod 'NEChatUIKit', :path => 'NEChatUIKit/NEChatUIKit.podspec' +# pod 'NEMapKit', :path => 'NEMapKit/NEMapKit.podspec' +# pod 'NERtcCallUIKit', :path => 'NERtcCallUIKit/NERtcCallUIKit.podspec' end