From d2d450d1d7a7c7faa38fdb35c4735e30b8a08d85 Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Mon, 20 May 2024 17:23:29 +0400 Subject: [PATCH 01/18] core: check known relays before file reception, support user approval of unknown relays (#4043) * core: check known relays before file reception, support user approval of unknown relays * comment * reset on not approved agent error * add privacyAskToApproveRelays to AppSettings * filter distinct servers * update simplexmq * remember user_approved_relays * refactor * rename * update simplexmq --------- Co-authored-by: Evgeny Poberezkin --- cabal.project | 2 +- scripts/nix/sha256map.nix | 2 +- simplex-chat.cabal | 1 + src/Simplex/Chat.hs | 110 +++++++++++++----- src/Simplex/Chat/AppSettings.hs | 6 + src/Simplex/Chat/Controller.hs | 7 +- src/Simplex/Chat/Messages.hs | 8 ++ ...20240515_rcv_files_user_approved_relays.hs | 18 +++ src/Simplex/Chat/Migrations/chat_schema.sql | 3 +- src/Simplex/Chat/Store/Files.hs | 49 ++++---- src/Simplex/Chat/Store/Migrations.hs | 4 +- src/Simplex/Chat/Types.hs | 3 +- src/Simplex/Chat/View.hs | 2 + 13 files changed, 155 insertions(+), 60 deletions(-) create mode 100644 src/Simplex/Chat/Migrations/M20240515_rcv_files_user_approved_relays.hs diff --git a/cabal.project b/cabal.project index 1a6942e4b5..190c6e06e0 100644 --- a/cabal.project +++ b/cabal.project @@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd source-repository-package type: git location: https://github.com/simplex-chat/simplexmq.git - tag: 1116aeeea1869e0de38e9faccea76b329b549804 + tag: 2e5433676eaa5de93ed1ea9726706b9633308477 source-repository-package type: git diff --git a/scripts/nix/sha256map.nix b/scripts/nix/sha256map.nix index 06875457b0..512638d454 100644 --- a/scripts/nix/sha256map.nix +++ b/scripts/nix/sha256map.nix @@ -1,5 +1,5 @@ { - "https://github.com/simplex-chat/simplexmq.git"."1116aeeea1869e0de38e9faccea76b329b549804" = "07ynn7f70hfsdrirmhb9zd257bx90d29l5gjyhh50wd12gaqdm0w"; + "https://github.com/simplex-chat/simplexmq.git"."2e5433676eaa5de93ed1ea9726706b9633308477" = "0ichdf5vsdizqxqy8amx3f5grx5sghiv2gajd2w3l73vnr2rv3bd"; "https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38"; "https://github.com/simplex-chat/direct-sqlcipher.git"."f814ee68b16a9447fbb467ccc8f29bdd3546bfd9" = "1ql13f4kfwkbaq7nygkxgw84213i0zm7c1a8hwvramayxl38dq5d"; "https://github.com/simplex-chat/sqlcipher-simple.git"."a46bd361a19376c5211f1058908fc0ae6bf42446" = "1z0r78d8f0812kxbgsm735qf6xx8lvaz27k1a0b4a2m0sshpd5gl"; diff --git a/simplex-chat.cabal b/simplex-chat.cabal index 525dc6295f..2b0a55bb68 100644 --- a/simplex-chat.cabal +++ b/simplex-chat.cabal @@ -144,6 +144,7 @@ library Simplex.Chat.Migrations.M20240430_ui_theme Simplex.Chat.Migrations.M20240501_chat_deleted Simplex.Chat.Migrations.M20240510_chat_items_via_proxy + Simplex.Chat.Migrations.M20240515_rcv_files_user_approved_relays Simplex.Chat.Mobile Simplex.Chat.Mobile.File Simplex.Chat.Mobile.Shared diff --git a/src/Simplex/Chat.hs b/src/Simplex/Chat.hs index acdfe116ff..743cef932c 100644 --- a/src/Simplex/Chat.hs +++ b/src/Simplex/Chat.hs @@ -47,6 +47,7 @@ import Data.Map.Strict (Map) import qualified Data.Map.Strict as M import Data.Maybe (catMaybes, fromMaybe, isJust, isNothing, listToMaybe, mapMaybe, maybeToList) import Data.Ord (Down (..)) +import qualified Data.Set as S import Data.Text (Text) import qualified Data.Text as T import Data.Text.Encoding (decodeLatin1, encodeUtf8) @@ -90,8 +91,9 @@ import Simplex.FileTransfer.Client.Presets (defaultXFTPServers) import Simplex.FileTransfer.Description (FileDescriptionURI (..), ValidFileDescription) import qualified Simplex.FileTransfer.Description as FD import Simplex.FileTransfer.Protocol (FileParty (..), FilePartyI) +import qualified Simplex.FileTransfer.Transport as XFTP import Simplex.Messaging.Agent as Agent -import Simplex.Messaging.Agent.Client (AgentStatsKey (..), SubInfo (..), agentClientStore, getAgentWorkersDetails, getAgentWorkersSummary, temporaryAgentError, withLockMap) +import Simplex.Messaging.Agent.Client (AgentStatsKey (..), SubInfo (..), agentClientStore, getAgentWorkersDetails, getAgentWorkersSummary, ipAddressProtected, temporaryAgentError, withLockMap) import Simplex.Messaging.Agent.Env.SQLite (AgentConfig (..), InitialAgentServers (..), createAgentStore, defaultAgentConfig) import Simplex.Messaging.Agent.Lock (withLock) import Simplex.Messaging.Agent.Protocol @@ -109,7 +111,7 @@ import qualified Simplex.Messaging.Crypto.Ratchet as CR import Simplex.Messaging.Encoding import Simplex.Messaging.Encoding.String import Simplex.Messaging.Parsers (base64P) -import Simplex.Messaging.Protocol (AProtoServerWithAuth (..), AProtocolType (..), EntityId, ErrorType (..), MsgBody, MsgFlags (..), NtfServer, ProtoServerWithAuth, ProtocolTypeI, SProtocolType (..), SubscriptionMode (..), UserProtocol, userProtocol) +import Simplex.Messaging.Protocol (AProtoServerWithAuth (..), AProtocolType (..), EntityId, ErrorType (..), MsgBody, MsgFlags (..), NtfServer, ProtoServerWithAuth (..), ProtocolTypeI, SProtocolType (..), SubscriptionMode (..), UserProtocol, XFTPServer, userProtocol) import qualified Simplex.Messaging.Protocol as SMP import Simplex.Messaging.ServiceScheme (ServiceScheme (..)) import qualified Simplex.Messaging.TMap as TM @@ -427,7 +429,7 @@ startReceiveUserFiles user = do filesToReceive <- withStore' (`getRcvFilesToReceive` user) forM_ filesToReceive $ \ft -> flip catchChatError (toView . CRChatError (Just user)) $ - toView =<< receiveFile' user ft Nothing Nothing + toView =<< receiveFile' user ft False Nothing Nothing restoreCalls :: CM' () restoreCalls = do @@ -2055,17 +2057,17 @@ processChatCommand' vr = \case ForwardFile chatName fileId -> forwardFile chatName fileId SendFile ForwardImage chatName fileId -> forwardFile chatName fileId SendImage SendFileDescription _chatName _f -> pure $ chatCmdError Nothing "TODO" - ReceiveFile fileId encrypted_ rcvInline_ filePath_ -> withUser $ \_ -> + ReceiveFile fileId userApprovedRelays encrypted_ rcvInline_ filePath_ -> withUser $ \_ -> withFileLock "receiveFile" fileId . procCmd $ do (user, ft@RcvFileTransfer {fileStatus}) <- withStore (`getRcvFileTransferById` fileId) encrypt <- (`fromMaybe` encrypted_) <$> chatReadVar encryptLocalFiles ft' <- (if encrypt && fileStatus == RFSNew then setFileToEncrypt else pure) ft - receiveFile' user ft' rcvInline_ filePath_ - SetFileToReceive fileId encrypted_ -> withUser $ \_ -> do + receiveFile' user ft' userApprovedRelays rcvInline_ filePath_ + SetFileToReceive fileId userApprovedRelays encrypted_ -> withUser $ \_ -> do withFileLock "setFileToReceive" fileId . procCmd $ do encrypt <- (`fromMaybe` encrypted_) <$> chatReadVar encryptLocalFiles cfArgs <- if encrypt then Just <$> (atomically . CF.randomArgs =<< asks random) else pure Nothing - withStore' $ \db -> setRcvFileToReceive db fileId cfArgs + withStore' $ \db -> setRcvFileToReceive db fileId userApprovedRelays cfArgs ok_ CancelFile fileId -> withUser $ \user@User {userId} -> withFileLock "cancelFile" fileId . procCmd $ @@ -2105,13 +2107,8 @@ processChatCommand' vr = \case liftIO $ removeFile fsFilePath `catchAll_` pure () lift . forM_ agentRcvFileId $ \(AgentRcvFileId aFileId) -> withAgent' (`xftpDeleteRcvFile` aFileId) - ci <- withStore $ \db -> do - liftIO $ do - updateCIFileStatus db user fileId CIFSRcvInvitation - updateRcvFileStatus db fileId FSNew - updateRcvFileAgentId db fileId Nothing - lookupChatItemByFileId db vr user fileId - pure $ CRRcvFileCancelled user ci ftr + aci_ <- resetRcvCIFileStatus user fileId CIFSRcvInvitation + pure $ CRRcvFileCancelled user aci_ ftr FileStatus fileId -> withUser $ \user -> do withStore (\db -> lookupChatItemByFileId db vr user fileId) >>= \case Nothing -> do @@ -3052,9 +3049,9 @@ setFileToEncrypt ft@RcvFileTransfer {fileId} = do withStore' $ \db -> setFileCryptoArgs db fileId cfArgs pure (ft :: RcvFileTransfer) {cryptoArgs = Just cfArgs} -receiveFile' :: User -> RcvFileTransfer -> Maybe Bool -> Maybe FilePath -> CM ChatResponse -receiveFile' user ft rcvInline_ filePath_ = do - (CRRcvFileAccepted user <$> acceptFileReceive user ft rcvInline_ filePath_) `catchChatError` processError +receiveFile' :: User -> RcvFileTransfer -> Bool -> Maybe Bool -> Maybe FilePath -> CM ChatResponse +receiveFile' user ft userApprovedRelays rcvInline_ filePath_ = do + (CRRcvFileAccepted user <$> acceptFileReceive user ft userApprovedRelays rcvInline_ filePath_) `catchChatError` processError where processError = \case -- TODO AChatItem in Cancelled events @@ -3062,8 +3059,8 @@ receiveFile' user ft rcvInline_ filePath_ = do ChatErrorAgent (CONN DUPLICATE) _ -> pure $ CRRcvFileAcceptedSndCancelled user ft e -> throwError e -acceptFileReceive :: User -> RcvFileTransfer -> Maybe Bool -> Maybe FilePath -> CM AChatItem -acceptFileReceive user@User {userId} RcvFileTransfer {fileId, xftpRcvFile, fileInvitation = FileInvitation {fileName = fName, fileConnReq, fileInline, fileSize}, fileStatus, grpMemberId, cryptoArgs} rcvInline_ filePath_ = do +acceptFileReceive :: User -> RcvFileTransfer -> Bool -> Maybe Bool -> Maybe FilePath -> CM AChatItem +acceptFileReceive user@User {userId} RcvFileTransfer {fileId, xftpRcvFile, fileInvitation = FileInvitation {fileName = fName, fileConnReq, fileInline, fileSize}, fileStatus, grpMemberId, cryptoArgs} userApprovedRelays rcvInline_ filePath_ = do unless (fileStatus == RFSNew) $ case fileStatus of RFSCancelled _ -> throwChatError $ CEFileCancelled fName _ -> throwChatError $ CEFileAlreadyReceiving fName @@ -3077,15 +3074,16 @@ acceptFileReceive user@User {userId} RcvFileTransfer {fileId, xftpRcvFile, fileI filePath <- getRcvFilePath fileId filePath_ fName True withStore $ \db -> acceptRcvFileTransfer db vr user fileId connIds ConnJoined filePath subMode -- XFTP - (Just XFTPRcvFile {}, _) -> do + (Just XFTPRcvFile {userApprovedRelays = approvedBeforeReady}, _) -> do + let userApproved = approvedBeforeReady || userApprovedRelays filePath <- getRcvFilePath fileId filePath_ fName False (ci, rfd) <- withStore $ \db -> do -- marking file as accepted and reading description in the same transaction -- to prevent race condition with appending description - ci <- xftpAcceptRcvFT db vr user fileId filePath + ci <- xftpAcceptRcvFT db vr user fileId filePath userApproved rfd <- getRcvFileDescrByRcvFileId db fileId pure (ci, rfd) - receiveViaCompleteFD user fileId rfd cryptoArgs + receiveViaCompleteFD user fileId rfd userApproved cryptoArgs pure ci -- group & direct file protocol _ -> do @@ -3130,18 +3128,61 @@ acceptFileReceive user@User {userId} RcvFileTransfer {fileId, xftpRcvFile, fileI || (rcvInline_ == Just True && fileSize <= fileChunkSize * offerChunks) ) -receiveViaCompleteFD :: User -> FileTransferId -> RcvFileDescr -> Maybe CryptoFileArgs -> CM () -receiveViaCompleteFD user fileId RcvFileDescr {fileDescrText, fileDescrComplete} cfArgs = +receiveViaCompleteFD :: User -> FileTransferId -> RcvFileDescr -> Bool -> Maybe CryptoFileArgs -> CM () +receiveViaCompleteFD user fileId RcvFileDescr {fileDescrText, fileDescrComplete} userApprovedRelays cfArgs = when fileDescrComplete $ do rd <- parseFileDescription fileDescrText - aFileId <- withAgent $ \a -> xftpReceiveFile a (aUserId user) rd cfArgs - startReceivingFile user fileId - withStore' $ \db -> updateRcvFileAgentId db fileId (Just $ AgentRcvFileId aFileId) + if userApprovedRelays + then receive' rd True + else do + let srvs = fileServers rd + unknownSrvs <- getUnknownSrvs srvs + let approved = null unknownSrvs + ifM + ((approved ||) <$> ipProtectedForSrvs srvs) + (receive' rd approved) + (relaysNotApproved unknownSrvs) + where + receive' :: ValidFileDescription 'FRecipient -> Bool -> CM () + receive' rd approved = do + aFileId <- withAgent $ \a -> xftpReceiveFile a (aUserId user) rd cfArgs approved + startReceivingFile user fileId + withStore' $ \db -> updateRcvFileAgentId db fileId (Just $ AgentRcvFileId aFileId) + fileServers :: ValidFileDescription 'FRecipient -> [XFTPServer] + fileServers (FD.ValidFileDescription FD.FileDescription {chunks}) = + S.toList $ S.fromList $ concatMap (\FD.FileChunk {replicas} -> map (\FD.FileChunkReplica {server} -> server) replicas) chunks + getUnknownSrvs :: [XFTPServer] -> CM [XFTPServer] + getUnknownSrvs srvs = do + ChatConfig {defaultServers = DefaultAgentServers {xftp = defXftp}} <- asks config + storedSrvs <- map (\ServerCfg {server} -> protoServer server) <$> withStore' (`getProtocolServers` user) + let defXftp' = L.map protoServer defXftp + knownSrvs = fromMaybe defXftp' $ nonEmpty storedSrvs + pure $ filter (`notElem` knownSrvs) srvs + ipProtectedForSrvs :: [XFTPServer] -> CM Bool + ipProtectedForSrvs srvs = do + netCfg <- lift $ withAgent' getNetworkConfig + pure $ all (ipAddressProtected netCfg) srvs + relaysNotApproved :: [XFTPServer] -> CM () + relaysNotApproved unknownSrvs = do + aci_ <- resetRcvCIFileStatus user fileId CIFSRcvInvitation + forM_ aci_ $ \aci -> toView $ CRChatItemUpdated user aci + throwChatError $ CEFileNotApproved fileId unknownSrvs + +resetRcvCIFileStatus :: User -> FileTransferId -> CIFileStatus 'MDRcv -> CM (Maybe AChatItem) +resetRcvCIFileStatus user fileId ciFileStatus = do + vr <- chatVersionRange + withStore $ \db -> do + liftIO $ do + updateCIFileStatus db user fileId ciFileStatus + updateRcvFileStatus db fileId FSNew + updateRcvFileAgentId db fileId Nothing + lookupChatItemByFileId db vr user fileId receiveViaURI :: User -> FileDescriptionURI -> CryptoFile -> CM RcvFileTransfer receiveViaURI user@User {userId} FileDescriptionURI {description} cf@CryptoFile {cryptoArgs} = do fileId <- withStore $ \db -> createRcvStandaloneFileTransfer db userId cf fileSize chunkSize - aFileId <- withAgent $ \a -> xftpReceiveFile a (aUserId user) description cryptoArgs + -- currently the only use case is user migrating via their configured servers, so we pass approvedRelays = True + aFileId <- withAgent $ \a -> xftpReceiveFile a (aUserId user) description cryptoArgs True withStore $ \db -> do liftIO $ do updateRcvFileStatus db fileId FSConnected @@ -3811,6 +3852,10 @@ processAgentMsgRcvFile _corrId aFileId msg = do RFERR e | temporaryAgentError e -> throwChatError $ CEXFTPRcvFile fileId (AgentRcvFileId aFileId) e + | e == XFTP "" XFTP.NOT_APPROVED -> do + aci_ <- resetRcvCIFileStatus user fileId CIFSRcvAborted + agentXFTPDeleteRcvFile aFileId fileId + forM_ aci_ $ \aci -> toView $ CRChatItemUpdated user aci | otherwise -> do ci <- withStore $ \db -> do liftIO $ updateFileCancelled db user fileId CIFSRcvError @@ -4862,8 +4907,9 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = autoAcceptFile :: Maybe (RcvFileTransfer, CIFile 'MDRcv) -> CM () autoAcceptFile = mapM_ $ \(ft, CIFile {fileSize}) -> do + -- ! autoAcceptFileSize is only used in tests ChatConfig {autoAcceptFileSize = sz} <- asks config - when (sz > fileSize) $ receiveFile' user ft Nothing Nothing >>= toView + when (sz > fileSize) $ receiveFile' user ft False Nothing Nothing >>= toView messageFileDescription :: Contact -> SharedMsgId -> FileDescr -> CM () messageFileDescription ct@Contact {contactId} sharedMsgId fileDescr = do @@ -4889,7 +4935,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = ci <- withStore $ \db -> getAChatItemBySharedMsgId db user cd sharedMsgId toView $ CRRcvFileDescrReady user ci ft' rfd case (fileStatus, xftpRcvFile) of - (RFSAccepted _, Just XFTPRcvFile {}) -> receiveViaCompleteFD user fileId rfd cryptoArgs + (RFSAccepted _, Just XFTPRcvFile {userApprovedRelays}) -> receiveViaCompleteFD user fileId rfd userApprovedRelays cryptoArgs _ -> pure () processFileInvitation :: Maybe FileInvitation -> MsgContent -> (DB.Connection -> FileInvitation -> Maybe InlineFileMode -> Integer -> ExceptT StoreError IO RcvFileTransfer) -> CM (Maybe (RcvFileTransfer, CIFile 'MDRcv)) @@ -7315,8 +7361,8 @@ chatCommandP = ("/fforward " <|> "/ff ") *> (ForwardFile <$> chatNameP' <* A.space <*> A.decimal), ("/image_forward " <|> "/imgf ") *> (ForwardImage <$> chatNameP' <* A.space <*> A.decimal), ("/fdescription " <|> "/fd") *> (SendFileDescription <$> chatNameP' <* A.space <*> filePath), - ("/freceive " <|> "/fr ") *> (ReceiveFile <$> A.decimal <*> optional (" encrypt=" *> onOffP) <*> optional (" inline=" *> onOffP) <*> optional (A.space *> filePath)), - "/_set_file_to_receive " *> (SetFileToReceive <$> A.decimal <*> optional (" encrypt=" *> onOffP)), + ("/freceive " <|> "/fr ") *> (ReceiveFile <$> A.decimal <*> (" approved_relays=" *> onOffP <|> pure False) <*> optional (" encrypt=" *> onOffP) <*> optional (" inline=" *> onOffP) <*> optional (A.space *> filePath)), + "/_set_file_to_receive " *> (SetFileToReceive <$> A.decimal <*> (" approved_relays=" *> onOffP <|> pure False) <*> optional (" encrypt=" *> onOffP)), ("/fcancel " <|> "/fc ") *> (CancelFile <$> A.decimal), ("/fstatus " <|> "/fs ") *> (FileStatus <$> A.decimal), "/_connect contact " *> (APIConnectContactViaAddress <$> A.decimal <*> incognitoOnOffP <* A.space <*> A.decimal), diff --git a/src/Simplex/Chat/AppSettings.hs b/src/Simplex/Chat/AppSettings.hs index 3d63cb2109..2b8b531dc3 100644 --- a/src/Simplex/Chat/AppSettings.hs +++ b/src/Simplex/Chat/AppSettings.hs @@ -29,6 +29,7 @@ data AppSettings = AppSettings { appPlatform :: Maybe AppPlatform, networkConfig :: Maybe NetworkConfig, privacyEncryptLocalFiles :: Maybe Bool, + privacyAskToApproveRelays :: Maybe Bool, privacyAcceptImages :: Maybe Bool, privacyLinkPreviews :: Maybe Bool, privacyShowChatPreviews :: Maybe Bool, @@ -61,6 +62,7 @@ defaultAppSettings = { appPlatform = Nothing, networkConfig = Just defaultNetworkConfig, privacyEncryptLocalFiles = Just True, + privacyAskToApproveRelays = Just True, privacyAcceptImages = Just True, privacyLinkPreviews = Just True, privacyShowChatPreviews = Just True, @@ -92,6 +94,7 @@ defaultParseAppSettings = { appPlatform = Nothing, networkConfig = Nothing, privacyEncryptLocalFiles = Nothing, + privacyAskToApproveRelays = Nothing, privacyAcceptImages = Nothing, privacyLinkPreviews = Nothing, privacyShowChatPreviews = Nothing, @@ -123,6 +126,7 @@ combineAppSettings platformDefaults storedSettings = { appPlatform = p appPlatform, networkConfig = p networkConfig, privacyEncryptLocalFiles = p privacyEncryptLocalFiles, + privacyAskToApproveRelays = p privacyAskToApproveRelays, privacyAcceptImages = p privacyAcceptImages, privacyLinkPreviews = p privacyLinkPreviews, privacyShowChatPreviews = p privacyShowChatPreviews, @@ -166,6 +170,7 @@ instance FromJSON AppSettings where appPlatform <- p "appPlatform" networkConfig <- p "networkConfig" privacyEncryptLocalFiles <- p "privacyEncryptLocalFiles" + privacyAskToApproveRelays <- p "privacyAskToApproveRelays" privacyAcceptImages <- p "privacyAcceptImages" privacyLinkPreviews <- p "privacyLinkPreviews" privacyShowChatPreviews <- p "privacyShowChatPreviews" @@ -194,6 +199,7 @@ instance FromJSON AppSettings where { appPlatform, networkConfig, privacyEncryptLocalFiles, + privacyAskToApproveRelays, privacyAcceptImages, privacyLinkPreviews, privacyShowChatPreviews, diff --git a/src/Simplex/Chat/Controller.hs b/src/Simplex/Chat/Controller.hs index 267298f188..9ff903514f 100644 --- a/src/Simplex/Chat/Controller.hs +++ b/src/Simplex/Chat/Controller.hs @@ -81,7 +81,7 @@ import Simplex.Messaging.Crypto.Ratchet (PQEncryption) import Simplex.Messaging.Encoding.String import Simplex.Messaging.Notifications.Protocol (DeviceToken (..), NtfTknStatus) import Simplex.Messaging.Parsers (defaultJSON, dropPrefix, enumJSON, parseAll, parseString, sumTypeJSON) -import Simplex.Messaging.Protocol (AProtoServerWithAuth, AProtocolType (..), CorrId, NtfServer, ProtoServerWithAuth, ProtocolTypeI, QueueId, SMPMsgMeta (..), SProtocolType, SubscriptionMode (..), UserProtocol, XFTPServerWithAuth, userProtocol) +import Simplex.Messaging.Protocol (AProtoServerWithAuth, AProtocolType (..), CorrId, NtfServer, ProtoServerWithAuth, ProtocolTypeI, QueueId, SMPMsgMeta (..), SProtocolType, SubscriptionMode (..), UserProtocol, XFTPServer, XFTPServerWithAuth, userProtocol) import Simplex.Messaging.TMap (TMap) import Simplex.Messaging.Transport (TLS, simplexMQVersion) import Simplex.Messaging.Transport.Client (TransportHost) @@ -458,8 +458,8 @@ data ChatCommand | ForwardFile ChatName FileTransferId | ForwardImage ChatName FileTransferId | SendFileDescription ChatName FilePath - | ReceiveFile {fileId :: FileTransferId, storeEncrypted :: Maybe Bool, fileInline :: Maybe Bool, filePath :: Maybe FilePath} - | SetFileToReceive {fileId :: FileTransferId, storeEncrypted :: Maybe Bool} + | ReceiveFile {fileId :: FileTransferId, userApprovedRelays :: Bool, storeEncrypted :: Maybe Bool, fileInline :: Maybe Bool, filePath :: Maybe FilePath} + | SetFileToReceive {fileId :: FileTransferId, userApprovedRelays :: Bool, storeEncrypted :: Maybe Bool} | CancelFile FileTransferId | FileStatus FileTransferId | ShowProfile -- UserId (not used in UI) @@ -1132,6 +1132,7 @@ data ChatErrorType | CEFileImageType {filePath :: FilePath} | CEFileImageSize {filePath :: FilePath} | CEFileNotReceived {fileId :: FileTransferId} + | CEFileNotApproved {fileId :: FileTransferId, unknownServers :: [XFTPServer]} | CEXFTPRcvFile {fileId :: FileTransferId, agentRcvFileId :: AgentRcvFileId, agentError :: AgentErrorType} | CEXFTPSndFile {fileId :: FileTransferId, agentSndFileId :: AgentSndFileId, agentError :: AgentErrorType} | CEFallbackToSMPProhibited {fileId :: FileTransferId} diff --git a/src/Simplex/Chat/Messages.hs b/src/Simplex/Chat/Messages.hs index 83417efa59..449731b91c 100644 --- a/src/Simplex/Chat/Messages.hs +++ b/src/Simplex/Chat/Messages.hs @@ -539,6 +539,7 @@ data CIFileStatus (d :: MsgDirection) where CIFSRcvInvitation :: CIFileStatus 'MDRcv CIFSRcvAccepted :: CIFileStatus 'MDRcv CIFSRcvTransfer :: {rcvProgress :: Int64, rcvTotal :: Int64} -> CIFileStatus 'MDRcv + CIFSRcvAborted :: CIFileStatus 'MDRcv CIFSRcvComplete :: CIFileStatus 'MDRcv CIFSRcvCancelled :: CIFileStatus 'MDRcv CIFSRcvError :: CIFileStatus 'MDRcv @@ -558,6 +559,7 @@ ciFileEnded = \case CIFSRcvInvitation -> False CIFSRcvAccepted -> False CIFSRcvTransfer {} -> False + CIFSRcvAborted -> True CIFSRcvCancelled -> True CIFSRcvComplete -> True CIFSRcvError -> True @@ -573,6 +575,7 @@ ciFileLoaded = \case CIFSRcvInvitation -> False CIFSRcvAccepted -> False CIFSRcvTransfer {} -> False + CIFSRcvAborted -> False CIFSRcvCancelled -> False CIFSRcvComplete -> True CIFSRcvError -> False @@ -592,6 +595,7 @@ instance MsgDirectionI d => StrEncoding (CIFileStatus d) where CIFSRcvInvitation -> "rcv_invitation" CIFSRcvAccepted -> "rcv_accepted" CIFSRcvTransfer rcvd total -> strEncode (Str "rcv_transfer", rcvd, total) + CIFSRcvAborted -> "rcv_aborted" CIFSRcvComplete -> "rcv_complete" CIFSRcvCancelled -> "rcv_cancelled" CIFSRcvError -> "rcv_error" @@ -614,6 +618,7 @@ instance StrEncoding ACIFileStatus where "rcv_invitation" -> pure $ AFS SMDRcv CIFSRcvInvitation "rcv_accepted" -> pure $ AFS SMDRcv CIFSRcvAccepted "rcv_transfer" -> AFS SMDRcv <$> progress CIFSRcvTransfer + "rcv_aborted" -> pure $ AFS SMDRcv CIFSRcvAborted "rcv_complete" -> pure $ AFS SMDRcv CIFSRcvComplete "rcv_cancelled" -> pure $ AFS SMDRcv CIFSRcvCancelled "rcv_error" -> pure $ AFS SMDRcv CIFSRcvError @@ -631,6 +636,7 @@ data JSONCIFileStatus | JCIFSRcvInvitation | JCIFSRcvAccepted | JCIFSRcvTransfer {rcvProgress :: Int64, rcvTotal :: Int64} + | JCIFSRcvAborted | JCIFSRcvComplete | JCIFSRcvCancelled | JCIFSRcvError @@ -646,6 +652,7 @@ jsonCIFileStatus = \case CIFSRcvInvitation -> JCIFSRcvInvitation CIFSRcvAccepted -> JCIFSRcvAccepted CIFSRcvTransfer rcvd total -> JCIFSRcvTransfer rcvd total + CIFSRcvAborted -> JCIFSRcvAborted CIFSRcvComplete -> JCIFSRcvComplete CIFSRcvCancelled -> JCIFSRcvCancelled CIFSRcvError -> JCIFSRcvError @@ -661,6 +668,7 @@ aciFileStatusJSON = \case JCIFSRcvInvitation -> AFS SMDRcv CIFSRcvInvitation JCIFSRcvAccepted -> AFS SMDRcv CIFSRcvAccepted JCIFSRcvTransfer rcvd total -> AFS SMDRcv $ CIFSRcvTransfer rcvd total + JCIFSRcvAborted -> AFS SMDRcv CIFSRcvAborted JCIFSRcvComplete -> AFS SMDRcv CIFSRcvComplete JCIFSRcvCancelled -> AFS SMDRcv CIFSRcvCancelled JCIFSRcvError -> AFS SMDRcv CIFSRcvError diff --git a/src/Simplex/Chat/Migrations/M20240515_rcv_files_user_approved_relays.hs b/src/Simplex/Chat/Migrations/M20240515_rcv_files_user_approved_relays.hs new file mode 100644 index 0000000000..cd4f647685 --- /dev/null +++ b/src/Simplex/Chat/Migrations/M20240515_rcv_files_user_approved_relays.hs @@ -0,0 +1,18 @@ +{-# LANGUAGE QuasiQuotes #-} + +module Simplex.Chat.Migrations.M20240515_rcv_files_user_approved_relays where + +import Database.SQLite.Simple (Query) +import Database.SQLite.Simple.QQ (sql) + +m20240515_rcv_files_user_approved_relays :: Query +m20240515_rcv_files_user_approved_relays = + [sql| +ALTER TABLE rcv_files ADD COLUMN user_approved_relays INTEGER NOT NULL DEFAULT 0; +|] + +down_m20240515_rcv_files_user_approved_relays :: Query +down_m20240515_rcv_files_user_approved_relays = + [sql| +ALTER TABLE rcv_files DROP COLUMN user_approved_relays; +|] diff --git a/src/Simplex/Chat/Migrations/chat_schema.sql b/src/Simplex/Chat/Migrations/chat_schema.sql index 3ac9b9a98e..96d55badf9 100644 --- a/src/Simplex/Chat/Migrations/chat_schema.sql +++ b/src/Simplex/Chat/Migrations/chat_schema.sql @@ -229,7 +229,8 @@ CREATE TABLE rcv_files( REFERENCES xftp_file_descriptions ON DELETE SET NULL, agent_rcv_file_id BLOB NULL, agent_rcv_file_deleted INTEGER DEFAULT 0 CHECK(agent_rcv_file_deleted NOT NULL), - to_receive INTEGER + to_receive INTEGER, + user_approved_relays INTEGER NOT NULL DEFAULT 0 ); CREATE TABLE snd_file_chunks( file_id INTEGER NOT NULL, diff --git a/src/Simplex/Chat/Store/Files.hs b/src/Simplex/Chat/Store/Files.hs index 528290aa59..d70bbb8970 100644 --- a/src/Simplex/Chat/Store/Files.hs +++ b/src/Simplex/Chat/Store/Files.hs @@ -514,7 +514,7 @@ createRcvFileTransfer db userId Contact {contactId, localDisplayName = c} f@File rfd_ <- mapM (createRcvFD_ db userId currentTs) fileDescr let rfdId = (\RcvFileDescr {fileDescrId} -> fileDescrId) <$> rfd_ -- cryptoArgs = Nothing here, the decision to encrypt is made when receiving it - xftpRcvFile = (\rfd -> XFTPRcvFile {rcvFileDescription = rfd, agentRcvFileId = Nothing, agentRcvFileDeleted = False}) <$> rfd_ + xftpRcvFile = (\rfd -> XFTPRcvFile {rcvFileDescription = rfd, agentRcvFileId = Nothing, agentRcvFileDeleted = False, userApprovedRelays = False}) <$> rfd_ fileProtocol = if isJust rfd_ then FPXFTP else FPSMP fileId <- liftIO $ do DB.execute @@ -535,7 +535,7 @@ createRcvGroupFileTransfer db userId GroupMember {groupId, groupMemberId, localD rfd_ <- mapM (createRcvFD_ db userId currentTs) fileDescr let rfdId = (\RcvFileDescr {fileDescrId} -> fileDescrId) <$> rfd_ -- cryptoArgs = Nothing here, the decision to encrypt is made when receiving it - xftpRcvFile = (\rfd -> XFTPRcvFile {rcvFileDescription = rfd, agentRcvFileId = Nothing, agentRcvFileDeleted = False}) <$> rfd_ + xftpRcvFile = (\rfd -> XFTPRcvFile {rcvFileDescription = rfd, agentRcvFileId = Nothing, agentRcvFileDeleted = False, userApprovedRelays = False}) <$> rfd_ fileProtocol = if isJust rfd_ then FPXFTP else FPSMP fileId <- liftIO $ do DB.execute @@ -676,7 +676,9 @@ getRcvFileTransfer_ db userId fileId = do [sql| SELECT r.file_status, r.file_queue_info, r.group_member_id, f.file_name, f.file_size, f.chunk_size, f.cancelled, cs.local_display_name, m.local_display_name, - f.file_path, f.file_crypto_key, f.file_crypto_nonce, r.file_inline, r.rcv_file_inline, r.agent_rcv_file_id, r.agent_rcv_file_deleted, c.connection_id, c.agent_conn_id + f.file_path, f.file_crypto_key, f.file_crypto_nonce, r.file_inline, r.rcv_file_inline, + r.agent_rcv_file_id, r.agent_rcv_file_deleted, r.user_approved_relays, + c.connection_id, c.agent_conn_id FROM rcv_files r JOIN files f USING (file_id) LEFT JOIN connections c ON r.file_id = c.rcv_file_id @@ -690,9 +692,9 @@ getRcvFileTransfer_ db userId fileId = do where rcvFileTransfer :: Maybe RcvFileDescr -> - (FileStatus, Maybe ConnReqInvitation, Maybe Int64, String, Integer, Integer, Maybe Bool) :. (Maybe ContactName, Maybe ContactName, Maybe FilePath, Maybe C.SbKey, Maybe C.CbNonce, Maybe InlineFileMode, Maybe InlineFileMode, Maybe AgentRcvFileId, Bool) :. (Maybe Int64, Maybe AgentConnId) -> + (FileStatus, Maybe ConnReqInvitation, Maybe Int64, String, Integer, Integer, Maybe Bool) :. (Maybe ContactName, Maybe ContactName, Maybe FilePath, Maybe C.SbKey, Maybe C.CbNonce, Maybe InlineFileMode, Maybe InlineFileMode, Maybe AgentRcvFileId, Bool, Bool) :. (Maybe Int64, Maybe AgentConnId) -> ExceptT StoreError IO RcvFileTransfer - rcvFileTransfer rfd_ ((fileStatus', fileConnReq, grpMemberId, fileName, fileSize, chunkSize, cancelled_) :. (contactName_, memberName_, filePath_, fileKey, fileNonce, fileInline, rcvFileInline, agentRcvFileId, agentRcvFileDeleted) :. (connId_, agentConnId_)) = + rcvFileTransfer rfd_ ((fileStatus', fileConnReq, grpMemberId, fileName, fileSize, chunkSize, cancelled_) :. (contactName_, memberName_, filePath_, fileKey, fileNonce, fileInline, rcvFileInline, agentRcvFileId, agentRcvFileDeleted, userApprovedRelays) :. (connId_, agentConnId_)) = case contactName_ <|> memberName_ <|> standaloneName_ of Nothing -> throwError $ SERcvFileInvalid fileId Just name -> @@ -709,7 +711,7 @@ getRcvFileTransfer_ db userId fileId = do ft senderDisplayName fileStatus = let fileInvitation = FileInvitation {fileName, fileSize, fileDigest = Nothing, fileConnReq, fileInline, fileDescr = Nothing} cryptoArgs = CFArgs <$> fileKey <*> fileNonce - xftpRcvFile = (\rfd -> XFTPRcvFile {rcvFileDescription = rfd, agentRcvFileId, agentRcvFileDeleted}) <$> rfd_ + xftpRcvFile = (\rfd -> XFTPRcvFile {rcvFileDescription = rfd, agentRcvFileId, agentRcvFileDeleted, userApprovedRelays}) <$> rfd_ in RcvFileTransfer {fileId, xftpRcvFile, fileInvitation, fileStatus, rcvFileInline, senderDisplayName, chunkSize, cancelled, grpMemberId, cryptoArgs} rfi = maybe (throwError $ SERcvFileInvalid fileId) pure =<< rfi_ rfi_ = case (filePath_, connId_, agentConnId_) of @@ -720,7 +722,7 @@ getRcvFileTransfer_ db userId fileId = do acceptRcvFileTransfer :: DB.Connection -> VersionRangeChat -> User -> Int64 -> (CommandId, ConnId) -> ConnStatus -> FilePath -> SubscriptionMode -> ExceptT StoreError IO AChatItem acceptRcvFileTransfer db vr user@User {userId} fileId (cmdId, acId) connStatus filePath subMode = ExceptT $ do currentTs <- getCurrentTime - acceptRcvFT_ db user fileId filePath Nothing currentTs + acceptRcvFT_ db user fileId filePath False Nothing currentTs DB.execute db "INSERT INTO connections (agent_conn_id, conn_status, conn_type, rcv_file_id, user_id, created_at, updated_at, to_subscribe) VALUES (?,?,?,?,?,?,?,?)" @@ -740,33 +742,40 @@ getContactByFileId db vr user@User {userId} fileId = do acceptRcvInlineFT :: DB.Connection -> VersionRangeChat -> User -> FileTransferId -> FilePath -> ExceptT StoreError IO AChatItem acceptRcvInlineFT db vr user fileId filePath = do - liftIO $ acceptRcvFT_ db user fileId filePath (Just IFMOffer) =<< getCurrentTime + liftIO $ acceptRcvFT_ db user fileId filePath False (Just IFMOffer) =<< getCurrentTime getChatItemByFileId db vr user fileId startRcvInlineFT :: DB.Connection -> User -> RcvFileTransfer -> FilePath -> Maybe InlineFileMode -> IO () startRcvInlineFT db user RcvFileTransfer {fileId} filePath rcvFileInline = - acceptRcvFT_ db user fileId filePath rcvFileInline =<< getCurrentTime + acceptRcvFT_ db user fileId filePath False rcvFileInline =<< getCurrentTime -xftpAcceptRcvFT :: DB.Connection -> VersionRangeChat -> User -> FileTransferId -> FilePath -> ExceptT StoreError IO AChatItem -xftpAcceptRcvFT db vr user fileId filePath = do - liftIO $ acceptRcvFT_ db user fileId filePath Nothing =<< getCurrentTime +xftpAcceptRcvFT :: DB.Connection -> VersionRangeChat -> User -> FileTransferId -> FilePath -> Bool -> ExceptT StoreError IO AChatItem +xftpAcceptRcvFT db vr user fileId filePath userApprovedRelays = do + liftIO $ acceptRcvFT_ db user fileId filePath userApprovedRelays Nothing =<< getCurrentTime getChatItemByFileId db vr user fileId -acceptRcvFT_ :: DB.Connection -> User -> FileTransferId -> FilePath -> Maybe InlineFileMode -> UTCTime -> IO () -acceptRcvFT_ db User {userId} fileId filePath rcvFileInline currentTs = do +acceptRcvFT_ :: DB.Connection -> User -> FileTransferId -> FilePath -> Bool -> Maybe InlineFileMode -> UTCTime -> IO () +acceptRcvFT_ db User {userId} fileId filePath userApprovedRelays rcvFileInline currentTs = do DB.execute db "UPDATE files SET file_path = ?, ci_file_status = ?, updated_at = ? WHERE user_id = ? AND file_id = ?" (filePath, CIFSRcvAccepted, currentTs, userId, fileId) DB.execute db - "UPDATE rcv_files SET rcv_file_inline = ?, file_status = ?, updated_at = ? WHERE file_id = ?" - (rcvFileInline, FSAccepted, currentTs, fileId) + "UPDATE rcv_files SET user_approved_relays = ?, rcv_file_inline = ?, file_status = ?, updated_at = ? WHERE file_id = ?" + (userApprovedRelays, rcvFileInline, FSAccepted, currentTs, fileId) -setRcvFileToReceive :: DB.Connection -> FileTransferId -> Maybe CryptoFileArgs -> IO () -setRcvFileToReceive db fileId cfArgs_ = do +setRcvFileToReceive :: DB.Connection -> FileTransferId -> Bool -> Maybe CryptoFileArgs -> IO () +setRcvFileToReceive db fileId userApprovedRelays cfArgs_ = do currentTs <- getCurrentTime - DB.execute db "UPDATE rcv_files SET to_receive = 1, updated_at = ? WHERE file_id = ?" (currentTs, fileId) + DB.execute + db + [sql| + UPDATE rcv_files + SET to_receive = 1, user_approved_relays = ?, updated_at = ? + WHERE file_id = ? + |] + (userApprovedRelays, currentTs, fileId) forM_ cfArgs_ $ \cfArgs -> setFileCryptoArgs_ db fileId cfArgs currentTs setFileCryptoArgs :: DB.Connection -> FileTransferId -> CryptoFileArgs -> IO () @@ -950,7 +959,7 @@ getFileTransferMeta_ db userId fileId = fileTransferMeta (fileName, fileSize, chunkSize, filePath, fileKey, fileNonce, fileInline, aSndFileId_, agentSndFileDeleted, privateSndFileDescr, cancelled_, xftpRedirectFor) = let cryptoArgs = CFArgs <$> fileKey <*> fileNonce xftpSndFile = (\fId -> XFTPSndFile {agentSndFileId = fId, privateSndFileDescr, agentSndFileDeleted, cryptoArgs}) <$> aSndFileId_ - in FileTransferMeta {fileId, xftpSndFile, xftpRedirectFor, fileName, fileSize, chunkSize, filePath, fileInline, cancelled = fromMaybe False cancelled_} + in FileTransferMeta {fileId, xftpSndFile, xftpRedirectFor, fileName, fileSize, chunkSize, filePath, fileInline, cancelled = fromMaybe False cancelled_} lookupFileTransferRedirectMeta :: DB.Connection -> User -> Int64 -> IO [FileTransferMeta] lookupFileTransferRedirectMeta db User {userId} fileId = do diff --git a/src/Simplex/Chat/Store/Migrations.hs b/src/Simplex/Chat/Store/Migrations.hs index ccc69d100e..a79a31f75d 100644 --- a/src/Simplex/Chat/Store/Migrations.hs +++ b/src/Simplex/Chat/Store/Migrations.hs @@ -108,6 +108,7 @@ import Simplex.Chat.Migrations.M20240402_item_forwarded import Simplex.Chat.Migrations.M20240430_ui_theme import Simplex.Chat.Migrations.M20240501_chat_deleted import Simplex.Chat.Migrations.M20240510_chat_items_via_proxy +import Simplex.Chat.Migrations.M20240515_rcv_files_user_approved_relays import Simplex.Messaging.Agent.Store.SQLite.Migrations (Migration (..)) schemaMigrations :: [(String, Query, Maybe Query)] @@ -215,7 +216,8 @@ schemaMigrations = ("20240402_item_forwarded", m20240402_item_forwarded, Just down_m20240402_item_forwarded), ("20240430_ui_theme", m20240430_ui_theme, Just down_m20240430_ui_theme), ("20240501_chat_deleted", m20240501_chat_deleted, Just down_m20240501_chat_deleted), - ("20240510_chat_items_via_proxy", m20240510_chat_items_via_proxy, Just down_m20240510_chat_items_via_proxy) + ("20240510_chat_items_via_proxy", m20240510_chat_items_via_proxy, Just down_m20240510_chat_items_via_proxy), + ("20240515_rcv_files_user_approved_relays", m20240515_rcv_files_user_approved_relays, Just down_m20240515_rcv_files_user_approved_relays) ] -- | The list of migrations in ascending order by date diff --git a/src/Simplex/Chat/Types.hs b/src/Simplex/Chat/Types.hs index 336448d7f5..ca6cd2e375 100644 --- a/src/Simplex/Chat/Types.hs +++ b/src/Simplex/Chat/Types.hs @@ -1072,7 +1072,8 @@ data RcvFileTransfer = RcvFileTransfer data XFTPRcvFile = XFTPRcvFile { rcvFileDescription :: RcvFileDescr, agentRcvFileId :: Maybe AgentRcvFileId, - agentRcvFileDeleted :: Bool + agentRcvFileDeleted :: Bool, + userApprovedRelays :: Bool } deriving (Eq, Show) diff --git a/src/Simplex/Chat/View.hs b/src/Simplex/Chat/View.hs index 4b3240fe46..1c2b0b2cc1 100644 --- a/src/Simplex/Chat/View.hs +++ b/src/Simplex/Chat/View.hs @@ -1766,6 +1766,7 @@ viewFileTransferStatusXFTP (AChatItem _ _ _ ChatItem {file = Just CIFile {fileId CIFSRcvInvitation -> ["receiving " <> fstr <> " not accepted yet, use " <> highlight ("/fr " <> show fileId) <> " to receive file"] CIFSRcvAccepted -> ["receiving " <> fstr <> " just started"] CIFSRcvTransfer progress total -> ["receiving " <> fstr <> " progress " <> fileProgressXFTP progress total fileSize] + CIFSRcvAborted -> ["receiving " <> fstr <> " aborted, use " <> highlight ("/fr " <> show fileId) <> " to receive file"] CIFSRcvComplete -> ["receiving " <> fstr <> " complete" <> maybe "" (\(CryptoFile fp _) -> ", path: " <> plain fp) fileSource] CIFSRcvCancelled -> ["receiving " <> fstr <> " cancelled"] CIFSRcvError -> ["receiving " <> fstr <> " error"] @@ -1969,6 +1970,7 @@ viewChatError logLevel testView = \case CEFileImageType _ -> ["image type must be jpg, send as a file using " <> highlight' "/f"] CEFileImageSize _ -> ["max image size: " <> sShow maxImageSize <> " bytes, resize it or send as a file using " <> highlight' "/f"] CEFileNotReceived fileId -> ["file " <> sShow fileId <> " not received"] + CEFileNotApproved fileId unknownSrvs -> ["file " <> sShow fileId <> " aborted, unknwon XFTP servers:"] <> map (plain . show) unknownSrvs CEXFTPRcvFile fileId aFileId e -> ["error receiving XFTP file " <> sShow fileId <> ", agent file id " <> sShow aFileId <> ": " <> sShow e | logLevel == CLLError] CEXFTPSndFile fileId aFileId e -> ["error sending XFTP file " <> sShow fileId <> ", agent file id " <> sShow aFileId <> ": " <> sShow e | logLevel == CLLError] CEFallbackToSMPProhibited fileId -> ["recipient tried to accept file " <> sShow fileId <> " via old protocol, prohibited"] From ec7b35adb90f9a15ffb9ac9a62a660775d622821 Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Mon, 20 May 2024 17:49:19 +0400 Subject: [PATCH 02/18] ios: check known relays before file reception, support user approval of unknown relays (#4044) * ios: check known relays before file reception, support user approval of unknown relays * add privacyAskToApproveRelays to AppSettings * less text * ui improvements, fixes * fix ntf * shorter alert * simplify settings * rename * icon --------- Co-authored-by: Evgeny Poberezkin --- apps/ios/Shared/Model/SimpleXAPI.swift | 54 +++++++++++++++---- apps/ios/Shared/Views/Chat/ChatInfoView.swift | 2 +- .../Views/Chat/ChatItem/CIFileView.swift | 7 ++- .../Views/Chat/ChatItem/CIImageView.swift | 6 +-- .../Views/Chat/ChatItem/CIVideoView.swift | 17 ++++-- .../Views/Chat/ChatItem/CIVoiceView.swift | 7 +-- .../Views/Chat/ChatItem/FramedItemView.swift | 2 +- .../Views/UserSettings/AppSettings.swift | 2 + .../Views/UserSettings/PrivacySettings.swift | 39 +++++++++----- .../ios/SimpleX NSE/NotificationService.swift | 6 ++- apps/ios/SimpleXChat/APITypes.swift | 12 +++-- apps/ios/SimpleXChat/AppGroup.swift | 4 ++ apps/ios/SimpleXChat/ChatTypes.swift | 4 ++ 13 files changed, 121 insertions(+), 41 deletions(-) diff --git a/apps/ios/Shared/Model/SimpleXAPI.swift b/apps/ios/Shared/Model/SimpleXAPI.swift index ef31d2f438..a6d574e38d 100644 --- a/apps/ios/Shared/Model/SimpleXAPI.swift +++ b/apps/ios/Shared/Model/SimpleXAPI.swift @@ -927,14 +927,19 @@ func standaloneFileInfo(url: String, ctrl: chat_ctrl? = nil) async -> MigrationF } } -func receiveFile(user: any UserLike, fileId: Int64, auto: Bool = false) async { - if let chatItem = await apiReceiveFile(fileId: fileId, encrypted: privacyEncryptLocalFilesGroupDefault.get(), auto: auto) { +func receiveFile(user: any UserLike, fileId: Int64, userApprovedRelays: Bool = false, auto: Bool = false) async { + if let chatItem = await apiReceiveFile( + fileId: fileId, + userApprovedRelays: userApprovedRelays || !privacyAskToApproveRelaysGroupDefault.get(), + encrypted: privacyEncryptLocalFilesGroupDefault.get(), + auto: auto + ) { await chatItemSimpleUpdate(user, chatItem) } } -func apiReceiveFile(fileId: Int64, encrypted: Bool, inline: Bool? = nil, auto: Bool = false) async -> AChatItem? { - let r = await chatSendCmd(.receiveFile(fileId: fileId, encrypted: encrypted, inline: inline)) +func apiReceiveFile(fileId: Int64, userApprovedRelays: Bool, encrypted: Bool, inline: Bool? = nil, auto: Bool = false) async -> AChatItem? { + let r = await chatSendCmd(.receiveFile(fileId: fileId, userApprovedRelays: userApprovedRelays, encrypted: encrypted, inline: inline)) let am = AlertManager.shared if case let .rcvFileAccepted(_, chatItem) = r { return chatItem } if case .rcvFileAcceptedSndCancelled = r { @@ -947,19 +952,50 @@ func apiReceiveFile(fileId: Int64, encrypted: Bool, inline: Bool? = nil, auto: B } } else if let networkErrorAlert = networkErrorAlert(r) { logger.error("apiReceiveFile network error: \(String(describing: r))") - am.showAlert(networkErrorAlert) + if !auto { + am.showAlert(networkErrorAlert) + } } else { switch chatError(r) { case .fileCancelled: logger.debug("apiReceiveFile ignoring fileCancelled error") case .fileAlreadyReceiving: logger.debug("apiReceiveFile ignoring fileAlreadyReceiving error") + case let .fileNotApproved(fileId, unknownServers): + logger.debug("apiReceiveFile fileNotApproved error") + if !auto { + let srvs = unknownServers.map { s in + if let srv = parseServerAddress(s), !srv.hostnames.isEmpty { + srv.hostnames[0] + } else { + serverHost(s) + } + } + am.showAlert(Alert( + title: Text("Unknown servers!"), + message: Text("Without Tor or VPN, your IP address will be visible to these XFTP relays: \(srvs.sorted().joined(separator: ", "))."), + primaryButton: .default( + Text("Download"), + action: { + Task { + logger.debug("apiReceiveFile fileNotApproved alert - in Task") + if let user = ChatModel.shared.currentUser { + await receiveFile(user: user, fileId: fileId, userApprovedRelays: true) + } + } + } + ), + secondaryButton: .cancel() + )) + } default: logger.error("apiReceiveFile error: \(String(describing: r))") - am.showAlertMsg( - title: "Error receiving file", - message: "Error: \(String(describing: r))" - ) + if !auto { + am.showAlertMsg( + title: "Error receiving file", + message: "Error: \(String(describing: r))" + ) + } } } return nil diff --git a/apps/ios/Shared/Views/Chat/ChatInfoView.swift b/apps/ios/Shared/Views/Chat/ChatInfoView.swift index 55e84f20d3..2e5a4f2af6 100644 --- a/apps/ios/Shared/Views/Chat/ChatInfoView.swift +++ b/apps/ios/Shared/Views/Chat/ChatInfoView.swift @@ -49,7 +49,7 @@ func localizedInfoRow(_ title: LocalizedStringKey, _ value: LocalizedStringKey) } } -private func serverHost(_ s: String) -> String { +func serverHost(_ s: String) -> String { if let i = s.range(of: "@")?.lowerBound { return String(s[i...].dropFirst()) } else { diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIFileView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIFileView.swift index ae9e09b138..0af0469e42 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIFileView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIFileView.swift @@ -60,6 +60,7 @@ struct CIFileView: View { case .rcvInvitation: return true case .rcvAccepted: return true case .rcvTransfer: return false + case .rcvAborted: return true case .rcvComplete: return true case .rcvCancelled: return false case .rcvError: return false @@ -73,10 +74,10 @@ struct CIFileView: View { logger.debug("CIFileView fileAction") if let file = file { switch (file.fileStatus) { - case .rcvInvitation: + case .rcvInvitation, .rcvAborted: if fileSizeValid(file) { Task { - logger.debug("CIFileView fileAction - in .rcvInvitation, in Task") + logger.debug("CIFileView fileAction - in .rcvInvitation, .rcvAborted, in Task") if let user = m.currentUser { await receiveFile(user: user, fileId: file.fileId) } @@ -148,6 +149,8 @@ struct CIFileView: View { } else { progressView() } + case .rcvAborted: + fileIcon("doc.fill", color: .accentColor, innerIcon: "exclamationmark.arrow.circlepath", innerIconSize: 12) case .rcvComplete: fileIcon("doc.fill") case .rcvCancelled: fileIcon("doc.fill", innerIcon: "xmark", innerIconSize: 10) case .rcvError: fileIcon("doc.fill", innerIcon: "xmark", innerIconSize: 10) diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIImageView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIImageView.swift index 16974147c8..7d33df6c60 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIImageView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIImageView.swift @@ -17,7 +17,6 @@ struct CIImageView: View { let maxWidth: CGFloat @Binding var imgWidth: CGFloat? @State var scrollProxy: ScrollViewProxy? - @State var metaColor: Color @State private var showFullScreenImage = false var body: some View { @@ -38,7 +37,7 @@ struct CIImageView: View { .onTapGesture { if let file = file { switch file.fileStatus { - case .rcvInvitation: + case .rcvInvitation, .rcvAborted: Task { if let user = m.currentUser { await receiveFile(user: user, fileId: file.fileId) @@ -103,6 +102,7 @@ struct CIImageView: View { case .rcvInvitation: fileIcon("arrow.down", 10, 13) case .rcvAccepted: fileIcon("ellipsis", 14, 11) case .rcvTransfer: progressView() + case .rcvAborted: fileIcon("exclamationmark.arrow.circlepath", 14, 11) case .rcvCancelled: fileIcon("xmark", 10, 13) case .rcvError: fileIcon("xmark", 10, 13) case .invalid: fileIcon("questionmark", 10, 13) @@ -116,7 +116,7 @@ struct CIImageView: View { .resizable() .aspectRatio(contentMode: .fit) .frame(width: size, height: size) - .foregroundColor(metaColor) + .foregroundColor(.white) .padding(padding) } diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIVideoView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIVideoView.swift index b4b190a43a..3bfe24b79d 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIVideoView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIVideoView.swift @@ -69,7 +69,7 @@ struct CIVideoView: View { .onTapGesture { if let file = file { switch file.fileStatus { - case .rcvInvitation: + case .rcvInvitation, .rcvAborted: receiveFileIfValidSize(file: file, receiveFile: receiveFile) case .rcvAccepted: switch file.fileProtocol { @@ -95,7 +95,7 @@ struct CIVideoView: View { } durationProgress() } - if let file = file, case .rcvInvitation = file.fileStatus { + if let file = file, showDownloadButton(file.fileStatus) { Button { receiveFileIfValidSize(file: file, receiveFile: receiveFile) } label: { @@ -105,6 +105,14 @@ struct CIVideoView: View { } } + private func showDownloadButton(_ fileStatus: CIFileStatus) -> Bool { + switch fileStatus { + case .rcvInvitation: true + case .rcvAborted: true + default: false + } + } + private func videoViewEncrypted(_ file: CIFile, _ defaultPreview: UIImage, _ duration: Int) -> some View { return ZStack(alignment: .topTrailing) { ZStack(alignment: .center) { @@ -280,6 +288,7 @@ struct CIVideoView: View { } else { progressView() } + case .rcvAborted: fileIcon("exclamationmark.arrow.circlepath", 14, 11) case .rcvCancelled: fileIcon("xmark", 10, 13) case .rcvError: fileIcon("xmark", 10, 13) case .invalid: fileIcon("questionmark", 10, 13) @@ -318,10 +327,10 @@ struct CIVideoView: View { } // TODO encrypt: where file size is checked? - private func receiveFileIfValidSize(file: CIFile, receiveFile: @escaping (User, Int64, Bool) async -> Void) { + private func receiveFileIfValidSize(file: CIFile, receiveFile: @escaping (User, Int64, Bool, Bool) async -> Void) { Task { if let user = m.currentUser { - await receiveFile(user, file.fileId, false) + await receiveFile(user, file.fileId, false, false) } } } diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIVoiceView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIVoiceView.swift index 3aecb65ebd..ba1712f6e3 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIVoiceView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIVoiceView.swift @@ -139,9 +139,10 @@ struct VoiceMessagePlayer: View { case .sndComplete: playbackButton() case .sndCancelled: playbackButton() case .sndError: playbackButton() - case .rcvInvitation: downloadButton(recordingFile) + case .rcvInvitation: downloadButton(recordingFile, "play.fill") case .rcvAccepted: loadingIcon() case .rcvTransfer: loadingIcon() + case .rcvAborted: downloadButton(recordingFile, "exclamationmark.arrow.circlepath") case .rcvComplete: playbackButton() case .rcvCancelled: playPauseIcon("play.fill", Color(uiColor: .tertiaryLabel)) case .rcvError: playPauseIcon("play.fill", Color(uiColor: .tertiaryLabel)) @@ -217,7 +218,7 @@ struct VoiceMessagePlayer: View { } } - private func downloadButton(_ recordingFile: CIFile) -> some View { + private func downloadButton(_ recordingFile: CIFile, _ icon: String) -> some View { Button { Task { if let user = chatModel.currentUser { @@ -225,7 +226,7 @@ struct VoiceMessagePlayer: View { } } } label: { - playPauseIcon("play.fill") + playPauseIcon(icon) } } diff --git a/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift b/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift index a1642769b3..9b4cecf526 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift @@ -115,7 +115,7 @@ struct FramedItemView: View { } else { switch (chatItem.content.msgContent) { case let .image(text, image): - CIImageView(chatItem: chatItem, image: image, maxWidth: maxWidth, imgWidth: $imgWidth, scrollProxy: scrollProxy, metaColor: metaColor) + CIImageView(chatItem: chatItem, image: image, maxWidth: maxWidth, imgWidth: $imgWidth, scrollProxy: scrollProxy) .overlay(DetermineWidth()) if text == "" && !chatItem.meta.isLive { Color.clear diff --git a/apps/ios/Shared/Views/UserSettings/AppSettings.swift b/apps/ios/Shared/Views/UserSettings/AppSettings.swift index ba192b333c..299c96626a 100644 --- a/apps/ios/Shared/Views/UserSettings/AppSettings.swift +++ b/apps/ios/Shared/Views/UserSettings/AppSettings.swift @@ -23,6 +23,7 @@ extension AppSettings { setNetCfg(val) } if let val = privacyEncryptLocalFiles { privacyEncryptLocalFilesGroupDefault.set(val) } + if let val = privacyAskToApproveRelays { privacyAskToApproveRelaysGroupDefault.set(val) } if let val = privacyAcceptImages { privacyAcceptImagesGroupDefault.set(val) def.setValue(val, forKey: DEFAULT_PRIVACY_ACCEPT_IMAGES) @@ -50,6 +51,7 @@ extension AppSettings { var c = AppSettings.defaults c.networkConfig = getNetCfg() c.privacyEncryptLocalFiles = privacyEncryptLocalFilesGroupDefault.get() + c.privacyAskToApproveRelays = privacyAskToApproveRelaysGroupDefault.get() c.privacyAcceptImages = privacyAcceptImagesGroupDefault.get() c.privacyLinkPreviews = def.bool(forKey: DEFAULT_PRIVACY_LINK_PREVIEWS) c.privacyShowChatPreviews = def.bool(forKey: DEFAULT_PRIVACY_SHOW_CHAT_PREVIEWS) diff --git a/apps/ios/Shared/Views/UserSettings/PrivacySettings.swift b/apps/ios/Shared/Views/UserSettings/PrivacySettings.swift index 8d13c6fb39..01f31d66b4 100644 --- a/apps/ios/Shared/Views/UserSettings/PrivacySettings.swift +++ b/apps/ios/Shared/Views/UserSettings/PrivacySettings.swift @@ -16,6 +16,7 @@ struct PrivacySettings: View { @AppStorage(DEFAULT_PRIVACY_SHOW_CHAT_PREVIEWS) private var showChatPreviews = true @AppStorage(DEFAULT_PRIVACY_SAVE_LAST_DRAFT) private var saveLastDraft = true @AppStorage(GROUP_DEFAULT_PRIVACY_ENCRYPT_LOCAL_FILES, store: groupDefaults) private var encryptLocalFiles = true + @AppStorage(GROUP_DEFAULT_PRIVACY_ASK_TO_APPROVE_RELAYS, store: groupDefaults) private var askToApproveRelays = true @State private var simplexLinkMode = privacySimplexLinkModeDefault.get() @AppStorage(DEFAULT_PRIVACY_PROTECT_SCREEN) private var protectScreen = false @AppStorage(DEFAULT_PERFORM_LA) private var prefPerformLA = false @@ -64,18 +65,6 @@ struct PrivacySettings: View { } Section { - settingsRow("lock.doc") { - Toggle("Encrypt local files", isOn: $encryptLocalFiles) - .onChange(of: encryptLocalFiles) { - setEncryptLocalFiles($0) - } - } - settingsRow("photo") { - Toggle("Auto-accept images", isOn: $autoAcceptImages) - .onChange(of: autoAcceptImages) { - privacyAcceptImagesGroupDefault.set($0) - } - } settingsRow("network") { Toggle("Send link previews", isOn: $useLinkPreviews) } @@ -108,6 +97,32 @@ struct PrivacySettings: View { Text("Chats") } + Section { + settingsRow("lock.doc") { + Toggle("Encrypt local files", isOn: $encryptLocalFiles) + .onChange(of: encryptLocalFiles) { + setEncryptLocalFiles($0) + } + } + settingsRow("photo") { + Toggle("Auto-accept images", isOn: $autoAcceptImages) + .onChange(of: autoAcceptImages) { + privacyAcceptImagesGroupDefault.set($0) + } + } + settingsRow("network.badge.shield.half.filled") { + Toggle("Protect IP address", isOn: $askToApproveRelays) + } + } header: { + Text("Files") + } footer: { + if askToApproveRelays { + Text("The app will ask to confirm downloads from unknown file servers (except .onion).") + } else { + Text("Without Tor or VPN, your IP address will be visible to file servers.") + } + } + Section { settingsRow("person") { Toggle("Contacts", isOn: $contactReceipts) diff --git a/apps/ios/SimpleX NSE/NotificationService.swift b/apps/ios/SimpleX NSE/NotificationService.swift index faa7f4f44c..12094c7053 100644 --- a/apps/ios/SimpleX NSE/NotificationService.swift +++ b/apps/ios/SimpleX NSE/NotificationService.swift @@ -696,14 +696,16 @@ func apiGetNtfMessage(nonce: String, encNtfInfo: String) -> NtfMessages? { } func apiReceiveFile(fileId: Int64, encrypted: Bool, inline: Bool? = nil) -> AChatItem? { - let r = sendSimpleXCmd(.receiveFile(fileId: fileId, encrypted: encrypted, inline: inline)) + let userApprovedRelays = !privacyAskToApproveRelaysGroupDefault.get() + let r = sendSimpleXCmd(.receiveFile(fileId: fileId, userApprovedRelays: userApprovedRelays, encrypted: encrypted, inline: inline)) if case let .rcvFileAccepted(_, chatItem) = r { return chatItem } logger.error("receiveFile error: \(responseError(r))") return nil } func apiSetFileToReceive(fileId: Int64, encrypted: Bool) { - let r = sendSimpleXCmd(.setFileToReceive(fileId: fileId, encrypted: encrypted)) + let userApprovedRelays = !privacyAskToApproveRelaysGroupDefault.get() + let r = sendSimpleXCmd(.setFileToReceive(fileId: fileId, userApprovedRelays: userApprovedRelays, encrypted: encrypted)) if case .cmdOk = r { return } logger.error("setFileToReceive error: \(responseError(r))") } diff --git a/apps/ios/SimpleXChat/APITypes.swift b/apps/ios/SimpleXChat/APITypes.swift index 97013ca2a4..7fa7e961ae 100644 --- a/apps/ios/SimpleXChat/APITypes.swift +++ b/apps/ios/SimpleXChat/APITypes.swift @@ -123,8 +123,8 @@ public enum ChatCommand { case apiGetNetworkStatuses case apiChatRead(type: ChatType, id: Int64, itemRange: (Int64, Int64)) case apiChatUnread(type: ChatType, id: Int64, unreadChat: Bool) - case receiveFile(fileId: Int64, encrypted: Bool?, inline: Bool?) - case setFileToReceive(fileId: Int64, encrypted: Bool?) + case receiveFile(fileId: Int64, userApprovedRelays: Bool, encrypted: Bool?, inline: Bool?) + case setFileToReceive(fileId: Int64, userApprovedRelays: Bool, encrypted: Bool?) case cancelFile(fileId: Int64) // remote desktop commands case setLocalDeviceName(displayName: String) @@ -282,8 +282,8 @@ public enum ChatCommand { case .apiGetNetworkStatuses: return "/_network_statuses" case let .apiChatRead(type, id, itemRange: (from, to)): return "/_read chat \(ref(type, id)) from=\(from) to=\(to)" case let .apiChatUnread(type, id, unreadChat): return "/_unread chat \(ref(type, id)) \(onOff(unreadChat))" - case let .receiveFile(fileId, encrypt, inline): return "/freceive \(fileId)\(onOffParam("encrypt", encrypt))\(onOffParam("inline", inline))" - case let .setFileToReceive(fileId, encrypt): return "/_set_file_to_receive \(fileId)\(onOffParam("encrypt", encrypt))" + case let .receiveFile(fileId, userApprovedRelays, encrypt, inline): return "/freceive \(fileId)\(onOffParam("approved_relays", userApprovedRelays))\(onOffParam("encrypt", encrypt))\(onOffParam("inline", inline))" + case let .setFileToReceive(fileId, userApprovedRelays, encrypt): return "/_set_file_to_receive \(fileId)\(onOffParam("approved_relays", userApprovedRelays))\(onOffParam("encrypt", encrypt))" case let .cancelFile(fileId): return "/fcancel \(fileId)" case let .setLocalDeviceName(displayName): return "/set device name \(displayName)" case let .connectRemoteCtrl(xrcpInv): return "/connect remote ctrl \(xrcpInv)" @@ -1760,6 +1760,7 @@ public enum ChatErrorType: Decodable { case fileImageType(filePath: String) case fileImageSize(filePath: String) case fileNotReceived(fileId: Int64) + case fileNotApproved(fileId: Int64, unknownServers: [String]) // case xFTPRcvFile // case xFTPSndFile case fallbackToSMPProhibited(fileId: Int64) @@ -2038,6 +2039,7 @@ public struct MigrationFileLinkData: Codable { public struct AppSettings: Codable, Equatable { public var networkConfig: NetCfg? = nil public var privacyEncryptLocalFiles: Bool? = nil + public var privacyAskToApproveRelays: Bool? = nil public var privacyAcceptImages: Bool? = nil public var privacyLinkPreviews: Bool? = nil public var privacyShowChatPreviews: Bool? = nil @@ -2061,6 +2063,7 @@ public struct AppSettings: Codable, Equatable { let def = AppSettings.defaults if networkConfig != def.networkConfig { empty.networkConfig = networkConfig } if privacyEncryptLocalFiles != def.privacyEncryptLocalFiles { empty.privacyEncryptLocalFiles = privacyEncryptLocalFiles } + if privacyAskToApproveRelays != def.privacyAskToApproveRelays { empty.privacyAskToApproveRelays = privacyAskToApproveRelays } if privacyAcceptImages != def.privacyAcceptImages { empty.privacyAcceptImages = privacyAcceptImages } if privacyLinkPreviews != def.privacyLinkPreviews { empty.privacyLinkPreviews = privacyLinkPreviews } if privacyShowChatPreviews != def.privacyShowChatPreviews { empty.privacyShowChatPreviews = privacyShowChatPreviews } @@ -2085,6 +2088,7 @@ public struct AppSettings: Codable, Equatable { AppSettings ( networkConfig: NetCfg.defaults, privacyEncryptLocalFiles: true, + privacyAskToApproveRelays: true, privacyAcceptImages: true, privacyLinkPreviews: true, privacyShowChatPreviews: true, diff --git a/apps/ios/SimpleXChat/AppGroup.swift b/apps/ios/SimpleXChat/AppGroup.swift index 118acae993..90ac403999 100644 --- a/apps/ios/SimpleXChat/AppGroup.swift +++ b/apps/ios/SimpleXChat/AppGroup.swift @@ -23,6 +23,7 @@ public let GROUP_DEFAULT_NTF_ENABLE_PERIODIC = "ntfEnablePeriodic" // no longer let GROUP_DEFAULT_PRIVACY_ACCEPT_IMAGES = "privacyAcceptImages" public let GROUP_DEFAULT_PRIVACY_TRANSFER_IMAGES_INLINE = "privacyTransferImagesInline" // no longer used public let GROUP_DEFAULT_PRIVACY_ENCRYPT_LOCAL_FILES = "privacyEncryptLocalFiles" +public let GROUP_DEFAULT_PRIVACY_ASK_TO_APPROVE_RELAYS = "privacyAskToApproveRelays" let GROUP_DEFAULT_NTF_BADGE_COUNT = "ntgBadgeCount" let GROUP_DEFAULT_NETWORK_USE_ONION_HOSTS = "networkUseOnionHosts" let GROUP_DEFAULT_NETWORK_SESSION_MODE = "networkSessionMode" @@ -73,6 +74,7 @@ public func registerGroupDefaults() { GROUP_DEFAULT_PRIVACY_ACCEPT_IMAGES: true, GROUP_DEFAULT_PRIVACY_TRANSFER_IMAGES_INLINE: false, GROUP_DEFAULT_PRIVACY_ENCRYPT_LOCAL_FILES: true, + GROUP_DEFAULT_PRIVACY_ASK_TO_APPROVE_RELAYS: true, GROUP_DEFAULT_CONFIRM_DB_UPGRADES: false, GROUP_DEFAULT_CALL_KIT_ENABLED: true, GROUP_DEFAULT_PQ_EXPERIMENTAL_ENABLED: false, @@ -181,6 +183,8 @@ public let privacyAcceptImagesGroupDefault = BoolDefault(defaults: groupDefaults public let privacyEncryptLocalFilesGroupDefault = BoolDefault(defaults: groupDefaults, forKey: GROUP_DEFAULT_PRIVACY_ENCRYPT_LOCAL_FILES) +public let privacyAskToApproveRelaysGroupDefault = BoolDefault(defaults: groupDefaults, forKey: GROUP_DEFAULT_PRIVACY_ASK_TO_APPROVE_RELAYS) + public let ntfBadgeCountGroupDefault = IntDefault(defaults: groupDefaults, forKey: GROUP_DEFAULT_NTF_BADGE_COUNT) public let networkUseOnionHostsGroupDefault = EnumDefault( diff --git a/apps/ios/SimpleXChat/ChatTypes.swift b/apps/ios/SimpleXChat/ChatTypes.swift index 0d2a042d9d..27e5a9818c 100644 --- a/apps/ios/SimpleXChat/ChatTypes.swift +++ b/apps/ios/SimpleXChat/ChatTypes.swift @@ -3174,6 +3174,7 @@ public struct CIFile: Decodable { case .rcvInvitation: return false case .rcvAccepted: return false case .rcvTransfer: return false + case .rcvAborted: return false case .rcvCancelled: return false case .rcvComplete: return true case .rcvError: return false @@ -3198,6 +3199,7 @@ public struct CIFile: Decodable { case .rcvInvitation: return nil case .rcvAccepted: return rcvCancelAction case .rcvTransfer: return rcvCancelAction + case .rcvAborted: return nil case .rcvCancelled: return nil case .rcvComplete: return nil case .rcvError: return nil @@ -3312,6 +3314,7 @@ public enum CIFileStatus: Decodable, Equatable { case rcvInvitation case rcvAccepted case rcvTransfer(rcvProgress: Int64, rcvTotal: Int64) + case rcvAborted case rcvComplete case rcvCancelled case rcvError @@ -3327,6 +3330,7 @@ public enum CIFileStatus: Decodable, Equatable { case .rcvInvitation: return "rcvInvitation" case .rcvAccepted: return "rcvAccepted" case let .rcvTransfer(rcvProgress, rcvTotal): return "rcvTransfer \(rcvProgress) \(rcvTotal)" + case .rcvAborted: return "rcvAborted" case .rcvComplete: return "rcvComplete" case .rcvCancelled: return "rcvCancelled" case .rcvError: return "rcvError" From ba203faad42a8da4bb9ba8fd8217eec428243000 Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Mon, 20 May 2024 17:58:30 +0400 Subject: [PATCH 03/18] android: check known relays before file reception, support user approval of unknown relays (#4196) --- .../chat/simplex/common/model/ChatModel.kt | 4 ++ .../chat/simplex/common/model/SimpleXAPI.kt | 48 +++++++++++++++---- .../common/views/chat/item/CIFileView.kt | 5 +- .../common/views/chat/item/CIImageView.kt | 10 ++-- .../common/views/chat/item/CIVIdeoView.kt | 5 +- .../common/views/chat/item/CIVoiceView.kt | 8 +++- .../common/views/chat/item/FramedItemView.kt | 2 +- .../views/usersettings/PrivacySettings.kt | 23 +++++++-- .../commonMain/resources/MR/base/strings.xml | 6 +++ 9 files changed, 84 insertions(+), 27 deletions(-) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt index 3780066092..56487874ba 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt @@ -2644,6 +2644,7 @@ data class CIFile( is CIFileStatus.RcvInvitation -> false is CIFileStatus.RcvAccepted -> false is CIFileStatus.RcvTransfer -> false + is CIFileStatus.RcvAborted -> false is CIFileStatus.RcvCancelled -> false is CIFileStatus.RcvComplete -> true is CIFileStatus.RcvError -> false @@ -2665,6 +2666,7 @@ data class CIFile( is CIFileStatus.RcvInvitation -> null is CIFileStatus.RcvAccepted -> rcvCancelAction is CIFileStatus.RcvTransfer -> rcvCancelAction + is CIFileStatus.RcvAborted -> null is CIFileStatus.RcvCancelled -> null is CIFileStatus.RcvComplete -> null is CIFileStatus.RcvError -> null @@ -2845,6 +2847,7 @@ sealed class CIFileStatus { @Serializable @SerialName("rcvInvitation") object RcvInvitation: CIFileStatus() @Serializable @SerialName("rcvAccepted") object RcvAccepted: CIFileStatus() @Serializable @SerialName("rcvTransfer") class RcvTransfer(val rcvProgress: Long, val rcvTotal: Long): CIFileStatus() + @Serializable @SerialName("rcvAborted") object RcvAborted: CIFileStatus() @Serializable @SerialName("rcvComplete") object RcvComplete: CIFileStatus() @Serializable @SerialName("rcvCancelled") object RcvCancelled: CIFileStatus() @Serializable @SerialName("rcvError") object RcvError: CIFileStatus() @@ -2859,6 +2862,7 @@ sealed class CIFileStatus { is RcvInvitation -> false is RcvAccepted -> false is RcvTransfer -> false + is RcvAborted -> false is RcvComplete -> false is RcvCancelled -> false is RcvError -> false diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt index fa9c2580ee..ca237cd52f 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt @@ -12,6 +12,7 @@ import dev.icerock.moko.resources.compose.painterResource import chat.simplex.common.platform.* import chat.simplex.common.ui.theme.* import chat.simplex.common.views.call.* +import chat.simplex.common.views.chat.group.toggleShowMemberMessages import chat.simplex.common.views.migration.MigrationFileLinkData import chat.simplex.common.views.onboarding.OnboardingStage import chat.simplex.common.views.usersettings.* @@ -106,6 +107,7 @@ class AppPreferences { val privacySaveLastDraft = mkBoolPreference(SHARED_PREFS_PRIVACY_SAVE_LAST_DRAFT, true) val privacyDeliveryReceiptsSet = mkBoolPreference(SHARED_PREFS_PRIVACY_DELIVERY_RECEIPTS_SET, false) val privacyEncryptLocalFiles = mkBoolPreference(SHARED_PREFS_PRIVACY_ENCRYPT_LOCAL_FILES, true) + val privacyAskToApproveRelays = mkBoolPreference(SHARED_PREFS_PRIVACY_ASK_TO_APPROVE_RELAYS, true) val experimentalCalls = mkBoolPreference(SHARED_PREFS_EXPERIMENTAL_CALLS, false) val showUnreadAndFavorites = mkBoolPreference(SHARED_PREFS_SHOW_UNREAD_AND_FAVORITES, false) val chatArchiveName = mkStrPreference(SHARED_PREFS_CHAT_ARCHIVE_NAME, null) @@ -292,6 +294,7 @@ class AppPreferences { private const val SHARED_PREFS_PRIVACY_SAVE_LAST_DRAFT = "PrivacySaveLastDraft" private const val SHARED_PREFS_PRIVACY_DELIVERY_RECEIPTS_SET = "PrivacyDeliveryReceiptsSet" private const val SHARED_PREFS_PRIVACY_ENCRYPT_LOCAL_FILES = "PrivacyEncryptLocalFiles" + private const val SHARED_PREFS_PRIVACY_ASK_TO_APPROVE_RELAYS = "PrivacyAskToApproveRelays" const val SHARED_PREFS_PRIVACY_FULL_BACKUP = "FullBackup" private const val SHARED_PREFS_EXPERIMENTAL_CALLS = "ExperimentalCalls" private const val SHARED_PREFS_SHOW_UNREAD_AND_FAVORITES = "ShowUnreadAndFavorites" @@ -1337,9 +1340,9 @@ object ChatController { } } - suspend fun apiReceiveFile(rh: Long?, fileId: Long, encrypted: Boolean, inline: Boolean? = null, auto: Boolean = false): AChatItem? { + suspend fun apiReceiveFile(rh: Long?, fileId: Long, userApprovedRelays: Boolean, encrypted: Boolean, inline: Boolean? = null, auto: Boolean = false): AChatItem? { // -1 here is to override default behavior of providing current remote host id because file can be asked by local device while remote is connected - val r = sendCmd(rh, CC.ReceiveFile(fileId, encrypted, inline)) + val r = sendCmd(rh, CC.ReceiveFile(fileId, userApprovedRelays = userApprovedRelays, encrypt = encrypted, inline = inline)) return when (r) { is CR.RcvFileAccepted -> r.chatItem is CR.RcvFileAcceptedSndCancelled -> { @@ -1358,7 +1361,23 @@ object ChatController { val maybeChatError = chatError(r) if (maybeChatError is ChatErrorType.FileCancelled || maybeChatError is ChatErrorType.FileAlreadyReceiving) { Log.d(TAG, "apiReceiveFile ignoring FileCancelled or FileAlreadyReceiving error") - } else { + } else if (maybeChatError is ChatErrorType.FileNotApproved) { + Log.d(TAG, "apiReceiveFile FileNotApproved error") + if (!auto) { + val srvs = maybeChatError.unknownServers.map{ serverHostname(it) } + AlertManager.shared.showAlertDialog( + title = generalGetString(MR.strings.file_not_approved_title), + text = generalGetString(MR.strings.file_not_approved_descr).format(srvs.sorted().joinToString(separator = ", ")), + confirmText = generalGetString(MR.strings.download_file), + onConfirm = { + val user = chatModel.currentUser.value + if (user != null) { + withBGApi { chatModel.controller.receiveFile(rh, user, fileId, userApprovedRelays = true) } + } + }, + ) + } + } else if (!auto) { apiErrorAlert("apiReceiveFile", generalGetString(MR.strings.error_receiving_file), r) } } @@ -2216,9 +2235,14 @@ object ChatController { } } - suspend fun receiveFile(rhId: Long?, user: UserLike, fileId: Long, auto: Boolean = false) { - val encrypted = appPrefs.privacyEncryptLocalFiles.get() - val chatItem = apiReceiveFile(rhId, fileId, encrypted = encrypted, auto = auto) + suspend fun receiveFile(rhId: Long?, user: UserLike, fileId: Long, userApprovedRelays: Boolean = false, auto: Boolean = false) { + val chatItem = apiReceiveFile( + rhId, + fileId, + userApprovedRelays = userApprovedRelays || !appPrefs.privacyAskToApproveRelays.get(), + encrypted = appPrefs.privacyEncryptLocalFiles.get(), + auto = auto + ) if (chatItem != null) { chatItemSimpleUpdate(rhId, user, chatItem) } @@ -2501,7 +2525,7 @@ sealed class CC { class ApiRejectContact(val contactReqId: Long): CC() class ApiChatRead(val type: ChatType, val id: Long, val range: ItemRange): CC() class ApiChatUnread(val type: ChatType, val id: Long, val unreadChat: Boolean): CC() - class ReceiveFile(val fileId: Long, val encrypt: Boolean, val inline: Boolean?): CC() + class ReceiveFile(val fileId: Long, val userApprovedRelays: Boolean, val encrypt: Boolean, val inline: Boolean?): CC() class CancelFile(val fileId: Long): CC() // Remote control class SetLocalDeviceName(val displayName: String): CC() @@ -2652,6 +2676,7 @@ sealed class CC { is ApiChatUnread -> "/_unread chat ${chatRef(type, id)} ${onOff(unreadChat)}" is ReceiveFile -> "/freceive $fileId" + + (" approved_relays=${onOff(userApprovedRelays)}") + (if (encrypt == null) "" else " encrypt=${onOff(encrypt)}") + (if (inline == null) "" else " inline=${onOff(inline)}") is CancelFile -> "/fcancel $fileId" @@ -4892,13 +4917,14 @@ sealed class ChatErrorType { is FileCancel -> "fileCancel" is FileAlreadyExists -> "fileAlreadyExists" is FileRead -> "fileRead" - is FileWrite -> "fileWrite" + is FileWrite -> "fileWrite $message" is FileSend -> "fileSend" is FileRcvChunk -> "fileRcvChunk" is FileInternal -> "fileInternal" is FileImageType -> "fileImageType" is FileImageSize -> "fileImageSize" is FileNotReceived -> "fileNotReceived" + is FileNotApproved -> "fileNotApproved" // is XFTPRcvFile -> "xftpRcvFile" // is XFTPSndFile -> "xftpSndFile" is FallbackToSMPProhibited -> "fallbackToSMPProhibited" @@ -4978,6 +5004,7 @@ sealed class ChatErrorType { @Serializable @SerialName("fileImageType") class FileImageType(val filePath: String): ChatErrorType() @Serializable @SerialName("fileImageSize") class FileImageSize(val filePath: String): ChatErrorType() @Serializable @SerialName("fileNotReceived") class FileNotReceived(val fileId: Long): ChatErrorType() + @Serializable @SerialName("fileNotApproved") class FileNotApproved(val fileId: Long, val unknownServers: List): ChatErrorType() // @Serializable @SerialName("xFTPRcvFile") object XFTPRcvFile: ChatErrorType() // @Serializable @SerialName("xFTPSndFile") object XFTPSndFile: ChatErrorType() @Serializable @SerialName("fallbackToSMPProhibited") class FallbackToSMPProhibited(val fileId: Long): ChatErrorType() @@ -5476,6 +5503,7 @@ enum class NotificationsMode() { data class AppSettings( var networkConfig: NetCfg? = null, var privacyEncryptLocalFiles: Boolean? = null, + var privacyAskToApproveRelays: Boolean? = null, var privacyAcceptImages: Boolean? = null, var privacyLinkPreviews: Boolean? = null, var privacyShowChatPreviews: Boolean? = null, @@ -5499,6 +5527,7 @@ data class AppSettings( val def = defaults if (networkConfig != def.networkConfig) { empty.networkConfig = networkConfig } if (privacyEncryptLocalFiles != def.privacyEncryptLocalFiles) { empty.privacyEncryptLocalFiles = privacyEncryptLocalFiles } + if (privacyAskToApproveRelays != def.privacyAskToApproveRelays) { empty.privacyAskToApproveRelays = privacyAskToApproveRelays } if (privacyAcceptImages != def.privacyAcceptImages) { empty.privacyAcceptImages = privacyAcceptImages } if (privacyLinkPreviews != def.privacyLinkPreviews) { empty.privacyLinkPreviews = privacyLinkPreviews } if (privacyShowChatPreviews != def.privacyShowChatPreviews) { empty.privacyShowChatPreviews = privacyShowChatPreviews } @@ -5530,6 +5559,7 @@ data class AppSettings( setNetCfg(net) } privacyEncryptLocalFiles?.let { def.privacyEncryptLocalFiles.set(it) } + privacyAskToApproveRelays?.let { def.privacyAskToApproveRelays.set(it) } privacyAcceptImages?.let { def.privacyAcceptImages.set(it) } privacyLinkPreviews?.let { def.privacyLinkPreviews.set(it) } privacyShowChatPreviews?.let { def.privacyShowChatPreviews.set(it) } @@ -5554,6 +5584,7 @@ data class AppSettings( get() = AppSettings( networkConfig = NetCfg.defaults, privacyEncryptLocalFiles = true, + privacyAskToApproveRelays = true, privacyAcceptImages = true, privacyLinkPreviews = true, privacyShowChatPreviews = true, @@ -5579,6 +5610,7 @@ data class AppSettings( return defaults.copy( networkConfig = getNetCfg(), privacyEncryptLocalFiles = def.privacyEncryptLocalFiles.get(), + privacyAskToApproveRelays = def.privacyAskToApproveRelays.get(), privacyAcceptImages = def.privacyAcceptImages.get(), privacyLinkPreviews = def.privacyLinkPreviews.get(), privacyShowChatPreviews = def.privacyShowChatPreviews.get(), diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIFileView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIFileView.kt index f079a152ab..a48bb2bb12 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIFileView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIFileView.kt @@ -1,6 +1,5 @@ package chat.simplex.common.views.chat.item -import androidx.compose.foundation.clickable import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.CornerSize @@ -64,7 +63,7 @@ fun CIFileView( fun fileAction() { if (file != null) { when { - file.fileStatus is CIFileStatus.RcvInvitation -> { + file.fileStatus is CIFileStatus.RcvInvitation || file.fileStatus is CIFileStatus.RcvAborted -> { if (fileSizeValid(file)) { receiveFile(file.fileId) } else { @@ -176,6 +175,8 @@ fun CIFileView( } else { progressIndicator() } + is CIFileStatus.RcvAborted -> + fileIcon(innerIcon = painterResource(MR.images.ic_sync_problem), color = MaterialTheme.colors.primary) is CIFileStatus.RcvComplete -> fileIcon() is CIFileStatus.RcvCancelled -> fileIcon(innerIcon = painterResource(MR.images.ic_close)) is CIFileStatus.RcvError -> fileIcon(innerIcon = painterResource(MR.images.ic_close)) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIImageView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIImageView.kt index 65fb38575d..7cffe4564b 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIImageView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIImageView.kt @@ -21,17 +21,12 @@ import chat.simplex.common.platform.* import chat.simplex.common.ui.theme.DEFAULT_MAX_IMAGE_WIDTH import chat.simplex.res.MR import dev.icerock.moko.resources.StringResource -import kotlinx.coroutines.flow.collect -import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.runBlocking -import java.io.File -import java.net.URI @Composable fun CIImageView( image: String, file: CIFile?, - metaColor: Color, imageProvider: () -> ImageGalleryProvider, showMenu: MutableState, receiveFile: (Long) -> Unit @@ -51,7 +46,7 @@ fun CIImageView( icon, stringResource(stringId), Modifier.fillMaxSize(), - tint = metaColor + tint = Color.White ) } @@ -78,6 +73,7 @@ fun CIImageView( is CIFileStatus.RcvInvitation -> fileIcon(painterResource(MR.images.ic_arrow_downward), MR.strings.icon_descr_asked_to_receive) is CIFileStatus.RcvAccepted -> fileIcon(painterResource(MR.images.ic_more_horiz), MR.strings.icon_descr_waiting_for_image) is CIFileStatus.RcvTransfer -> progressIndicator() + is CIFileStatus.RcvAborted -> fileIcon(painterResource(MR.images.ic_sync_problem), MR.strings.icon_descr_file) is CIFileStatus.RcvCancelled -> fileIcon(painterResource(MR.images.ic_close), MR.strings.icon_descr_file) is CIFileStatus.RcvError -> fileIcon(painterResource(MR.images.ic_close), MR.strings.icon_descr_file) is CIFileStatus.Invalid -> fileIcon(painterResource(MR.images.ic_question_mark), MR.strings.icon_descr_file) @@ -206,7 +202,7 @@ fun CIImageView( imageView(base64ToBitmap(image), onClick = { if (file != null) { when (file.fileStatus) { - CIFileStatus.RcvInvitation -> + CIFileStatus.RcvInvitation, CIFileStatus.RcvAborted -> if (fileSizeValid()) { receiveFile(file.fileId) } else { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIVIdeoView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIVIdeoView.kt index a79e509d02..749816f918 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIVIdeoView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIVIdeoView.kt @@ -73,7 +73,7 @@ fun CIVideoView( VideoPreviewImageView(preview, onClick = { if (file != null) { when (file.fileStatus) { - CIFileStatus.RcvInvitation -> + CIFileStatus.RcvInvitation, CIFileStatus.RcvAborted -> receiveFileIfValidSize(file, receiveFile) CIFileStatus.RcvAccepted -> when (file.fileProtocol) { @@ -102,7 +102,7 @@ fun CIVideoView( if (file != null) { DurationProgress(file, remember { mutableStateOf(false) }, remember { mutableStateOf(duration * 1000L) }, remember { mutableStateOf(0L) }/*, soundEnabled*/) } - if (file?.fileStatus is CIFileStatus.RcvInvitation) { + if (file?.fileStatus is CIFileStatus.RcvInvitation || file?.fileStatus is CIFileStatus.RcvAborted) { PlayButton(error = false, { showMenu.value = true }) { receiveFileIfValidSize(file, receiveFile) } } } @@ -396,6 +396,7 @@ private fun loadingIndicator(file: CIFile?) { } else { progressIndicator() } + is CIFileStatus.RcvAborted -> fileIcon(painterResource(MR.images.ic_sync_problem), MR.strings.icon_descr_file) is CIFileStatus.RcvCancelled -> fileIcon(painterResource(MR.images.ic_close), MR.strings.icon_descr_file) is CIFileStatus.RcvError -> fileIcon(painterResource(MR.images.ic_close), MR.strings.icon_descr_file) is CIFileStatus.Invalid -> fileIcon(painterResource(MR.images.ic_question_mark), MR.strings.icon_descr_file) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIVoiceView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIVoiceView.kt index cac89b2587..f973a6ea66 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIVoiceView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIVoiceView.kt @@ -22,6 +22,7 @@ import chat.simplex.common.views.helpers.* import chat.simplex.common.model.* import chat.simplex.common.platform.* import chat.simplex.res.MR +import dev.icerock.moko.resources.ImageResource import kotlinx.coroutines.flow.* // TODO refactor https://github.com/simplex-chat/simplex-chat/pull/1451#discussion_r1033429901 @@ -220,7 +221,8 @@ private fun PlayPauseButton( error: Boolean, play: () -> Unit, pause: () -> Unit, - longClick: () -> Unit + longClick: () -> Unit, + icon: ImageResource = MR.images.ic_play_arrow_filled, ) { val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage val receivedColor = CurrentColors.collectAsState().value.appColors.receivedMessage @@ -241,7 +243,7 @@ private fun PlayPauseButton( contentAlignment = Alignment.Center ) { Icon( - if (audioPlaying) painterResource(MR.images.ic_pause_filled) else painterResource(MR.images.ic_play_arrow_filled), + if (audioPlaying) painterResource(MR.images.ic_pause_filled) else painterResource(icon), contentDescription = null, Modifier.size(36.dp), tint = if (error) WarningOrange else if (!enabled) MaterialTheme.colors.secondary else MaterialTheme.colors.primary @@ -294,6 +296,8 @@ private fun VoiceMsgIndicator( ) { ProgressIndicator() } + } else if (file?.fileStatus is CIFileStatus.RcvAborted) { + PlayPauseButton(audioPlaying, sent, 0f, strokeWidth, strokeColor, true, error, { receiveFile(file.fileId) }, {}, longClick = longClick, icon = MR.images.ic_sync_problem) } else { PlayPauseButton(audioPlaying, sent, 0f, strokeWidth, strokeColor, false, false, {}, {}, longClick) } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/FramedItemView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/FramedItemView.kt index aec314d2c1..4dc0fd9cf5 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/FramedItemView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/FramedItemView.kt @@ -241,7 +241,7 @@ fun FramedItemView( } else { when (val mc = ci.content.msgContent) { is MsgContent.MCImage -> { - CIImageView(image = mc.image, file = ci.file, metaColor = metaColor, imageProvider ?: return@PriorityLayout, showMenu, receiveFile) + CIImageView(image = mc.image, file = ci.file, imageProvider ?: return@PriorityLayout, showMenu, receiveFile) if (mc.text == "" && !ci.meta.isLive) { metaColor = Color.White } else { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/PrivacySettings.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/PrivacySettings.kt index b376285259..dc0760193d 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/PrivacySettings.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/PrivacySettings.kt @@ -1,6 +1,7 @@ package chat.simplex.common.views.usersettings import SectionBottomSpacer +import SectionCustomFooter import SectionDividerSpaced import SectionItemView import SectionTextFooter @@ -63,10 +64,6 @@ fun PrivacySettingsView( SectionDividerSpaced() SectionView(stringResource(MR.strings.settings_section_title_chats)) { - SettingsPreferenceItem(painterResource(MR.images.ic_lock), stringResource(MR.strings.encrypt_local_files), chatModel.controller.appPrefs.privacyEncryptLocalFiles, onChange = { enable -> - withBGApi { chatModel.controller.apiSetEncryptLocalFiles(enable) } - }) - SettingsPreferenceItem(painterResource(MR.images.ic_image), stringResource(MR.strings.auto_accept_images), chatModel.controller.appPrefs.privacyAcceptImages) SettingsPreferenceItem(painterResource(MR.images.ic_travel_explore), stringResource(MR.strings.send_link_previews), chatModel.controller.appPrefs.privacyLinkPreviews) SettingsPreferenceItem( painterResource(MR.images.ic_chat_bubble), @@ -91,6 +88,22 @@ fun PrivacySettingsView( chatModel.simplexLinkMode.value = it }) } + SectionDividerSpaced() + + SectionView(stringResource(MR.strings.settings_section_title_files)) { + SettingsPreferenceItem(painterResource(MR.images.ic_lock), stringResource(MR.strings.encrypt_local_files), chatModel.controller.appPrefs.privacyEncryptLocalFiles, onChange = { enable -> + withBGApi { chatModel.controller.apiSetEncryptLocalFiles(enable) } + }) + SettingsPreferenceItem(painterResource(MR.images.ic_image), stringResource(MR.strings.auto_accept_images), chatModel.controller.appPrefs.privacyAcceptImages) + SettingsPreferenceItem(painterResource(MR.images.ic_security), stringResource(MR.strings.protect_ip_address), chatModel.controller.appPrefs.privacyAskToApproveRelays) + } + SectionCustomFooter { + if (chatModel.controller.appPrefs.privacyAskToApproveRelays.state.value) { + Text(stringResource(MR.strings.app_will_ask_to_confirm_unknown_file_servers)) + } else { + Text(stringResource(MR.strings.without_tor_or_vpn_ip_address_will_be_visible_to_file_servers)) + } + } val currentUser = chatModel.currentUser.value if (currentUser != null) { @@ -141,7 +154,7 @@ fun PrivacySettingsView( } if (!chatModel.desktopNoUserNoRemote) { - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true) DeliveryReceiptsSection( currentUser = currentUser, setOrAskSendReceiptsContacts = { enable -> diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml index 93e6a902f4..9308f5886e 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml @@ -119,6 +119,8 @@ Error joining group Cannot receive file Sender cancelled file transfer. + Unknown servers! + Without Tor or VPN, your IP address will be visible to these XFTP relays:\n%1$s. Error receiving file Error creating address Contact already exists @@ -992,6 +994,9 @@ Protect app screen Encrypt local files Auto-accept images + Protect IP address + The app will ask to confirm downloads from unknown file servers (except .onion or when SOCKS proxy is enabled). + Without Tor or VPN, your IP address will be visible to file servers. Send link previews Show last messages Message draft @@ -1056,6 +1061,7 @@ APP DEVICE CHATS + FILES SEND DELIVERY RECEIPTS TO Restart Shutdown From 423fc96638b6e7b76c134a936d793b4abfa6c0e6 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Mon, 20 May 2024 18:38:46 +0100 Subject: [PATCH 04/18] core: 5.8.0.2 (simplexmq 5.8.0.2) --- cabal.project | 2 +- package.yaml | 2 +- scripts/nix/sha256map.nix | 2 +- simplex-chat.cabal | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cabal.project b/cabal.project index 190c6e06e0..3595f999e3 100644 --- a/cabal.project +++ b/cabal.project @@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd source-repository-package type: git location: https://github.com/simplex-chat/simplexmq.git - tag: 2e5433676eaa5de93ed1ea9726706b9633308477 + tag: e3f5d244c1a435593e33adc023bf1f920f379f8d source-repository-package type: git diff --git a/package.yaml b/package.yaml index 64a6c15894..df815e75a8 100644 --- a/package.yaml +++ b/package.yaml @@ -1,5 +1,5 @@ name: simplex-chat -version: 5.8.0.1 +version: 5.8.0.2 #synopsis: #description: homepage: https://github.com/simplex-chat/simplex-chat#readme diff --git a/scripts/nix/sha256map.nix b/scripts/nix/sha256map.nix index 512638d454..a1f698fb4e 100644 --- a/scripts/nix/sha256map.nix +++ b/scripts/nix/sha256map.nix @@ -1,5 +1,5 @@ { - "https://github.com/simplex-chat/simplexmq.git"."2e5433676eaa5de93ed1ea9726706b9633308477" = "0ichdf5vsdizqxqy8amx3f5grx5sghiv2gajd2w3l73vnr2rv3bd"; + "https://github.com/simplex-chat/simplexmq.git"."e3f5d244c1a435593e33adc023bf1f920f379f8d" = "1klin78kgvgzdvf64nahn3280m7hw5f8wzrca43cmyajm2qp3wfs"; "https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38"; "https://github.com/simplex-chat/direct-sqlcipher.git"."f814ee68b16a9447fbb467ccc8f29bdd3546bfd9" = "1ql13f4kfwkbaq7nygkxgw84213i0zm7c1a8hwvramayxl38dq5d"; "https://github.com/simplex-chat/sqlcipher-simple.git"."a46bd361a19376c5211f1058908fc0ae6bf42446" = "1z0r78d8f0812kxbgsm735qf6xx8lvaz27k1a0b4a2m0sshpd5gl"; diff --git a/simplex-chat.cabal b/simplex-chat.cabal index 2b0a55bb68..96689b9f30 100644 --- a/simplex-chat.cabal +++ b/simplex-chat.cabal @@ -5,7 +5,7 @@ cabal-version: 1.12 -- see: https://github.com/sol/hpack name: simplex-chat -version: 5.8.0.1 +version: 5.8.0.2 category: Web, System, Services, Cryptography homepage: https://github.com/simplex-chat/simplex-chat#readme author: simplex.chat From c59eb06b8a9760d5d551eadd2b601e04b42bb9c4 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Mon, 20 May 2024 21:23:40 +0100 Subject: [PATCH 05/18] 5.8-beta.2: ios 218, android 210, desktop 47 --- apps/ios/SimpleX.xcodeproj/project.pbxproj | 52 +++++++++++----------- apps/multiplatform/gradle.properties | 8 ++-- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/apps/ios/SimpleX.xcodeproj/project.pbxproj b/apps/ios/SimpleX.xcodeproj/project.pbxproj index 31d4442bf0..3ea66b6087 100644 --- a/apps/ios/SimpleX.xcodeproj/project.pbxproj +++ b/apps/ios/SimpleX.xcodeproj/project.pbxproj @@ -76,11 +76,11 @@ 5C9CC7AD28C55D7800BEF955 /* DatabaseEncryptionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C9CC7AC28C55D7800BEF955 /* DatabaseEncryptionView.swift */; }; 5C9D13A3282187BB00AB8B43 /* WebRTC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C9D13A2282187BB00AB8B43 /* WebRTC.swift */; }; 5C9D811A2AA8727A001D49FD /* CryptoFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C9D81182AA7A4F1001D49FD /* CryptoFile.swift */; }; - 5C9F3DCC2BF7A6900003B86B /* libHSsimplex-chat-5.8.0.1-BrjXjAnJqNV7yWXU89n05g.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C9F3DC72BF7A6900003B86B /* libHSsimplex-chat-5.8.0.1-BrjXjAnJqNV7yWXU89n05g.a */; }; - 5C9F3DCD2BF7A6900003B86B /* libHSsimplex-chat-5.8.0.1-BrjXjAnJqNV7yWXU89n05g-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C9F3DC82BF7A6900003B86B /* libHSsimplex-chat-5.8.0.1-BrjXjAnJqNV7yWXU89n05g-ghc9.6.3.a */; }; - 5C9F3DCE2BF7A6900003B86B /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C9F3DC92BF7A6900003B86B /* libgmp.a */; }; - 5C9F3DCF2BF7A6900003B86B /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C9F3DCA2BF7A6900003B86B /* libgmpxx.a */; }; - 5C9F3DD02BF7A6900003B86B /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C9F3DCB2BF7A6900003B86B /* libffi.a */; }; + 5C9F3DD62BFBCDD90003B86B /* libHSsimplex-chat-5.8.0.2-8RkLdmy05dJBsgWrGV50Uf-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C9F3DD12BFBCDD80003B86B /* libHSsimplex-chat-5.8.0.2-8RkLdmy05dJBsgWrGV50Uf-ghc9.6.3.a */; }; + 5C9F3DD72BFBCDD90003B86B /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C9F3DD22BFBCDD80003B86B /* libffi.a */; }; + 5C9F3DD82BFBCDD90003B86B /* libHSsimplex-chat-5.8.0.2-8RkLdmy05dJBsgWrGV50Uf.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C9F3DD32BFBCDD80003B86B /* libHSsimplex-chat-5.8.0.2-8RkLdmy05dJBsgWrGV50Uf.a */; }; + 5C9F3DD92BFBCDD90003B86B /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C9F3DD42BFBCDD90003B86B /* libgmpxx.a */; }; + 5C9F3DDA2BFBCDD90003B86B /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C9F3DD52BFBCDD90003B86B /* libgmp.a */; }; 5C9FD96E27A5D6ED0075386C /* SendMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C9FD96D27A5D6ED0075386C /* SendMessageView.swift */; }; 5CA059DC279559F40002BEB4 /* Tests_iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CA059DB279559F40002BEB4 /* Tests_iOS.swift */; }; 5CA059DE279559F40002BEB4 /* Tests_iOSLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CA059DD279559F40002BEB4 /* Tests_iOSLaunchTests.swift */; }; @@ -354,11 +354,11 @@ 5C9CC7AC28C55D7800BEF955 /* DatabaseEncryptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatabaseEncryptionView.swift; sourceTree = ""; }; 5C9D13A2282187BB00AB8B43 /* WebRTC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebRTC.swift; sourceTree = ""; }; 5C9D81182AA7A4F1001D49FD /* CryptoFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CryptoFile.swift; sourceTree = ""; }; - 5C9F3DC72BF7A6900003B86B /* libHSsimplex-chat-5.8.0.1-BrjXjAnJqNV7yWXU89n05g.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.8.0.1-BrjXjAnJqNV7yWXU89n05g.a"; sourceTree = ""; }; - 5C9F3DC82BF7A6900003B86B /* libHSsimplex-chat-5.8.0.1-BrjXjAnJqNV7yWXU89n05g-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.8.0.1-BrjXjAnJqNV7yWXU89n05g-ghc9.6.3.a"; sourceTree = ""; }; - 5C9F3DC92BF7A6900003B86B /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = ""; }; - 5C9F3DCA2BF7A6900003B86B /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = ""; }; - 5C9F3DCB2BF7A6900003B86B /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = ""; }; + 5C9F3DD12BFBCDD80003B86B /* libHSsimplex-chat-5.8.0.2-8RkLdmy05dJBsgWrGV50Uf-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.8.0.2-8RkLdmy05dJBsgWrGV50Uf-ghc9.6.3.a"; sourceTree = ""; }; + 5C9F3DD22BFBCDD80003B86B /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = ""; }; + 5C9F3DD32BFBCDD80003B86B /* libHSsimplex-chat-5.8.0.2-8RkLdmy05dJBsgWrGV50Uf.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.8.0.2-8RkLdmy05dJBsgWrGV50Uf.a"; sourceTree = ""; }; + 5C9F3DD42BFBCDD90003B86B /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = ""; }; + 5C9F3DD52BFBCDD90003B86B /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = ""; }; 5C9FD96A27A56D4D0075386C /* JSON.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSON.swift; sourceTree = ""; }; 5C9FD96D27A5D6ED0075386C /* SendMessageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendMessageView.swift; sourceTree = ""; }; 5CA059C3279559F40002BEB4 /* SimpleXApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimpleXApp.swift; sourceTree = ""; }; @@ -529,13 +529,13 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 5C9F3DCF2BF7A6900003B86B /* libgmpxx.a in Frameworks */, + 5C9F3DD92BFBCDD90003B86B /* libgmpxx.a in Frameworks */, + 5C9F3DDA2BFBCDD90003B86B /* libgmp.a in Frameworks */, + 5C9F3DD82BFBCDD90003B86B /* libHSsimplex-chat-5.8.0.2-8RkLdmy05dJBsgWrGV50Uf.a in Frameworks */, 5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */, - 5C9F3DCE2BF7A6900003B86B /* libgmp.a in Frameworks */, - 5C9F3DCC2BF7A6900003B86B /* libHSsimplex-chat-5.8.0.1-BrjXjAnJqNV7yWXU89n05g.a in Frameworks */, - 5C9F3DD02BF7A6900003B86B /* libffi.a in Frameworks */, + 5C9F3DD62BFBCDD90003B86B /* libHSsimplex-chat-5.8.0.2-8RkLdmy05dJBsgWrGV50Uf-ghc9.6.3.a in Frameworks */, 5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */, - 5C9F3DCD2BF7A6900003B86B /* libHSsimplex-chat-5.8.0.1-BrjXjAnJqNV7yWXU89n05g-ghc9.6.3.a in Frameworks */, + 5C9F3DD72BFBCDD90003B86B /* libffi.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -601,11 +601,11 @@ 5C764E5C279C70B7000C6508 /* Libraries */ = { isa = PBXGroup; children = ( - 5C9F3DCB2BF7A6900003B86B /* libffi.a */, - 5C9F3DC92BF7A6900003B86B /* libgmp.a */, - 5C9F3DCA2BF7A6900003B86B /* libgmpxx.a */, - 5C9F3DC82BF7A6900003B86B /* libHSsimplex-chat-5.8.0.1-BrjXjAnJqNV7yWXU89n05g-ghc9.6.3.a */, - 5C9F3DC72BF7A6900003B86B /* libHSsimplex-chat-5.8.0.1-BrjXjAnJqNV7yWXU89n05g.a */, + 5C9F3DD22BFBCDD80003B86B /* libffi.a */, + 5C9F3DD52BFBCDD90003B86B /* libgmp.a */, + 5C9F3DD42BFBCDD90003B86B /* libgmpxx.a */, + 5C9F3DD12BFBCDD80003B86B /* libHSsimplex-chat-5.8.0.2-8RkLdmy05dJBsgWrGV50Uf-ghc9.6.3.a */, + 5C9F3DD32BFBCDD80003B86B /* libHSsimplex-chat-5.8.0.2-8RkLdmy05dJBsgWrGV50Uf.a */, ); path = Libraries; sourceTree = ""; @@ -1552,7 +1552,7 @@ CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 217; + CURRENT_PROJECT_VERSION = 218; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; @@ -1601,7 +1601,7 @@ CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 217; + CURRENT_PROJECT_VERSION = 218; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; @@ -1687,7 +1687,7 @@ CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 217; + CURRENT_PROJECT_VERSION = 218; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; GCC_OPTIMIZATION_LEVEL = s; @@ -1724,7 +1724,7 @@ CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 217; + CURRENT_PROJECT_VERSION = 218; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; ENABLE_CODE_COVERAGE = NO; @@ -1761,7 +1761,7 @@ CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES; CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 217; + CURRENT_PROJECT_VERSION = 218; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; DYLIB_COMPATIBILITY_VERSION = 1; @@ -1812,7 +1812,7 @@ CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES; CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 217; + CURRENT_PROJECT_VERSION = 218; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; DYLIB_COMPATIBILITY_VERSION = 1; diff --git a/apps/multiplatform/gradle.properties b/apps/multiplatform/gradle.properties index 05d63578e7..01e3b17296 100644 --- a/apps/multiplatform/gradle.properties +++ b/apps/multiplatform/gradle.properties @@ -26,11 +26,11 @@ android.enableJetifier=true kotlin.mpp.androidSourceSetLayoutVersion=2 kotlin.jvm.target=11 -android.version_name=5.8-beta.1 -android.version_code=209 +android.version_name=5.8-beta.2 +android.version_code=210 -desktop.version_name=5.8-beta.1 -desktop.version_code=46 +desktop.version_name=5.8-beta.2 +desktop.version_code=47 kotlin.version=1.9.23 gradle.plugin.version=8.2.0 From 9eb6034e1a9486bf1c0eb00f9e6df3e9ee7f10ac Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Wed, 22 May 2024 20:30:24 +0100 Subject: [PATCH 06/18] core: 5.7.4.0 (simplexmq 5.7.4.1: networking improvements) --- cabal.project | 2 +- package.yaml | 2 +- scripts/nix/sha256map.nix | 2 +- simplex-chat.cabal | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cabal.project b/cabal.project index 73ece133e4..c95e3c8f0c 100644 --- a/cabal.project +++ b/cabal.project @@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd source-repository-package type: git location: https://github.com/simplex-chat/simplexmq.git - tag: 1339a8da1105ae836b3804113498dabbdf5901ee + tag: 769e54db76fc33a04085410cdf78ae77ed9717b6 source-repository-package type: git diff --git a/package.yaml b/package.yaml index eba20290ef..fa4d066c6b 100644 --- a/package.yaml +++ b/package.yaml @@ -1,5 +1,5 @@ name: simplex-chat -version: 5.7.3.0 +version: 5.7.4.0 #synopsis: #description: homepage: https://github.com/simplex-chat/simplex-chat#readme diff --git a/scripts/nix/sha256map.nix b/scripts/nix/sha256map.nix index 23d7bdbaaf..40cfbdb8e0 100644 --- a/scripts/nix/sha256map.nix +++ b/scripts/nix/sha256map.nix @@ -1,5 +1,5 @@ { - "https://github.com/simplex-chat/simplexmq.git"."1339a8da1105ae836b3804113498dabbdf5901ee" = "0hkjcs2kv87vbj67rqp04a4l6qjqs4b0qcpwf0mw6f56lfps9751"; + "https://github.com/simplex-chat/simplexmq.git"."769e54db76fc33a04085410cdf78ae77ed9717b6" = "01bwy6hnkpp51jzdym8880462003npgzb2lns5946nww2smybrk6"; "https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38"; "https://github.com/simplex-chat/direct-sqlcipher.git"."f814ee68b16a9447fbb467ccc8f29bdd3546bfd9" = "1ql13f4kfwkbaq7nygkxgw84213i0zm7c1a8hwvramayxl38dq5d"; "https://github.com/simplex-chat/sqlcipher-simple.git"."a46bd361a19376c5211f1058908fc0ae6bf42446" = "1z0r78d8f0812kxbgsm735qf6xx8lvaz27k1a0b4a2m0sshpd5gl"; diff --git a/simplex-chat.cabal b/simplex-chat.cabal index 6d66e19696..86b2b9668e 100644 --- a/simplex-chat.cabal +++ b/simplex-chat.cabal @@ -5,7 +5,7 @@ cabal-version: 1.12 -- see: https://github.com/sol/hpack name: simplex-chat -version: 5.7.3.0 +version: 5.7.4.0 category: Web, System, Services, Cryptography homepage: https://github.com/simplex-chat/simplex-chat#readme author: simplex.chat From 096498278244793124c7fdfe10bf6328ad1d0683 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Thu, 23 May 2024 22:50:23 +0100 Subject: [PATCH 07/18] core: ensure that messages are sent to different members (#4221) * core: ensure that messages are sent to different members * update simplexmq --- cabal.project | 2 +- scripts/nix/sha256map.nix | 2 +- src/Simplex/Chat.hs | 37 +++++++++++++++++++++++-------------- src/Simplex/Chat/Archive.hs | 1 + src/Simplex/Chat/Util.hs | 30 ++++++++++++++++++++++++++++++ tests/ChatTests/Direct.hs | 7 ++++--- 6 files changed, 60 insertions(+), 19 deletions(-) diff --git a/cabal.project b/cabal.project index c95e3c8f0c..62764bb139 100644 --- a/cabal.project +++ b/cabal.project @@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd source-repository-package type: git location: https://github.com/simplex-chat/simplexmq.git - tag: 769e54db76fc33a04085410cdf78ae77ed9717b6 + tag: 6309f92c6860fce39d6675eb92fc460bdc3db01d source-repository-package type: git diff --git a/scripts/nix/sha256map.nix b/scripts/nix/sha256map.nix index 40cfbdb8e0..74286532bd 100644 --- a/scripts/nix/sha256map.nix +++ b/scripts/nix/sha256map.nix @@ -1,5 +1,5 @@ { - "https://github.com/simplex-chat/simplexmq.git"."769e54db76fc33a04085410cdf78ae77ed9717b6" = "01bwy6hnkpp51jzdym8880462003npgzb2lns5946nww2smybrk6"; + "https://github.com/simplex-chat/simplexmq.git"."6309f92c6860fce39d6675eb92fc460bdc3db01d" = "0aiyjcjraispkripv1viry6357nxvydv2sb6k5ali0hr8cnsskg3"; "https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38"; "https://github.com/simplex-chat/direct-sqlcipher.git"."f814ee68b16a9447fbb467ccc8f29bdd3546bfd9" = "1ql13f4kfwkbaq7nygkxgw84213i0zm7c1a8hwvramayxl38dq5d"; "https://github.com/simplex-chat/sqlcipher-simple.git"."a46bd361a19376c5211f1058908fc0ae6bf42446" = "1z0r78d8f0812kxbgsm735qf6xx8lvaz27k1a0b4a2m0sshpd5gl"; diff --git a/src/Simplex/Chat.hs b/src/Simplex/Chat.hs index d56e731246..55eecd499f 100644 --- a/src/Simplex/Chat.hs +++ b/src/Simplex/Chat.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE BangPatterns #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE FlexibleContexts #-} @@ -46,6 +47,7 @@ import qualified Data.List.NonEmpty as L import Data.Map.Strict (Map) import qualified Data.Map.Strict as M import Data.Maybe (catMaybes, fromMaybe, isJust, isNothing, listToMaybe, mapMaybe, maybeToList) +import qualified Data.Set as S import Data.Text (Text) import qualified Data.Text as T import Data.Text.Encoding (decodeLatin1, encodeUtf8) @@ -1681,7 +1683,7 @@ processChatCommand' vr = \case sndMsgs <- lift $ createSndMessages idsEvts let msgReqs_ :: NonEmpty (Either ChatError MsgReq) = L.zipWith (fmap . ctMsgReq) ctConns sndMsgs (errs, ctSndMsgs :: [(Contact, SndMessage)]) <- - lift $ partitionEithers . L.toList . zipWith3' combineResults ctConns sndMsgs <$> deliverMessagesB msgReqs_ + partitionEithers . L.toList . zipWith3' combineResults ctConns sndMsgs <$> deliverMessagesB msgReqs_ timestamp <- liftIO getCurrentTime lift . void $ withStoreBatch' $ \db -> map (createCI db user timestamp) ctSndMsgs pure CRBroadcastSent {user, msgContent = mc, successes = length ctSndMsgs, failures = length errs, timestamp} @@ -2378,7 +2380,7 @@ processChatCommand' vr = \case Just changedCts -> do let idsEvts = L.map ctSndEvent changedCts msgReqs_ <- lift $ L.zipWith ctMsgReq changedCts <$> createSndMessages idsEvts - (errs, cts) <- lift $ partitionEithers . L.toList . L.zipWith (second . const) changedCts <$> deliverMessagesB msgReqs_ + (errs, cts) <- partitionEithers . L.toList . L.zipWith (second . const) changedCts <$> deliverMessagesB msgReqs_ unless (null errs) $ toView $ CRChatErrors (Just user) errs let changedCts' = filter (\ChangedProfileContact {ct, ct'} -> directOrUsed ct' && mergedPreferences ct' /= mergedPreferences ct) cts lift $ createContactsSndFeatureItems user' changedCts' @@ -6471,21 +6473,21 @@ deliverMessage conn cmEventTag msgBody msgId = do deliverMessage' :: Connection -> MsgFlags -> MsgBody -> MessageId -> CM (Int64, PQEncryption) deliverMessage' conn msgFlags msgBody msgId = - lift (deliverMessages ((conn, msgFlags, msgBody, msgId) :| [])) >>= \case + deliverMessages ((conn, msgFlags, msgBody, msgId) :| []) >>= \case r :| [] -> liftEither r rs -> throwChatError $ CEInternalError $ "deliverMessage: expected 1 result, got " <> show (length rs) type MsgReq = (Connection, MsgFlags, MsgBody, MessageId) -deliverMessages :: NonEmpty MsgReq -> CM' (NonEmpty (Either ChatError (Int64, PQEncryption))) +deliverMessages :: NonEmpty MsgReq -> CM (NonEmpty (Either ChatError (Int64, PQEncryption))) deliverMessages msgs = deliverMessagesB $ L.map Right msgs -deliverMessagesB :: NonEmpty (Either ChatError MsgReq) -> CM' (NonEmpty (Either ChatError (Int64, PQEncryption))) +deliverMessagesB :: NonEmpty (Either ChatError MsgReq) -> CM (NonEmpty (Either ChatError (Int64, PQEncryption))) deliverMessagesB msgReqs = do msgReqs' <- liftIO compressBodies - sent <- L.zipWith prepareBatch msgReqs' <$> withAgent' (`sendMessagesB` L.map toAgent msgReqs') - void $ withStoreBatch' $ \db -> map (updatePQSndEnabled db) (rights . L.toList $ sent) - withStoreBatch $ \db -> L.map (bindRight $ createDelivery db) sent + sent <- L.zipWith prepareBatch msgReqs' <$> withAgent (`sendMessagesB` L.map toAgent msgReqs') + lift . void $ withStoreBatch' $ \db -> map (updatePQSndEnabled db) (rights . L.toList $ sent) + lift . withStoreBatch $ \db -> L.map (bindRight $ createDelivery db) sent where compressBodies = forME msgReqs $ \mr@(conn@Connection {pqSupport, connChatVersion = v}, msgFlags, msgBody, msgId) -> @@ -6544,10 +6546,11 @@ sendGroupMessage' user GroupInfo {groupId} members chatMsgEvent = do msg@SndMessage {msgId, msgBody} <- createSndMessage chatMsgEvent (GroupId groupId) recipientMembers <- liftIO $ shuffleMembers (filter memberCurrent members) let msgFlags = MsgFlags {notification = hasNotification $ toCMEventTag chatMsgEvent} - (toSend, pending) = foldr addMember ([], []) recipientMembers + (toSend, pending, _, dups) = foldr addMember ([], [], S.empty, 0 :: Int) recipientMembers -- TODO PQ either somehow ensure that group members connections cannot have pqSupport/pqEncryption or pass Off's here msgReqs = map (\(_, conn) -> (conn, msgFlags, msgBody, msgId)) toSend - delivered <- maybe (pure []) (fmap L.toList . lift . deliverMessages) $ L.nonEmpty msgReqs + when (dups /= 0) $ logError $ "sendGroupMessage: " <> tshow dups <> " duplicate members" + delivered <- maybe (pure []) (fmap L.toList . deliverMessages) $ L.nonEmpty msgReqs let errors = lefts delivered unless (null errors) $ toView $ CRChatErrors (Just user) errors stored <- lift . withStoreBatch' $ \db -> map (\m -> createPendingGroupMessage db (groupMemberId' m) msgId Nothing) pending @@ -6560,10 +6563,16 @@ sendGroupMessage' user GroupInfo {groupId} members chatMsgEvent = do liftM2 (<>) (shuffle adminMs) (shuffle otherMs) where isAdmin GroupMember {memberRole} = memberRole >= GRAdmin - addMember m (toSend, pending) = case memberSendAction chatMsgEvent members m of - Just (MSASend conn) -> ((m, conn) : toSend, pending) - Just MSAPending -> (toSend, m : pending) - Nothing -> (toSend, pending) + addMember m acc@(toSend, pending, !mIds, !dups) = case memberSendAction chatMsgEvent members m of + Just a + | mId `S.member` mIds -> (toSend, pending, mIds, dups + 1) + | otherwise -> case a of + MSASend conn -> ((m, conn) : toSend, pending, mIds', dups) + MSAPending -> (toSend, m : pending, mIds', dups) + Nothing -> acc + where + mId = groupMemberId' m + mIds' = S.insert mId mIds filterSent :: [Either ChatError a] -> [mem] -> (mem -> GroupMember) -> [GroupMember] filterSent rs ms mem = [mem m | (Right _, m) <- zip rs ms] diff --git a/src/Simplex/Chat/Archive.hs b/src/Simplex/Chat/Archive.hs index 8550c03438..01897de791 100644 --- a/src/Simplex/Chat/Archive.hs +++ b/src/Simplex/Chat/Archive.hs @@ -26,6 +26,7 @@ import Data.Text (Text) import qualified Data.Text as T import qualified Database.SQLite3 as SQL import Simplex.Chat.Controller +import Simplex.Chat.Util () import Simplex.Messaging.Agent.Client (agentClientStore) import Simplex.Messaging.Agent.Store.SQLite (SQLiteStore (..), closeSQLiteStore, keyString, sqlString, storeKey) import Simplex.Messaging.Util diff --git a/src/Simplex/Chat/Util.hs b/src/Simplex/Chat/Util.hs index 2b2bd599ae..3f7d19fd6d 100644 --- a/src/Simplex/Chat/Util.hs +++ b/src/Simplex/Chat/Util.hs @@ -1,10 +1,18 @@ +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE InstanceSigs #-} +{-# LANGUAGE RankNTypes #-} {-# LANGUAGE TupleSections #-} +{-# OPTIONS_GHC -Wno-orphans #-} module Simplex.Chat.Util (week, encryptFile, chunkSize, liftIOEither, shuffle) where +import Control.Exception (Exception) import Control.Monad import Control.Monad.Except import Control.Monad.IO.Class +import Control.Monad.IO.Unlift (MonadUnliftIO (..)) +import Control.Monad.Reader +import Data.Bifunctor (first) import qualified Data.ByteString.Lazy as LB import Data.List (sortBy) import Data.Ord (comparing) @@ -13,6 +21,7 @@ import Data.Word (Word16) import Simplex.Messaging.Crypto.File (CryptoFile (..), CryptoFileArgs (..)) import qualified Simplex.Messaging.Crypto.File as CF import System.Random (randomRIO) +import qualified UnliftIO.Exception as E import UnliftIO.IO (IOMode (..), withFile) week :: NominalDiffTime @@ -46,3 +55,24 @@ shuffle xs = map snd . sortBy (comparing fst) <$> mapM (\x -> (,x) <$> random) x liftIOEither :: (MonadIO m, MonadError e m) => IO (Either e a) -> m a liftIOEither a = liftIO a >>= liftEither {-# INLINE liftIOEither #-} + +newtype InternalException e = InternalException {unInternalException :: e} + deriving (Eq, Show) + +instance Exception e => Exception (InternalException e) + +instance Exception e => MonadUnliftIO (ExceptT e IO) where + {-# INLINE withRunInIO #-} + withRunInIO :: ((forall a. ExceptT e IO a -> IO a) -> IO b) -> ExceptT e IO b + withRunInIO inner = + ExceptT . fmap (first unInternalException) . E.try $ + withRunInIO $ \run -> + inner $ run . (either (E.throwIO . InternalException) pure <=< runExceptT) + +instance Exception e => MonadUnliftIO (ExceptT e (ReaderT r IO)) where + {-# INLINE withRunInIO #-} + withRunInIO :: ((forall a. ExceptT e (ReaderT r IO) a -> IO a) -> IO b) -> ExceptT e (ReaderT r IO) b + withRunInIO inner = + withExceptT unInternalException . ExceptT . E.try $ + withRunInIO $ \run -> + inner $ run . (either (E.throwIO . InternalException) pure <=< runExceptT) diff --git a/tests/ChatTests/Direct.hs b/tests/ChatTests/Direct.hs index 82eb4def39..1579dedaa7 100644 --- a/tests/ChatTests/Direct.hs +++ b/tests/ChatTests/Direct.hs @@ -185,9 +185,10 @@ testAddContact = versionTestMatrix2 runTestAddContact bob #$> ("/_read chat @2", id, "ok") alice #$> ("/read user", id, "ok") alice #$> ("/_read user 1", id, "ok") - features = if pqExpected - then chatFeatures - else (0, e2eeInfoNoPQStr) : tail chatFeatures + features = + if pqExpected + then chatFeatures + else (0, e2eeInfoNoPQStr) : tail chatFeatures testDuplicateContactsSeparate :: HasCallStack => FilePath -> IO () testDuplicateContactsSeparate = From 291df6e9d0bd75c2b6e1d06a7fce5e4574c8c865 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Fri, 24 May 2024 21:09:21 +0100 Subject: [PATCH 08/18] core: logging of chat events (#4216) * core: update simplexmq (persist server errors) * fix * same config * logging * logging 2 * log * log 2 * finally * catch better * more logs * logs * fix * more logging, context from PROHIBITED * warning * more logs * logs3 * logs4 * logs in simplexmq * log locks from simplemq * log queue size * log sendMessagesB in simplexmq * update simplexmq * logs5 * logs6 * logs7 * logs8 * logs8 * logs9 * logs10 * log11 * log12 * fix test * more logs * logging * clean up * refactor * simplify * tags * log level * remove network errors from the log * rename --- .../src/Directory/Events.hs | 12 ++- .../src/Directory/Service.hs | 1 + .../src/Directory/Store.hs | 13 +-- cabal.project | 2 +- package.yaml | 23 ++++- scripts/nix/sha256map.nix | 2 +- simplex-chat.cabal | 14 +-- src/Simplex/Chat.hs | 91 +++++++++++++------ src/Simplex/Chat/Controller.hs | 2 + src/Simplex/Chat/Messages.hs | 7 +- src/Simplex/Chat/Store/Messages.hs | 8 +- src/Simplex/Chat/View.hs | 6 +- tests/ChatClient.hs | 3 +- tests/ChatTests/Direct.hs | 12 +-- tests/ChatTests/Groups.hs | 4 +- tests/MobileTests.hs | 2 +- 16 files changed, 139 insertions(+), 63 deletions(-) diff --git a/apps/simplex-directory-service/src/Directory/Events.hs b/apps/simplex-directory-service/src/Directory/Events.hs index 87950ecce7..31a7e94aad 100644 --- a/apps/simplex-directory-service/src/Directory/Events.hs +++ b/apps/simplex-directory-service/src/Directory/Events.hs @@ -35,8 +35,10 @@ import Simplex.Chat.Messages.CIContent import Simplex.Chat.Protocol (MsgContent (..)) import Simplex.Chat.Types import Simplex.Chat.Types.Shared +import Simplex.Messaging.Agent.Protocol (AgentErrorType (..)) import Simplex.Messaging.Encoding.String -import Simplex.Messaging.Util ((<$?>)) +import Simplex.Messaging.Protocol (BrokerErrorType (..)) +import Simplex.Messaging.Util (tshow, (<$?>)) data DirectoryEvent = DEContactConnected Contact @@ -53,6 +55,7 @@ data DirectoryEvent | DEItemEditIgnored Contact | DEItemDeleteIgnored Contact | DEContactCommand Contact ChatItemId ADirectoryCmd + | DELogChatResponse Text deriving (Show) crDirectoryEvent :: ChatResponse -> Maybe DirectoryEvent @@ -77,6 +80,13 @@ crDirectoryEvent = \case where ciId = chatItemId' ci err = ADC SDRUser DCUnknownCommand + CRMessageError {severity, errorMessage} -> Just $ DELogChatResponse $ "message error: " <> severity <> ", " <> errorMessage + CRChatCmdError {chatError} -> Just $ DELogChatResponse $ "chat cmd error: " <> tshow chatError + CRChatError {chatError} -> case chatError of + ChatErrorAgent {agentError = BROKER _ NETWORK} -> Nothing + ChatErrorAgent {agentError = BROKER _ TIMEOUT} -> Nothing + _ -> Just $ DELogChatResponse $ "chat error: " <> tshow chatError + CRChatErrors {chatErrors} -> Just $ DELogChatResponse $ "chat errors: " <> T.intercalate ", " (map tshow chatErrors) _ -> Nothing data DirectoryRole = DRUser | DRSuperUser diff --git a/apps/simplex-directory-service/src/Directory/Service.hs b/apps/simplex-directory-service/src/Directory/Service.hs index eefb1f77a4..a61e405cb8 100644 --- a/apps/simplex-directory-service/src/Directory/Service.hs +++ b/apps/simplex-directory-service/src/Directory/Service.hs @@ -102,6 +102,7 @@ directoryService st DirectoryOpts {superUsers, serviceName, searchResults, testi case sUser of SDRUser -> deUserCommand env ct ciId cmd SDRSuperUser -> deSuperUserCommand ct ciId cmd + DELogChatResponse r -> logInfo r where withSuperUsers action = void . forkIO $ forM_ superUsers $ \KnownContact {contactId} -> action contactId notifySuperUsers s = withSuperUsers $ \contactId -> sendMessage' cc contactId s diff --git a/apps/simplex-directory-service/src/Directory/Store.hs b/apps/simplex-directory-service/src/Directory/Store.hs index 5082cab2ce..c810102e08 100644 --- a/apps/simplex-directory-service/src/Directory/Store.hs +++ b/apps/simplex-directory-service/src/Directory/Store.hs @@ -39,8 +39,8 @@ import Data.Text (Text) import Simplex.Chat.Types import Simplex.Messaging.Encoding.String import Simplex.Messaging.Util (ifM) -import System.IO (Handle, IOMode (..), openFile, BufferMode (..), hSetBuffering) -import System.Directory (renameFile, doesFileExist) +import System.Directory (doesFileExist, renameFile) +import System.IO (BufferMode (..), Handle, IOMode (..), hSetBuffering, openFile) data DirectoryStore = DirectoryStore { groupRegs :: TVar [GroupReg], @@ -112,7 +112,7 @@ addGroupReg st ct GroupInfo {groupId} grStatus = do let ugrId = 1 + foldl' maxUgrId 0 grs grData' = grData {userGroupRegId_ = ugrId} gr' = gr {userGroupRegId = ugrId} - in (grData', gr' : grs) + in (grData', gr' : grs) ctId = contactId' ct maxUgrId mx GroupReg {dbContactId, userGroupRegId} | dbContactId == ctId && userGroupRegId > mx = userGroupRegId @@ -311,14 +311,15 @@ readDirectoryData f = Right r -> case r of GRCreate gr@GroupRegData {dbGroupId_ = gId} -> do when (isJust $ M.lookup gId m) $ - putStrLn $ "Warning: duplicate group with ID " <> show gId <> ", group replaced." + putStrLn $ + "Warning: duplicate group with ID " <> show gId <> ", group replaced." pure $ M.insert gId gr m GRUpdateStatus gId groupRegStatus_ -> case M.lookup gId m of Just gr -> pure $ M.insert gId gr {groupRegStatus_} m - Nothing -> m <$ putStrLn ("Warning: no group with ID " <> show gId <>", status update ignored.") + Nothing -> m <$ putStrLn ("Warning: no group with ID " <> show gId <> ", status update ignored.") GRUpdateOwner gId grOwnerId -> case M.lookup gId m of Just gr -> pure $ M.insert gId gr {dbOwnerMemberId_ = Just grOwnerId} m - Nothing -> m <$ putStrLn ("Warning: no group with ID " <> show gId <>", owner update ignored.") + Nothing -> m <$ putStrLn ("Warning: no group with ID " <> show gId <> ", owner update ignored.") writeDirectoryData :: FilePath -> [GroupRegData] -> IO Handle writeDirectoryData f grs = do diff --git a/cabal.project b/cabal.project index 859f5ac1ac..a68df42bf7 100644 --- a/cabal.project +++ b/cabal.project @@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd source-repository-package type: git location: https://github.com/simplex-chat/simplexmq.git - tag: e7a73a4c89ed02e248e2d77e267037c9d4433820 + tag: bd67844169d2206d8543c01e6ed966315115b0e3 source-repository-package type: git diff --git a/package.yaml b/package.yaml index df815e75a8..d31a3086a4 100644 --- a/package.yaml +++ b/package.yaml @@ -152,12 +152,31 @@ tests: ghc-options: # - -haddock - -O2 - - -Wall + - -Weverything + - -Wno-missing-exported-signatures + - -Wno-missing-import-lists + - -Wno-missed-specialisations + - -Wno-all-missed-specialisations + - -Wno-unsafe + - -Wno-safe + - -Wno-missing-local-signatures + - -Wno-missing-kind-signatures + - -Wno-missing-deriving-strategies + - -Wno-monomorphism-restriction + - -Wno-prepositive-qualified-module + - -Wno-unused-packages + - -Wno-implicit-prelude + - -Wno-missing-safe-haskell-mode + - -Wno-missing-export-lists + - -Wno-partial-fields - -Wcompat + - -Werror=incomplete-record-updates - -Werror=incomplete-patterns + - -Werror=missing-methods + - -Werror=incomplete-uni-patterns + - -Werror=tabs - -Wredundant-constraints - -Wincomplete-record-updates - - -Wincomplete-uni-patterns - -Wunused-type-patterns default-extensions: diff --git a/scripts/nix/sha256map.nix b/scripts/nix/sha256map.nix index b4c90d8980..468ca71307 100644 --- a/scripts/nix/sha256map.nix +++ b/scripts/nix/sha256map.nix @@ -1,5 +1,5 @@ { - "https://github.com/simplex-chat/simplexmq.git"."e7a73a4c89ed02e248e2d77e267037c9d4433820" = "1zrsvnx8qnkvlxhkikl97bmi5nyian8wq20pn330159cviihfxl1"; + "https://github.com/simplex-chat/simplexmq.git"."bd67844169d2206d8543c01e6ed966315115b0e3" = "1g218q15hrg21h8gyidavfys5zx8dzmxq7iwfm5bfaw71grpd7pn"; "https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38"; "https://github.com/simplex-chat/direct-sqlcipher.git"."f814ee68b16a9447fbb467ccc8f29bdd3546bfd9" = "1ql13f4kfwkbaq7nygkxgw84213i0zm7c1a8hwvramayxl38dq5d"; "https://github.com/simplex-chat/sqlcipher-simple.git"."a46bd361a19376c5211f1058908fc0ae6bf42446" = "1z0r78d8f0812kxbgsm735qf6xx8lvaz27k1a0b4a2m0sshpd5gl"; diff --git a/simplex-chat.cabal b/simplex-chat.cabal index 96689b9f30..691baa7264 100644 --- a/simplex-chat.cabal +++ b/simplex-chat.cabal @@ -190,7 +190,7 @@ library src default-extensions: StrictData - ghc-options: -O2 -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns + ghc-options: -O2 -Weverything -Wno-missing-exported-signatures -Wno-missing-import-lists -Wno-missed-specialisations -Wno-all-missed-specialisations -Wno-unsafe -Wno-safe -Wno-missing-local-signatures -Wno-missing-kind-signatures -Wno-missing-deriving-strategies -Wno-monomorphism-restriction -Wno-prepositive-qualified-module -Wno-unused-packages -Wno-implicit-prelude -Wno-missing-safe-haskell-mode -Wno-missing-export-lists -Wno-partial-fields -Wcompat -Werror=incomplete-record-updates -Werror=incomplete-patterns -Werror=missing-methods -Werror=incomplete-uni-patterns -Werror=tabs -Wredundant-constraints -Wincomplete-record-updates -Wunused-type-patterns build-depends: aeson ==2.2.* , ansi-terminal >=0.10 && <0.12 @@ -252,7 +252,7 @@ executable simplex-bot apps/simplex-bot default-extensions: StrictData - ghc-options: -O2 -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns -threaded + ghc-options: -O2 -Weverything -Wno-missing-exported-signatures -Wno-missing-import-lists -Wno-missed-specialisations -Wno-all-missed-specialisations -Wno-unsafe -Wno-safe -Wno-missing-local-signatures -Wno-missing-kind-signatures -Wno-missing-deriving-strategies -Wno-monomorphism-restriction -Wno-prepositive-qualified-module -Wno-unused-packages -Wno-implicit-prelude -Wno-missing-safe-haskell-mode -Wno-missing-export-lists -Wno-partial-fields -Wcompat -Werror=incomplete-record-updates -Werror=incomplete-patterns -Werror=missing-methods -Werror=incomplete-uni-patterns -Werror=tabs -Wredundant-constraints -Wincomplete-record-updates -Wunused-type-patterns -threaded build-depends: aeson ==2.2.* , ansi-terminal >=0.10 && <0.12 @@ -315,7 +315,7 @@ executable simplex-bot-advanced apps/simplex-bot-advanced default-extensions: StrictData - ghc-options: -O2 -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns -threaded + ghc-options: -O2 -Weverything -Wno-missing-exported-signatures -Wno-missing-import-lists -Wno-missed-specialisations -Wno-all-missed-specialisations -Wno-unsafe -Wno-safe -Wno-missing-local-signatures -Wno-missing-kind-signatures -Wno-missing-deriving-strategies -Wno-monomorphism-restriction -Wno-prepositive-qualified-module -Wno-unused-packages -Wno-implicit-prelude -Wno-missing-safe-haskell-mode -Wno-missing-export-lists -Wno-partial-fields -Wcompat -Werror=incomplete-record-updates -Werror=incomplete-patterns -Werror=missing-methods -Werror=incomplete-uni-patterns -Werror=tabs -Wredundant-constraints -Wincomplete-record-updates -Wunused-type-patterns -threaded build-depends: aeson ==2.2.* , ansi-terminal >=0.10 && <0.12 @@ -381,7 +381,7 @@ executable simplex-broadcast-bot Broadcast.Bot Broadcast.Options Paths_simplex_chat - ghc-options: -O2 -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns -threaded + ghc-options: -O2 -Weverything -Wno-missing-exported-signatures -Wno-missing-import-lists -Wno-missed-specialisations -Wno-all-missed-specialisations -Wno-unsafe -Wno-safe -Wno-missing-local-signatures -Wno-missing-kind-signatures -Wno-missing-deriving-strategies -Wno-monomorphism-restriction -Wno-prepositive-qualified-module -Wno-unused-packages -Wno-implicit-prelude -Wno-missing-safe-haskell-mode -Wno-missing-export-lists -Wno-partial-fields -Wcompat -Werror=incomplete-record-updates -Werror=incomplete-patterns -Werror=missing-methods -Werror=incomplete-uni-patterns -Werror=tabs -Wredundant-constraints -Wincomplete-record-updates -Wunused-type-patterns -threaded build-depends: aeson ==2.2.* , ansi-terminal >=0.10 && <0.12 @@ -445,7 +445,7 @@ executable simplex-chat apps/simplex-chat default-extensions: StrictData - ghc-options: -O2 -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns -threaded + ghc-options: -O2 -Weverything -Wno-missing-exported-signatures -Wno-missing-import-lists -Wno-missed-specialisations -Wno-all-missed-specialisations -Wno-unsafe -Wno-safe -Wno-missing-local-signatures -Wno-missing-kind-signatures -Wno-missing-deriving-strategies -Wno-monomorphism-restriction -Wno-prepositive-qualified-module -Wno-unused-packages -Wno-implicit-prelude -Wno-missing-safe-haskell-mode -Wno-missing-export-lists -Wno-partial-fields -Wcompat -Werror=incomplete-record-updates -Werror=incomplete-patterns -Werror=missing-methods -Werror=incomplete-uni-patterns -Werror=tabs -Wredundant-constraints -Wincomplete-record-updates -Wunused-type-patterns -threaded build-depends: aeson ==2.2.* , ansi-terminal >=0.10 && <0.12 @@ -515,7 +515,7 @@ executable simplex-directory-service Directory.Service Directory.Store Paths_simplex_chat - ghc-options: -O2 -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns -threaded + ghc-options: -O2 -Weverything -Wno-missing-exported-signatures -Wno-missing-import-lists -Wno-missed-specialisations -Wno-all-missed-specialisations -Wno-unsafe -Wno-safe -Wno-missing-local-signatures -Wno-missing-kind-signatures -Wno-missing-deriving-strategies -Wno-monomorphism-restriction -Wno-prepositive-qualified-module -Wno-unused-packages -Wno-implicit-prelude -Wno-missing-safe-haskell-mode -Wno-missing-export-lists -Wno-partial-fields -Wcompat -Werror=incomplete-record-updates -Werror=incomplete-patterns -Werror=missing-methods -Werror=incomplete-uni-patterns -Werror=tabs -Wredundant-constraints -Wincomplete-record-updates -Wunused-type-patterns -threaded build-depends: aeson ==2.2.* , ansi-terminal >=0.10 && <0.12 @@ -610,7 +610,7 @@ test-suite simplex-chat-test apps/simplex-directory-service/src default-extensions: StrictData - ghc-options: -O2 -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Wunused-type-patterns -threaded + ghc-options: -O2 -Weverything -Wno-missing-exported-signatures -Wno-missing-import-lists -Wno-missed-specialisations -Wno-all-missed-specialisations -Wno-unsafe -Wno-safe -Wno-missing-local-signatures -Wno-missing-kind-signatures -Wno-missing-deriving-strategies -Wno-monomorphism-restriction -Wno-prepositive-qualified-module -Wno-unused-packages -Wno-implicit-prelude -Wno-missing-safe-haskell-mode -Wno-missing-export-lists -Wno-partial-fields -Wcompat -Werror=incomplete-record-updates -Werror=incomplete-patterns -Werror=missing-methods -Werror=incomplete-uni-patterns -Werror=tabs -Wredundant-constraints -Wincomplete-record-updates -Wunused-type-patterns -threaded build-depends: QuickCheck ==2.14.* , aeson ==2.2.* diff --git a/src/Simplex/Chat.hs b/src/Simplex/Chat.hs index 1165c7ccff..e259629d2b 100644 --- a/src/Simplex/Chat.hs +++ b/src/Simplex/Chat.hs @@ -229,6 +229,7 @@ newChatController smpAgent <- getSMPAgentClient aCfg {tbqSize} servers agentStore backgroundMode agentAsync <- newTVarIO Nothing random <- liftIO C.newRandom + eventSeq <- newTVarIO 0 inputQ <- newTBQueueIO tbqSize outputQ <- newTBQueueIO tbqSize connNetworkStatuses <- atomically TM.empty @@ -266,6 +267,7 @@ newChatController chatStore, chatStoreChanged, random, + eventSeq, inputQ, outputQ, connNetworkStatuses, @@ -3317,7 +3319,10 @@ deleteGroupLink_ user gInfo conn = do agentSubscriber :: CM' () agentSubscriber = do q <- asks $ subQ . smpAgent - forever $ atomically (readTBQueue q) >>= process + forever (atomically (readTBQueue q) >>= process) + `E.catchAny` \e -> do + toView' $ CRChatError Nothing $ ChatErrorAgent (CRITICAL True $ "Message reception stopped: " <> show e) Nothing + E.throwIO e where process :: (ACorrId, EntityId, APartyCmd 'Agent) -> CM' () process (corrId, entId, APC e msg) = run $ case e of @@ -3937,7 +3942,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = -- TODO only acknowledge without saving message? -- probably this branch is never executed, so there should be no reason -- to save message if contact hasn't been created yet - chat item isn't created anyway - withAckMessage' agentConnId meta $ + withAckMessage' "new contact msg" agentConnId meta $ void $ saveDirectRcvMSG conn meta msgBody SENT msgId _proxy -> @@ -3968,14 +3973,18 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = forM_ contData $ \(hostConnId, xGrpMemIntroCont) -> sendXGrpMemInv hostConnId (Just directConnReq) xGrpMemIntroCont CRContactUri _ -> throwChatError $ CECommandError "unexpected ConnectionRequestUri type" - MSG msgMeta _msgFlags msgBody -> - withAckMessage agentConnId msgMeta True $ do + MSG msgMeta _msgFlags msgBody -> do + tags <- newTVarIO [] + withAckMessage "contact msg" agentConnId msgMeta True (Just tags) $ \eInfo -> do let MsgMeta {pqEncryption} = msgMeta (ct', conn') <- updateContactPQRcv user ct conn pqEncryption checkIntegrityCreateItem (CDDirectRcv ct') msgMeta `catchChatError` \_ -> pure () (conn'', msg@RcvMessage {chatMsgEvent = ACME _ event}) <- saveDirectRcvMSG conn' msgMeta msgBody + let tag = toCMEventTag event + atomically $ writeTVar tags [tshow tag] + logInfo $ "contact msg=" <> tshow tag <> " " <> eInfo let ct'' = ct' {activeConn = Just conn''} :: Contact - assertDirectAllowed user MDRcv ct'' $ toCMEventTag event + assertDirectAllowed user MDRcv ct'' tag case event of XMsgNew mc -> newContentMessage ct'' mc msg msgMeta XMsgFileDescr sharedMsgId fileDescr -> messageFileDescription ct'' sharedMsgId fileDescr @@ -4000,9 +4009,9 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = BFileChunk sharedMsgId chunk -> bFileChunk ct'' sharedMsgId chunk msgMeta _ -> messageError $ "unsupported message: " <> T.pack (show event) let Contact {chatSettings = ChatSettings {sendRcpts}} = ct'' - pure $ fromMaybe (sendRcptsContacts user) sendRcpts && hasDeliveryReceipt (toCMEventTag event) + pure $ fromMaybe (sendRcptsContacts user) sendRcpts && hasDeliveryReceipt tag RCVD msgMeta msgRcpt -> - withAckMessage' agentConnId msgMeta $ + withAckMessage' "contact rcvd" agentConnId msgMeta $ directMsgReceived ct conn msgMeta msgRcpt CONF confId pqSupport _ connInfo -> do conn' <- processCONFpqSupport conn pqSupport @@ -4381,19 +4390,26 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = void $ sendDirectMemberMessage imConn (XGrpMemCon memberId) groupId _ -> messageWarning "sendXGrpMemCon: member category GCPreMember or GCPostMember is expected" MSG msgMeta _msgFlags msgBody -> do - withAckMessage agentConnId msgMeta True $ do + tags <- newTVarIO [] + withAckMessage "group msg" agentConnId msgMeta True (Just tags) $ \eInfo -> do checkIntegrityCreateItem (CDGroupRcv gInfo m) msgMeta `catchChatError` \_ -> pure () forM_ aChatMsgs $ \case Right (ACMsg _ chatMsg) -> - processEvent chatMsg `catchChatError` \e -> toView $ CRChatError (Just user) e - Left e -> toView $ CRChatError (Just user) (ChatError . CEException $ "error parsing chat message: " <> e) - forwardMsg_ `catchChatError` \_ -> pure () + processEvent tags eInfo chatMsg `catchChatError` \e -> toView $ CRChatError (Just user) e + Left e -> do + atomically $ modifyTVar' tags ("error" :) + logInfo $ "group msg=error " <> eInfo <> " " <> tshow e + toView $ CRChatError (Just user) (ChatError . CEException $ "error parsing chat message: " <> e) + forwardMsg_ `catchChatError` (toView . CRChatError (Just user)) checkSendRcpt $ rights aChatMsgs where aChatMsgs = parseChatMessages msgBody brokerTs = metaBrokerTs msgMeta - processEvent :: MsgEncodingI e => ChatMessage e -> CM () - processEvent chatMsg = do + processEvent :: TVar [Text] -> Text -> MsgEncodingI e => ChatMessage e -> CM () + processEvent tags eInfo chatMsg@ChatMessage {chatMsgEvent} = do + let tag = toCMEventTag chatMsgEvent + atomically $ modifyTVar' tags (tshow tag :) + logInfo $ "group msg=" <> tshow tag <> " " <> eInfo (m', conn', msg@RcvMessage {chatMsgEvent = ACME _ event}) <- saveGroupRcvMsg user groupId m conn msgMeta msgBody chatMsg case event of XMsgNew mc -> memberCanSend m' $ newGroupContentMessage gInfo m' mc msg brokerTs False @@ -4424,7 +4440,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = XInfoProbeCheck probeHash -> xInfoProbeCheck (COMGroupMember m') probeHash XInfoProbeOk probe -> xInfoProbeOk (COMGroupMember m') probe BFileChunk sharedMsgId chunk -> bFileChunkGroup gInfo sharedMsgId chunk msgMeta - _ -> messageError $ "unsupported message: " <> T.pack (show event) + _ -> messageError $ "unsupported message: " <> tshow event checkSendRcpt :: [AChatMessage] -> CM Bool checkSendRcpt aMsgs = do currentMemCount <- withStore' $ \db -> getGroupCurrentMembersCount db user gInfo @@ -4458,7 +4474,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = sendGroupMessage' user gInfo ms msg _ -> pure () RCVD msgMeta msgRcpt -> - withAckMessage' agentConnId msgMeta $ + withAckMessage' "group rcvd" agentConnId msgMeta $ groupMsgReceived gInfo m conn msgMeta msgRcpt SENT msgId proxy -> do sentMsgDeliveryEvent conn msgId @@ -4582,7 +4598,8 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = lookupChatItemByFileId db vr user fileId toView $ CRSndFileRcvCancelled user ci ft _ -> throwChatError $ CEFileSend fileId err - MSG meta _ _ -> withAckMessage' agentConnId meta $ pure () + MSG meta _ _ -> + withAckMessage' "file msg" agentConnId meta $ pure () OK -> -- [async agent commands] continuation on receiving OK when (corrId /= "") $ withCompletedCommand conn agentMsg $ \_cmdData -> pure () @@ -4658,7 +4675,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = RcvChunkOk -> if B.length chunk /= fromInteger chunkSize then badRcvFileChunk ft "incorrect chunk size" - else withAckMessage' agentConnId meta $ appendFileChunk ft chunkNo chunk False + else withAckMessage' "file msg" agentConnId meta $ appendFileChunk ft chunkNo chunk False RcvChunkFinal -> if B.length chunk > fromInteger chunkSize then badRcvFileChunk ft "incorrect chunk size" @@ -4672,7 +4689,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = getChatItemByFileId db vr user fileId toView $ CRRcvFileComplete user ci forM_ conn_ $ \conn -> deleteAgentConnectionAsync user (aConnId conn) - RcvChunkDuplicate -> withAckMessage' agentConnId meta $ pure () + RcvChunkDuplicate -> withAckMessage' "file msg" agentConnId meta $ pure () RcvChunkError -> badRcvFileChunk ft $ "incorrect chunk number " <> show chunkNo processUserContactRequest :: ACommand 'Agent e -> ConnectionEntity -> Connection -> UserContact -> CM () @@ -4756,25 +4773,45 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = withStore' $ \db -> updateCommandStatus db user cmdId CSError throwChatError . CEAgentCommandError $ msg - withAckMessage' :: ConnId -> MsgMeta -> CM () -> CM () - withAckMessage' cId msgMeta action = do - withAckMessage cId msgMeta False $ action $> False + withAckMessage' :: Text -> ConnId -> MsgMeta -> CM () -> CM () + withAckMessage' label cId msgMeta action = do + withAckMessage label cId msgMeta False Nothing $ \_ -> action $> False - withAckMessage :: ConnId -> MsgMeta -> Bool -> CM Bool -> CM () - withAckMessage cId msgMeta showCritical action = + withAckMessage :: Text -> ConnId -> MsgMeta -> Bool -> Maybe (TVar [Text]) -> (Text -> CM Bool) -> CM () + withAckMessage label cId msgMeta showCritical tags action = do -- [async agent commands] command should be asynchronous -- TODO catching error and sending ACK after an error, particularly if it is a database error, will result in the message not processed (and no notification to the user). -- Possible solutions are: -- 1) retry processing several times -- 2) stabilize database -- 3) show screen of death to the user asking to restart - tryChatError action >>= \case - Right withRcpt -> ackMsg msgMeta $ if withRcpt then Just "" else Nothing + eInfo <- eventInfo + logInfo $ label <> ": " <> eInfo + tryChatError (action eInfo) >>= \case + Right withRcpt -> + withLog (eInfo <> " ok") $ ackMsg msgMeta $ if withRcpt then Just "" else Nothing -- If showCritical is True, then these errors don't result in ACK and show user visible alert -- This prevents losing the message that failed to be processed. Left (ChatErrorStore SEDBBusyError {message}) | showCritical -> throwError $ ChatErrorAgent (CRITICAL True message) Nothing - Left e -> ackMsg msgMeta Nothing >> throwError e + Left e -> do + withLog (eInfo <> " error: " <> tshow e) $ ackMsg msgMeta Nothing + throwError e where + eventInfo = do + v <- asks eventSeq + eId <- atomically $ stateTVar v $ \i -> (i + 1, i + 1) + pure $ "conn_id=" <> tshow cId <> " event_id=" <> tshow eId + withLog eInfo' ack = do + ts <- showTags + logInfo $ T.unwords [label, "ack:", ts, eInfo'] + ack + logInfo $ T.unwords [label, "ack=success:", ts, eInfo'] + showTags = do + ts <- maybe (pure []) readTVarIO tags + pure $ case ts of + [] -> "no_chat_messages" + [t] -> "chat_message=" <> t + _ -> "chat_message_batch=" <> T.intercalate "," (reverse ts) ackMsg :: MsgMeta -> Maybe MsgReceiptInfo -> CM () ackMsg MsgMeta {recipient = (msgId, _)} rcpt = withAgent $ \a -> ackMessageAsync a "" cId msgId rcpt @@ -6608,6 +6645,8 @@ deliverMessagesB msgReqs = do where updatePQ = updateConnPQSndEnabled db connId pqSndEnabled' +-- TODO combine profile update and message into one batch +-- Take into account that it may not fit, and that we currently don't support sending multiple messages to the same connection in one call. sendGroupMessage :: MsgEncodingI e => User -> GroupInfo -> [GroupMember] -> ChatMsgEvent e -> CM (SndMessage, [GroupMember]) sendGroupMessage user gInfo members chatMsgEvent = do when shouldSendProfileUpdate $ diff --git a/src/Simplex/Chat/Controller.hs b/src/Simplex/Chat/Controller.hs index 9ff903514f..2c4c09c79c 100644 --- a/src/Simplex/Chat/Controller.hs +++ b/src/Simplex/Chat/Controller.hs @@ -13,6 +13,7 @@ {-# LANGUAGE StrictData #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeApplications #-} +{-# OPTIONS_GHC -fno-warn-implicit-lift #-} module Simplex.Chat.Controller where @@ -205,6 +206,7 @@ data ChatController = ChatController chatStore :: SQLiteStore, chatStoreChanged :: TVar Bool, -- if True, chat should be fully restarted random :: TVar ChaChaDRG, + eventSeq :: TVar Int, inputQ :: TBQueue String, outputQ :: TBQueue (Maybe CorrId, Maybe RemoteHostId, ChatResponse), connNetworkStatuses :: TMap AgentConnId NetworkStatus, diff --git a/src/Simplex/Chat/Messages.hs b/src/Simplex/Chat/Messages.hs index 449731b91c..9742439fb3 100644 --- a/src/Simplex/Chat/Messages.hs +++ b/src/Simplex/Chat/Messages.hs @@ -14,6 +14,7 @@ {-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -fno-warn-ambiguous-fields #-} +{-# OPTIONS_GHC -fno-warn-operator-whitespace #-} module Simplex.Chat.Messages where @@ -455,10 +456,10 @@ deriving instance Show ACIReaction data JSONCIReaction c d = JSONCIReaction {chatInfo :: ChatInfo c, chatReaction :: CIReaction c d} type family ChatTypeQuotable (a :: ChatType) :: Constraint where - ChatTypeQuotable CTDirect = () - ChatTypeQuotable CTGroup = () + ChatTypeQuotable 'CTDirect = () + ChatTypeQuotable 'CTGroup = () ChatTypeQuotable a = - (Int ~ Bool, TypeError (Type.Text "ChatType " :<>: ShowType a :<>: Type.Text " cannot be quoted")) + (Int ~ Bool, TypeError ('Type.Text "ChatType " ':<>: 'ShowType a ':<>: 'Type.Text " cannot be quoted")) data CIQDirection (c :: ChatType) where CIQDirectSnd :: CIQDirection 'CTDirect diff --git a/src/Simplex/Chat/Store/Messages.hs b/src/Simplex/Chat/Store/Messages.hs index b0a0495c16..0487b80c17 100644 --- a/src/Simplex/Chat/Store/Messages.hs +++ b/src/Simplex/Chat/Store/Messages.hs @@ -838,7 +838,7 @@ toLocalChatItem currentTs ((itemId, itemTs, AMsgDirection msgDir, itemContentTex ciMeta content status = let itemDeleted' = case itemDeleted of DBCINotDeleted -> Nothing - _ -> Just (CIDeleted @CTLocal deletedTs) + _ -> Just (CIDeleted @'CTLocal deletedTs) itemEdited' = fromMaybe False itemEdited itemForwarded = toCIForwardedFrom forwardedFromRow in mkCIMeta itemId content itemText status sentViaProxy sharedMsgId itemForwarded itemDeleted' itemEdited' ciTimed itemLive currentTs itemTs Nothing createdAt updatedAt @@ -1458,7 +1458,7 @@ toDirectChatItem currentTs (((itemId, itemTs, AMsgDirection msgDir, itemContentT ciMeta content status = let itemDeleted' = case itemDeleted of DBCINotDeleted -> Nothing - _ -> Just (CIDeleted @CTDirect deletedTs) + _ -> Just (CIDeleted @'CTDirect deletedTs) itemEdited' = fromMaybe False itemEdited itemForwarded = toCIForwardedFrom forwardedFromRow in mkCIMeta itemId content itemText status sentViaProxy sharedMsgId itemForwarded itemDeleted' itemEdited' ciTimed itemLive currentTs itemTs Nothing createdAt updatedAt @@ -1520,7 +1520,7 @@ toGroupChatItem currentTs userContactId (((itemId, itemTs, AMsgDirection msgDir, DBCINotDeleted -> Nothing DBCIBlocked -> Just (CIBlocked deletedTs) DBCIBlockedByAdmin -> Just (CIBlockedByAdmin deletedTs) - _ -> Just (maybe (CIDeleted @CTGroup deletedTs) (CIModerated deletedTs) deletedByGroupMember_) + _ -> Just (maybe (CIDeleted @'CTGroup deletedTs) (CIModerated deletedTs) deletedByGroupMember_) itemEdited' = fromMaybe False itemEdited itemForwarded = toCIForwardedFrom forwardedFromRow in mkCIMeta itemId content itemText status sentViaProxy sharedMsgId itemForwarded itemDeleted' itemEdited' ciTimed itemLive currentTs itemTs forwardedByMember createdAt updatedAt @@ -1919,7 +1919,7 @@ markGroupChatItemDeleted db User {userId} GroupInfo {groupId} ci@ChatItem {meta} let itemId = chatItemId' ci (deletedByGroupMemberId, itemDeleted) = case byGroupMember_ of Just m@GroupMember {groupMemberId} -> (Just groupMemberId, Just $ CIModerated (Just deletedTs) m) - _ -> (Nothing, Just $ CIDeleted @CTGroup (Just deletedTs)) + _ -> (Nothing, Just $ CIDeleted @'CTGroup (Just deletedTs)) insertChatItemMessage_ db itemId msgId currentTs DB.execute db diff --git a/src/Simplex/Chat/View.hs b/src/Simplex/Chat/View.hs index 1c2b0b2cc1..08980f21d2 100644 --- a/src/Simplex/Chat/View.hs +++ b/src/Simplex/Chat/View.hs @@ -2028,14 +2028,16 @@ viewChatError logLevel testView = \case DBErrorOpen e -> ["error opening database after encryption: " <> sqliteError' e] e -> ["chat database error: " <> sShow e] ChatErrorAgent err entity_ -> case err of - CMD PROHIBITED -> [withConnEntity <> "error: command is prohibited"] + CMD PROHIBITED cxt -> [withConnEntity <> plain ("error: command is prohibited, " <> cxt)] SMP _ SMP.AUTH -> [ withConnEntity <> "error: connection authorization failed - this could happen if connection was deleted,\ \ secured with different credentials, or due to a bug - please re-create the connection" ] + BROKER _ NETWORK -> [] + BROKER _ TIMEOUT -> [] AGENT A_DUPLICATE -> [withConnEntity <> "error: AGENT A_DUPLICATE" | logLevel == CLLDebug] - AGENT A_PROHIBITED -> [withConnEntity <> "error: AGENT A_PROHIBITED" | logLevel <= CLLWarning] + AGENT (A_PROHIBITED e) -> [withConnEntity <> "error: AGENT A_PROHIBITED, " <> plain e | logLevel <= CLLWarning] CONN NOT_FOUND -> [withConnEntity <> "error: CONN NOT_FOUND" | logLevel <= CLLWarning] CRITICAL restart e -> [plain $ "critical error: " <> e] <> ["please restart the app" | restart] INTERNAL e -> [plain $ "internal error: " <> e] diff --git a/tests/ChatClient.hs b/tests/ChatClient.hs index 2bcd52ab3f..83ac69ebe9 100644 --- a/tests/ChatClient.hs +++ b/tests/ChatClient.hs @@ -431,7 +431,8 @@ serverCfg = smpHandshakeTimeout = 1000000, controlPort = Nothing, smpAgentCfg = defaultSMPClientAgentConfig, - allowSMPProxy = False + allowSMPProxy = False, + serverClientConcurrency = 16 } withSmpServer :: IO () -> IO () diff --git a/tests/ChatTests/Direct.hs b/tests/ChatTests/Direct.hs index 2e549d9dd1..24281ae830 100644 --- a/tests/ChatTests/Direct.hs +++ b/tests/ChatTests/Direct.hs @@ -2310,12 +2310,12 @@ testAbortSwitchContact tmp = do alice <## "bob: you started changing address" -- repeat switch is prohibited alice ##> "/switch bob" - alice <## "error: command is prohibited" + alice <## "error: command is prohibited, switchConnectionAsync: already switching" -- stop switch alice #$> ("/abort switch bob", id, "switch aborted") -- repeat switch stop is prohibited alice ##> "/abort switch bob" - alice <## "error: command is prohibited" + alice <## "error: command is prohibited, abortConnectionSwitch: not allowed" withTestChatContactConnected tmp "bob" $ \bob -> do bob <## "alice started changing address for you" -- alice changes address again @@ -2356,12 +2356,12 @@ testAbortSwitchGroupMember tmp = do alice <## "#team: you started changing address for bob" -- repeat switch is prohibited alice ##> "/switch #team bob" - alice <## "error: command is prohibited" + alice <## "error: command is prohibited, switchConnectionAsync: already switching" -- stop switch alice #$> ("/abort switch #team bob", id, "switch aborted") -- repeat switch stop is prohibited alice ##> "/abort switch #team bob" - alice <## "error: command is prohibited" + alice <## "error: command is prohibited, abortConnectionSwitch: not allowed" withTestChatContactConnected tmp "bob" $ \bob -> do bob <## "#team: connected to server(s)" bob <## "#team: alice started changing address for you" @@ -2485,7 +2485,7 @@ setupDesynchronizedRatchet tmp alice = do withTestChat tmp "bob_old" $ \bob -> do bob <## "1 contacts connected (use /cs for the list)" bob ##> "/sync alice" - bob <## "error: command is prohibited" + bob <## "error: command is prohibited, synchronizeRatchet: not allowed" alice #> "@bob 1" bob <## "alice: decryption error (connection out of sync), synchronization required" bob <## "use /sync alice to synchronize" @@ -2495,7 +2495,7 @@ setupDesynchronizedRatchet tmp alice = do bob ##> "/tail @alice 1" bob <# "alice> decryption error, possibly due to the device change (header, 3 messages)" bob ##> "@alice 1" - bob <## "error: command is prohibited" + bob <## "error: command is prohibited, sendMessagesB: send prohibited" (alice "/sync #team alice" - bob <## "error: command is prohibited" + bob <## "error: command is prohibited, synchronizeRatchet: not allowed" alice #> "#team 1" bob <## "#team alice: decryption error (connection out of sync), synchronization required" bob <## "use /sync #team alice to synchronize" @@ -3294,7 +3294,7 @@ testGroupSyncRatchet tmp = bob <## "1 contacts connected (use /cs for the list)" bob <## "#team: connected to server(s)" bob `send` "#team 1" - bob <## "error: command is prohibited" -- silence? + bob <## "error: command is prohibited, sendMessagesB: send prohibited" -- silence? bob <# "#team 1" (alice copyBytes toPtr (ptr' `plusPtr` 5) sz' contents `shouldBe` src - sz' `shouldBe` fromIntegral len + sz' `shouldBe` len testMissingFileCApi :: FilePath -> IO () testMissingFileCApi tmp = do From 23581f59aeaf308015a711558d8985e03ccaa581 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Fri, 24 May 2024 21:33:45 +0100 Subject: [PATCH 09/18] core: 5.8.0.3 --- package.yaml | 2 +- simplex-chat.cabal | 2 +- src/Simplex/Chat/Remote.hs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.yaml b/package.yaml index d31a3086a4..39410d16e0 100644 --- a/package.yaml +++ b/package.yaml @@ -1,5 +1,5 @@ name: simplex-chat -version: 5.8.0.2 +version: 5.8.0.3 #synopsis: #description: homepage: https://github.com/simplex-chat/simplex-chat#readme diff --git a/simplex-chat.cabal b/simplex-chat.cabal index 691baa7264..11c0cc0731 100644 --- a/simplex-chat.cabal +++ b/simplex-chat.cabal @@ -5,7 +5,7 @@ cabal-version: 1.12 -- see: https://github.com/sol/hpack name: simplex-chat -version: 5.8.0.2 +version: 5.8.0.3 category: Web, System, Services, Cryptography homepage: https://github.com/simplex-chat/simplex-chat#readme author: simplex.chat diff --git a/src/Simplex/Chat/Remote.hs b/src/Simplex/Chat/Remote.hs index e8d13402ef..5b98ea119c 100644 --- a/src/Simplex/Chat/Remote.hs +++ b/src/Simplex/Chat/Remote.hs @@ -72,11 +72,11 @@ import UnliftIO.Directory (copyFile, createDirectoryIfMissing, doesDirectoryExis -- when acting as host minRemoteCtrlVersion :: AppVersion -minRemoteCtrlVersion = AppVersion [5, 7, 0, 3] +minRemoteCtrlVersion = AppVersion [5, 8, 0, 2] -- when acting as controller minRemoteHostVersion :: AppVersion -minRemoteHostVersion = AppVersion [5, 7, 0, 3] +minRemoteHostVersion = AppVersion [5, 8, 0, 2] currentAppVersion :: AppVersion currentAppVersion = AppVersion SC.version From ab47a5a27e76620d11edefcea257fc3773cb059a Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Fri, 24 May 2024 22:59:37 +0100 Subject: [PATCH 10/18] Revert "ui: comment smp proxy ui (#4204)" This reverts commit a0d6ae15ab10b711b596ca3d5052e3950aee43c3. --- .../UserSettings/NetworkAndServers.swift | 46 +++++++++---------- .../views/usersettings/NetworkAndServers.kt | 22 ++++----- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/apps/ios/Shared/Views/UserSettings/NetworkAndServers.swift b/apps/ios/Shared/Views/UserSettings/NetworkAndServers.swift index 54a4ef1489..6d849479e5 100644 --- a/apps/ios/Shared/Views/UserSettings/NetworkAndServers.swift +++ b/apps/ios/Shared/Views/UserSettings/NetworkAndServers.swift @@ -82,29 +82,29 @@ struct NetworkAndServers: View { Text("Using .onion hosts requires compatible VPN provider.") } -// Section { -// Picker("Private routing", selection: $proxyMode) { -// ForEach(SMPProxyMode.values, id: \.self) { Text($0.text) } -// } -// .frame(height: 36) -// -// Picker("Allow downgrade", selection: $proxyFallback) { -// ForEach(SMPProxyFallback.values, id: \.self) { Text($0.text) } -// } -// .disabled(proxyMode == .never) -// .frame(height: 36) -// -// Toggle("Show message status", isOn: $showSentViaProxy) -// } header: { -// Text("Private message routing") -// } footer: { -// VStack(alignment: .leading) { -// Text("To protect your IP address, private routing uses your SMP servers to deliver messages.") -// if showSentViaProxy { -// Text("Show → on messages sent via private routing.") -// } -// } -// } + Section { + Picker("Private routing", selection: $proxyMode) { + ForEach(SMPProxyMode.values, id: \.self) { Text($0.text) } + } + .frame(height: 36) + + Picker("Allow downgrade", selection: $proxyFallback) { + ForEach(SMPProxyFallback.values, id: \.self) { Text($0.text) } + } + .disabled(proxyMode == .never) + .frame(height: 36) + + Toggle("Show message status", isOn: $showSentViaProxy) + } header: { + Text("Private message routing") + } footer: { + VStack(alignment: .leading) { + Text("To protect your IP address, private routing uses your SMP servers to deliver messages.") + if showSentViaProxy { + Text("Show → on messages sent via private routing.") + } + } + } Section("Calls") { NavigationLink { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NetworkAndServers.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NetworkAndServers.kt index b2124df988..d07fad8623 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NetworkAndServers.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NetworkAndServers.kt @@ -250,17 +250,17 @@ fun NetworkAndServersView() { Divider(Modifier.padding(start = DEFAULT_PADDING_HALF, top = 24.dp, end = DEFAULT_PADDING_HALF, bottom = 30.dp)) } -// if (currentRemoteHost == null) { -// SectionView(generalGetString(MR.strings.settings_section_title_private_message_routing)) { -// SMPProxyModePicker(smpProxyMode, showModal, updateSMPProxyMode) -// SMPProxyFallbackPicker(smpProxyFallback, showModal, updateSMPProxyFallback, enabled = remember { mutableStateOf(smpProxyMode.value != SMPProxyMode.Never) }) -// SettingsPreferenceItem(painterResource(MR.images.ic_arrow_forward), stringResource(MR.strings.private_routing_show_message_status), chatModel.controller.appPrefs.showSentViaProxy) -// } -// SectionCustomFooter { -// Text(stringResource(MR.strings.private_routing_explanation)) -// } -// Divider(Modifier.padding(start = DEFAULT_PADDING_HALF, top = 32.dp, end = DEFAULT_PADDING_HALF, bottom = 30.dp)) -// } + if (currentRemoteHost == null) { + SectionView(generalGetString(MR.strings.settings_section_title_private_message_routing)) { + SMPProxyModePicker(smpProxyMode, showModal, updateSMPProxyMode) + SMPProxyFallbackPicker(smpProxyFallback, showModal, updateSMPProxyFallback, enabled = remember { mutableStateOf(smpProxyMode.value != SMPProxyMode.Never) }) + SettingsPreferenceItem(painterResource(MR.images.ic_arrow_forward), stringResource(MR.strings.private_routing_show_message_status), chatModel.controller.appPrefs.showSentViaProxy) + } + SectionCustomFooter { + Text(stringResource(MR.strings.private_routing_explanation)) + } + Divider(Modifier.padding(start = DEFAULT_PADDING_HALF, top = 32.dp, end = DEFAULT_PADDING_HALF, bottom = 30.dp)) + } SectionView(generalGetString(MR.strings.settings_section_title_calls)) { SettingsActionItem(painterResource(MR.images.ic_electrical_services), stringResource(MR.strings.webrtc_ice_servers), { ModalManager.start.showModal { RTCServersView(m) } }) From bf91666f07528f6229b38177b152c987c9bcb691 Mon Sep 17 00:00:00 2001 From: Stanislav Dmitrenko <7953703+avently@users.noreply.github.com> Date: Sat, 25 May 2024 15:52:16 +0700 Subject: [PATCH 11/18] android, desktop: wallpapers (#4109) * android, desktop: wallpapers * changes * removed unused * changes * backgrounds moved to themes. can be exported/imported * changes and refactoring * scrollable * change * reorder * theme per background * changes * don't drop customization in same cases * changes * changes * fix state update * different defaults * fix Android * removed migration * temporary * returned theme name as uppercase back * resilient to wrong preset name * more * live color change without button * fix * Revert "temporary" This reverts commit 705c92ee569ba6210b18b74ececd7cb890dffb2b. * changes * changes * almost candy * old picker and ability to specify hex color * different image * picker * user theme override, fixes, import/export theme with image * revert when about to merge: useful layout for theming * custom image displaying and deletion work correctly * performance * moved code up * changes * color changes in picker when changing themes * reset color without closing modal * unused * log * currentTheme instead of MaterialTheme * different inheritance logic * fix and move sent/received message colors to top * remove background * performance * fix wrong base * changes * fix * small * custom image selection made normally * better color picker * better picker * refactor, fixes, optimizations * working with unknown base theme + tests * change * delete wallpaper dir when importing archive * function rename * fix bug with state update * update colors * fix text colors * update images * changes * remote desktop and theme mode dropdown * default theme * additional accent 2 changes * fix default wallpaper * removed ChatListAlwaysVisible * renaming * update messages * changes * default theme * unused * member icon background color * image quality * fix wallpaper on empty notes screen * update colors * change * update colors * fix update on android * fix update on both platforms * update colors, remove serializable * fix color --------- Co-authored-by: Evgeny Poberezkin --- .../chat/simplex/app/MessagesFetcherWorker.kt | 4 +- .../main/java/chat/simplex/app/SimplexApp.kt | 6 +- .../java/chat/simplex/app/SimplexService.kt | 2 +- apps/multiplatform/common/build.gradle.kts | 3 + .../simplex/common/platform/Files.android.kt | 2 + .../common/platform/Resources.android.kt | 7 + .../views/usersettings/Appearance.android.kt | 31 +- .../chat/simplex/common/model/ChatModel.kt | 33 +- .../chat/simplex/common/model/SimpleXAPI.kt | 126 ++- .../other/wheel-picker/FWheelPickerDefault.kt | 4 +- .../chat/simplex/common/platform/AppCommon.kt | 6 + .../chat/simplex/common/platform/Core.kt | 15 +- .../chat/simplex/common/platform/Files.kt | 58 +- .../chat/simplex/common/platform/Resources.kt | 4 + .../chat/simplex/common/ui/theme/Color.kt | 13 +- .../chat/simplex/common/ui/theme/Theme.kt | 613 +++++++++-- .../simplex/common/ui/theme/ThemeManager.kt | 293 ++++-- .../simplex/common/views/chat/ChatInfoView.kt | 65 ++ .../common/views/chat/ChatItemInfoView.kt | 2 +- .../simplex/common/views/chat/ChatView.kt | 711 ++++++------- ...ComposeContextInvitingContactMemberView.kt | 2 +- .../common/views/chat/ComposeFileView.kt | 2 +- .../common/views/chat/ComposeImageView.kt | 2 +- .../simplex/common/views/chat/ComposeView.kt | 6 +- .../common/views/chat/ComposeVoiceView.kt | 2 +- .../common/views/chat/ContextItemView.kt | 4 +- .../views/chat/group/GroupChatInfoView.kt | 11 +- .../views/chat/item/CIGroupInvitationView.kt | 9 +- .../common/views/chat/item/CIMetaView.kt | 6 +- .../views/chat/item/CIRcvDecryptionError.kt | 11 +- .../common/views/chat/item/CIVoiceView.kt | 8 +- .../common/views/chat/item/ChatItemView.kt | 66 +- .../common/views/chat/item/DeletedItemView.kt | 4 +- .../common/views/chat/item/FramedItemView.kt | 26 +- .../views/chat/item/IntegrityErrorItemView.kt | 5 +- .../views/chat/item/MarkedDeletedItemView.kt | 4 +- .../common/views/chat/item/TextItemView.kt | 2 +- .../common/views/database/DatabaseView.kt | 2 + .../common/views/helpers/ChatInfoImage.kt | 8 +- .../common/views/helpers/ChatWallpaper.kt | 415 ++++++++ .../common/views/helpers/CloseSheetBar.kt | 2 +- .../common/views/helpers/LinkPreviews.kt | 2 +- .../simplex/common/views/helpers/ModalView.kt | 5 +- .../common/views/helpers/ThemeModeEditor.kt | 463 +++++++++ .../simplex/common/views/helpers/Utils.kt | 58 +- .../common/views/localauth/LocalAuthView.kt | 2 +- .../common/views/migration/MigrateToDevice.kt | 2 +- .../common/views/usersettings/Appearance.kt | 972 +++++++++++++++--- .../common/views/usersettings/SettingsView.kt | 2 +- .../commonMain/resources/MR/ar/strings.xml | 1 - .../commonMain/resources/MR/base/strings.xml | 43 +- .../commonMain/resources/MR/bg/strings.xml | 1 - .../commonMain/resources/MR/cs/strings.xml | 1 - .../commonMain/resources/MR/de/strings.xml | 1 - .../commonMain/resources/MR/es/strings.xml | 1 - .../commonMain/resources/MR/fi/strings.xml | 1 - .../commonMain/resources/MR/fr/strings.xml | 1 - .../commonMain/resources/MR/hi/strings.xml | 1 - .../commonMain/resources/MR/hu/strings.xml | 1 - .../resources/MR/images/wallpaper_cats@4x.png | Bin 0 -> 51580 bytes .../MR/images/wallpaper_flowers@4x.png | Bin 0 -> 177014 bytes .../MR/images/wallpaper_hearts@4x.png | Bin 0 -> 80475 bytes .../resources/MR/images/wallpaper_kids@4x.png | Bin 0 -> 171840 bytes .../MR/images/wallpaper_school@4x.png | Bin 0 -> 238390 bytes .../MR/images/wallpaper_travel@4x.png | Bin 0 -> 80606 bytes .../commonMain/resources/MR/it/strings.xml | 1 - .../commonMain/resources/MR/iw/strings.xml | 1 - .../commonMain/resources/MR/ja/strings.xml | 1 - .../commonMain/resources/MR/ko/strings.xml | 1 - .../commonMain/resources/MR/lt/strings.xml | 1 - .../commonMain/resources/MR/ml/strings.xml | 1 - .../commonMain/resources/MR/nl/strings.xml | 1 - .../commonMain/resources/MR/pl/strings.xml | 1 - .../resources/MR/pt-rBR/strings.xml | 1 - .../commonMain/resources/MR/pt/strings.xml | 1 - .../commonMain/resources/MR/ru/strings.xml | 1 - .../commonMain/resources/MR/th/strings.xml | 1 - .../commonMain/resources/MR/tr/strings.xml | 1 - .../commonMain/resources/MR/uk/strings.xml | 1 - .../resources/MR/zh-rCN/strings.xml | 1 - .../resources/MR/zh-rTW/strings.xml | 1 - .../kotlin/chat/simplex/app/ThemesTest.kt | 38 + .../kotlin/chat/simplex/common/DesktopApp.kt | 3 +- .../common/platform/AppCommon.desktop.kt | 2 +- .../simplex/common/platform/Files.desktop.kt | 2 + .../common/platform/Resources.desktop.kt | 18 +- .../simplex/common/ui/theme/Theme.desktop.kt | 4 + .../common/views/call/CallView.desktop.kt | 5 - .../views/usersettings/Appearance.desktop.kt | 24 +- .../kotlin/chat/simplex/desktop/Main.kt | 1 + 90 files changed, 3379 insertions(+), 887 deletions(-) create mode 100644 apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ChatWallpaper.kt create mode 100644 apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ThemeModeEditor.kt create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/wallpaper_cats@4x.png create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/wallpaper_flowers@4x.png create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/wallpaper_hearts@4x.png create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/wallpaper_kids@4x.png create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/wallpaper_school@4x.png create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/wallpaper_travel@4x.png create mode 100644 apps/multiplatform/common/src/commonTest/kotlin/chat/simplex/app/ThemesTest.kt diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/MessagesFetcherWorker.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/MessagesFetcherWorker.kt index 0152f5e8c2..64b6639a58 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/MessagesFetcherWorker.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/MessagesFetcherWorker.kt @@ -7,7 +7,7 @@ import chat.simplex.app.SimplexService.Companion.showPassphraseNotification import chat.simplex.common.model.ChatController import chat.simplex.common.views.helpers.DBMigrationResult import chat.simplex.common.platform.chatModel -import chat.simplex.common.platform.initChatControllerAndRunMigrations +import chat.simplex.common.platform.initChatControllerOnStart import chat.simplex.common.views.helpers.DatabaseUtils import kotlinx.coroutines.* import java.util.Date @@ -60,7 +60,7 @@ class MessagesFetcherWork( try { // In case of self-destruct is enabled the initialization process will not start in SimplexApp, Let's start it here if (DatabaseUtils.ksSelfDestructPassword.get() != null && chatModel.chatDbStatus.value == null) { - initChatControllerAndRunMigrations() + initChatControllerOnStart() } withTimeout(durationSeconds * 1000L) { val chatController = ChatController diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexApp.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexApp.kt index 83105c678a..95bba8e8a2 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexApp.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexApp.kt @@ -6,7 +6,6 @@ import android.content.Context import chat.simplex.common.platform.Log import android.content.Intent import android.content.pm.ActivityInfo -import android.media.AudioManager import android.os.* import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect @@ -66,6 +65,7 @@ class SimplexApp: Application(), LifecycleEventObserver { context = this initHaskell() initMultiplatform() + runMigrations() tmpDir.deleteRecursively() tmpDir.mkdir() @@ -74,7 +74,7 @@ class SimplexApp: Application(), LifecycleEventObserver { // It's important, otherwise, user may be locked in undefined state appPrefs.onboardingStage.set(OnboardingStage.Step1_SimpleXInfo) } else if (DatabaseUtils.ksAppPassword.get() == null || DatabaseUtils.ksSelfDestructPassword.get() == null) { - initChatControllerAndRunMigrations() + initChatControllerOnStart() } ProcessLifecycleOwner.get().lifecycle.addObserver(this@SimplexApp) } @@ -254,7 +254,7 @@ class SimplexApp: Application(), LifecycleEventObserver { override fun androidSetNightModeIfSupported() { if (Build.VERSION.SDK_INT < 31) return - val light = if (CurrentColors.value.name == DefaultTheme.SYSTEM.name) { + val light = if (CurrentColors.value.name == DefaultTheme.SYSTEM_THEME_NAME) { null } else { CurrentColors.value.colors.isLight diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexService.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexService.kt index f56bf4fe00..a5f5d84ec2 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexService.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexService.kt @@ -77,7 +77,7 @@ class SimplexService: Service() { isServiceStarted = true // In case of self-destruct is enabled the initialization process will not start in SimplexApp, Let's start it here if (DatabaseUtils.ksSelfDestructPassword.get() != null && chatModel.chatDbStatus.value == null) { - initChatControllerAndRunMigrations() + initChatControllerOnStart() } } } diff --git a/apps/multiplatform/common/build.gradle.kts b/apps/multiplatform/common/build.gradle.kts index 1f55a7195c..4fa865a6d3 100644 --- a/apps/multiplatform/common/build.gradle.kts +++ b/apps/multiplatform/common/build.gradle.kts @@ -53,6 +53,9 @@ kotlin { val commonTest by getting { dependencies { implementation(kotlin("test")) + implementation(kotlin("test-junit")) + implementation(kotlin("test-common")) + implementation(kotlin("test-annotations-common")) } } val androidMain by getting { diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/Files.android.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/Files.android.kt index dfc8c1d4e7..ea092453ee 100644 --- a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/Files.android.kt +++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/Files.android.kt @@ -15,8 +15,10 @@ actual val dataDir: File = androidAppContext.dataDir actual val tmpDir: File = androidAppContext.getDir("temp", Application.MODE_PRIVATE) actual val filesDir: File = File(dataDir.absolutePath + File.separator + "files") actual val appFilesDir: File = File(filesDir.absolutePath + File.separator + "app_files") +actual val wallpapersDir: File = File(filesDir.absolutePath + File.separator + "assets" + File.separator + "wallpapers").also { it.mkdirs() } actual val coreTmpDir: File = File(filesDir.absolutePath + File.separator + "temp_files") actual val dbAbsolutePrefixPath: String = dataDir.absolutePath + File.separator + "files" +actual val preferencesDir = File(dataDir.absolutePath + File.separator + "shared_prefs") actual val chatDatabaseFileName: String = "files_chat.db" actual val agentDatabaseFileName: String = "files_agent.db" diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/Resources.android.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/Resources.android.kt index e15d1f9268..91d19759ea 100644 --- a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/Resources.android.kt +++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/Resources.android.kt @@ -7,6 +7,8 @@ import android.content.SharedPreferences import android.content.res.Configuration import android.text.BidiFormatter import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.font.Font @@ -14,9 +16,11 @@ import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp +import androidx.core.graphics.drawable.toBitmap import chat.simplex.common.model.AppPreferences import com.russhwolf.settings.Settings import com.russhwolf.settings.SharedPreferencesSettings +import dev.icerock.moko.resources.ImageResource import dev.icerock.moko.resources.StringResource import dev.icerock.moko.resources.desc.desc @@ -51,3 +55,6 @@ actual fun windowWidth(): Dp = LocalConfiguration.current.screenWidthDp.dp actual fun desktopExpandWindowToWidth(width: Dp) {} actual fun isRtl(text: CharSequence): Boolean = BidiFormatter.getInstance().isRtl(text) + +actual fun ImageResource.toComposeImageBitmap(): ImageBitmap? = + getDrawable(androidAppContext)?.toBitmap()?.asImageBitmap() diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/usersettings/Appearance.android.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/usersettings/Appearance.android.kt index 5a60e1d1b0..7cb5c77f6e 100644 --- a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/usersettings/Appearance.android.kt +++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/usersettings/Appearance.android.kt @@ -19,14 +19,10 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.shadow -import androidx.compose.ui.graphics.* import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.unit.dp -import androidx.core.content.ContextCompat -import androidx.core.graphics.drawable.toBitmap -import chat.simplex.common.R import chat.simplex.common.model.* import chat.simplex.common.ui.theme.* import chat.simplex.common.views.helpers.* @@ -34,7 +30,6 @@ import chat.simplex.common.model.ChatModel import chat.simplex.common.platform.* import chat.simplex.common.helpers.APPLICATION_ID import chat.simplex.common.helpers.saveAppLocale -import chat.simplex.common.views.usersettings.AppearanceScope.ColorEditor import chat.simplex.res.MR import dev.icerock.moko.resources.ImageResource import dev.icerock.moko.resources.compose.painterResource @@ -46,9 +41,8 @@ enum class AppIcon(val image: ImageResource) { } @Composable -actual fun AppearanceView(m: ChatModel, showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit)) { +actual fun AppearanceView(m: ChatModel) { val appIcon = remember { mutableStateOf(findEnabledIcon()) } - fun setAppIcon(newIcon: AppIcon) { if (appIcon.value == newIcon) return val newComponent = ComponentName(APPLICATION_ID, "chat.simplex.app.MainActivity_${newIcon.name.lowercase()}") @@ -65,18 +59,11 @@ actual fun AppearanceView(m: ChatModel, showSettingsModal: (@Composable (ChatMod appIcon.value = newIcon } - AppearanceScope.AppearanceLayout( appIcon, m.controller.appPrefs.appLanguage, m.controller.appPrefs.systemDarkTheme, changeIcon = ::setAppIcon, - showSettingsModal = showSettingsModal, - editColor = { name, initialColor -> - ModalManager.start.showModalCloseable { close -> - ColorEditor(name, initialColor, close) - } - }, ) } @@ -86,8 +73,6 @@ fun AppearanceScope.AppearanceLayout( languagePref: SharedPreference, systemDarkTheme: SharedPreference, changeIcon: (AppIcon) -> Unit, - showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit), - editColor: (ThemeColor, Color) -> Unit, ) { ColumnWithScrollBar( Modifier.fillMaxWidth(), @@ -120,6 +105,13 @@ fun AppearanceScope.AppearanceLayout( } // } } + + SectionDividerSpaced(maxTopPadding = true) + ThemesSection(systemDarkTheme) + + SectionDividerSpaced(maxTopPadding = true) + ProfileImageSection() + SectionDividerSpaced() SectionView(stringResource(MR.strings.settings_section_title_icon), padding = PaddingValues(horizontal = DEFAULT_PADDING_HALF)) { @@ -145,11 +137,6 @@ fun AppearanceScope.AppearanceLayout( } } - SectionDividerSpaced(maxTopPadding = true) - ProfileImageSection() - - SectionDividerSpaced(maxTopPadding = true) - ThemesSection(systemDarkTheme, showSettingsModal, editColor) SectionBottomSpacer() } } @@ -169,8 +156,6 @@ fun PreviewAppearanceSettings() { languagePref = SharedPreference({ null }, {}), systemDarkTheme = SharedPreference({ null }, {}), changeIcon = {}, - showSettingsModal = { {} }, - editColor = { _, _ -> }, ) } } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt index 56487874ba..74a54e54cf 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt @@ -4,7 +4,7 @@ import androidx.compose.material.* import androidx.compose.runtime.* import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.compose.runtime.snapshots.SnapshotStateMap -import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.* import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.font.* import androidx.compose.ui.text.style.TextDecoration @@ -399,6 +399,18 @@ object ChatModel { currentUser.value = updated } + fun updateCurrentUserUiThemes(rhId: Long?, uiThemes: ThemeModeOverrides?) { + val current = currentUser.value ?: return + val updated = current.copy( + uiThemes = uiThemes + ) + val i = users.indexOfFirst { it.user.userId == current.userId && it.user.remoteHostId == rhId } + if (i != -1) { + users[i] = users[i].copy(user = updated) + } + currentUser.value = updated + } + suspend fun addLiveDummy(chatInfo: ChatInfo): ChatItem { val cItem = ChatItem.liveDummy(chatInfo is ChatInfo.Direct) withContext(Dispatchers.Main) { @@ -682,7 +694,8 @@ data class User( override val showNtfs: Boolean, val sendRcptsContacts: Boolean, val sendRcptsSmallGroups: Boolean, - val viewPwdHash: UserPwdHash? + val viewPwdHash: UserPwdHash?, + val uiThemes: ThemeModeOverrides? = null, ): NamedChat, UserLike { override val displayName: String get() = profile.displayName override val fullName: String get() = profile.fullName @@ -709,6 +722,7 @@ data class User( sendRcptsContacts = true, sendRcptsSmallGroups = false, viewPwdHash = null, + uiThemes = null, ) } } @@ -1041,7 +1055,8 @@ data class Contact( override val updatedAt: Instant, val chatTs: Instant?, val contactGroupMemberId: Long? = null, - val contactGrpInvSent: Boolean + val contactGrpInvSent: Boolean, + val uiThemes: ThemeModeOverrides? = null, ): SomeChat, NamedChat { override val chatType get() = ChatType.Direct override val id get() = "@$contactId" @@ -1113,7 +1128,8 @@ data class Contact( createdAt = Clock.System.now(), updatedAt = Clock.System.now(), chatTs = Clock.System.now(), - contactGrpInvSent = false + contactGrpInvSent = false, + uiThemes = null, ) } } @@ -1253,7 +1269,8 @@ data class GroupInfo ( val chatSettings: ChatSettings, override val createdAt: Instant, override val updatedAt: Instant, - val chatTs: Instant? + val chatTs: Instant?, + val uiThemes: ThemeModeOverrides? = null, ): SomeChat, NamedChat { override val chatType get() = ChatType.Group override val id get() = "#$groupId" @@ -1295,7 +1312,8 @@ data class GroupInfo ( chatSettings = ChatSettings(enableNtfs = MsgFilter.All, sendRcpts = null, favorite = false), createdAt = Clock.System.now(), updatedAt = Clock.System.now(), - chatTs = Clock.System.now() + chatTs = Clock.System.now(), + uiThemes = null, ) } } @@ -1915,12 +1933,13 @@ data class ChatItem ( itemDeleted: CIDeleted? = null, itemEdited: Boolean = false, itemTimed: CITimed? = null, + itemLive: Boolean = false, deletable: Boolean = true, editable: Boolean = true ) = ChatItem( chatDir = dir, - meta = CIMeta.getSample(id, ts, text, status, sentViaProxy, itemForwarded, itemDeleted, itemEdited, itemTimed, deletable, editable), + meta = CIMeta.getSample(id, ts, text, status, sentViaProxy, itemForwarded, itemDeleted, itemEdited, itemTimed, itemLive, deletable, editable), content = CIContent.SndMsgContent(msgContent = MsgContent.MCText(text)), quotedItem = quotedItem, reactions = listOf(), diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt index ca237cd52f..40207a25ce 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt @@ -26,8 +26,7 @@ import kotlinx.coroutines.sync.withLock import kotlinx.datetime.Clock import kotlinx.datetime.Instant import kotlinx.serialization.* -import kotlinx.serialization.builtins.MapSerializer -import kotlinx.serialization.builtins.serializer +import kotlinx.serialization.builtins.* import kotlinx.serialization.json.* import java.util.Date @@ -168,13 +167,20 @@ class AppPreferences { val selfDestruct = mkBoolPreference(SHARED_PREFS_SELF_DESTRUCT, false) val selfDestructDisplayName = mkStrPreference(SHARED_PREFS_SELF_DESTRUCT_DISPLAY_NAME, null) - val currentTheme = mkStrPreference(SHARED_PREFS_CURRENT_THEME, DefaultTheme.SYSTEM.name) - val systemDarkTheme = mkStrPreference(SHARED_PREFS_SYSTEM_DARK_THEME, DefaultTheme.SIMPLEX.name) - val themeOverrides = mkMapPreference(SHARED_PREFS_THEMES, mapOf(), encode = { + val currentTheme = mkStrPreference(SHARED_PREFS_CURRENT_THEME, DefaultTheme.SYSTEM_THEME_NAME) + val systemDarkTheme = mkStrPreference(SHARED_PREFS_SYSTEM_DARK_THEME, DefaultTheme.SIMPLEX.themeName) + val currentThemeIds = mkMapPreference(SHARED_PREFS_CURRENT_THEME_IDs, mapOf(), encode = { + json.encodeToString(MapSerializer(String.serializer(), String.serializer()), it) + }, decode = { + json.decodeFromString(MapSerializer(String.serializer(), String.serializer()), it) + }) + // Deprecated. Remove key from preferences in 2025 + val themeOverridesOld = mkMapPreference(SHARED_PREFS_THEMES_OLD, mapOf(), encode = { json.encodeToString(MapSerializer(String.serializer(), ThemeOverrides.serializer()), it) }, decode = { - json.decodeFromString(MapSerializer(String.serializer(), ThemeOverrides.serializer()), it) + jsonCoerceInputValues.decodeFromString(MapSerializer(String.serializer(), ThemeOverrides.serializer()), it) }, settingsThemes) + val themeOverrides = mkThemeOverridesPreference() val profileImageCornerRadius = mkFloatPreference(SHARED_PREFS_PROFILE_IMAGE_CORNER_RADIUS, 22.5f) val whatsNewVersion = mkStrPreference(SHARED_PREFS_WHATS_NEW_VERSION, null) @@ -269,6 +275,12 @@ class AppPreferences { set = fun(value) = prefs.putString(prefName, encode(value)) ) + private fun mkThemeOverridesPreference(): SharedPreference> = + SharedPreference( + get = fun() = themeOverridesStore ?: (readThemeOverrides()).also { themeOverridesStore = it }, + set = fun(value) { if (writeThemeOverrides(value)) { themeOverridesStore = value } } + ) + companion object { const val SHARED_PREFS_ID = "chat.simplex.app.SIMPLEX_APP_PREFS" internal const val SHARED_PREFS_THEMES_ID = "chat.simplex.app.THEMES" @@ -345,8 +357,10 @@ class AppPreferences { private const val SHARED_PREFS_SELF_DESTRUCT_DISPLAY_NAME = "LocalAuthenticationSelfDestructDisplayName" private const val SHARED_PREFS_PQ_EXPERIMENTAL_ENABLED = "PQExperimentalEnabled" // no longer used private const val SHARED_PREFS_CURRENT_THEME = "CurrentTheme" + private const val SHARED_PREFS_CURRENT_THEME_IDs = "CurrentThemeIds" private const val SHARED_PREFS_SYSTEM_DARK_THEME = "SystemDarkTheme" - private const val SHARED_PREFS_THEMES = "Themes" + private const val SHARED_PREFS_THEMES_OLD = "Themes" + private const val SHARED_PREFS_THEME_OVERRIDES = "ThemeOverrides" private const val SHARED_PREFS_PROFILE_IMAGE_CORNER_RADIUS = "ProfileImageCornerRadius" private const val SHARED_PREFS_WHATS_NEW_VERSION = "WhatsNewVersion" private const val SHARED_PREFS_LAST_MIGRATED_VERSION_CODE = "LastMigratedVersionCode" @@ -361,6 +375,8 @@ class AppPreferences { private const val SHARED_PREFS_IOS_CALL_KIT_ENABLED = "iOSCallKitEnabled" private const val SHARED_PREFS_IOS_CALL_KIT_CALLS_IN_RECENTS = "iOSCallKitCallsInRecents" + + private var themeOverridesStore: List? = null } } @@ -445,8 +461,13 @@ object ChatController { Log.d(TAG, "startChatWithTemporaryDatabase") val migrationActiveUser = apiGetActiveUser(null, ctrl) ?: apiCreateActiveUser(null, Profile(displayName = "Temp", fullName = ""), ctrl = ctrl) apiSetNetworkConfig(netCfg, ctrl) - apiSetTempFolder(getMigrationTempFilesDirectory().absolutePath, ctrl) - apiSetFilesFolder(getMigrationTempFilesDirectory().absolutePath, ctrl) + apiSetAppFilePaths( + getMigrationTempFilesDirectory().absolutePath, + getMigrationTempFilesDirectory().absolutePath, + wallpapersDir.parentFile.absolutePath, + remoteHostsDir.absolutePath, + ctrl + ) apiStartChat(ctrl) return migrationActiveUser } @@ -665,22 +686,10 @@ object ChatController { } } - suspend fun apiSetTempFolder(tempFolder: String, ctrl: ChatCtrl? = null) { - val r = sendCmd(null, CC.SetTempFolder(tempFolder), ctrl) + suspend fun apiSetAppFilePaths(filesFolder: String, tempFolder: String, assetsFolder: String, remoteHostsFolder: String, ctrl: ChatCtrl? = null) { + val r = sendCmd(null, CC.ApiSetAppFilePaths(filesFolder, tempFolder, assetsFolder, remoteHostsFolder), ctrl) if (r is CR.CmdOk) return - throw Exception("failed to set temp folder: ${r.responseType} ${r.details}") - } - - suspend fun apiSetFilesFolder(filesFolder: String, ctrl: ChatCtrl? = null) { - val r = sendCmd(null, CC.SetFilesFolder(filesFolder), ctrl) - if (r is CR.CmdOk) return - throw Exception("failed to set files folder: ${r.responseType} ${r.details}") - } - - suspend fun apiSetRemoteHostsFolder(remoteHostsFolder: String) { - val r = sendCmd(null, CC.SetRemoteHostsFolder(remoteHostsFolder)) - if (r is CR.CmdOk) return - throw Exception("failed to set remote hosts folder: ${r.responseType} ${r.details}") + throw Exception("failed to set app file paths: ${r.responseType} ${r.details}") } suspend fun apiSetEncryptLocalFiles(enable: Boolean) = sendCommandOkResp(null, CC.ApiSetEncryptLocalFiles(enable)) @@ -1166,6 +1175,20 @@ object ChatController { return null } + suspend fun apiSetUserUIThemes(rh: Long?, userId: Long, themes: ThemeModeOverrides?): Boolean { + val r = sendCmd(rh, CC.ApiSetUserUIThemes(userId, themes)) + if (r is CR.CmdOk) return true + Log.e(TAG, "apiSetUserUIThemes bad response: ${r.responseType} ${r.details}") + return false + } + + suspend fun apiSetChatUIThemes(rh: Long?, chatId: ChatId, themes: ThemeModeOverrides?): Boolean { + val r = sendCmd(rh, CC.ApiSetChatUIThemes(chatId, themes)) + if (r is CR.CmdOk) return true + Log.e(TAG, "apiSetChatUIThemes bad response: ${r.responseType} ${r.details}") + return false + } + suspend fun apiCreateUserAddress(rh: Long?): String? { val userId = kotlin.runCatching { currentUserId("apiCreateUserAddress") }.getOrElse { return null } val r = sendCmd(rh, CC.ApiCreateMyAddress(userId)) @@ -2437,9 +2460,8 @@ sealed class CC { class ApiDeleteUser(val userId: Long, val delSMPQueues: Boolean, val viewPwd: String?): CC() class StartChat(val mainApp: Boolean): CC() class ApiStopChat: CC() - class SetTempFolder(val tempFolder: String): CC() - class SetFilesFolder(val filesFolder: String): CC() - class SetRemoteHostsFolder(val remoteHostsFolder: String): CC() + @Serializable + class ApiSetAppFilePaths(val appFilesFolder: String, val appTempFolder: String, val appAssetsFolder: String, val appRemoteHostsFolder: String): CC() class ApiSetEncryptLocalFiles(val enable: Boolean): CC() class ApiExportArchive(val config: ArchiveConfig): CC() class ApiImportArchive(val config: ArchiveConfig): CC() @@ -2507,6 +2529,8 @@ sealed class CC { class ApiSetContactPrefs(val contactId: Long, val prefs: ChatPreferences): CC() class ApiSetContactAlias(val contactId: Long, val localAlias: String): CC() class ApiSetConnectionAlias(val connId: Long, val localAlias: String): CC() + class ApiSetUserUIThemes(val userId: Long, val themes: ThemeModeOverrides?): CC() + class ApiSetChatUIThemes(val chatId: String, val themes: ThemeModeOverrides?): CC() class ApiCreateMyAddress(val userId: Long): CC() class ApiDeleteMyAddress(val userId: Long): CC() class ApiShowMyAddress(val userId: Long): CC() @@ -2574,9 +2598,7 @@ sealed class CC { is ApiDeleteUser -> "/_delete user $userId del_smp=${onOff(delSMPQueues)}${maybePwd(viewPwd)}" is StartChat -> "/_start main=${onOff(mainApp)}" is ApiStopChat -> "/_stop" - is SetTempFolder -> "/_temp_folder $tempFolder" - is SetFilesFolder -> "/_files_folder $filesFolder" - is SetRemoteHostsFolder -> "/remote_hosts_folder $remoteHostsFolder" + is ApiSetAppFilePaths -> "/set file paths ${json.encodeToString(this)}" is ApiSetEncryptLocalFiles -> "/_files_encrypt ${onOff(enable)}" is ApiExportArchive -> "/_db export ${json.encodeToString(config)}" is ApiImportArchive -> "/_db import ${json.encodeToString(config)}" @@ -2656,6 +2678,8 @@ sealed class CC { is ApiSetContactPrefs -> "/_set prefs @$contactId ${json.encodeToString(prefs)}" is ApiSetContactAlias -> "/_set alias @$contactId ${localAlias.trim()}" is ApiSetConnectionAlias -> "/_set alias :$connId ${localAlias.trim()}" + is ApiSetUserUIThemes -> "/_set theme user $userId ${if (themes != null) json.encodeToString(themes) else ""}" + is ApiSetChatUIThemes -> "/_set theme $chatId ${if (themes != null) json.encodeToString(themes) else ""}" is ApiCreateMyAddress -> "/_address $userId" is ApiDeleteMyAddress -> "/_delete_address $userId" is ApiShowMyAddress -> "/_show_address $userId" @@ -2720,9 +2744,7 @@ sealed class CC { is ApiDeleteUser -> "apiDeleteUser" is StartChat -> "startChat" is ApiStopChat -> "apiStopChat" - is SetTempFolder -> "setTempFolder" - is SetFilesFolder -> "setFilesFolder" - is SetRemoteHostsFolder -> "setRemoteHostsFolder" + is ApiSetAppFilePaths -> "apiSetAppFilePaths" is ApiSetEncryptLocalFiles -> "apiSetEncryptLocalFiles" is ApiExportArchive -> "apiExportArchive" is ApiImportArchive -> "apiImportArchive" @@ -2790,6 +2812,8 @@ sealed class CC { is ApiSetContactPrefs -> "apiSetContactPrefs" is ApiSetContactAlias -> "apiSetContactAlias" is ApiSetConnectionAlias -> "apiSetConnectionAlias" + is ApiSetUserUIThemes -> "apiSetUserUIThemes" + is ApiSetChatUIThemes -> "apiSetChatUIThemes" is ApiCreateMyAddress -> "apiCreateMyAddress" is ApiDeleteMyAddress -> "apiDeleteMyAddress" is ApiShowMyAddress -> "apiShowMyAddress" @@ -4061,6 +4085,15 @@ val json = Json { explicitNulls = false } +// Can decode unknown enum to default value specified for this field +val jsonCoerceInputValues = Json { + prettyPrint = true + ignoreUnknownKeys = true + encodeDefaults = true + explicitNulls = false + coerceInputValues = true +} + val jsonShort = Json { prettyPrint = false ignoreUnknownKeys = true @@ -5521,6 +5554,11 @@ data class AppSettings( var androidCallOnLockScreen: AppSettingsLockScreenCalls? = null, var iosCallKitEnabled: Boolean? = null, var iosCallKitCallsInRecents: Boolean? = null, + var uiProfileImageCornerRadius: Float? = null, + var uiColorScheme: String? = null, + var uiDarkColorScheme: String? = null, + var uiCurrentThemeIds: Map? = null, + var uiThemes: List? = null, ) { fun prepareForExport(): AppSettings { val empty = AppSettings() @@ -5545,6 +5583,11 @@ data class AppSettings( if (androidCallOnLockScreen != def.androidCallOnLockScreen) { empty.androidCallOnLockScreen = androidCallOnLockScreen } if (iosCallKitEnabled != def.iosCallKitEnabled) { empty.iosCallKitEnabled = iosCallKitEnabled } if (iosCallKitCallsInRecents != def.iosCallKitCallsInRecents) { empty.iosCallKitCallsInRecents = iosCallKitCallsInRecents } + if (uiProfileImageCornerRadius != def.uiProfileImageCornerRadius) { empty.uiProfileImageCornerRadius = uiProfileImageCornerRadius } + if (uiColorScheme != def.uiColorScheme) { empty.uiColorScheme = uiColorScheme } + if (uiDarkColorScheme != def.uiDarkColorScheme) { empty.uiDarkColorScheme = uiDarkColorScheme } + if (uiCurrentThemeIds != def.uiCurrentThemeIds) { empty.uiCurrentThemeIds = uiCurrentThemeIds } + if (uiThemes != def.uiThemes) { empty.uiThemes = uiThemes } return empty } @@ -5577,6 +5620,11 @@ data class AppSettings( androidCallOnLockScreen?.let { def.callOnLockScreen.set(it.toCallOnLockScreen()) } iosCallKitEnabled?.let { def.iosCallKitEnabled.set(it) } iosCallKitCallsInRecents?.let { def.iosCallKitCallsInRecents.set(it) } + uiProfileImageCornerRadius?.let { def.profileImageCornerRadius.set(it) } + uiColorScheme?.let { def.currentTheme.set(it) } + uiDarkColorScheme?.let { def.systemDarkTheme.set(it) } + uiCurrentThemeIds?.let { def.currentThemeIds.set(it) } + uiThemes?.let { def.themeOverrides.set(it.skipDuplicates()) } } companion object { @@ -5601,7 +5649,12 @@ data class AppSettings( confirmDBUpgrades = false, androidCallOnLockScreen = AppSettingsLockScreenCalls.SHOW, iosCallKitEnabled = true, - iosCallKitCallsInRecents = false + iosCallKitCallsInRecents = false, + uiProfileImageCornerRadius = 22.5f, + uiColorScheme = DefaultTheme.SYSTEM_THEME_NAME, + uiDarkColorScheme = DefaultTheme.SIMPLEX.themeName, + uiCurrentThemeIds = null, + uiThemes = null, ) val current: AppSettings @@ -5628,6 +5681,11 @@ data class AppSettings( androidCallOnLockScreen = AppSettingsLockScreenCalls.from(def.callOnLockScreen.get()), iosCallKitEnabled = def.iosCallKitEnabled.get(), iosCallKitCallsInRecents = def.iosCallKitCallsInRecents.get(), + uiProfileImageCornerRadius = def.profileImageCornerRadius.get(), + uiColorScheme = def.currentTheme.get() ?: DefaultTheme.SYSTEM_THEME_NAME, + uiDarkColorScheme = def.systemDarkTheme.get() ?: DefaultTheme.SIMPLEX.themeName, + uiCurrentThemeIds = def.currentThemeIds.get(), + uiThemes = def.themeOverrides.get(), ) } } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/wheel-picker/FWheelPickerDefault.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/wheel-picker/FWheelPickerDefault.kt index 9760e9c9f2..052e388f97 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/wheel-picker/FWheelPickerDefault.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/wheel-picker/FWheelPickerDefault.kt @@ -2,7 +2,6 @@ package com.sd.lib.compose.wheel_picker import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.background -import chat.simplex.common.ui.theme.isSystemInDarkTheme import androidx.compose.foundation.layout.* import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -12,6 +11,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp +import chat.simplex.common.ui.theme.isInDarkTheme /** * The default implementation of focus view in vertical. @@ -76,7 +76,7 @@ fun FWheelPickerFocusHorizontal( */ private val DefaultDividerColor: Color @Composable - get() = (if (isSystemInDarkTheme()) { + get() = (if (isInDarkTheme()) { Color.White } else { Color.Black diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/AppCommon.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/AppCommon.kt index 7d5b1b0196..10cb17df1d 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/AppCommon.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/AppCommon.kt @@ -42,6 +42,12 @@ fun runMigrations() { ChatController.appPrefs.currentTheme.set(DefaultTheme.SIMPLEX.name) } lastMigration.set(117) + } else if (lastMigration.get() < 203) { + // Moving to a different key for storing themes as a List + val oldOverrides = ChatController.appPrefs.themeOverridesOld.get().values.toList() + ChatController.appPrefs.themeOverrides.set(oldOverrides) + ChatController.appPrefs.currentThemeIds.set(oldOverrides.associate { it.base.themeName to it.themeId }) + lastMigration.set(203) } else { lastMigration.set(BuildConfigCommon.ANDROID_VERSION_CODE) break diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Core.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Core.kt index 0d447a4a5a..85179d66c7 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Core.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Core.kt @@ -43,14 +43,13 @@ val appPreferences: AppPreferences val chatController: ChatController = ChatController -fun initChatControllerAndRunMigrations() { +fun initChatControllerOnStart() { withLongRunningApi { if (appPreferences.chatStopped.get() && appPreferences.storeDBPassphrase.get() && ksDatabasePassword.get() != null) { initChatController(startChat = ::showStartChatAfterRestartAlert) } else { initChatController() } - runMigrations() } } @@ -88,11 +87,13 @@ suspend fun initChatController(useKey: String? = null, confirmMigrations: Migrat return } platform.androidRestartNetworkObserver() - controller.apiSetTempFolder(coreTmpDir.absolutePath) - controller.apiSetFilesFolder(appFilesDir.absolutePath) - if (appPlatform.isDesktop) { - controller.apiSetRemoteHostsFolder(remoteHostsDir.absolutePath) - } + controller.apiSetAppFilePaths( + appFilesDir.absolutePath, + coreTmpDir.absolutePath, + wallpapersDir.parentFile.absolutePath, + remoteHostsDir.absolutePath, + ctrl + ) controller.apiSetEncryptLocalFiles(controller.appPrefs.privacyEncryptLocalFiles.get()) // If we migrated successfully means previous re-encryption process on database level finished successfully too if (appPreferences.encryptionStartedAt.get() != null) appPreferences.encryptionStartedAt.set(null) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Files.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Files.kt index c788a6902e..250afe03c4 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Files.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Files.kt @@ -1,10 +1,12 @@ package chat.simplex.common.platform import androidx.compose.runtime.Composable -import chat.simplex.common.model.CIFile -import chat.simplex.common.model.CryptoFile +import chat.simplex.common.model.* +import chat.simplex.common.ui.theme.* import chat.simplex.common.views.helpers.generalGetString import chat.simplex.res.MR +import com.charleskorn.kaml.* +import kotlinx.serialization.encodeToString import java.io.* import java.net.URI import java.net.URLDecoder @@ -14,8 +16,10 @@ expect val dataDir: File expect val tmpDir: File expect val filesDir: File expect val appFilesDir: File +expect val wallpapersDir: File expect val coreTmpDir: File expect val dbAbsolutePrefixPath: String +expect val preferencesDir: File expect val chatDatabaseFileName: String expect val agentDatabaseFileName: String @@ -78,6 +82,20 @@ fun getAppFilePath(fileName: String): String { } } +fun getWallpaperFilePath(fileName: String): String { + val rh = chatModel.currentRemoteHost.value + val s = File.separator + val path = if (rh == null) { + wallpapersDir.absolutePath + s + fileName + } else { + remoteHostsDir.absolutePath + s + rh.storePath + s + "simplex_v1_assets" + s + "wallpapers" + s + fileName + } + File(path).parentFile.mkdirs() + return path +} + +fun getPreferenceFilePath(fileName: String = "themes.yaml"): String = preferencesDir.absolutePath + File.separator + fileName + fun getLoadedFilePath(file: CIFile?): String? { val f = file?.fileSource?.filePath return if (f != null && file.loaded) { @@ -98,6 +116,42 @@ fun getLoadedFileSource(file: CIFile?): CryptoFile? { } } +fun readThemeOverrides(): List { + return try { + val file = File(getPreferenceFilePath("themes.yaml")) + if (!file.exists()) return emptyList() + + file.inputStream().use { + val map = yaml.parseToYamlNode(it).yamlMap + val list = map.get("themes") + val res = ArrayList() + list?.items?.forEach { + try { + res.add(yaml.decodeFromYamlNode(ThemeOverrides.serializer(), it)) + } catch (e: Throwable) { + Log.e(TAG, "Error while reading specific theme: ${e.stackTraceToString()}") + } + } + res.skipDuplicates() + } + } catch (e: Throwable) { + Log.e(TAG, "Error while reading themes file: ${e.stackTraceToString()}") + emptyList() + } +} + +fun writeThemeOverrides(overrides: List): Boolean = + try { + File(getPreferenceFilePath("themes.yaml")).outputStream().use { + val string = yaml.encodeToString(ThemesFile(themes = overrides)) + it.bufferedWriter().use { it.write(string) } + } + true + } catch (e: Throwable) { + Log.e(TAG, "Error while writing themes file: ${e.stackTraceToString()}") + false + } + private fun fileReady(file: CIFile, filePath: String) = File(filePath).exists() && CIFile.cachedRemoteFileRequests[file.fileSource] != false diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Resources.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Resources.kt index 2ee668fb23..8e45ded4f0 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Resources.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Resources.kt @@ -1,11 +1,13 @@ package chat.simplex.common.platform import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.text.font.Font import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.Dp import com.russhwolf.settings.Settings +import dev.icerock.moko.resources.ImageResource import dev.icerock.moko.resources.StringResource @Composable @@ -31,3 +33,5 @@ expect fun windowWidth(): Dp expect fun desktopExpandWindowToWidth(width: Dp) expect fun isRtl(text: CharSequence): Boolean + +expect fun ImageResource.toComposeImageBitmap(): ImageBitmap? diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/Color.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/Color.kt index 5eeedbb2a0..c50ea5c349 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/Color.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/Color.kt @@ -31,17 +31,6 @@ val WarningOrange = Color(255, 127, 0, 255) val WarningYellow = Color(255, 192, 0, 255) val FileLight = Color(183, 190, 199, 255) val FileDark = Color(101, 101, 106, 255) -val SentMessageColor = Color(0x1E45B8FF) val MenuTextColor: Color @Composable get () = if (isInDarkTheme()) LocalContentColor.current.copy(alpha = 0.8f) else Color.Black -val NoteFolderIconColor: Color @Composable get() = with(CurrentColors.collectAsState().value.appColors.sentMessage) { - // Default color looks too light and better to have it here a little bit brighter - if (alpha == SentMessageColor.alpha) { - copy(min(SentMessageColor.alpha + 0.1f, 1f)) - } else { - // Color is non-standard and theme maker can choose color without alpha at all since the theme bound to dark/light variant, - // and it shouldn't be universal - this - } -} - +val NoteFolderIconColor: Color @Composable get() = MaterialTheme.appColors.primaryVariant2 diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/Theme.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/Theme.kt index 62acc13bfe..5099513884 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/Theme.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/Theme.kt @@ -6,53 +6,136 @@ import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.* -import androidx.compose.ui.text.TextStyle import androidx.compose.ui.unit.dp import chat.simplex.common.model.ChatController -import chat.simplex.common.platform.isInNightMode +import chat.simplex.common.model.ChatController.appPrefs +import chat.simplex.common.platform.* +import chat.simplex.common.ui.theme.ThemeManager.colorFromReadableHex +import chat.simplex.common.ui.theme.ThemeManager.toReadableHex import chat.simplex.common.views.helpers.* import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import chat.simplex.res.MR +import kotlinx.serialization.Transient +import java.util.UUID enum class DefaultTheme { - SYSTEM, LIGHT, DARK, SIMPLEX; + LIGHT, DARK, SIMPLEX, BLACK; + + companion object { + const val SYSTEM_THEME_NAME: String = "SYSTEM" + } + + val themeName: String + get() = name + + val mode: DefaultThemeMode get() = if (this == LIGHT) DefaultThemeMode.LIGHT else DefaultThemeMode.DARK // Call it only with base theme, not SYSTEM - fun hasChangedAnyColor(colors: Colors, appColors: AppColors): Boolean { - val palette = when (this) { - SYSTEM -> return false - LIGHT -> LightColorPalette - DARK -> DarkColorPalette - SIMPLEX -> SimplexColorPalette - } - val appPalette = when (this) { - SYSTEM -> return false - LIGHT -> LightColorPaletteApp - DARK -> DarkColorPaletteApp - SIMPLEX -> SimplexColorPaletteApp - } - return colors.primary != palette.primary || - colors.primaryVariant != palette.primaryVariant || - colors.secondary != palette.secondary || - colors.secondaryVariant != palette.secondaryVariant || - colors.background != palette.background || - colors.surface != palette.surface || - appColors != appPalette + fun hasChangedAnyColor(overrides: ThemeOverrides?): Boolean { + if (overrides == null) return false + return overrides.colors != ThemeColors() || + overrides.wallpaper != null && (overrides.wallpaper.background != null || overrides.wallpaper.tint != null) } } -data class AppColors( - val title: Color, - val sentMessage: Color, - val receivedMessage: Color -) +@Serializable +enum class DefaultThemeMode { + @SerialName("light") LIGHT, + @SerialName("dark") DARK +} + +@Stable +class AppColors( + title: Color, + primaryVariant2: Color, + sentMessage: Color, + sentQuote: Color, + receivedMessage: Color, + receivedQuote: Color, +) { + var title by mutableStateOf(title, structuralEqualityPolicy()) + internal set + var primaryVariant2 by mutableStateOf(primaryVariant2, structuralEqualityPolicy()) + internal set + var sentMessage by mutableStateOf(sentMessage, structuralEqualityPolicy()) + internal set + var sentQuote by mutableStateOf(sentQuote, structuralEqualityPolicy()) + internal set + var receivedMessage by mutableStateOf(receivedMessage, structuralEqualityPolicy()) + internal set + var receivedQuote by mutableStateOf(receivedQuote, structuralEqualityPolicy()) + internal set + + fun copy( + title: Color = this.title, + primaryVariant2: Color = this.primaryVariant2, + sentMessage: Color = this.sentMessage, + sentQuote: Color = this.sentQuote, + receivedMessage: Color = this.receivedMessage, + receivedQuote: Color = this.receivedQuote, + ): AppColors = AppColors( + title, + primaryVariant2, + sentMessage, + sentQuote, + receivedMessage, + receivedQuote, + ) + + override fun toString(): String { + return buildString { + append("AppColors(") + append("title=$title, ") + append("primaryVariant2=$primaryVariant2, ") + append("sentMessage=$sentMessage, ") + append("sentQuote=$sentQuote, ") + append("receivedMessage=$receivedMessage, ") + append("receivedQuote=$receivedQuote") + append(")") + } + } +} + +@Stable +class AppWallpaper( + background: Color? = null, + tint: Color? = null, + type: WallpaperType = WallpaperType.Empty, +) { + var background by mutableStateOf(background, structuralEqualityPolicy()) + internal set + var tint by mutableStateOf(tint, structuralEqualityPolicy()) + internal set + var type by mutableStateOf(type, structuralEqualityPolicy()) + internal set + + fun copy( + background: Color? = this.background, + tint: Color? = this.tint, + type: WallpaperType = this.type, + ): AppWallpaper = AppWallpaper( + background, + tint, + type, + ) + + override fun toString(): String { + return buildString { + append("AppWallpaper(") + append("background=$background, ") + append("tint=$tint, ") + append("type=$type") + append(")") + } + } +} enum class ThemeColor { - PRIMARY, PRIMARY_VARIANT, SECONDARY, SECONDARY_VARIANT, BACKGROUND, SURFACE, TITLE, SENT_MESSAGE, RECEIVED_MESSAGE; + PRIMARY, PRIMARY_VARIANT, SECONDARY, SECONDARY_VARIANT, BACKGROUND, SURFACE, TITLE, SENT_MESSAGE, SENT_QUOTE, RECEIVED_MESSAGE, RECEIVED_QUOTE, PRIMARY_VARIANT2, WALLPAPER_BACKGROUND, WALLPAPER_TINT; - fun fromColors(colors: Colors, appColors: AppColors): Color { + fun fromColors(colors: Colors, appColors: AppColors, appWallpaper: AppWallpaper): Color? { return when (this) { PRIMARY -> colors.primary PRIMARY_VARIANT -> colors.primaryVariant @@ -61,8 +144,13 @@ enum class ThemeColor { BACKGROUND -> colors.background SURFACE -> colors.surface TITLE -> appColors.title + PRIMARY_VARIANT2 -> appColors.primaryVariant2 SENT_MESSAGE -> appColors.sentMessage + SENT_QUOTE -> appColors.sentQuote RECEIVED_MESSAGE -> appColors.receivedMessage + RECEIVED_QUOTE -> appColors.receivedQuote + WALLPAPER_BACKGROUND -> appWallpaper.background + WALLPAPER_TINT -> appWallpaper.tint } } @@ -75,8 +163,13 @@ enum class ThemeColor { BACKGROUND -> generalGetString(MR.strings.color_background) SURFACE -> generalGetString(MR.strings.color_surface) TITLE -> generalGetString(MR.strings.color_title) + PRIMARY_VARIANT2 -> generalGetString(MR.strings.color_primary_variant2) SENT_MESSAGE -> generalGetString(MR.strings.color_sent_message) + SENT_QUOTE -> generalGetString(MR.strings.color_sent_quote) RECEIVED_MESSAGE -> generalGetString(MR.strings.color_received_message) + RECEIVED_QUOTE -> generalGetString(MR.strings.color_received_quote) + WALLPAPER_BACKGROUND -> generalGetString(MR.strings.color_wallpaper_background) + WALLPAPER_TINT -> generalGetString(MR.strings.color_wallpaper_tint) } } @@ -92,45 +185,232 @@ data class ThemeColors( @SerialName("menus") val surface: String? = null, val title: String? = null, + @SerialName("accentVariant2") + val primaryVariant2: String? = null, val sentMessage: String? = null, + @SerialName("sentReply") + val sentQuote: String? = null, val receivedMessage: String? = null, + @SerialName("receivedReply") + val receivedQuote: String? = null, ) { - fun toColors(base: DefaultTheme): Colors { + companion object { + fun from(colors: Colors, appColors: AppColors): ThemeColors = + ThemeColors( + primary = colors.primary.toReadableHex(), + primaryVariant = colors.primaryVariant.toReadableHex(), + secondary = colors.secondary.toReadableHex(), + secondaryVariant = colors.secondaryVariant.toReadableHex(), + background = colors.background.toReadableHex(), + surface = colors.surface.toReadableHex(), + title = appColors.title.toReadableHex(), + primaryVariant2 = appColors.primaryVariant2.toReadableHex(), + sentMessage = appColors.sentMessage.toReadableHex(), + sentQuote = appColors.sentQuote.toReadableHex(), + receivedMessage = appColors.receivedMessage.toReadableHex(), + receivedQuote = appColors.receivedQuote.toReadableHex(), + ) + } +} + +@Serializable +data class ThemeWallpaper ( + val preset: String? = null, + val scale: Float? = null, + val scaleType: WallpaperScaleType? = null, + val background: String? = null, + val tint: String? = null, + val image: String? = null, + val imageFile: String? = null, +) { + fun toAppWallpaper(): AppWallpaper { + return AppWallpaper( + background = background?.colorFromReadableHex(), + tint = tint?.colorFromReadableHex(), + type = WallpaperType.from(this) ?: WallpaperType.Empty + ) + } + + fun withFilledWallpaperBase64(): ThemeWallpaper { + val aw = toAppWallpaper() + val type = aw.type + return ThemeWallpaper( + image = if (type is WallpaperType.Image && type.image != null) resizeImageToStrSize(type.image!!, 5_000_000) else null, + imageFile = null, + preset = if (type is WallpaperType.Preset) type.filename else null, + scale = if (type is WallpaperType.Preset) type.scale else if (type is WallpaperType.Image) type.scale else 1f, + scaleType = if (type is WallpaperType.Image) type.scaleType else null, + background = aw.background?.toReadableHex(), + tint = aw.tint?.toReadableHex(), + ) + } + + fun withFilledWallpaperPath(): ThemeWallpaper { + val aw = toAppWallpaper() + val type = aw.type + return ThemeWallpaper( + image = null, + imageFile = if (type is WallpaperType.Image) type.filename else null, + preset = if (type is WallpaperType.Preset) type.filename else null, + scale = if (scale == null) null else if (type is WallpaperType.Preset) type.scale else if (type is WallpaperType.Image) scale else null, + scaleType = if (scaleType == null) null else if (type is WallpaperType.Image) type.scaleType else null, + background = aw.background?.toReadableHex(), + tint = aw.tint?.toReadableHex(), + ) + } + + fun importFromString(): ThemeWallpaper = + if (preset == null && image != null) { + // Need to save image from string and to save its path + try { + val parsed = base64ToBitmap(image) + val filename = saveWallpaperFile(parsed) + copy(image = null, imageFile = filename) + } catch (e: Exception) { + Log.e(TAG, "Error while parsing/copying the image: ${e.stackTraceToString()}") + ThemeWallpaper() + } + } else this + + companion object { + fun from(type: WallpaperType, background: String?, tint: String?): ThemeWallpaper { + return ThemeWallpaper( + image = null, + imageFile = if (type is WallpaperType.Image) type.filename else null, + preset = if (type is WallpaperType.Preset) type.filename else null, + scale = if (type is WallpaperType.Preset) type.scale else if (type is WallpaperType.Image) type.scale else null, + scaleType = if (type is WallpaperType.Image) type.scaleType else null, + background = background, + tint = tint, + ) + } + } +} + +@Serializable +data class ThemesFile( + val themes: List = emptyList() +) + +@Serializable +data class ThemeOverrides ( + val themeId: String = UUID.randomUUID().toString(), + val base: DefaultTheme, + val colors: ThemeColors = ThemeColors(), + val wallpaper: ThemeWallpaper? = null, +) { + + fun isSame(type: WallpaperType?, themeName: String): Boolean = + ( + (wallpaper?.preset != null && type is WallpaperType.Preset && wallpaper.preset == type.filename) || + (wallpaper?.imageFile != null && type is WallpaperType.Image) || + (wallpaper?.preset == null && wallpaper?.imageFile == null && (type == WallpaperType.Empty || type == null)) + ) && base.themeName == themeName + + fun withUpdatedColor(name: ThemeColor, color: String?): ThemeOverrides { + return copy( + colors = when (name) { + ThemeColor.PRIMARY -> colors.copy(primary = color) + ThemeColor.PRIMARY_VARIANT -> colors.copy(primaryVariant = color) + ThemeColor.SECONDARY -> colors.copy(secondary = color) + ThemeColor.SECONDARY_VARIANT -> colors.copy(secondaryVariant = color) + ThemeColor.BACKGROUND -> colors.copy(background = color) + ThemeColor.SURFACE -> colors.copy(surface = color) + ThemeColor.TITLE -> colors.copy(title = color) + ThemeColor.PRIMARY_VARIANT2 -> colors.copy(primaryVariant2 = color) + ThemeColor.SENT_MESSAGE -> colors.copy(sentMessage = color) + ThemeColor.SENT_QUOTE -> colors.copy(sentQuote = color) + ThemeColor.RECEIVED_MESSAGE -> colors.copy(receivedMessage = color) + ThemeColor.RECEIVED_QUOTE -> colors.copy(receivedQuote = color) + ThemeColor.WALLPAPER_BACKGROUND -> colors.copy() + ThemeColor.WALLPAPER_TINT -> colors.copy() + }, wallpaper = when (name) { + ThemeColor.WALLPAPER_BACKGROUND -> wallpaper?.copy(background = color) + ThemeColor.WALLPAPER_TINT -> wallpaper?.copy(tint = color) + else -> wallpaper?.copy() + } + ) + } + + fun toColors(base: DefaultTheme, perChatTheme: ThemeColors?, perUserTheme: ThemeColors?, presetWallpaperTheme: ThemeColors?): Colors { val baseColors = when (base) { DefaultTheme.LIGHT -> LightColorPalette DefaultTheme.DARK -> DarkColorPalette DefaultTheme.SIMPLEX -> SimplexColorPalette - // shouldn't be here - DefaultTheme.SYSTEM -> LightColorPalette + DefaultTheme.BLACK -> BlackColorPalette } return baseColors.copy( - primary = primary?.colorFromReadableHex() ?: baseColors.primary, - primaryVariant = primaryVariant?.colorFromReadableHex() ?: baseColors.primaryVariant, - secondary = secondary?.colorFromReadableHex() ?: baseColors.secondary, - secondaryVariant = secondaryVariant?.colorFromReadableHex() ?: baseColors.secondaryVariant, - background = background?.colorFromReadableHex() ?: baseColors.background, - surface = surface?.colorFromReadableHex() ?: baseColors.surface, + primary = perChatTheme?.primary?.colorFromReadableHex() ?: perUserTheme?.primary?.colorFromReadableHex() ?: colors.primary?.colorFromReadableHex() ?: presetWallpaperTheme?.primary?.colorFromReadableHex() ?: baseColors.primary, + primaryVariant = perChatTheme?.primaryVariant?.colorFromReadableHex() ?: perUserTheme?.primaryVariant?.colorFromReadableHex() ?: colors.primaryVariant?.colorFromReadableHex() ?: presetWallpaperTheme?.primaryVariant?.colorFromReadableHex() ?: baseColors.primaryVariant, + secondary = perChatTheme?.secondary?.colorFromReadableHex() ?: perUserTheme?.secondary?.colorFromReadableHex() ?: colors.secondary?.colorFromReadableHex() ?: presetWallpaperTheme?.secondary?.colorFromReadableHex() ?: baseColors.secondary, + secondaryVariant = perChatTheme?.secondaryVariant?.colorFromReadableHex() ?: perUserTheme?.secondaryVariant?.colorFromReadableHex() ?: colors.secondaryVariant?.colorFromReadableHex() ?: presetWallpaperTheme?.secondaryVariant?.colorFromReadableHex() ?: baseColors.secondaryVariant, + background = perChatTheme?.background?.colorFromReadableHex() ?: perUserTheme?.background?.colorFromReadableHex() ?: colors.background?.colorFromReadableHex() ?: presetWallpaperTheme?.background?.colorFromReadableHex() ?: baseColors.background, + surface = perChatTheme?.surface?.colorFromReadableHex() ?: perUserTheme?.surface?.colorFromReadableHex() ?: colors.surface?.colorFromReadableHex() ?: presetWallpaperTheme?.surface?.colorFromReadableHex() ?: baseColors.surface, ) } - fun toAppColors(base: DefaultTheme): AppColors { + fun toAppColors(base: DefaultTheme, perChatTheme: ThemeColors?, perChatWallpaperType: WallpaperType?, perUserTheme: ThemeColors?, perUserWallpaperType: WallpaperType?, presetWallpaperTheme: ThemeColors?): AppColors { val baseColors = when (base) { DefaultTheme.LIGHT -> LightColorPaletteApp DefaultTheme.DARK -> DarkColorPaletteApp DefaultTheme.SIMPLEX -> SimplexColorPaletteApp - // shouldn't be here - DefaultTheme.SYSTEM -> LightColorPaletteApp + DefaultTheme.BLACK -> BlackColorPaletteApp } + + val sentMessageFallback = colors.sentMessage?.colorFromReadableHex() ?: presetWallpaperTheme?.sentMessage?.colorFromReadableHex() ?: baseColors.sentMessage + val sentQuoteFallback = colors.sentQuote?.colorFromReadableHex() ?: presetWallpaperTheme?.sentQuote?.colorFromReadableHex() ?: baseColors.sentQuote + val receivedMessageFallback = colors.receivedMessage?.colorFromReadableHex() ?: presetWallpaperTheme?.receivedMessage?.colorFromReadableHex() ?: baseColors.receivedMessage + val receivedQuoteFallback = colors.receivedQuote?.colorFromReadableHex() ?: presetWallpaperTheme?.receivedQuote?.colorFromReadableHex() ?: baseColors.receivedQuote return baseColors.copy( - title = title?.colorFromReadableHex() ?: baseColors.title, - sentMessage = sentMessage?.colorFromReadableHex() ?: baseColors.sentMessage, - receivedMessage = receivedMessage?.colorFromReadableHex() ?: baseColors.receivedMessage, + title = perChatTheme?.title?.colorFromReadableHex() ?: perUserTheme?.title?.colorFromReadableHex() ?: colors.title?.colorFromReadableHex() ?: presetWallpaperTheme?.title?.colorFromReadableHex() ?: baseColors.title, + primaryVariant2 = perChatTheme?.primaryVariant2?.colorFromReadableHex() ?: perUserTheme?.primaryVariant2?.colorFromReadableHex() ?: colors.primaryVariant2?.colorFromReadableHex() ?: presetWallpaperTheme?.primaryVariant2?.colorFromReadableHex() ?: baseColors.primaryVariant2, + sentMessage = if (perChatTheme?.sentMessage != null) perChatTheme.sentMessage.colorFromReadableHex() + else if (perUserTheme != null && (perChatWallpaperType == null || perUserWallpaperType == null || perChatWallpaperType.sameType(perUserWallpaperType))) perUserTheme.sentMessage?.colorFromReadableHex() ?: sentMessageFallback + else sentMessageFallback, + sentQuote = if (perChatTheme?.sentQuote != null) perChatTheme.sentQuote.colorFromReadableHex() + else if (perUserTheme != null && (perChatWallpaperType == null || perUserWallpaperType == null || perChatWallpaperType.sameType(perUserWallpaperType))) perUserTheme.sentQuote?.colorFromReadableHex() ?: sentQuoteFallback + else sentQuoteFallback, + receivedMessage = if (perChatTheme?.receivedMessage != null) perChatTheme.receivedMessage.colorFromReadableHex() + else if (perUserTheme != null && (perChatWallpaperType == null || perUserWallpaperType == null || perChatWallpaperType.sameType(perUserWallpaperType))) perUserTheme.receivedMessage?.colorFromReadableHex() ?: receivedMessageFallback + else receivedMessageFallback, + receivedQuote = if (perChatTheme?.receivedQuote != null) perChatTheme.receivedQuote.colorFromReadableHex() + else if (perUserTheme != null && (perChatWallpaperType == null || perUserWallpaperType == null || perChatWallpaperType.sameType(perUserWallpaperType))) perUserTheme.receivedQuote?.colorFromReadableHex() ?: receivedQuoteFallback + else receivedQuoteFallback, ) } - fun withFilledColors(base: DefaultTheme): ThemeColors { - val c = toColors(base) - val ac = toAppColors(base) + fun toAppWallpaper(themeOverridesForType: WallpaperType?, perChatTheme: ThemeModeOverride?, perUserTheme: ThemeModeOverride?, materialBackgroundColor: Color): AppWallpaper { + val mainType = when { + themeOverridesForType != null -> themeOverridesForType + // type can be null if override is empty `"wallpaper": "{}"`, in this case no wallpaper is needed, empty. + // It's not null to override upper level wallpaper + perChatTheme?.wallpaper != null -> perChatTheme.wallpaper.toAppWallpaper().type + perUserTheme?.wallpaper != null -> perUserTheme.wallpaper.toAppWallpaper().type + else -> wallpaper?.toAppWallpaper()?.type ?: return AppWallpaper() + } + val first: ThemeWallpaper? = if (mainType.sameType(perChatTheme?.wallpaper?.toAppWallpaper()?.type)) perChatTheme?.wallpaper else null + val second: ThemeWallpaper? = if (mainType.sameType(perUserTheme?.wallpaper?.toAppWallpaper()?.type)) perUserTheme?.wallpaper else null + val third: ThemeWallpaper? = if (mainType.sameType(this.wallpaper?.toAppWallpaper()?.type)) this.wallpaper else null + + return AppWallpaper(type = when (mainType) { + is WallpaperType.Preset -> mainType.copy( + scale = mainType.scale ?: first?.scale ?: second?.scale ?: third?.scale + ) + is WallpaperType.Image -> mainType.copy( + scale = if (themeOverridesForType == null) mainType.scale ?: first?.scale ?: second?.scale ?: third?.scale else second?.scale ?: third?.scale ?: mainType.scale, + scaleType = if (themeOverridesForType == null) mainType.scaleType ?: first?.scaleType ?: second?.scaleType ?: third?.scaleType else second?.scaleType ?: third?.scaleType ?: mainType.scaleType, + filename = if (themeOverridesForType == null) mainType.filename else first?.imageFile ?: second?.imageFile ?: third?.imageFile ?: mainType.filename, + ) + is WallpaperType.Empty -> mainType + }, + background = (first?.background ?: second?.background ?: third?.background)?.colorFromReadableHex() ?: mainType.defaultBackgroundColor(base, materialBackgroundColor), + tint = (first?.tint ?: second?.tint ?: third?.tint)?.colorFromReadableHex() ?: mainType.defaultTintColor(base) + ) + } + + fun withFilledColors(base: DefaultTheme, perChatTheme: ThemeColors?, perChatWallpaperType: WallpaperType?, perUserTheme: ThemeColors?, perUserWallpaperType: WallpaperType?, presetWallpaperTheme: ThemeColors?): ThemeColors { + val c = toColors(base, perChatTheme, perUserTheme, presetWallpaperTheme) + val ac = toAppColors(base, perChatTheme, perChatWallpaperType, perUserTheme, perUserWallpaperType, presetWallpaperTheme) return ThemeColors( primary = c.primary.toReadableHex(), primaryVariant = c.primaryVariant.toReadableHex(), @@ -139,23 +419,71 @@ data class ThemeColors( background = c.background.toReadableHex(), surface = c.surface.toReadableHex(), title = ac.title.toReadableHex(), + primaryVariant2 = ac.primaryVariant2.toReadableHex(), sentMessage = ac.sentMessage.toReadableHex(), - receivedMessage = ac.receivedMessage.toReadableHex() + sentQuote = ac.sentQuote.toReadableHex(), + receivedMessage = ac.receivedMessage.toReadableHex(), + receivedQuote = ac.receivedQuote.toReadableHex(), ) } } -private fun String.colorFromReadableHex(): Color = - Color(this.replace("#", "").toLongOrNull(16) ?: Color.White.toArgb().toLong()) +fun List.getTheme(themeId: String?): ThemeOverrides? = + firstOrNull { it.themeId == themeId } -private fun Color.toReadableHex(): String = "#" + Integer.toHexString(toArgb()) +fun List.getTheme(themeId: String?, type: WallpaperType?, base: DefaultTheme): ThemeOverrides? = + firstOrNull { it.themeId == themeId || it.isSame(type, base.themeName)} + +fun List.replace(theme: ThemeOverrides): List { + val index = indexOfFirst { it.themeId == theme.themeId || + // prevent situation when two themes has the same type but different theme id (maybe something was changed in prefs by hand) + it.isSame(WallpaperType.from(theme.wallpaper), theme.base.themeName) + } + return if (index != -1) { + val a = ArrayList(this) + a[index] = theme + a + } else { + this + theme + } +} + +fun List.sameTheme(type: WallpaperType?, themeName: String): ThemeOverrides? = firstOrNull { it.isSame(type, themeName) } + +/** See [ThemesTest.testSkipDuplicates] */ +fun List.skipDuplicates(): List { + val res = ArrayList() + forEach { theme -> + val themeType = WallpaperType.from(theme.wallpaper) + if (res.none { it.themeId == theme.themeId || it.isSame(themeType, theme.base.themeName) }) { + res.add(theme) + } + } + return res +} @Serializable -data class ThemeOverrides ( - val base: DefaultTheme, - val colors: ThemeColors +data class ThemeModeOverrides ( + val light: ThemeModeOverride? = null, + val dark: ThemeModeOverride? = null ) { - fun withUpdatedColor(name: ThemeColor, color: String): ThemeOverrides { + fun preferredMode(darkTheme: Boolean): ThemeModeOverride? = when (darkTheme) { + false -> light + else -> dark + } +} + +@Serializable +data class ThemeModeOverride ( + val mode: DefaultThemeMode = CurrentColors.value.base.mode, + val colors: ThemeColors = ThemeColors(), + val wallpaper: ThemeWallpaper? = null, +) { + + @Transient + val type = WallpaperType.from(wallpaper) + + fun withUpdatedColor(name: ThemeColor, color: String?): ThemeModeOverride { return copy(colors = when (name) { ThemeColor.PRIMARY -> colors.copy(primary = color) ThemeColor.PRIMARY_VARIANT -> colors.copy(primaryVariant = color) @@ -164,9 +492,27 @@ data class ThemeOverrides ( ThemeColor.BACKGROUND -> colors.copy(background = color) ThemeColor.SURFACE -> colors.copy(surface = color) ThemeColor.TITLE -> colors.copy(title = color) + ThemeColor.PRIMARY_VARIANT2 -> colors.copy(primaryVariant2 = color) ThemeColor.SENT_MESSAGE -> colors.copy(sentMessage = color) + ThemeColor.SENT_QUOTE -> colors.copy(sentQuote = color) ThemeColor.RECEIVED_MESSAGE -> colors.copy(receivedMessage = color) - }) + ThemeColor.RECEIVED_QUOTE -> colors.copy(receivedQuote = color) + ThemeColor.WALLPAPER_BACKGROUND -> colors.copy() + ThemeColor.WALLPAPER_TINT -> colors.copy() + }, wallpaper = when (name) { + ThemeColor.WALLPAPER_BACKGROUND -> wallpaper?.copy(background = color) + ThemeColor.WALLPAPER_TINT -> wallpaper?.copy(tint = color) + else -> wallpaper?.copy() + } + ) + } + companion object { + fun withFilledAppDefaults(mode: DefaultThemeMode, base: DefaultTheme): ThemeModeOverride = + ThemeModeOverride( + mode = mode, + colors = ThemeOverrides(base = base).withFilledColors(base, null, null, null, null, null), + wallpaper = ThemeWallpaper(preset = PresetWallpaper.SCHOOL.filename) + ) } } @@ -204,7 +550,6 @@ val DarkColorPalette = darkColors( // background = Color.Black, surface = Color(0xFF222222), // background = Color(0xFF121212), -// surface = Color(0xFF121212), error = Color.Red, onBackground = Color(0xFFFFFBFA), onSurface = Color(0xFFFFFBFA), @@ -212,8 +557,11 @@ val DarkColorPalette = darkColors( ) val DarkColorPaletteApp = AppColors( title = SimplexBlue, - sentMessage = SentMessageColor, - receivedMessage = Color(0x20B1B0B5) + primaryVariant2 = Color(0xFF18262E), + sentMessage = Color(0xFF18262E), + sentQuote = Color(0xFF1D3847), + receivedMessage = Color(0xff262627), + receivedQuote = Color(0xff373739), ) val LightColorPalette = lightColors( @@ -231,8 +579,11 @@ val LightColorPalette = lightColors( ) val LightColorPaletteApp = AppColors( title = SimplexBlue, - sentMessage = SentMessageColor, - receivedMessage = Color(0x20B1B0B5) + primaryVariant2 = Color(0xFFE9F7FF), + sentMessage = Color(0xFFE9F7FF), + sentQuote = Color(0xFFD6F0FF), + receivedMessage = Color(0xfff5f5f6), + receivedQuote = Color(0xffececee), ) val SimplexColorPalette = darkColors( @@ -251,11 +602,39 @@ val SimplexColorPalette = darkColors( ) val SimplexColorPaletteApp = AppColors( title = Color(0xFF267BE5), - sentMessage = SentMessageColor, - receivedMessage = Color(0x20B1B0B5) + primaryVariant2 = Color(0xFF172941), + sentMessage = Color(0xFF172941), + sentQuote = Color(0xFF1C3A57), + receivedMessage = Color(0xff25283a), + receivedQuote = Color(0xff36394a), ) -val CurrentColors: MutableStateFlow = MutableStateFlow(ThemeManager.currentColors(isInNightMode())) +val BlackColorPalette = darkColors( + primary = Color(0xff0077e0), // If this value changes also need to update #0088ff in string resource files + primaryVariant = Color(0xff0077e0), + secondary = HighOrLowlight, + secondaryVariant = DarkGray, + background = Color(0xff070707), + surface = Color(0xff161617), + // background = Color(0xFF121212), + // surface = Color(0xFF121212), + error = Color.Red, + onBackground = Color(0xFFFFFBFA), + onSurface = Color(0xFFFFFBFA), + // onError: Color = Color.Black, +) +val BlackColorPaletteApp = AppColors( + title = Color(0xff0077e0), + primaryVariant2 = Color(0xff243747), + sentMessage = Color(0xFF18262E), + sentQuote = Color(0xFF1D3847), + receivedMessage = Color(0xff1b1b1b), + receivedQuote = Color(0xff29292b), +) + +var systemInDarkThemeCurrently: Boolean = isInNightMode() + +val CurrentColors: MutableStateFlow = MutableStateFlow(ThemeManager.currentColors(null, null, chatModel.currentUser.value?.uiThemes, appPreferences.themeOverrides.get())) @Composable fun isInDarkTheme(): Boolean = !CurrentColors.collectAsState().value.colors.isLight @@ -263,31 +642,113 @@ fun isInDarkTheme(): Boolean = !CurrentColors.collectAsState().value.colors.isLi @Composable expect fun isSystemInDarkTheme(): Boolean +internal val LocalAppColors = staticCompositionLocalOf { LightColorPaletteApp } +internal val LocalAppWallpaper = staticCompositionLocalOf { AppWallpaper() } + +val MaterialTheme.appColors: AppColors + @Composable + @ReadOnlyComposable + get() = LocalAppColors.current + +fun AppColors.updateColorsFrom(other: AppColors) { + title = other.title + primaryVariant2 = other.primaryVariant2 + sentMessage = other.sentMessage + sentQuote = other.sentQuote + receivedMessage = other.receivedMessage + receivedQuote = other.receivedQuote +} + +fun AppWallpaper.updateWallpaperFrom(other: AppWallpaper) { + background = other.background + tint = other.tint + type = other.type +} + +val MaterialTheme.wallpaper: AppWallpaper + @Composable + @ReadOnlyComposable + get() = LocalAppWallpaper.current + fun reactOnDarkThemeChanges(isDark: Boolean) { - if (ChatController.appPrefs.currentTheme.get() == DefaultTheme.SYSTEM.name && CurrentColors.value.colors.isLight == isDark) { + systemInDarkThemeCurrently = isDark + if (ChatController.appPrefs.currentTheme.get() == DefaultTheme.SYSTEM_THEME_NAME && CurrentColors.value.colors.isLight == isDark) { // Change active colors from light to dark and back based on system theme - ThemeManager.applyTheme(DefaultTheme.SYSTEM.name, isDark) + ThemeManager.applyTheme(DefaultTheme.SYSTEM_THEME_NAME) } } @Composable fun SimpleXTheme(darkTheme: Boolean? = null, content: @Composable () -> Unit) { - LaunchedEffect(darkTheme) { - // For preview - if (darkTheme != null) - CurrentColors.value = ThemeManager.currentColors(darkTheme) - } - val systemDark = isSystemInDarkTheme() - LaunchedEffect(systemDark) { - reactOnDarkThemeChanges(systemDark) +// TODO: Fix preview working with dark/light theme + +// LaunchedEffect(darkTheme) { +// // For preview +// if (darkTheme != null) +// CurrentColors.value = ThemeManager.currentColors(darkTheme, null, null, chatModel.currentUser.value?.uiThemes, appPreferences.themeOverrides.get()) +// } + val systemDark = rememberUpdatedState(isSystemInDarkTheme()) + LaunchedEffect(Unit) { + // snapshotFlow vs LaunchedEffect reduce number of recomposes + snapshotFlow { systemDark.value } + .collect { + reactOnDarkThemeChanges(systemDark.value) + } } val theme by CurrentColors.collectAsState() + LaunchedEffect(Unit) { + // snapshotFlow vs LaunchedEffect reduce number of recomposes when user is changed or it's themes + snapshotFlow { chatModel.currentUser.value?.uiThemes } + .collect { + ThemeManager.applyTheme(appPrefs.currentTheme.get()!!) + } + } MaterialTheme( colors = theme.colors, typography = Typography, shapes = Shapes, content = { - CompositionLocalProvider(LocalContentColor provides MaterialTheme.colors.onBackground, content = content) + val rememberedAppColors = remember { + // Explicitly creating a new object here so we don't mutate the initial [appColors] + // provided, and overwrite the values set in it. + theme.appColors.copy() + }.apply { updateColorsFrom(theme.appColors) } + val rememberedWallpaper = remember { + // Explicitly creating a new object here so we don't mutate the initial [wallpaper] + // provided, and overwrite the values set in it. + theme.wallpaper.copy() + }.apply { updateWallpaperFrom(theme.wallpaper) } + CompositionLocalProvider( + LocalContentColor provides MaterialTheme.colors.onBackground, + LocalAppColors provides rememberedAppColors, + LocalAppWallpaper provides rememberedWallpaper, + content = content) + } + ) +} + +@Composable +fun SimpleXThemeOverride(theme: ThemeManager.ActiveTheme, content: @Composable () -> Unit) { + MaterialTheme( + colors = theme.colors, + typography = Typography, + shapes = Shapes, + content = { + val rememberedAppColors = remember { + // Explicitly creating a new object here so we don't mutate the initial [appColors] + // provided, and overwrite the values set in it. + theme.appColors.copy() + }.apply { updateColorsFrom(theme.appColors) } + val rememberedWallpaper = remember { + // Explicitly creating a new object here so we don't mutate the initial [wallpaper] + // provided, and overwrite the values set in it. + theme.wallpaper.copy() + }.apply { updateWallpaperFrom(theme.wallpaper) } + CompositionLocalProvider( + LocalContentColor provides MaterialTheme.colors.onBackground, + LocalAppColors provides rememberedAppColors, + LocalAppWallpaper provides rememberedWallpaper, + content = content) } ) } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/ThemeManager.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/ThemeManager.kt index 49d3203455..2f8f6ed0bf 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/ThemeManager.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/ThemeManager.kt @@ -1,14 +1,14 @@ package chat.simplex.common.ui.theme import androidx.compose.material.Colors +import androidx.compose.runtime.MutableState import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.text.font.FontFamily -import chat.simplex.res.MR -import chat.simplex.common.model.AppPreferences -import chat.simplex.common.model.ChatController -import chat.simplex.common.platform.platform -import chat.simplex.common.views.helpers.generalGetString +import chat.simplex.common.model.* +import chat.simplex.common.platform.* +import chat.simplex.common.views.helpers.* +import java.io.File // https://github.com/rsms/inter // I place it here because IDEA shows an error (but still works anyway) when this declaration inside Type.kt @@ -18,140 +18,215 @@ expect val EmojiFont: FontFamily object ThemeManager { private val appPrefs: AppPreferences = ChatController.appPrefs - data class ActiveTheme(val name: String, val base: DefaultTheme, val colors: Colors, val appColors: AppColors) + data class ActiveTheme(val name: String, val base: DefaultTheme, val colors: Colors, val appColors: AppColors, val wallpaper: AppWallpaper = AppWallpaper()) private fun systemDarkThemeColors(): Pair = when (appPrefs.systemDarkTheme.get()) { - DefaultTheme.DARK.name -> DarkColorPalette to DefaultTheme.DARK - DefaultTheme.SIMPLEX.name -> SimplexColorPalette to DefaultTheme.SIMPLEX + DefaultTheme.DARK.themeName -> DarkColorPalette to DefaultTheme.DARK + DefaultTheme.SIMPLEX.themeName -> SimplexColorPalette to DefaultTheme.SIMPLEX + DefaultTheme.BLACK.themeName -> BlackColorPalette to DefaultTheme.BLACK else -> SimplexColorPalette to DefaultTheme.SIMPLEX } - fun currentColors(darkForSystemTheme: Boolean): ActiveTheme { + private fun nonSystemThemeName(): String { val themeName = appPrefs.currentTheme.get()!! - val themeOverrides = appPrefs.themeOverrides.get() - - val nonSystemThemeName = if (themeName != DefaultTheme.SYSTEM.name) { + return if (themeName != DefaultTheme.SYSTEM_THEME_NAME) { themeName } else { - if (darkForSystemTheme) appPrefs.systemDarkTheme.get()!! else DefaultTheme.LIGHT.name + if (systemInDarkThemeCurrently) appPrefs.systemDarkTheme.get()!! else DefaultTheme.LIGHT.themeName } - val theme = themeOverrides[nonSystemThemeName] + } + + fun defaultActiveTheme(appSettingsTheme: List): ThemeOverrides? { + val nonSystemThemeName = nonSystemThemeName() + val defaultThemeId = appPrefs.currentThemeIds.get()[nonSystemThemeName] + return appSettingsTheme.getTheme(defaultThemeId) + } + + fun defaultActiveTheme(perUserTheme: ThemeModeOverrides?, appSettingsTheme: List): ThemeModeOverride { + val perUserTheme = if (!CurrentColors.value.colors.isLight) perUserTheme?.dark else perUserTheme?.light + if (perUserTheme != null) { + return perUserTheme + } + val defaultTheme = defaultActiveTheme(appSettingsTheme) + return ThemeModeOverride(colors = defaultTheme?.colors ?: ThemeColors(), wallpaper = defaultTheme?.wallpaper) + } + + fun currentColors(themeOverridesForType: WallpaperType?, perChatTheme: ThemeModeOverride?, perUserTheme: ThemeModeOverrides?, appSettingsTheme: List): ActiveTheme { + val themeName = appPrefs.currentTheme.get()!! + val nonSystemThemeName = nonSystemThemeName() + val defaultTheme = defaultActiveTheme(appSettingsTheme) + val baseTheme = when (nonSystemThemeName) { - DefaultTheme.LIGHT.name -> Triple(DefaultTheme.LIGHT, LightColorPalette, LightColorPaletteApp) - DefaultTheme.DARK.name -> Triple(DefaultTheme.DARK, DarkColorPalette, DarkColorPaletteApp) - DefaultTheme.SIMPLEX.name -> Triple(DefaultTheme.SIMPLEX, SimplexColorPalette, SimplexColorPaletteApp) - else -> Triple(DefaultTheme.LIGHT, LightColorPalette, LightColorPaletteApp) + DefaultTheme.LIGHT.themeName -> ActiveTheme(DefaultTheme.LIGHT.themeName, DefaultTheme.LIGHT, LightColorPalette, LightColorPaletteApp, AppWallpaper(type = PresetWallpaper.SCHOOL.toType(DefaultTheme.LIGHT))) + DefaultTheme.DARK.themeName -> ActiveTheme(DefaultTheme.DARK.themeName, DefaultTheme.DARK, DarkColorPalette, DarkColorPaletteApp, AppWallpaper(type = PresetWallpaper.SCHOOL.toType(DefaultTheme.DARK))) + DefaultTheme.SIMPLEX.themeName -> ActiveTheme(DefaultTheme.SIMPLEX.themeName, DefaultTheme.SIMPLEX, SimplexColorPalette, SimplexColorPaletteApp, AppWallpaper(type = PresetWallpaper.SCHOOL.toType(DefaultTheme.SIMPLEX))) + DefaultTheme.BLACK.themeName -> ActiveTheme(DefaultTheme.BLACK.themeName, DefaultTheme.BLACK, BlackColorPalette, BlackColorPaletteApp, AppWallpaper(type = PresetWallpaper.SCHOOL.toType(DefaultTheme.BLACK))) + else -> ActiveTheme(DefaultTheme.LIGHT.themeName, DefaultTheme.LIGHT, LightColorPalette, LightColorPaletteApp, AppWallpaper(type = PresetWallpaper.SCHOOL.toType(DefaultTheme.LIGHT))) } - if (theme == null) { - return ActiveTheme(themeName, baseTheme.first, baseTheme.second, baseTheme.third) + + val perUserTheme = if (baseTheme.colors.isLight) perUserTheme?.light else perUserTheme?.dark + val theme = (appSettingsTheme.sameTheme(themeOverridesForType ?: perChatTheme?.type ?: perUserTheme?.type ?: defaultTheme?.wallpaper?.toAppWallpaper()?.type, nonSystemThemeName) ?: defaultTheme) + + if (theme == null && perUserTheme == null && perChatTheme == null && themeOverridesForType == null) { + return ActiveTheme(themeName, baseTheme.base, baseTheme.colors, baseTheme.appColors, baseTheme.wallpaper) } - return ActiveTheme(themeName, baseTheme.first, theme.colors.toColors(theme.base), theme.colors.toAppColors(theme.base)) + val presetWallpaperTheme = when { + perChatTheme?.wallpaper != null -> if (perChatTheme.wallpaper.preset != null) PresetWallpaper.from(perChatTheme.wallpaper.preset)?.colors?.get(baseTheme.base) else null + perUserTheme?.wallpaper != null -> if (perUserTheme.wallpaper.preset != null) PresetWallpaper.from(perUserTheme.wallpaper.preset)?.colors?.get(baseTheme.base) else null + else -> if (theme?.wallpaper?.preset != null) PresetWallpaper.from(theme.wallpaper.preset)?.colors?.get(baseTheme.base) else null + } + val themeOrEmpty = theme ?: ThemeOverrides(base = baseTheme.base) + val colors = themeOrEmpty.toColors(themeOrEmpty.base, perChatTheme?.colors, perUserTheme?.colors, presetWallpaperTheme) + return ActiveTheme( + themeName, + baseTheme.base, + colors, + themeOrEmpty.toAppColors(themeOrEmpty.base, perChatTheme?.colors, perChatTheme?.type, perUserTheme?.colors, perUserTheme?.type, presetWallpaperTheme), + themeOrEmpty.toAppWallpaper(themeOverridesForType, perChatTheme, perUserTheme, colors.background) + ) } - fun currentThemeOverridesForExport(darkForSystemTheme: Boolean): ThemeOverrides { - val themeName = appPrefs.currentTheme.get()!! - val nonSystemThemeName = if (themeName != DefaultTheme.SYSTEM.name) { - themeName - } else { - if (darkForSystemTheme) appPrefs.systemDarkTheme.get()!! else DefaultTheme.LIGHT.name - } - val overrides = appPrefs.themeOverrides.get().toMutableMap() - val nonFilledTheme = overrides[nonSystemThemeName] ?: ThemeOverrides(base = CurrentColors.value.base, colors = ThemeColors()) - return nonFilledTheme.copy(colors = nonFilledTheme.colors.withFilledColors(CurrentColors.value.base)) + fun currentThemeOverridesForExport(perChatTheme: ThemeModeOverride?, perUserTheme: ThemeModeOverrides?): ThemeOverrides { + val current = currentColors(null, perChatTheme, perUserTheme, appPrefs.themeOverrides.get()) + val wType = current.wallpaper.type + val wBackground = current.wallpaper.background + val wTint = current.wallpaper.tint + return ThemeOverrides( + themeId = "", + base = current.base, + colors = ThemeColors.from(current.colors, current.appColors), + wallpaper = if (wType !is WallpaperType.Empty) ThemeWallpaper.from(wType, wBackground?.toReadableHex(), wTint?.toReadableHex()).withFilledWallpaperBase64() else null + ) } - // colors, default theme enum, localized name of theme - fun allThemes(darkForSystemTheme: Boolean): List> { - val allThemes = ArrayList>() - allThemes.add( - Triple( - if (darkForSystemTheme) systemDarkThemeColors().first else LightColorPalette, - DefaultTheme.SYSTEM, - generalGetString(MR.strings.theme_system) - ) - ) - allThemes.add( - Triple( - LightColorPalette, - DefaultTheme.LIGHT, - generalGetString(MR.strings.theme_light) - ) - ) - allThemes.add( - Triple( - DarkColorPalette, - DefaultTheme.DARK, - generalGetString(MR.strings.theme_dark) - ) - ) - allThemes.add( - Triple( - SimplexColorPalette, - DefaultTheme.SIMPLEX, - generalGetString(MR.strings.theme_simplex) - ) - ) - return allThemes - } - - fun applyTheme(theme: String, darkForSystemTheme: Boolean) { + fun applyTheme(theme: String) { appPrefs.currentTheme.set(theme) - CurrentColors.value = currentColors(darkForSystemTheme) + CurrentColors.value = currentColors(null, null, chatModel.currentUser.value?.uiThemes, appPrefs.themeOverrides.get()) platform.androidSetNightModeIfSupported() } - fun changeDarkTheme(theme: String, darkForSystemTheme: Boolean) { + fun changeDarkTheme(theme: String) { appPrefs.systemDarkTheme.set(theme) - CurrentColors.value = currentColors(darkForSystemTheme) + CurrentColors.value = currentColors(null, null, chatModel.currentUser.value?.uiThemes, appPrefs.themeOverrides.get()) } - fun saveAndApplyThemeColor(name: ThemeColor, color: Color? = null, darkForSystemTheme: Boolean) { - val themeName = appPrefs.currentTheme.get()!! - val nonSystemThemeName = if (themeName != DefaultTheme.SYSTEM.name) { - themeName - } else { - if (darkForSystemTheme) appPrefs.systemDarkTheme.get()!! else DefaultTheme.LIGHT.name + fun saveAndApplyThemeColor(baseTheme: DefaultTheme, name: ThemeColor, color: Color? = null, pref: SharedPreference> = appPrefs.themeOverrides) { + val nonSystemThemeName = baseTheme.themeName + val overrides = pref.get() + val themeId = appPrefs.currentThemeIds.get()[nonSystemThemeName] + val prevValue = overrides.getTheme(themeId) ?: ThemeOverrides(base = baseTheme) + pref.set(overrides.replace(prevValue.withUpdatedColor(name, color?.toReadableHex()))) + val themeIds = appPrefs.currentThemeIds.get().toMutableMap() + themeIds[nonSystemThemeName] = prevValue.themeId + appPrefs.currentThemeIds.set(themeIds) + CurrentColors.value = currentColors(null, null, chatModel.currentUser.value?.uiThemes, appPrefs.themeOverrides.get()) + } + + fun applyThemeColor(name: ThemeColor, color: Color? = null, pref: MutableState) { + pref.value = pref.value.withUpdatedColor(name, color?.toReadableHex()) + } + + fun saveAndApplyWallpaper(baseTheme: DefaultTheme, type: WallpaperType?, pref: SharedPreference> = appPrefs.themeOverrides) { + val nonSystemThemeName = baseTheme.themeName + val overrides = pref.get() + val theme = overrides.sameTheme(type, baseTheme.themeName) + val prevValue = theme ?: ThemeOverrides(base = baseTheme) + pref.set(overrides.replace(prevValue.copy(wallpaper = if (type != null && type !is WallpaperType.Empty) ThemeWallpaper.from(type, prevValue.wallpaper?.background, prevValue.wallpaper?.tint) else null))) + val themeIds = appPrefs.currentThemeIds.get().toMutableMap() + themeIds[nonSystemThemeName] = prevValue.themeId + appPrefs.currentThemeIds.set(themeIds) + CurrentColors.value = currentColors( null, null, chatModel.currentUser.value?.uiThemes, appPrefs.themeOverrides.get()) + } + + fun copyFromSameThemeOverrides(type: WallpaperType?, lowerLevelOverride: ThemeModeOverride?, pref: MutableState): Boolean { + val overrides = appPrefs.themeOverrides.get() + val sameWallpaper = if (lowerLevelOverride?.type?.sameType(type) == true) lowerLevelOverride.wallpaper else overrides.sameTheme(type, CurrentColors.value.base.themeName)?.wallpaper + if (sameWallpaper == null) { + if (type != null) { + pref.value = ThemeModeOverride(wallpaper = ThemeWallpaper.from(type, null, null).copy(scale = null, scaleType = null)) + } else { + // Make an empty wallpaper to override any top level ones + pref.value = ThemeModeOverride(wallpaper = ThemeWallpaper()) + } + return true } - var colorToSet = color - if (colorToSet == null) { - // Setting default color from a base theme - colorToSet = when(nonSystemThemeName) { - DefaultTheme.LIGHT.name -> name.fromColors(LightColorPalette, LightColorPaletteApp) - DefaultTheme.DARK.name -> name.fromColors(DarkColorPalette, DarkColorPaletteApp) - DefaultTheme.SIMPLEX.name -> name.fromColors(SimplexColorPalette, SimplexColorPaletteApp) - // Will not be here - else -> return + var type = sameWallpaper.toAppWallpaper().type + if (type is WallpaperType.Image && sameWallpaper.imageFile == type.filename) { + // same image file. Needs to be copied first in order to be able to remove the file once it's not needed anymore without affecting main theme override + val filename = saveWallpaperFile(File(getWallpaperFilePath(type.filename)).toURI()) + if (filename != null) { + type = WallpaperType.Image(filename, type.scale, type.scaleType) + } else { + Log.e(TAG, "Error while copying wallpaper from global overrides to chat overrides") + return false } } - val overrides = appPrefs.themeOverrides.get().toMutableMap() - val prevValue = overrides[nonSystemThemeName] ?: ThemeOverrides(base = CurrentColors.value.base, colors = ThemeColors()) - overrides[nonSystemThemeName] = prevValue.withUpdatedColor(name, colorToSet.toReadableHex()) - appPrefs.themeOverrides.set(overrides) - CurrentColors.value = currentColors(!CurrentColors.value.colors.isLight) + val prevValue = pref.value + pref.value = prevValue.copy( + colors = ThemeColors(), + wallpaper = ThemeWallpaper.from(type, null, null).copy(scale = null, scaleType = null) + ) + return true } - fun saveAndApplyThemeOverrides(theme: ThemeOverrides, darkForSystemTheme: Boolean) { - val overrides = appPrefs.themeOverrides.get().toMutableMap() - val prevValue = overrides[theme.base.name] ?: ThemeOverrides(base = CurrentColors.value.base, colors = ThemeColors()) - overrides[theme.base.name] = prevValue.copy(colors = theme.colors) - appPrefs.themeOverrides.set(overrides) - appPrefs.currentTheme.set(theme.base.name) - CurrentColors.value = currentColors(!CurrentColors.value.colors.isLight) + fun applyWallpaper(type: WallpaperType?, pref: MutableState) { + val prevValue = pref.value + pref.value = prevValue.copy( + wallpaper = if (type != null) + ThemeWallpaper.from(type, prevValue.wallpaper?.background, prevValue.wallpaper?.tint) + else null + ) } - fun resetAllThemeColors(darkForSystemTheme: Boolean) { - val themeName = appPrefs.currentTheme.get()!! - val nonSystemThemeName = if (themeName != DefaultTheme.SYSTEM.name) { - themeName - } else { - if (darkForSystemTheme) appPrefs.systemDarkTheme.get()!! else DefaultTheme.LIGHT.name + fun saveAndApplyThemeOverrides(theme: ThemeOverrides, pref: SharedPreference> = appPrefs.themeOverrides) { + val wallpaper = theme.wallpaper?.importFromString() + val nonSystemThemeName = theme.base.themeName + val overrides = pref.get() + val prevValue = overrides.getTheme(null, wallpaper?.toAppWallpaper()?.type, theme.base) ?: ThemeOverrides(base = theme.base) + if (prevValue.wallpaper?.imageFile != null) { + File(getWallpaperFilePath(prevValue.wallpaper.imageFile)).delete() + } + pref.set(overrides.replace(prevValue.copy(base = theme.base, colors = theme.colors, wallpaper = wallpaper))) + appPrefs.currentTheme.set(nonSystemThemeName) + val currentThemeIds = appPrefs.currentThemeIds.get().toMutableMap() + currentThemeIds[nonSystemThemeName] = prevValue.themeId + appPrefs.currentThemeIds.set(currentThemeIds) + CurrentColors.value = currentColors(null, null, chatModel.currentUser.value?.uiThemes, appPrefs.themeOverrides.get()) + } + + fun resetAllThemeColors(pref: SharedPreference> = appPrefs.themeOverrides) { + val nonSystemThemeName = nonSystemThemeName() + val themeId = appPrefs.currentThemeIds.get()[nonSystemThemeName] ?: return + val overrides = pref.get() + val prevValue = overrides.getTheme(themeId) ?: return + pref.set(overrides.replace(prevValue.copy(colors = ThemeColors(), wallpaper = prevValue.wallpaper?.copy(background = null, tint = null)))) + CurrentColors.value = currentColors(null, null, chatModel.currentUser.value?.uiThemes, appPrefs.themeOverrides.get()) + } + + fun resetAllThemeColors(pref: MutableState) { + val prevValue = pref.value + pref.value = prevValue.copy(colors = ThemeColors(), wallpaper = prevValue.wallpaper?.copy(background = null, tint = null)) + } + + fun removeTheme(themeId: String?) { + val themes = ArrayList(appPrefs.themeOverrides.get()) + themes.removeAll { it.themeId == themeId } + appPrefs.themeOverrides.set(themes) + } + + fun String.colorFromReadableHex(): Color = + Color(this.replace("#", "").toLongOrNull(16) ?: Color.White.toArgb().toLong()) + + fun Color.toReadableHex(): String { + val s = Integer.toHexString(toArgb()) + return when { + this == Color.Transparent -> "#00ffffff" + s.length == 1 -> "#ff$s$s$s$s$s$s" + s.length == 2 -> "#ff$s$s$s" + s.length == 3 -> "#ff$s$s" + s.length == 6 && this.alpha == 0f -> "#00$s" + s.length == 6 -> "#ff$s" + else -> "#$s" } - val overrides = appPrefs.themeOverrides.get().toMutableMap() - val prevValue = overrides[nonSystemThemeName] ?: return - overrides[nonSystemThemeName] = prevValue.copy(colors = ThemeColors()) - appPrefs.themeOverrides.set(overrides) - CurrentColors.value = currentColors(!CurrentColors.value.colors.isLight) } } - -private fun Color.toReadableHex(): String = "#" + Integer.toHexString(toArgb()) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatInfoView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatInfoView.kt index dcd36e026b..9b1e908e6b 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatInfoView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatInfoView.kt @@ -29,6 +29,7 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import chat.simplex.common.model.* +import chat.simplex.common.model.ChatController.appPrefs import chat.simplex.common.model.ChatModel.controller import chat.simplex.common.ui.theme.* import chat.simplex.common.views.helpers.* @@ -337,6 +338,16 @@ fun ChatInfoLayout( if (cStats != null && cStats.ratchetSyncAllowed) { SynchronizeConnectionButton(syncContactConnection) } + + WallpaperButton { + ModalManager.end.showModal { + val chat = remember { derivedStateOf { chatModel.chats.firstOrNull { it.id == chat.id } } } + val c = chat.value + if (c != null) { + ChatWallpaperEditorModal(c) + } + } + } // } else if (developerTools) { // SynchronizeConnectionButtonForce(syncContactConnectionForce) // } @@ -642,6 +653,15 @@ private fun SendReceiptsOption(currentUser: User, state: State, on ) } +@Composable +fun WallpaperButton(onClick: () -> Unit) { + SettingsActionItem( + painterResource(MR.images.ic_image), + stringResource(MR.strings.settings_section_title_chat_theme), + click = onClick + ) +} + @Composable fun ClearChatButton(onClick: () -> Unit) { SettingsActionItem( @@ -675,6 +695,51 @@ fun ShareAddressButton(onClick: () -> Unit) { ) } +@Composable +fun ModalData.ChatWallpaperEditorModal(chat: Chat) { + val themes = remember(CurrentColors.collectAsState().value.base) { + (chat.chatInfo as? ChatInfo.Direct)?.contact?.uiThemes + ?: (chat.chatInfo as? ChatInfo.Group)?.groupInfo?.uiThemes + ?: ThemeModeOverrides() + } + val globalThemeUsed = remember { stateGetOrPut("globalThemeUsed") { false } } + val initialTheme = remember(CurrentColors.collectAsState().value.base) { + val preferred = themes.preferredMode(!CurrentColors.value.colors.isLight) + globalThemeUsed.value = preferred == null + preferred ?: ThemeManager.defaultActiveTheme(chatModel.currentUser.value?.uiThemes, appPrefs.themeOverrides.get()) + } + ChatWallpaperEditor( + initialTheme, + applyToMode = if (themes.light == themes.dark) null else initialTheme.mode, + globalThemeUsed = globalThemeUsed, + save = { applyToMode, newTheme -> + save(applyToMode, newTheme, chatModel.getChat(chat.id) ?: chat) + }) +} + +suspend fun save(applyToMode: DefaultThemeMode?, newTheme: ThemeModeOverride?, chat: Chat) { + val unchangedThemes: ThemeModeOverrides = ((chat.chatInfo as? ChatInfo.Direct)?.contact?.uiThemes ?: (chat.chatInfo as? ChatInfo.Group)?.groupInfo?.uiThemes) ?: ThemeModeOverrides() + val wallpaperFiles = listOf(unchangedThemes.light?.wallpaper?.imageFile, unchangedThemes.dark?.wallpaper?.imageFile) + var changedThemes: ThemeModeOverrides? = unchangedThemes + val changed = newTheme?.copy(wallpaper = newTheme.wallpaper?.withFilledWallpaperPath()) + changedThemes = when (applyToMode) { + null -> changedThemes?.copy(light = changed?.copy(mode = DefaultThemeMode.LIGHT), dark = changed?.copy(mode = DefaultThemeMode.DARK)) + DefaultThemeMode.LIGHT -> changedThemes?.copy(light = changed?.copy(mode = applyToMode)) + DefaultThemeMode.DARK -> changedThemes?.copy(dark = changed?.copy(mode = applyToMode)) + } + changedThemes = if (changedThemes?.light != null || changedThemes?.dark != null) changedThemes else null + val wallpaperFilesToDelete = wallpaperFiles - changedThemes?.light?.wallpaper?.imageFile - changedThemes?.dark?.wallpaper?.imageFile + wallpaperFilesToDelete.forEach(::removeWallpaperFile) + + if (controller.apiSetChatUIThemes(chat.remoteHostId, chat.id, changedThemes)) { + if (chat.chatInfo is ChatInfo.Direct) { + chatModel.updateChatInfo(chat.remoteHostId, chat.chatInfo.copy(contact = chat.chatInfo.contact.copy(uiThemes = changedThemes))) + } else if (chat.chatInfo is ChatInfo.Group) { + chatModel.updateChatInfo(chat.remoteHostId, chat.chatInfo.copy(groupInfo = chat.chatInfo.groupInfo.copy(uiThemes = changedThemes))) + } + } +} + private fun setContactAlias(chat: Chat, localAlias: String, chatModel: ChatModel) = withBGApi { val chatRh = chat.remoteHostId chatModel.controller.apiSetContactAlias(chatRh, chat.chatInfo.apiId, localAlias)?.let { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatItemInfoView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatItemInfoView.kt index e00592bce9..1e564db134 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatItemInfoView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatItemInfoView.kt @@ -42,7 +42,7 @@ sealed class CIInfoTab { @Composable fun ChatItemInfoView(chatRh: Long?, ci: ChatItem, ciInfo: ChatItemInfo, devTools: Boolean) { val sent = ci.chatDir.sent - val appColors = CurrentColors.collectAsState().value.appColors + val appColors = MaterialTheme.appColors val uriHandler = LocalUriHandler.current val selection = remember { mutableStateOf(CIInfoTab.History) } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt index 6c3a884a0e..60f741b9af 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt @@ -5,25 +5,24 @@ import androidx.compose.foundation.* import androidx.compose.foundation.gestures.* import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.* -import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.* import androidx.compose.runtime.* import androidx.compose.runtime.saveable.mapSaver import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.* -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color +import androidx.compose.ui.draw.drawBehind +import androidx.compose.ui.graphics.* import androidx.compose.ui.platform.* import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.intl.Locale import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.text.* import androidx.compose.ui.unit.* import chat.simplex.common.model.* +import chat.simplex.common.model.ChatController.appPrefs import chat.simplex.common.model.ChatModel.controller import chat.simplex.common.ui.theme.* import chat.simplex.common.views.call.* @@ -118,369 +117,373 @@ fun ChatView(chatId: String, chatModel: ChatModel, onComposed: suspend (chatId: val clipboard = LocalClipboardManager.current when (chat.chatInfo) { is ChatInfo.Direct, is ChatInfo.Group, is ChatInfo.Local -> { - ChatLayout( - chat, - unreadCount, - composeState, - composeView = { - Column( - Modifier.fillMaxWidth(), - horizontalAlignment = Alignment.CenterHorizontally - ) { - if ( - chat.chatInfo is ChatInfo.Direct - && !chat.chatInfo.contact.ready - && chat.chatInfo.contact.active - && !chat.chatInfo.contact.nextSendGrpInv + val perChatTheme = remember(chat.chatInfo, CurrentColors.value.base) { if (chat.chatInfo is ChatInfo.Direct) chat.chatInfo.contact.uiThemes?.preferredMode(!CurrentColors.value.colors.isLight) else if (chat.chatInfo is ChatInfo.Group) chat.chatInfo.groupInfo.uiThemes?.preferredMode(!CurrentColors.value.colors.isLight) else null } + val overrides = if (perChatTheme != null) ThemeManager.currentColors(null, perChatTheme, chatModel.currentUser.value?.uiThemes, appPrefs.themeOverrides.get()) else null + SimpleXThemeOverride(overrides ?: CurrentColors.collectAsState().value) { + ChatLayout( + chat, + unreadCount, + composeState, + composeView = { + Column( + Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally ) { - Text( - generalGetString(MR.strings.contact_connection_pending), - Modifier.padding(top = 4.dp), - fontSize = 14.sp, - color = MaterialTheme.colors.secondary + if ( + chat.chatInfo is ChatInfo.Direct + && !chat.chatInfo.contact.ready + && chat.chatInfo.contact.active + && !chat.chatInfo.contact.nextSendGrpInv + ) { + Text( + generalGetString(MR.strings.contact_connection_pending), + Modifier.padding(top = 4.dp), + fontSize = 14.sp, + color = MaterialTheme.colors.secondary + ) + } + ComposeView( + chatModel, chat, composeState, attachmentOption, + showChooseAttachment = { scope.launch { attachmentBottomSheetState.show() } } ) } - ComposeView( - chatModel, chat, composeState, attachmentOption, - showChooseAttachment = { scope.launch { attachmentBottomSheetState.show() } } - ) - } - }, - attachmentOption, - attachmentBottomSheetState, - searchText, - useLinkPreviews = useLinkPreviews, - linkMode = chatModel.simplexLinkMode.value, - back = { - hideKeyboard(view) - AudioPlayer.stop() - chatModel.chatId.value = null - chatModel.groupMembers.clear() - }, - info = { - if (ModalManager.end.hasModalsOpen()) { - ModalManager.end.closeModals() - return@ChatLayout - } - hideKeyboard(view) - withBGApi { - // The idea is to preload information before showing a modal because large groups can take time to load all members - var preloadedContactInfo: Pair? = null - var preloadedCode: String? = null - var preloadedLink: Pair? = null - if (chat.chatInfo is ChatInfo.Direct) { - preloadedContactInfo = chatModel.controller.apiContactInfo(chatRh, chat.chatInfo.apiId) - preloadedCode = chatModel.controller.apiGetContactCode(chatRh, chat.chatInfo.apiId)?.second - } else if (chat.chatInfo is ChatInfo.Group) { - setGroupMembers(chatRh, chat.chatInfo.groupInfo, chatModel) - preloadedLink = chatModel.controller.apiGetGroupLink(chatRh, chat.chatInfo.groupInfo.groupId) + }, + attachmentOption, + attachmentBottomSheetState, + searchText, + useLinkPreviews = useLinkPreviews, + linkMode = chatModel.simplexLinkMode.value, + back = { + hideKeyboard(view) + AudioPlayer.stop() + chatModel.chatId.value = null + chatModel.groupMembers.clear() + }, + info = { + if (ModalManager.end.hasModalsOpen()) { + ModalManager.end.closeModals() + return@ChatLayout } - ModalManager.end.showModalCloseable(true) { close -> - val chat = remember { activeChat }.value - if (chat?.chatInfo is ChatInfo.Direct) { - var contactInfo: Pair? by remember { mutableStateOf(preloadedContactInfo) } - var code: String? by remember { mutableStateOf(preloadedCode) } - KeyChangeEffect(chat.id, ChatModel.networkStatuses.toMap()) { - contactInfo = chatModel.controller.apiContactInfo(chatRh, chat.chatInfo.apiId) - preloadedContactInfo = contactInfo - code = chatModel.controller.apiGetContactCode(chatRh, chat.chatInfo.apiId)?.second - preloadedCode = code - } - ChatInfoView(chatModel, (chat.chatInfo as ChatInfo.Direct).contact, contactInfo?.first, contactInfo?.second, chat.chatInfo.localAlias, code, close) - } else if (chat?.chatInfo is ChatInfo.Group) { - var link: Pair? by remember(chat.id) { mutableStateOf(preloadedLink) } - KeyChangeEffect(chat.id) { - setGroupMembers(chatRh, (chat.chatInfo as ChatInfo.Group).groupInfo, chatModel) - link = chatModel.controller.apiGetGroupLink(chatRh, chat.chatInfo.groupInfo.groupId) - preloadedLink = link - } - GroupChatInfoView(chatModel, chatRh, chat.id, link?.first, link?.second, { - link = it - preloadedLink = it - }, close) - } - } - } - }, - showMemberInfo = { groupInfo: GroupInfo, member: GroupMember -> - hideKeyboard(view) - withBGApi { - val r = chatModel.controller.apiGroupMemberInfo(chatRh, groupInfo.groupId, member.groupMemberId) - val stats = r?.second - val (_, code) = if (member.memberActive) { - val memCode = chatModel.controller.apiGetGroupMemberCode(chatRh, groupInfo.apiId, member.groupMemberId) - member to memCode?.second - } else { - member to null - } - setGroupMembers(chatRh, groupInfo, chatModel) - ModalManager.end.closeModals() - ModalManager.end.showModalCloseable(true) { close -> - remember { derivedStateOf { chatModel.getGroupMember(member.groupMemberId) } }.value?.let { mem -> - GroupMemberInfoView(chatRh, groupInfo, mem, stats, code, chatModel, close, close) - } - } - } - }, - loadPrevMessages = { - if (chatModel.chatId.value != activeChat.value?.id) return@ChatLayout - val c = chatModel.getChat(chatModel.chatId.value ?: return@ChatLayout) - val firstId = chatModel.chatItems.value.firstOrNull()?.id - if (c != null && firstId != null) { + hideKeyboard(view) withBGApi { - apiLoadPrevMessages(c, chatModel, firstId, searchText.value) + // The idea is to preload information before showing a modal because large groups can take time to load all members + var preloadedContactInfo: Pair? = null + var preloadedCode: String? = null + var preloadedLink: Pair? = null + if (chat.chatInfo is ChatInfo.Direct) { + preloadedContactInfo = chatModel.controller.apiContactInfo(chatRh, chat.chatInfo.apiId) + preloadedCode = chatModel.controller.apiGetContactCode(chatRh, chat.chatInfo.apiId)?.second + } else if (chat.chatInfo is ChatInfo.Group) { + setGroupMembers(chatRh, chat.chatInfo.groupInfo, chatModel) + preloadedLink = chatModel.controller.apiGetGroupLink(chatRh, chat.chatInfo.groupInfo.groupId) + } + ModalManager.end.showModalCloseable(true) { close -> + val chat = remember { activeChat }.value + if (chat?.chatInfo is ChatInfo.Direct) { + var contactInfo: Pair? by remember { mutableStateOf(preloadedContactInfo) } + var code: String? by remember { mutableStateOf(preloadedCode) } + KeyChangeEffect(chat.id, ChatModel.networkStatuses.toMap()) { + contactInfo = chatModel.controller.apiContactInfo(chatRh, chat.chatInfo.apiId) + preloadedContactInfo = contactInfo + code = chatModel.controller.apiGetContactCode(chatRh, chat.chatInfo.apiId)?.second + preloadedCode = code + } + ChatInfoView(chatModel, (chat.chatInfo as ChatInfo.Direct).contact, contactInfo?.first, contactInfo?.second, chat.chatInfo.localAlias, code, close) + } else if (chat?.chatInfo is ChatInfo.Group) { + var link: Pair? by remember(chat.id) { mutableStateOf(preloadedLink) } + KeyChangeEffect(chat.id) { + setGroupMembers(chatRh, (chat.chatInfo as ChatInfo.Group).groupInfo, chatModel) + link = chatModel.controller.apiGetGroupLink(chatRh, chat.chatInfo.groupInfo.groupId) + preloadedLink = link + } + GroupChatInfoView(chatModel, chatRh, chat.id, link?.first, link?.second, { + link = it + preloadedLink = it + }, close) + } + } } - } - }, - deleteMessage = { itemId, mode -> - withBGApi { - val cInfo = chat.chatInfo - val toDeleteItem = chatModel.chatItems.value.firstOrNull { it.id == itemId } - val toModerate = toDeleteItem?.memberToModerate(chat.chatInfo) - val groupInfo = toModerate?.first - val groupMember = toModerate?.second - val deletedChatItem: ChatItem? - val toChatItem: ChatItem? - if (mode == CIDeleteMode.cidmBroadcast && groupInfo != null && groupMember != null) { - val r = chatModel.controller.apiDeleteMemberChatItem( - chatRh, - groupId = groupInfo.groupId, - groupMemberId = groupMember.groupMemberId, - itemId = itemId - ) - deletedChatItem = r?.first - toChatItem = r?.second - } else { - val r = chatModel.controller.apiDeleteChatItem( - chatRh, + }, + showMemberInfo = { groupInfo: GroupInfo, member: GroupMember -> + hideKeyboard(view) + withBGApi { + val r = chatModel.controller.apiGroupMemberInfo(chatRh, groupInfo.groupId, member.groupMemberId) + val stats = r?.second + val (_, code) = if (member.memberActive) { + val memCode = chatModel.controller.apiGetGroupMemberCode(chatRh, groupInfo.apiId, member.groupMemberId) + member to memCode?.second + } else { + member to null + } + setGroupMembers(chatRh, groupInfo, chatModel) + ModalManager.end.closeModals() + ModalManager.end.showModalCloseable(true) { close -> + remember { derivedStateOf { chatModel.getGroupMember(member.groupMemberId) } }.value?.let { mem -> + GroupMemberInfoView(chatRh, groupInfo, mem, stats, code, chatModel, close, close) + } + } + } + }, + loadPrevMessages = { + if (chatModel.chatId.value != activeChat.value?.id) return@ChatLayout + val c = chatModel.getChat(chatModel.chatId.value ?: return@ChatLayout) + val firstId = chatModel.chatItems.value.firstOrNull()?.id + if (c != null && firstId != null) { + withBGApi { + apiLoadPrevMessages(c, chatModel, firstId, searchText.value) + } + } + }, + deleteMessage = { itemId, mode -> + withBGApi { + val cInfo = chat.chatInfo + val toDeleteItem = chatModel.chatItems.value.firstOrNull { it.id == itemId } + val toModerate = toDeleteItem?.memberToModerate(chat.chatInfo) + val groupInfo = toModerate?.first + val groupMember = toModerate?.second + val deletedChatItem: ChatItem? + val toChatItem: ChatItem? + if (mode == CIDeleteMode.cidmBroadcast && groupInfo != null && groupMember != null) { + val r = chatModel.controller.apiDeleteMemberChatItem( + chatRh, + groupId = groupInfo.groupId, + groupMemberId = groupMember.groupMemberId, + itemId = itemId + ) + deletedChatItem = r?.first + toChatItem = r?.second + } else { + val r = chatModel.controller.apiDeleteChatItem( + chatRh, + type = cInfo.chatType, + id = cInfo.apiId, + itemId = itemId, + mode = mode + ) + deletedChatItem = r?.deletedChatItem?.chatItem + toChatItem = r?.toChatItem?.chatItem + } + if (toChatItem == null && deletedChatItem != null) { + chatModel.removeChatItem(chatRh, cInfo, deletedChatItem) + } else if (toChatItem != null) { + chatModel.upsertChatItem(chatRh, cInfo, toChatItem) + } + } + }, + deleteMessages = { itemIds -> + if (itemIds.isNotEmpty()) { + val chatInfo = chat.chatInfo + withBGApi { + val deletedItems: ArrayList = arrayListOf() + for (itemId in itemIds) { + val di = chatModel.controller.apiDeleteChatItem( + chatRh, chatInfo.chatType, chatInfo.apiId, itemId, CIDeleteMode.cidmInternal + )?.deletedChatItem?.chatItem + if (di != null) { + deletedItems.add(di) + } + } + for (di in deletedItems) { + chatModel.removeChatItem(chatRh, chatInfo, di) + } + } + } + }, + receiveFile = { fileId -> + withBGApi { chatModel.controller.receiveFile(chatRh, user, fileId) } + }, + cancelFile = { fileId -> + withBGApi { chatModel.controller.cancelFile(chatRh, user, fileId) } + }, + joinGroup = { groupId, onComplete -> + withBGApi { + chatModel.controller.apiJoinGroup(chatRh, groupId) + onComplete.invoke() + } + }, + startCall = out@{ media -> + withBGApi { + val cInfo = chat.chatInfo + if (cInfo is ChatInfo.Direct) { + val contactInfo = chatModel.controller.apiContactInfo(chat.remoteHostId, cInfo.contact.contactId) + val profile = contactInfo?.second ?: chatModel.currentUser.value?.profile?.toProfile() ?: return@withBGApi + chatModel.activeCall.value = Call(remoteHostId = chatRh, contact = cInfo.contact, callState = CallState.WaitCapabilities, localMedia = media, userProfile = profile) + chatModel.showCallView.value = true + chatModel.callCommand.add(WCallCommand.Capabilities(media)) + } + } + }, + endCall = { + val call = chatModel.activeCall.value + if (call != null) withBGApi { chatModel.callManager.endCall(call) } + }, + acceptCall = { contact -> + hideKeyboard(view) + withBGApi { + val invitation = chatModel.callInvitations.remove(contact.id) + ?: controller.apiGetCallInvitations(chatModel.remoteHostId()).firstOrNull { it.contact.id == contact.id } + if (invitation == null) { + AlertManager.shared.showAlertMsg(generalGetString(MR.strings.call_already_ended)) + } else { + chatModel.callManager.acceptIncomingCall(invitation = invitation) + } + } + }, + acceptFeature = { contact, feature, param -> + withBGApi { + chatModel.controller.allowFeatureToContact(chatRh, contact, feature, param) + } + }, + openDirectChat = { contactId -> + withBGApi { + openDirectChat(chatRh, contactId, chatModel) + } + }, + updateContactStats = { contact -> + withBGApi { + val r = chatModel.controller.apiContactInfo(chatRh, chat.chatInfo.apiId) + if (r != null) { + val contactStats = r.first + if (contactStats != null) + chatModel.updateContactConnectionStats(chatRh, contact, contactStats) + } + } + }, + updateMemberStats = { groupInfo, member -> + withBGApi { + val r = chatModel.controller.apiGroupMemberInfo(chatRh, groupInfo.groupId, member.groupMemberId) + if (r != null) { + val memStats = r.second + if (memStats != null) { + chatModel.updateGroupMemberConnectionStats(chatRh, groupInfo, r.first, memStats) + } + } + } + }, + syncContactConnection = { contact -> + withBGApi { + val cStats = chatModel.controller.apiSyncContactRatchet(chatRh, contact.contactId, force = false) + if (cStats != null) { + chatModel.updateContactConnectionStats(chatRh, contact, cStats) + } + } + }, + syncMemberConnection = { groupInfo, member -> + withBGApi { + val r = chatModel.controller.apiSyncGroupMemberRatchet(chatRh, groupInfo.apiId, member.groupMemberId, force = false) + if (r != null) { + chatModel.updateGroupMemberConnectionStats(chatRh, groupInfo, r.first, r.second) + } + } + }, + findModelChat = { chatId -> + chatModel.getChat(chatId) + }, + findModelMember = { memberId -> + chatModel.groupMembers.find { it.id == memberId } + }, + setReaction = { cInfo, cItem, add, reaction -> + withBGApi { + val updatedCI = chatModel.controller.apiChatItemReaction( + rh = chatRh, type = cInfo.chatType, id = cInfo.apiId, - itemId = itemId, - mode = mode + itemId = cItem.id, + add = add, + reaction = reaction ) - deletedChatItem = r?.deletedChatItem?.chatItem - toChatItem = r?.toChatItem?.chatItem + if (updatedCI != null) { + chatModel.updateChatItem(cInfo, updatedCI) + } } - if (toChatItem == null && deletedChatItem != null) { - chatModel.removeChatItem(chatRh, cInfo, deletedChatItem) - } else if (toChatItem != null) { - chatModel.upsertChatItem(chatRh, cInfo, toChatItem) - } - } - }, - deleteMessages = { itemIds -> - if (itemIds.isNotEmpty()) { - val chatInfo = chat.chatInfo - withBGApi { - val deletedItems: ArrayList = arrayListOf() - for (itemId in itemIds) { - val di = chatModel.controller.apiDeleteChatItem( - chatRh, chatInfo.chatType, chatInfo.apiId, itemId, CIDeleteMode.cidmInternal - )?.deletedChatItem?.chatItem - if (di != null) { - deletedItems.add(di) + }, + showItemDetails = { cInfo, cItem -> + suspend fun loadChatItemInfo(): ChatItemInfo? { + val ciInfo = chatModel.controller.apiGetChatItemInfo(chatRh, cInfo.chatType, cInfo.apiId, cItem.id) + if (ciInfo != null) { + if (chat.chatInfo is ChatInfo.Group) { + setGroupMembers(chatRh, chat.chatInfo.groupInfo, chatModel) } } - for (di in deletedItems) { - chatModel.removeChatItem(chatRh, chatInfo, di) - } + return ciInfo } - } - }, - receiveFile = { fileId -> - withBGApi { chatModel.controller.receiveFile(chatRh, user, fileId) } - }, - cancelFile = { fileId -> - withBGApi { chatModel.controller.cancelFile(chatRh, user, fileId) } - }, - joinGroup = { groupId, onComplete -> - withBGApi { - chatModel.controller.apiJoinGroup(chatRh, groupId) - onComplete.invoke() - } - }, - startCall = out@{ media -> - withBGApi { - val cInfo = chat.chatInfo - if (cInfo is ChatInfo.Direct) { - val contactInfo = chatModel.controller.apiContactInfo(chat.remoteHostId, cInfo.contact.contactId) - val profile = contactInfo?.second ?: chatModel.currentUser.value?.profile?.toProfile() ?: return@withBGApi - chatModel.activeCall.value = Call(remoteHostId = chatRh, contact = cInfo.contact, callState = CallState.WaitCapabilities, localMedia = media, userProfile = profile) - chatModel.showCallView.value = true - chatModel.callCommand.add(WCallCommand.Capabilities(media)) - } - } - }, - endCall = { - val call = chatModel.activeCall.value - if (call != null) withBGApi { chatModel.callManager.endCall(call) } - }, - acceptCall = { contact -> - hideKeyboard(view) - withBGApi { - val invitation = chatModel.callInvitations.remove(contact.id) - ?: controller.apiGetCallInvitations(chatModel.remoteHostId()).firstOrNull { it.contact.id == contact.id } - if (invitation == null) { - AlertManager.shared.showAlertMsg(generalGetString(MR.strings.call_already_ended)) - } else { - chatModel.callManager.acceptIncomingCall(invitation = invitation) - } - } - }, - acceptFeature = { contact, feature, param -> - withBGApi { - chatModel.controller.allowFeatureToContact(chatRh, contact, feature, param) - } - }, - openDirectChat = { contactId -> - withBGApi { - openDirectChat(chatRh, contactId, chatModel) - } - }, - updateContactStats = { contact -> - withBGApi { - val r = chatModel.controller.apiContactInfo(chatRh, chat.chatInfo.apiId) - if (r != null) { - val contactStats = r.first - if (contactStats != null) - chatModel.updateContactConnectionStats(chatRh, contact, contactStats) - } - } - }, - updateMemberStats = { groupInfo, member -> - withBGApi { - val r = chatModel.controller.apiGroupMemberInfo(chatRh, groupInfo.groupId, member.groupMemberId) - if (r != null) { - val memStats = r.second - if (memStats != null) { - chatModel.updateGroupMemberConnectionStats(chatRh, groupInfo, r.first, memStats) - } - } - } - }, - syncContactConnection = { contact -> - withBGApi { - val cStats = chatModel.controller.apiSyncContactRatchet(chatRh, contact.contactId, force = false) - if (cStats != null) { - chatModel.updateContactConnectionStats(chatRh, contact, cStats) - } - } - }, - syncMemberConnection = { groupInfo, member -> - withBGApi { - val r = chatModel.controller.apiSyncGroupMemberRatchet(chatRh, groupInfo.apiId, member.groupMemberId, force = false) - if (r != null) { - chatModel.updateGroupMemberConnectionStats(chatRh, groupInfo, r.first, r.second) - } - } - }, - findModelChat = { chatId -> - chatModel.getChat(chatId) - }, - findModelMember = { memberId -> - chatModel.groupMembers.find { it.id == memberId } - }, - setReaction = { cInfo, cItem, add, reaction -> - withBGApi { - val updatedCI = chatModel.controller.apiChatItemReaction( - rh = chatRh, - type = cInfo.chatType, - id = cInfo.apiId, - itemId = cItem.id, - add = add, - reaction = reaction - ) - if (updatedCI != null) { - chatModel.updateChatItem(cInfo, updatedCI) - } - } - }, - showItemDetails = { cInfo, cItem -> - suspend fun loadChatItemInfo(): ChatItemInfo? { - val ciInfo = chatModel.controller.apiGetChatItemInfo(chatRh, cInfo.chatType, cInfo.apiId, cItem.id) - if (ciInfo != null) { - if (chat.chatInfo is ChatInfo.Group) { - setGroupMembers(chatRh, chat.chatInfo.groupInfo, chatModel) - } - } - return ciInfo - } - withBGApi { - var initialCiInfo = loadChatItemInfo() ?: return@withBGApi - ModalManager.end.closeModals() - ModalManager.end.showModalCloseable(endButtons = { - ShareButton { - clipboard.shareText(itemInfoShareText(chatModel, cItem, initialCiInfo, chatModel.controller.appPrefs.developerTools.get())) - } - }) { close -> - var ciInfo by remember(cItem.id) { mutableStateOf(initialCiInfo) } - ChatItemInfoView(chatRh, cItem, ciInfo, devTools = chatModel.controller.appPrefs.developerTools.get()) - LaunchedEffect(cItem.id) { - withContext(Dispatchers.Default) { - for (apiResp in controller.messagesChannel) { - val msg = apiResp.resp - if (apiResp.remoteHostId == chatRh && - msg is CR.ChatItemStatusUpdated && - msg.chatItem.chatItem.id == cItem.id - ) { - ciInfo = loadChatItemInfo() ?: return@withContext - initialCiInfo = ciInfo + withBGApi { + var initialCiInfo = loadChatItemInfo() ?: return@withBGApi + ModalManager.end.closeModals() + ModalManager.end.showModalCloseable(endButtons = { + ShareButton { + clipboard.shareText(itemInfoShareText(chatModel, cItem, initialCiInfo, chatModel.controller.appPrefs.developerTools.get())) + } + }) { close -> + var ciInfo by remember(cItem.id) { mutableStateOf(initialCiInfo) } + ChatItemInfoView(chatRh, cItem, ciInfo, devTools = chatModel.controller.appPrefs.developerTools.get()) + LaunchedEffect(cItem.id) { + withContext(Dispatchers.Default) { + for (apiResp in controller.messagesChannel) { + val msg = apiResp.resp + if (apiResp.remoteHostId == chatRh && + msg is CR.ChatItemStatusUpdated && + msg.chatItem.chatItem.id == cItem.id + ) { + ciInfo = loadChatItemInfo() ?: return@withContext + initialCiInfo = ciInfo + } } } } - } - KeyChangeEffect(chatModel.chatId.value) { - close() + KeyChangeEffect(chatModel.chatId.value) { + close() + } } } - } - }, - addMembers = { groupInfo -> - hideKeyboard(view) - withBGApi { - setGroupMembers(chatRh, groupInfo, chatModel) - ModalManager.end.closeModals() - ModalManager.end.showModalCloseable(true) { close -> - AddGroupMembersView(chatRh, groupInfo, false, chatModel, close) + }, + addMembers = { groupInfo -> + hideKeyboard(view) + withBGApi { + setGroupMembers(chatRh, groupInfo, chatModel) + ModalManager.end.closeModals() + ModalManager.end.showModalCloseable(true) { close -> + AddGroupMembersView(chatRh, groupInfo, false, chatModel, close) + } } - } - }, - openGroupLink = { groupInfo -> - hideKeyboard(view) - withBGApi { - val link = chatModel.controller.apiGetGroupLink(chatRh, groupInfo.groupId) - ModalManager.end.closeModals() - ModalManager.end.showModalCloseable(true) { - GroupLinkView(chatModel, chatRh, groupInfo, link?.first, link?.second, onGroupLinkUpdated = null) + }, + openGroupLink = { groupInfo -> + hideKeyboard(view) + withBGApi { + val link = chatModel.controller.apiGetGroupLink(chatRh, groupInfo.groupId) + ModalManager.end.closeModals() + ModalManager.end.showModalCloseable(true) { + GroupLinkView(chatModel, chatRh, groupInfo, link?.first, link?.second, onGroupLinkUpdated = null) + } } - } - }, - markRead = { range, unreadCountAfter -> - chatModel.markChatItemsRead(chat, range, unreadCountAfter) - ntfManager.cancelNotificationsForChat(chat.id) - withBGApi { - chatModel.controller.apiChatRead( - chatRh, - chat.chatInfo.chatType, - chat.chatInfo.apiId, - range - ) - } - }, - changeNtfsState = { enabled, currentValue -> toggleNotifications(chat, enabled, chatModel, currentValue) }, - onSearchValueChanged = { value -> - if (searchText.value == value) return@ChatLayout - if (chatModel.chatId.value != activeChat.value?.id) return@ChatLayout - val c = chatModel.getChat(chatModel.chatId.value ?: return@ChatLayout) ?: return@ChatLayout - withBGApi { - apiFindMessages(c, chatModel, value) - searchText.value = value - } - }, - onComposed, - developerTools = chatModel.controller.appPrefs.developerTools.get(), - showViaProxy = chatModel.controller.appPrefs.showSentViaProxy.get(), - ) + }, + markRead = { range, unreadCountAfter -> + chatModel.markChatItemsRead(chat, range, unreadCountAfter) + ntfManager.cancelNotificationsForChat(chat.id) + withBGApi { + chatModel.controller.apiChatRead( + chatRh, + chat.chatInfo.chatType, + chat.chatInfo.apiId, + range + ) + } + }, + changeNtfsState = { enabled, currentValue -> toggleNotifications(chat, enabled, chatModel, currentValue) }, + onSearchValueChanged = { value -> + if (searchText.value == value) return@ChatLayout + if (chatModel.chatId.value != activeChat.value?.id) return@ChatLayout + val c = chatModel.getChat(chatModel.chatId.value ?: return@ChatLayout) ?: return@ChatLayout + withBGApi { + apiFindMessages(c, chatModel, value) + searchText.value = value + } + }, + onComposed, + developerTools = chatModel.controller.appPrefs.developerTools.get(), + showViaProxy = chatModel.controller.appPrefs.showSentViaProxy.get(), + ) + } } is ChatInfo.ContactConnection -> { val close = { chatModel.chatId.value = null } @@ -598,9 +601,19 @@ fun ChatLayout( floatingActionButton = { floatingButton.value() }, contentColor = LocalContentColor.current, drawerContentColor = LocalContentColor.current, + backgroundColor = Color.Unspecified ) { contentPadding -> + val wallpaperImage = MaterialTheme.wallpaper.type.image + val wallpaperType = MaterialTheme.wallpaper.type + val backgroundColor = MaterialTheme.wallpaper.background ?: wallpaperType.defaultBackgroundColor(CurrentColors.value.base, MaterialTheme.colors.background) + val tintColor = MaterialTheme.wallpaper.tint ?: wallpaperType.defaultTintColor(CurrentColors.value.base) BoxWithConstraints(Modifier - .fillMaxHeight() + .fillMaxSize() + .background(MaterialTheme.colors.background) + .then(if (wallpaperImage != null) + Modifier.drawBehind { chatViewBackground(wallpaperImage, wallpaperType, backgroundColor, tintColor) } + else + Modifier) .padding(contentPadding) ) { ChatItemsList( @@ -1262,7 +1275,7 @@ val MEMBER_IMAGE_SIZE: Dp = 38.dp @Composable fun MemberImage(member: GroupMember) { - ProfileImage(MEMBER_IMAGE_SIZE, member.memberProfile.image) + ProfileImage(MEMBER_IMAGE_SIZE, member.memberProfile.image, backgroundColor = MaterialTheme.colors.background) } @Composable diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeContextInvitingContactMemberView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeContextInvitingContactMemberView.kt index 20316dd524..bc82bc593f 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeContextInvitingContactMemberView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeContextInvitingContactMemberView.kt @@ -16,7 +16,7 @@ import dev.icerock.moko.resources.compose.stringResource @Composable fun ComposeContextInvitingContactMemberView() { - val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage + val sentColor = MaterialTheme.appColors.sentMessage Row( Modifier .height(60.dp) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeFileView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeFileView.kt index 83076f885b..7ab7963547 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeFileView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeFileView.kt @@ -16,7 +16,7 @@ import chat.simplex.res.MR @Composable fun ComposeFileView(fileName: String, cancelFile: () -> Unit, cancelEnabled: Boolean) { - val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage + val sentColor = MaterialTheme.appColors.sentMessage Row( Modifier .height(60.dp) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeImageView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeImageView.kt index 906065f741..97b6f9afda 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeImageView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeImageView.kt @@ -20,7 +20,7 @@ import chat.simplex.common.views.helpers.UploadContent @Composable fun ComposeImageView(media: ComposePreview.MediaPreview, cancelImages: () -> Unit, cancelEnabled: Boolean) { - val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage + val sentColor = MaterialTheme.appColors.sentMessage Row( Modifier .padding(top = 8.dp) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeView.kt index d9ea35096b..24533247ba 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeView.kt @@ -776,7 +776,7 @@ fun ComposeView( @Composable fun MsgNotAllowedView(reason: String, icon: Painter) { - val color = CurrentColors.collectAsState().value.appColors.receivedMessage + val color = MaterialTheme.appColors.receivedMessage Row(Modifier.padding(top = 5.dp).fillMaxWidth().background(color).padding(horizontal = DEFAULT_PADDING_HALF, vertical = DEFAULT_PADDING_HALF * 1.5f), verticalAlignment = Alignment.CenterVertically) { Icon(icon, null, tint = MaterialTheme.colors.secondary) Spacer(Modifier.width(DEFAULT_PADDING_HALF)) @@ -862,7 +862,7 @@ fun ComposeView( } } Row( - modifier = Modifier.padding(end = 8.dp), + modifier = Modifier.background(MaterialTheme.colors.background).padding(end = 8.dp), verticalAlignment = Alignment.Bottom, ) { val isGroupAndProhibitedFiles = chat.chatInfo is ChatInfo.Group && !chat.chatInfo.groupInfo.fullGroupPreferences.files.on(chat.chatInfo.groupInfo.membership) @@ -974,7 +974,7 @@ fun ComposeView( val timedMessageAllowed = remember(chat.chatInfo) { chat.chatInfo.featureEnabled(ChatFeature.TimedMessages) } val sendButtonColor = if (chat.chatInfo.incognito) - if (isSystemInDarkTheme()) Indigo else Indigo.copy(alpha = 0.7F) + if (isInDarkTheme()) Indigo else Indigo.copy(alpha = 0.7F) else MaterialTheme.colors.primary SendMsgView( composeState, diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeVoiceView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeVoiceView.kt index a4c90d30dd..b71d090a4e 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeVoiceView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeVoiceView.kt @@ -35,7 +35,7 @@ fun ComposeVoiceView( ) { val progress = rememberSaveable { mutableStateOf(0) } val duration = rememberSaveable(recordedDurationMs) { mutableStateOf(recordedDurationMs) } - val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage + val sentColor = MaterialTheme.appColors.sentMessage Box { Box( Modifier diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ContextItemView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ContextItemView.kt index ce34ecf0c3..0c4efa7d0d 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ContextItemView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ContextItemView.kt @@ -30,8 +30,8 @@ fun ContextItemView( cancelContextItem: () -> Unit ) { val sent = contextItem.chatDir.sent - val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage - val receivedColor = CurrentColors.collectAsState().value.appColors.receivedMessage + val sentColor = MaterialTheme.appColors.sentMessage + val receivedColor = MaterialTheme.appColors.receivedMessage @Composable fun MessageText(attachment: ImageResource?, lines: Int) { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupChatInfoView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupChatInfoView.kt index c52dd941fd..69b4de6803 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupChatInfoView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupChatInfoView.kt @@ -9,7 +9,6 @@ import SectionSpacer import SectionTextFooter import SectionView import androidx.compose.desktop.ui.tooling.preview.Preview -import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.* import androidx.compose.material.* @@ -233,6 +232,16 @@ fun GroupChatInfoLayout( } else { SendReceiptsOptionDisabled() } + + WallpaperButton { + ModalManager.end.showModal { + val chat = remember { derivedStateOf { chatModel.chats.firstOrNull { it.id == chat.id } } } + val c = chat.value + if (c != null) { + ChatWallpaperEditorModal(c) + } + } + } } SectionTextFooter(stringResource(MR.strings.only_group_owners_can_change_prefs)) SectionDividerSpaced(maxTopPadding = true) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIGroupInvitationView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIGroupInvitationView.kt index a2338bb895..577327c159 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIGroupInvitationView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIGroupInvitationView.kt @@ -83,8 +83,8 @@ fun CIGroupInvitationView( } } - val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage - val receivedColor = CurrentColors.collectAsState().value.appColors.receivedMessage + val sentColor = MaterialTheme.appColors.sentMessage + val receivedColor = MaterialTheme.appColors.receivedMessage Surface( modifier = if (action && !inProgress.value) Modifier.clickable(onClick = { inProgress.value = true @@ -110,6 +110,7 @@ fun CIGroupInvitationView( .padding(bottom = 4.dp), ) { groupInfoView() + val secondaryColor = MaterialTheme.colors.secondary Column(Modifier.padding(top = 2.dp, start = 5.dp)) { Divider(Modifier.fillMaxWidth().padding(bottom = 4.dp)) if (action) { @@ -117,7 +118,7 @@ fun CIGroupInvitationView( Text( buildAnnotatedString { append(generalGetString(if (chatIncognito) MR.strings.group_invitation_tap_to_join_incognito else MR.strings.group_invitation_tap_to_join)) - withStyle(reserveTimestampStyle) { append(reserveSpaceForMeta(ci.meta, timedMessagesTTL, encrypted = null, showStatus = false, showEdited = false)) } + withStyle(reserveTimestampStyle) { append(reserveSpaceForMeta(ci.meta, timedMessagesTTL, encrypted = null, showStatus = false, showEdited = false, secondaryColor = secondaryColor)) } }, color = if (inProgress.value) MaterialTheme.colors.secondary @@ -128,7 +129,7 @@ fun CIGroupInvitationView( Text( buildAnnotatedString { append(groupInvitationStr()) - withStyle(reserveTimestampStyle) { append(reserveSpaceForMeta(ci.meta, timedMessagesTTL, encrypted = null, showStatus = false, showEdited = false)) } + withStyle(reserveTimestampStyle) { append(reserveSpaceForMeta(ci.meta, timedMessagesTTL, encrypted = null, showStatus = false, showEdited = false, secondaryColor = secondaryColor)) } } ) } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIMetaView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIMetaView.kt index 14fa6910da..def3b14ebc 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIMetaView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIMetaView.kt @@ -12,7 +12,6 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.desktop.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import chat.simplex.common.ui.theme.CurrentColors import chat.simplex.common.model.* import chat.simplex.common.ui.theme.isInDarkTheme import chat.simplex.res.MR @@ -86,7 +85,7 @@ private fun CIMetaText( Spacer(Modifier.width(4.dp)) } if (showViaProxy && meta.sentViaProxy == true) { - Icon(painterResource(MR.images.ic_arrow_forward), null, Modifier.height(17.dp), tint = CurrentColors.value.colors.secondary) + Icon(painterResource(MR.images.ic_arrow_forward), null, Modifier.height(17.dp), tint = MaterialTheme.colors.secondary) } if (showStatus) { val statusIcon = meta.statusIcon(MaterialTheme.colors.primary, color, paleColor) @@ -115,6 +114,7 @@ fun reserveSpaceForMeta( meta: CIMeta, chatTTL: Int?, encrypted: Boolean?, + secondaryColor: Color, showStatus: Boolean = true, showEdited: Boolean = true, showViaProxy: Boolean = false @@ -132,7 +132,7 @@ fun reserveSpaceForMeta( if (showViaProxy && meta.sentViaProxy == true) { res += iconSpace } - if (showStatus && (meta.statusIcon(CurrentColors.value.colors.secondary) != null || !meta.disappearing)) { + if (showStatus && (meta.statusIcon(secondaryColor) != null || !meta.disappearing)) { res += iconSpace } if (encrypted != null) { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIRcvDecryptionError.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIRcvDecryptionError.kt index eb5d1e731a..dd0e9cf1a2 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIRcvDecryptionError.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIRcvDecryptionError.kt @@ -14,6 +14,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import chat.simplex.common.model.* import chat.simplex.common.ui.theme.CurrentColors +import chat.simplex.common.ui.theme.appColors import chat.simplex.common.views.helpers.AlertManager import chat.simplex.common.views.helpers.generalGetString import chat.simplex.res.MR @@ -137,7 +138,7 @@ fun DecryptionErrorItemFixButton( onClick: () -> Unit, syncSupported: Boolean ) { - val receivedColor = CurrentColors.collectAsState().value.appColors.receivedMessage + val receivedColor = MaterialTheme.appColors.receivedMessage Surface( Modifier.clickable(onClick = onClick), shape = RoundedCornerShape(18.dp), @@ -164,10 +165,11 @@ fun DecryptionErrorItemFixButton( tint = if (syncSupported) MaterialTheme.colors.primary else MaterialTheme.colors.secondary ) Spacer(Modifier.padding(2.dp)) + val secondaryColor = MaterialTheme.colors.secondary Text( buildAnnotatedString { append(generalGetString(MR.strings.fix_connection)) - withStyle(reserveTimestampStyle) { append(reserveSpaceForMeta(ci.meta, null, encrypted = null)) } + withStyle(reserveTimestampStyle) { append(reserveSpaceForMeta(ci.meta, null, encrypted = null, secondaryColor = secondaryColor)) } withStyle(reserveTimestampStyle) { append(" ") } // for icon }, color = if (syncSupported) MaterialTheme.colors.primary else MaterialTheme.colors.secondary @@ -184,7 +186,7 @@ fun DecryptionErrorItem( ci: ChatItem, onClick: () -> Unit ) { - val receivedColor = CurrentColors.collectAsState().value.appColors.receivedMessage + val receivedColor = MaterialTheme.appColors.receivedMessage Surface( Modifier.clickable(onClick = onClick), shape = RoundedCornerShape(18.dp), @@ -195,10 +197,11 @@ fun DecryptionErrorItem( Modifier.padding(vertical = 6.dp, horizontal = 12.dp), contentAlignment = Alignment.BottomEnd, ) { + val secondaryColor = MaterialTheme.colors.secondary Text( buildAnnotatedString { withStyle(SpanStyle(fontStyle = FontStyle.Italic, color = Color.Red)) { append(ci.content.text) } - withStyle(reserveTimestampStyle) { append(reserveSpaceForMeta(ci.meta, null, encrypted = null)) } + withStyle(reserveTimestampStyle) { append(reserveSpaceForMeta(ci.meta, null, encrypted = null, secondaryColor = secondaryColor)) } }, style = MaterialTheme.typography.body1.copy(lineHeight = 22.sp) ) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIVoiceView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIVoiceView.kt index f973a6ea66..96aaf586e9 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIVoiceView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIVoiceView.kt @@ -154,8 +154,8 @@ private fun VoiceLayout( } when { hasText -> { - val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage - val receivedColor = CurrentColors.collectAsState().value.appColors.receivedMessage + val sentColor = MaterialTheme.appColors.sentMessage + val receivedColor = MaterialTheme.appColors.receivedMessage Spacer(Modifier.width(6.dp)) VoiceMsgIndicator(file, audioPlaying.value, sent, hasText, progress, duration, brokenAudio, play, pause, longClick, receiveFile) Row(verticalAlignment = Alignment.CenterVertically) { @@ -224,8 +224,8 @@ private fun PlayPauseButton( longClick: () -> Unit, icon: ImageResource = MR.images.ic_play_arrow_filled, ) { - val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage - val receivedColor = CurrentColors.collectAsState().value.appColors.receivedMessage + val sentColor = MaterialTheme.appColors.sentMessage + val receivedColor = MaterialTheme.appColors.receivedMessage Surface( Modifier.drawRingModifier(angle, strokeColor, strokeWidth), color = if (sent) sentColor else receivedColor, diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/ChatItemView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/ChatItemView.kt index 0bc0415590..7fbec84c4d 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/ChatItemView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/ChatItemView.kt @@ -819,40 +819,38 @@ expect fun copyItemToClipboard(cItem: ChatItem, clipboard: ClipboardManager) @Preview @Composable -fun PreviewChatItemView() { - SimpleXTheme { - ChatItemView( - rhId = null, - ChatInfo.Direct.sampleData, - ChatItem.getSampleData( - 1, CIDirection.DirectSnd(), Clock.System.now(), "hello" - ), - useLinkPreviews = true, - linkMode = SimplexLinkMode.DESCRIPTION, - composeState = remember { mutableStateOf(ComposeState(useLinkPreviews = true)) }, - revealed = remember { mutableStateOf(false) }, - range = 0..1, - deleteMessage = { _, _ -> }, - deleteMessages = { _ -> }, - receiveFile = { _ -> }, - cancelFile = {}, - joinGroup = { _, _ -> }, - acceptCall = { _ -> }, - scrollToItem = {}, - acceptFeature = { _, _, _ -> }, - openDirectChat = { _ -> }, - updateContactStats = { }, - updateMemberStats = { _, _ -> }, - syncContactConnection = { }, - syncMemberConnection = { _, _ -> }, - findModelChat = { null }, - findModelMember = { null }, - setReaction = { _, _, _, _ -> }, - showItemDetails = { _, _ -> }, - developerTools = false, - showViaProxy = false - ) - } +fun PreviewChatItemView( + chatItem: ChatItem = ChatItem.getSampleData(1, CIDirection.DirectSnd(), Clock.System.now(), "hello") +) { + ChatItemView( + rhId = null, + ChatInfo.Direct.sampleData, + chatItem, + useLinkPreviews = true, + linkMode = SimplexLinkMode.DESCRIPTION, + composeState = remember { mutableStateOf(ComposeState(useLinkPreviews = true)) }, + revealed = remember { mutableStateOf(false) }, + range = 0..1, + deleteMessage = { _, _ -> }, + deleteMessages = { _ -> }, + receiveFile = { _ -> }, + cancelFile = {}, + joinGroup = { _, _ -> }, + acceptCall = { _ -> }, + scrollToItem = {}, + acceptFeature = { _, _, _ -> }, + openDirectChat = { _ -> }, + updateContactStats = { }, + updateMemberStats = { _, _ -> }, + syncContactConnection = { }, + syncMemberConnection = { _, _ -> }, + findModelChat = { null }, + findModelMember = { null }, + setReaction = { _, _, _, _ -> }, + showItemDetails = { _, _ -> }, + developerTools = false, + showViaProxy = false, + ) } @Preview diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/DeletedItemView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/DeletedItemView.kt index 644c1997c4..9b7db099b6 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/DeletedItemView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/DeletedItemView.kt @@ -18,8 +18,8 @@ import chat.simplex.common.ui.theme.* @Composable fun DeletedItemView(ci: ChatItem, timedMessagesTTL: Int?, showViaProxy: Boolean) { val sent = ci.chatDir.sent - val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage - val receivedColor = CurrentColors.collectAsState().value.appColors.receivedMessage + val sentColor = MaterialTheme.appColors.sentMessage + val receivedColor = MaterialTheme.appColors.receivedMessage Surface( shape = RoundedCornerShape(18.dp), color = if (sent) sentColor else receivedColor, diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/FramedItemView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/FramedItemView.kt index 4dc0fd9cf5..8969ca9b21 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/FramedItemView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/FramedItemView.kt @@ -46,9 +46,6 @@ fun FramedItemView( return if (chatInfo is ChatInfo.Group) chatInfo.groupInfo.membership else null } - @Composable - fun Color.toQuote(): Color = if (isInDarkTheme()) lighter(0.12f) else darker(0.12f) - @Composable fun ciQuotedMsgTextView(qi: CIQuote, lines: Int) { MarkdownText( @@ -89,11 +86,11 @@ fun FramedItemView( @Composable fun FramedItemHeader(caption: String, italic: Boolean, icon: Painter? = null, pad: Boolean = false) { - val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage - val receivedColor = CurrentColors.collectAsState().value.appColors.receivedMessage + val sentColor = MaterialTheme.appColors.sentQuote + val receivedColor = MaterialTheme.appColors.receivedQuote Row( Modifier - .background(if (sent) sentColor.toQuote() else receivedColor.toQuote()) + .background(if (sent) sentColor else receivedColor) .fillMaxWidth() .padding(start = 8.dp, top = 6.dp, end = 12.dp, bottom = if (pad || (ci.quotedItem == null && ci.meta.itemForwarded == null)) 6.dp else 0.dp), horizontalArrangement = Arrangement.spacedBy(4.dp), @@ -122,11 +119,11 @@ fun FramedItemView( @Composable fun ciQuoteView(qi: CIQuote) { - val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage - val receivedColor = CurrentColors.collectAsState().value.appColors.receivedMessage + val sentColor = MaterialTheme.appColors.sentQuote + val receivedColor = MaterialTheme.appColors.receivedQuote Row( Modifier - .background(if (sent) sentColor.toQuote() else receivedColor.toQuote()) + .background(if (sent) sentColor else receivedColor) .fillMaxWidth() .combinedClickable( onLongClick = { showMenu.value = true }, @@ -188,10 +185,17 @@ fun FramedItemView( val transparentBackground = (ci.content.msgContent is MsgContent.MCImage || ci.content.msgContent is MsgContent.MCVideo) && !ci.meta.isLive && ci.content.text.isEmpty() && ci.quotedItem == null && ci.meta.itemForwarded == null - val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage - val receivedColor = CurrentColors.collectAsState().value.appColors.receivedMessage + val sentColor = MaterialTheme.appColors.sentMessage + val receivedColor = MaterialTheme.appColors.receivedMessage Box(Modifier .clip(RoundedCornerShape(18.dp)) + .background( + when { + transparentBackground -> Color.Transparent + sent -> MaterialTheme.colors.background + else -> MaterialTheme.colors.background + } + ) .background( when { transparentBackground -> Color.Transparent diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/IntegrityErrorItemView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/IntegrityErrorItemView.kt index bd2aaf140c..dc585358c4 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/IntegrityErrorItemView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/IntegrityErrorItemView.kt @@ -17,8 +17,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import chat.simplex.common.model.ChatItem import chat.simplex.common.model.MsgErrorType -import chat.simplex.common.ui.theme.CurrentColors -import chat.simplex.common.ui.theme.SimpleXTheme +import chat.simplex.common.ui.theme.* import chat.simplex.common.views.helpers.AlertManager import chat.simplex.common.views.helpers.generalGetString import chat.simplex.res.MR @@ -51,7 +50,7 @@ fun IntegrityErrorItemView(msgError: MsgErrorType, ci: ChatItem, timedMessagesTT @Composable fun CIMsgError(ci: ChatItem, timedMessagesTTL: Int?, onClick: () -> Unit) { - val receivedColor = CurrentColors.collectAsState().value.appColors.receivedMessage + val receivedColor = MaterialTheme.appColors.receivedMessage Surface( Modifier.clickable(onClick = onClick), shape = RoundedCornerShape(18.dp), diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/MarkedDeletedItemView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/MarkedDeletedItemView.kt index 6ecec47b6f..5b5438d76f 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/MarkedDeletedItemView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/MarkedDeletedItemView.kt @@ -21,8 +21,8 @@ import kotlinx.datetime.Clock @Composable fun MarkedDeletedItemView(ci: ChatItem, timedMessagesTTL: Int?, revealed: MutableState, showViaProxy: Boolean) { - val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage - val receivedColor = CurrentColors.collectAsState().value.appColors.receivedMessage + val sentColor = MaterialTheme.appColors.sentMessage + val receivedColor = MaterialTheme.appColors.receivedMessage Surface( shape = RoundedCornerShape(18.dp), color = if (ci.chatDir.sent) sentColor else receivedColor, diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/TextItemView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/TextItemView.kt index 343fc47f76..c0e222d7d1 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/TextItemView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/TextItemView.kt @@ -78,7 +78,7 @@ fun MarkdownText ( val reserve = if (textLayoutDirection != LocalLayoutDirection.current && meta != null) { "\n" } else if (meta != null) { - reserveSpaceForMeta(meta, chatTTL, null, showViaProxy = showViaProxy) + reserveSpaceForMeta(meta, chatTTL, null, secondaryColor = MaterialTheme.colors.secondary, showViaProxy = showViaProxy) } else { " " } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt index 40dfbeac73..330003b743 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt @@ -486,6 +486,8 @@ fun deleteChatDatabaseFilesAndState() { tmpDir.deleteRecursively() getMigrationTempFilesDirectory().deleteRecursively() tmpDir.mkdir() + wallpapersDir.deleteRecursively() + wallpapersDir.mkdirs() DatabaseUtils.ksDatabasePassword.remove() controller.appPrefs.storeDBPassphrase.set(true) controller.ctrl = null diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ChatInfoImage.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ChatInfoImage.kt index 34d916781b..3d57f0f8b7 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ChatInfoImage.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ChatInfoImage.kt @@ -2,12 +2,14 @@ package chat.simplex.common.views.helpers import androidx.compose.desktop.ui.tooling.preview.Preview import androidx.compose.foundation.Image +import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.* import androidx.compose.material.Icon import androidx.compose.material.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.geometry.Size @@ -51,7 +53,8 @@ fun ProfileImage( size: Dp, image: String? = null, icon: ImageResource = MR.images.ic_account_circle_filled, - color: Color = MaterialTheme.colors.secondaryVariant + color: Color = MaterialTheme.colors.secondaryVariant, + backgroundColor: Color? = null ) { Box(Modifier.size(size)) { if (image == null) { @@ -61,6 +64,9 @@ fun ProfileImage( else -> null } if (iconToReplace != null) { + if (backgroundColor != null) { + Box(Modifier.size(size * 0.7f).align(Alignment.Center).background(backgroundColor, CircleShape)) + } Icon( iconToReplace, contentDescription = stringResource(MR.strings.icon_descr_profile_image_placeholder), diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ChatWallpaper.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ChatWallpaper.kt new file mode 100644 index 0000000000..cd18ad1dab --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ChatWallpaper.kt @@ -0,0 +1,415 @@ +package chat.simplex.common.views.helpers + +import androidx.compose.ui.geometry.Size +import androidx.compose.ui.graphics.* +import androidx.compose.ui.graphics.drawscope.DrawScope +import androidx.compose.ui.graphics.drawscope.clipRect +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.unit.IntOffset +import androidx.compose.ui.unit.IntSize +import chat.simplex.common.model.ChatController.appPrefs +import chat.simplex.common.platform.* +import chat.simplex.common.ui.theme.* +import chat.simplex.common.ui.theme.ThemeManager.colorFromReadableHex +import chat.simplex.res.MR +import dev.icerock.moko.resources.ImageResource +import dev.icerock.moko.resources.StringResource +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import java.io.File +import kotlin.math.* + +enum class PresetWallpaper( + val res: ImageResource, + val filename: String, + val text: StringResource, + val scale: Float, + val background: Map, + val tint: Map, + val colors: Map, +) { + CATS(MR.images.wallpaper_cats, "cats", MR.strings.wallpaper_cats, 0.63f, + wallpaperBackgrounds(light = "#ffF8F6EA"), + tint = mapOf( + DefaultTheme.LIGHT to "#ffefdca6".colorFromReadableHex(), + DefaultTheme.DARK to "#ff4b3b0e".colorFromReadableHex(), + DefaultTheme.SIMPLEX to "#ff51400f".colorFromReadableHex(), + DefaultTheme.BLACK to "#ff4b3b0e".colorFromReadableHex() + ), + mapOf( + DefaultTheme.LIGHT to ThemeColors( + sentMessage = "#fffffaed", + sentQuote = "#fffaf0d6", + receivedMessage = "#ffF8F7F4", + receivedQuote = "#ffefede9", + ), + DefaultTheme.DARK to ThemeColors( + sentMessage = "#ff2f2919", + sentQuote = "#ff473a1d", + receivedMessage = "#ff272624", + receivedQuote = "#ff373633", + ), + DefaultTheme.SIMPLEX to ThemeColors( + sentMessage = "#ff41371b", + sentQuote = "#ff654f1c", + receivedMessage = "#ff272624", + receivedQuote = "#ff373633", + ), + DefaultTheme.BLACK to ThemeColors( + sentMessage = "#ff41371b", + sentQuote = "#ff654f1c", + receivedMessage = "#ff1f1e1b", + receivedQuote = "#ff2f2d27", + ), + ) + ), + FLOWERS(MR.images.wallpaper_flowers, "flowers", MR.strings.wallpaper_flowers, 0.53f, + wallpaperBackgrounds(light = "#ffE2FFE4"), + tint = mapOf( + DefaultTheme.LIGHT to "#ff9CEA59".colorFromReadableHex(), + DefaultTheme.DARK to "#ff31560D".colorFromReadableHex(), + DefaultTheme.SIMPLEX to "#ff36600f".colorFromReadableHex(), + DefaultTheme.BLACK to "#ff31560D".colorFromReadableHex() + ), + mapOf( + DefaultTheme.LIGHT to ThemeColors( + sentMessage = "#fff1ffe5", + sentQuote = "#ffdcf9c4", + receivedMessage = "#ffF4F8F2", + receivedQuote = "#ffe7ece7", + ), + DefaultTheme.DARK to ThemeColors( + sentMessage = "#ff163521", + sentQuote = "#ff1B5330", + receivedMessage = "#ff242523", + receivedQuote = "#ff353733", + ), + DefaultTheme.SIMPLEX to ThemeColors( + sentMessage = "#ff184739", + sentQuote = "#ff1F6F4B", + receivedMessage = "#ff242523", + receivedQuote = "#ff353733", + ), + DefaultTheme.BLACK to ThemeColors( + sentMessage = "#ff184739", + sentQuote = "#ff1F6F4B", + receivedMessage = "#ff1c1f1a", + receivedQuote = "#ff282b25", + ), + ) + ), + HEARTS(MR.images.wallpaper_hearts, "hearts", MR.strings.wallpaper_hearts, 0.59f, + wallpaperBackgrounds(light = "#ffFDECEC"), + tint = mapOf( + DefaultTheme.LIGHT to "#fffde0e0".colorFromReadableHex(), + DefaultTheme.DARK to "#ff3c0f0f".colorFromReadableHex(), + DefaultTheme.SIMPLEX to "#ff411010".colorFromReadableHex(), + DefaultTheme.BLACK to "#ff3C0F0F".colorFromReadableHex() + ), + mapOf( + DefaultTheme.LIGHT to ThemeColors( + sentMessage = "#fffff4f4", + sentQuote = "#ffffdfdf", + receivedMessage = "#fff8f6f6", + receivedQuote = "#ffefebeb", + ), + DefaultTheme.DARK to ThemeColors( + sentMessage = "#ff301515", + sentQuote = "#ff4C1818", + receivedMessage = "#ff242121", + receivedQuote = "#ff3b3535", + ), + DefaultTheme.SIMPLEX to ThemeColors( + sentMessage = "#ff491A28", + sentQuote = "#ff761F29", + receivedMessage = "#ff242121", + receivedQuote = "#ff3b3535", + ), + DefaultTheme.BLACK to ThemeColors( + sentMessage = "#ff491A28", + sentQuote = "#ff761F29", + receivedMessage = "#ff1f1b1b", + receivedQuote = "#ff2e2626", + ), + ) + ), + KIDS(MR.images.wallpaper_kids, "kids", MR.strings.wallpaper_kids, 0.53f, + wallpaperBackgrounds(light = "#ffdbfdfb"), + tint = mapOf( + DefaultTheme.LIGHT to "#ffadeffc".colorFromReadableHex(), + DefaultTheme.DARK to "#ff16404B".colorFromReadableHex(), + DefaultTheme.SIMPLEX to "#ff184753".colorFromReadableHex(), + DefaultTheme.BLACK to "#ff16404B".colorFromReadableHex() + ), + mapOf( + DefaultTheme.LIGHT to ThemeColors( + sentMessage = "#ffeafeff", + sentQuote = "#ffcbf4f7", + receivedMessage = "#fff3fafa", + receivedQuote = "#ffe4efef", + ), + DefaultTheme.DARK to ThemeColors( + sentMessage = "#ff16302F", + sentQuote = "#ff1a4a49", + receivedMessage = "#ff252626", + receivedQuote = "#ff373A39", + ), + DefaultTheme.SIMPLEX to ThemeColors( + sentMessage = "#ff1a4745", + sentQuote = "#ff1d6b69", + receivedMessage = "#ff252626", + receivedQuote = "#ff373a39", + ), + DefaultTheme.BLACK to ThemeColors( + sentMessage = "#ff1a4745", + sentQuote = "#ff1d6b69", + receivedMessage = "#ff1e1f1f", + receivedQuote = "#ff262b29", + ), + ) + ), + SCHOOL(MR.images.wallpaper_school, "school", MR.strings.wallpaper_school, 0.53f, + wallpaperBackgrounds(light = "#ffE7F5FF"), + tint = mapOf( + DefaultTheme.LIGHT to "#ffCEEBFF".colorFromReadableHex(), + DefaultTheme.DARK to "#ff0F293B".colorFromReadableHex(), + DefaultTheme.SIMPLEX to "#ff112f43".colorFromReadableHex(), + DefaultTheme.BLACK to "#ff0F293B".colorFromReadableHex() + ), + mapOf( + DefaultTheme.LIGHT to ThemeColors( + sentMessage = "#ffeef9ff", + sentQuote = "#ffD6EDFA", + receivedMessage = "#ffF3F5F9", + receivedQuote = "#ffe4e8ee", + ), + DefaultTheme.DARK to ThemeColors( + sentMessage = "#ff172833", + sentQuote = "#ff1C3E4F", + receivedMessage = "#ff26282c", + receivedQuote = "#ff393c40", + ), + DefaultTheme.SIMPLEX to ThemeColors( + sentMessage = "#ff1A3C5D", + sentQuote = "#ff235b80", + receivedMessage = "#ff26282c", + receivedQuote = "#ff393c40", + ), + DefaultTheme.BLACK to ThemeColors( + sentMessage = "#ff1A3C5D", + sentQuote = "#ff235b80", + receivedMessage = "#ff1d1e22", + receivedQuote = "#ff292b2f", + ), + ) + ), + TRAVEL(MR.images.wallpaper_travel, "travel", MR.strings.wallpaper_travel, 0.68f, + wallpaperBackgrounds(light = "#fff9eeff"), + tint = mapOf( + DefaultTheme.LIGHT to "#ffeedbfe".colorFromReadableHex(), + DefaultTheme.DARK to "#ff311E48".colorFromReadableHex(), + DefaultTheme.SIMPLEX to "#ff35204e".colorFromReadableHex(), + DefaultTheme.BLACK to "#ff311E48".colorFromReadableHex() + ), + mapOf( + DefaultTheme.LIGHT to ThemeColors( + sentMessage = "#fffcf6ff", + sentQuote = "#fff2e0fc", + receivedMessage = "#ffF6F4F7", + receivedQuote = "#ffede9ee", + ), + DefaultTheme.DARK to ThemeColors( + sentMessage = "#ff33263B", + sentQuote = "#ff53385E", + receivedMessage = "#ff272528", + receivedQuote = "#ff3B373E", + ), + DefaultTheme.SIMPLEX to ThemeColors( + sentMessage = "#ff3C255D", + sentQuote = "#ff623485", + receivedMessage = "#ff26273B", + receivedQuote = "#ff3A394F", + ), + DefaultTheme.BLACK to ThemeColors( + sentMessage = "#ff3C255D", + sentQuote = "#ff623485", + receivedMessage = "#ff231f23", + receivedQuote = "#ff2c2931", + ), + ) + ); + + fun toType(base: DefaultTheme, scale: Float? = null): WallpaperType = + WallpaperType.Preset( + filename, + scale ?: appPrefs.themeOverrides.get().firstOrNull { it.wallpaper != null && it.wallpaper.preset == filename && it.base == base }?.wallpaper?.scale ?: 1f + ) + + companion object { + fun from(filename: String): PresetWallpaper? = + entries.firstOrNull { it.filename == filename } + } +} + +fun wallpaperBackgrounds(light: String): Map = + mapOf( + DefaultTheme.LIGHT to light.colorFromReadableHex(), + DefaultTheme.DARK to "#ff121212".colorFromReadableHex(), + DefaultTheme.SIMPLEX to "#ff111528".colorFromReadableHex(), + DefaultTheme.BLACK to "#ff070707".colorFromReadableHex() + ) + +@Serializable +enum class WallpaperScaleType(val contentScale: ContentScale, val text: StringResource) { + @SerialName("fill") FILL(ContentScale.Crop, MR.strings.wallpaper_scale_fill), + @SerialName("fit") FIT(ContentScale.Fit, MR.strings.wallpaper_scale_fit), + @SerialName("repeat") REPEAT(ContentScale.Fit, MR.strings.wallpaper_scale_repeat), +} + +sealed class WallpaperType { + abstract val scale: Float? + + val image by lazy { + val filename = when (this) { + is Preset -> filename + is Image -> filename + else -> return@lazy null + } + if (filename == "") return@lazy null + if (cachedImages[filename] != null) { + cachedImages[filename] + } else { + val res = if (this is Preset) { + (PresetWallpaper.from(filename) ?: PresetWallpaper.CATS).res.toComposeImageBitmap()!! + } else { + try { + // In case of unintentional image deletion don't crash the app + File(getWallpaperFilePath(filename)).inputStream().use { loadImageBitmap(it) } + } catch (e: Exception) { + Log.e(TAG, "Error while loading wallpaper file: ${e.stackTraceToString()}") + null + } + } + res?.prepareToDraw() + cachedImages[filename] = res ?: return@lazy null + res + } + } + + fun sameType(other: WallpaperType?): Boolean = + if (this is Preset && other is Preset) this.filename == other.filename + else this.javaClass == other?.javaClass + + fun samePreset(other: PresetWallpaper?): Boolean = this is Preset && filename == other?.filename + + data class Preset( + val filename: String, + override val scale: Float?, + ): WallpaperType() { + val predefinedImageScale = PresetWallpaper.from(filename)?.scale ?: 1f + } + + data class Image( + val filename: String, + override val scale: Float?, + val scaleType: WallpaperScaleType?, + ): WallpaperType() + + object Empty: WallpaperType() { + override val scale: Float? + get() = null + } + + fun defaultBackgroundColor(theme: DefaultTheme, materialBackground: Color): Color = + if (this is Preset) { + (PresetWallpaper.from(filename) ?: PresetWallpaper.CATS).background[theme]!! + } else { + materialBackground + } + + fun defaultTintColor(theme: DefaultTheme): Color = + if (this is Preset) { + (PresetWallpaper.from(filename) ?: PresetWallpaper.CATS).tint[theme]!! + } else if (this is Image && scaleType == WallpaperScaleType.REPEAT) { + Color.Transparent + } else { + Color.Transparent + } + + companion object { + var cachedImages: MutableMap = mutableMapOf() + + fun from(wallpaper: ThemeWallpaper?): WallpaperType? { + return if (wallpaper == null) { + null + } else if (wallpaper.preset != null) { + Preset(wallpaper.preset, wallpaper.scale) + } else if (wallpaper.imageFile != null) { + Image(wallpaper.imageFile, wallpaper.scale, wallpaper.scaleType) + } else { + Empty + } + } + } +} + +fun DrawScope.chatViewBackground(image: ImageBitmap, imageType: WallpaperType, background: Color, tint: Color) = clipRect { + val quality = FilterQuality.High + fun repeat(imageScale: Float) { + val scale = imageScale * density + for (h in 0..(size.height / image.height / scale).roundToInt()) { + for (w in 0..(size.width / image.width / scale).roundToInt()) { + drawImage( + image, + dstOffset = IntOffset(x = (w * image.width * scale).roundToInt(), y = (h * image.height * scale).roundToInt()), + dstSize = IntSize((image.width * scale).roundToInt(), (image.height * scale).roundToInt()), + colorFilter = ColorFilter.tint(tint, BlendMode.SrcIn), + filterQuality = quality + ) + } + } + } + + drawRect(background) + when (imageType) { + is WallpaperType.Preset -> repeat((imageType.scale ?: 1f) * imageType.predefinedImageScale) + is WallpaperType.Image -> when (val scaleType = imageType.scaleType ?: WallpaperScaleType.FILL) { + WallpaperScaleType.REPEAT -> repeat(imageType.scale ?: 1f) + WallpaperScaleType.FILL, WallpaperScaleType.FIT -> { + val scale = scaleType.contentScale.computeScaleFactor(Size(image.width.toFloat(), image.height.toFloat()), Size(size.width, size.height)) + val scaledWidth = (image.width * scale.scaleX).roundToInt() + val scaledHeight = (image.height * scale.scaleY).roundToInt() + drawImage(image, dstOffset = IntOffset(x = ((size.width - scaledWidth) / 2).roundToInt(), y = ((size.height - scaledHeight) / 2).roundToInt()), dstSize = IntSize(scaledWidth, scaledHeight), filterQuality = quality) + if (scaleType == WallpaperScaleType.FIT) { + if (scaledWidth < size.width) { + // has black lines at left and right sides + var x = (size.width - scaledWidth) / 2 + while (x > 0) { + drawImage(image, dstOffset = IntOffset(x = (x - scaledWidth).roundToInt(), y = ((size.height - scaledHeight) / 2).roundToInt()), dstSize = IntSize(scaledWidth, scaledHeight), filterQuality = quality) + x -= scaledWidth + } + x = size.width - (size.width - scaledWidth) / 2 + while (x < size.width) { + drawImage(image, dstOffset = IntOffset(x = x.roundToInt(), y = ((size.height - scaledHeight) / 2).roundToInt()), dstSize = IntSize(scaledWidth, scaledHeight), filterQuality = quality) + x += scaledWidth + } + } else { + // has black lines at top and bottom sides + var y = (size.height - scaledHeight) / 2 + while (y > 0) { + drawImage(image, dstOffset = IntOffset(x = ((size.width - scaledWidth) / 2).roundToInt(), y = (y - scaledHeight).roundToInt()), dstSize = IntSize(scaledWidth, scaledHeight), filterQuality = quality) + y -= scaledHeight + } + y = size.height - (size.height - scaledHeight) / 2 + while (y < size.height) { + drawImage(image, dstOffset = IntOffset(x = ((size.width - scaledWidth) / 2).roundToInt(), y = y.roundToInt()), dstSize = IntSize(scaledWidth, scaledHeight), filterQuality = quality) + y += scaledHeight + } + } + } + drawRect(tint) + } + } + is WallpaperType.Empty -> {} + } +} diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/CloseSheetBar.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/CloseSheetBar.kt index 2fb27e29b1..b26a047b0e 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/CloseSheetBar.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/CloseSheetBar.kt @@ -51,7 +51,7 @@ fun CloseSheetBar(close: (() -> Unit)?, showClose: Boolean = true, tintColor: Co @Composable fun AppBarTitle(title: String, hostDevice: Pair? = null, withPadding: Boolean = true, bottomPadding: Dp = DEFAULT_PADDING * 1.5f) { val theme = CurrentColors.collectAsState() - val titleColor = CurrentColors.collectAsState().value.appColors.title + val titleColor = MaterialTheme.appColors.title val brush = if (theme.value.base == DefaultTheme.SIMPLEX) Brush.linearGradient(listOf(titleColor.darker(0.2f), titleColor.lighter(0.35f)), Offset(0f, Float.POSITIVE_INFINITY), Offset(Float.POSITIVE_INFINITY, 0f)) else // color is not updated when changing themes if I pass null here diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/LinkPreviews.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/LinkPreviews.kt index 93d0a56766..20b8f7c09f 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/LinkPreviews.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/LinkPreviews.kt @@ -76,7 +76,7 @@ suspend fun getLinkPreview(url: String): LinkPreview? { @Composable fun ComposeLinkView(linkPreview: LinkPreview?, cancelPreview: () -> Unit, cancelEnabled: Boolean) { - val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage + val sentColor = MaterialTheme.appColors.sentMessage Row( Modifier.fillMaxWidth().padding(top = 8.dp).background(sentColor), verticalAlignment = Alignment.CenterVertically diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ModalView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ModalView.kt index 887a5bfdd9..6ee60c4596 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ModalView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ModalView.kt @@ -41,9 +41,12 @@ enum class ModalPlacement { } class ModalData { - private val state = mutableMapOf>() + private val state = mutableMapOf>() fun stateGetOrPut (key: String, default: () -> T): MutableState = state.getOrPut(key) { mutableStateOf(default() as Any) } as MutableState + + fun stateGetOrPutNullable (key: String, default: () -> T?): MutableState = + state.getOrPut(key) { mutableStateOf(default() as Any?) } as MutableState } class ModalManager(private val placement: ModalPlacement? = null) { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ThemeModeEditor.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ThemeModeEditor.kt new file mode 100644 index 0000000000..9df4c80b0e --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ThemeModeEditor.kt @@ -0,0 +1,463 @@ +package chat.simplex.common.views.helpers + +import SectionBottomSpacer +import SectionItemView +import SectionSpacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.runtime.* +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import chat.simplex.common.model.ChatController.appPrefs +import chat.simplex.common.platform.* +import chat.simplex.common.ui.theme.* +import chat.simplex.common.views.usersettings.* +import chat.simplex.common.views.usersettings.AppearanceScope.WallpaperPresetSelector +import chat.simplex.common.views.usersettings.AppearanceScope.editColor +import chat.simplex.res.MR +import dev.icerock.moko.resources.compose.painterResource +import dev.icerock.moko.resources.compose.stringResource +import java.net.URI + +@Composable +fun ModalData.UserWallpaperEditor( + theme: ThemeModeOverride, + applyToMode: DefaultThemeMode?, + globalThemeUsed: MutableState, + save: suspend (applyToMode: DefaultThemeMode?, ThemeModeOverride?) -> Unit +) { + ColumnWithScrollBar( + Modifier + .fillMaxSize() + ) { + val applyToMode = remember { stateGetOrPutNullable("applyToMode") { applyToMode } } + var showMore by remember { stateGetOrPut("showMore") { false } } + val themeModeOverride = remember { stateGetOrPut("themeModeOverride") { theme } } + val currentTheme by CurrentColors.collectAsState() + + AppBarTitle(stringResource(MR.strings.settings_section_title_user_theme)) + val wallpaperImage = MaterialTheme.wallpaper.type.image + val wallpaperType = MaterialTheme.wallpaper.type + + val onTypeCopyFromSameTheme = { type: WallpaperType? -> + if (type is WallpaperType.Image && chatModel.remoteHostId() != null) { + false + } else { + ThemeManager.copyFromSameThemeOverrides(type, null, themeModeOverride) + withBGApi { save(applyToMode.value, themeModeOverride.value) } + globalThemeUsed.value = false + true + } + } + val preApplyGlobalIfNeeded = { type: WallpaperType? -> + if (globalThemeUsed.value) { + onTypeCopyFromSameTheme(type) + } + } + val onTypeChange: (WallpaperType?) -> Unit = { type: WallpaperType? -> + if (globalThemeUsed.value) { + preApplyGlobalIfNeeded(type) + // Saves copied static image instead of original from global theme + ThemeManager.applyWallpaper(themeModeOverride.value.type, themeModeOverride) + } else { + ThemeManager.applyWallpaper(type, themeModeOverride) + } + withBGApi { save(applyToMode.value, themeModeOverride.value) } + } + + val importWallpaperLauncher = rememberFileChooserLauncher(true) { to: URI? -> + if (to != null) { + val filename = saveWallpaperFile(to) + if (filename != null) { + onTypeChange(WallpaperType.Image(filename, 1f, WallpaperScaleType.FILL)) + } + } + } + + val currentColors = { type: WallpaperType? -> + // If applying for : + // - all themes: no overrides needed + // - specific user: only user overrides for currently selected theme are needed, because they will NOT be copied when other wallpaper is selected + val perUserOverride = if (wallpaperType.sameType(type)) chatModel.currentUser.value?.uiThemes else null + ThemeManager.currentColors(type, null, perUserOverride, appPrefs.themeOverrides.get()) + } + val onChooseType: (WallpaperType?) -> Unit = { type: WallpaperType? -> + when { + // don't have image in parent or already selected wallpaper with custom image + type is WallpaperType.Image && chatModel.remoteHostId() != null -> { /* do nothing */ } + type is WallpaperType.Image && (wallpaperType is WallpaperType.Image || currentColors(type).wallpaper.type.image == null) -> withLongRunningApi { importWallpaperLauncher.launch("image/*") } + type is WallpaperType.Image -> onTypeCopyFromSameTheme(currentColors(type).wallpaper.type) + themeModeOverride.value.type != type || currentTheme.wallpaper.type != type -> onTypeCopyFromSameTheme(type) + else -> onTypeChange(type) + } + } + + val editColor = { name: ThemeColor -> + editColor( + name, + wallpaperType, + wallpaperImage, + onColorChange = { color -> + preApplyGlobalIfNeeded(themeModeOverride.value.type) + ThemeManager.applyThemeColor(name, color, themeModeOverride) + withBGApi { save(applyToMode.value, themeModeOverride.value) } + } + ) + } + + WallpaperPresetSelector( + selectedWallpaper = wallpaperType, + baseTheme = currentTheme.base, + currentColors = { type -> + // If applying for : + // - all themes: no overrides needed + // - specific user: only user overrides for currently selected theme are needed, because they will NOT be copied when other wallpaper is selected + val perUserOverride = if (wallpaperType.sameType(type)) chatModel.currentUser.value?.uiThemes else null + ThemeManager.currentColors(type, null, perUserOverride, appPrefs.themeOverrides.get()) + }, + onChooseType = onChooseType + ) + + WallpaperSetupView( + themeModeOverride.value.type, + CurrentColors.collectAsState().value.base, + currentTheme.wallpaper, + currentTheme.appColors.sentMessage, + currentTheme.appColors.sentQuote, + currentTheme.appColors.receivedMessage, + currentTheme.appColors.receivedQuote, + editColor = { name -> editColor(name) }, + onTypeChange = onTypeChange, + ) + + SectionSpacer() + + if (!globalThemeUsed.value) { + ResetToGlobalThemeButton { + themeModeOverride.value = ThemeManager.defaultActiveTheme(chatModel.currentUser.value?.uiThemes, appPrefs.themeOverrides.get()) + globalThemeUsed.value = true + withBGApi { save(applyToMode.value, null) } + } + } + + SetDefaultThemeButton { + globalThemeUsed.value = false + val lightBase = DefaultTheme.LIGHT + val darkBase = if (CurrentColors.value.base != DefaultTheme.LIGHT) CurrentColors.value.base else if (appPrefs.systemDarkTheme.get() == DefaultTheme.DARK.themeName) DefaultTheme.DARK else if (appPrefs.systemDarkTheme.get() == DefaultTheme.BLACK.themeName) DefaultTheme.BLACK else DefaultTheme.SIMPLEX + val mode = themeModeOverride.value.mode + withBGApi { + // Saving for both modes in one place by changing mode once per save + if (applyToMode.value == null) { + val oppositeMode = if (mode == DefaultThemeMode.LIGHT) DefaultThemeMode.DARK else DefaultThemeMode.LIGHT + save(oppositeMode, ThemeModeOverride.withFilledAppDefaults(oppositeMode, if (oppositeMode == DefaultThemeMode.LIGHT) lightBase else darkBase)) + } + themeModeOverride.value = ThemeModeOverride.withFilledAppDefaults(mode, if (mode == DefaultThemeMode.LIGHT) lightBase else darkBase) + save(themeModeOverride.value.mode, themeModeOverride.value) + } + } + + KeyChangeEffect(theme.mode) { + themeModeOverride.value = theme + if (applyToMode.value != null) { + applyToMode.value = theme.mode + } + } + + // Applies updated global theme if current one tracks global theme + KeyChangeEffect(CurrentColors.collectAsState().value) { + if (globalThemeUsed.value) { + themeModeOverride.value = ThemeManager.defaultActiveTheme(chatModel.currentUser.value?.uiThemes, appPrefs.themeOverrides.get()) + globalThemeUsed.value = true + } + } + + SectionSpacer() + + if (showMore) { + val values by remember { mutableStateOf( + listOf( + null to generalGetString(MR.strings.chat_theme_apply_to_all_modes), + DefaultThemeMode.LIGHT to generalGetString(MR.strings.chat_theme_apply_to_light_mode), + DefaultThemeMode.DARK to generalGetString(MR.strings.chat_theme_apply_to_dark_mode), + ) + ) + } + ExposedDropDownSettingRow( + generalGetString(MR.strings.chat_theme_apply_to_mode), + values, + applyToMode, + icon = null, + enabled = remember { mutableStateOf(true) }, + onSelected = { + applyToMode.value = it + if (it != null && it != CurrentColors.value.base.mode) { + val lightBase = DefaultTheme.LIGHT + val darkBase = if (CurrentColors.value.base != DefaultTheme.LIGHT) CurrentColors.value.base else if (appPrefs.systemDarkTheme.get() == DefaultTheme.DARK.themeName) DefaultTheme.DARK else if (appPrefs.systemDarkTheme.get() == DefaultTheme.BLACK.themeName) DefaultTheme.BLACK else DefaultTheme.SIMPLEX + ThemeManager.applyTheme(if (it == DefaultThemeMode.LIGHT) lightBase.themeName else darkBase.themeName) + } + } + ) + + SectionSpacer() + + AppearanceScope.CustomizeThemeColorsSection(currentTheme, editColor = editColor) + } else { + AdvancedSettingsButton { showMore = true } + } + + SectionBottomSpacer() + } +} + +@Composable +fun ModalData.ChatWallpaperEditor( + theme: ThemeModeOverride, + applyToMode: DefaultThemeMode?, + globalThemeUsed: MutableState, + save: suspend (applyToMode: DefaultThemeMode?, ThemeModeOverride?) -> Unit +) { + ColumnWithScrollBar( + Modifier + .fillMaxSize() + ) { + val applyToMode = remember { stateGetOrPutNullable("applyToMode") { applyToMode } } + var showMore by remember { stateGetOrPut("showMore") { false } } + val themeModeOverride = remember { stateGetOrPut("themeModeOverride") { theme } } + val currentTheme by remember(themeModeOverride.value, CurrentColors.collectAsState().value) { + mutableStateOf( + ThemeManager.currentColors(null, if (themeModeOverride.value == ThemeModeOverride()) null else themeModeOverride.value, chatModel.currentUser.value?.uiThemes, appPreferences.themeOverrides.get()) + ) + } + + AppBarTitle(stringResource(MR.strings.settings_section_title_chat_theme)) + + val onTypeCopyFromSameTheme: (WallpaperType?) -> Boolean = { type -> + if (type is WallpaperType.Image && chatModel.remoteHostId() != null) { + false + } else { + val success = ThemeManager.copyFromSameThemeOverrides(type, chatModel.currentUser.value?.uiThemes?.preferredMode(!CurrentColors.value.colors.isLight), themeModeOverride) + if (success) { + withBGApi { save(applyToMode.value, themeModeOverride.value) } + globalThemeUsed.value = false + } + success + } + } + val preApplyGlobalIfNeeded = { type: WallpaperType? -> + if (globalThemeUsed.value) { + onTypeCopyFromSameTheme(type) + } + } + val onTypeChange: (WallpaperType?) -> Unit = { type -> + if (globalThemeUsed.value) { + preApplyGlobalIfNeeded(type) + // Saves copied static image instead of original from global theme + ThemeManager.applyWallpaper(themeModeOverride.value.type, themeModeOverride) + } else { + ThemeManager.applyWallpaper(type, themeModeOverride) + } + withBGApi { save(applyToMode.value, themeModeOverride.value) } + } + + val editColor: (ThemeColor) -> Unit = { name: ThemeColor -> + ModalManager.end.showModal { + val currentTheme by remember(themeModeOverride.value, CurrentColors.collectAsState().value) { + mutableStateOf( + ThemeManager.currentColors(null, themeModeOverride.value, chatModel.currentUser.value?.uiThemes, appPreferences.themeOverrides.get()) + ) + } + val initialColor: Color = when (name) { + ThemeColor.WALLPAPER_BACKGROUND -> currentTheme.wallpaper.background ?: Color.Transparent + ThemeColor.WALLPAPER_TINT -> currentTheme.wallpaper.tint ?: Color.Transparent + ThemeColor.PRIMARY -> currentTheme.colors.primary + ThemeColor.PRIMARY_VARIANT -> currentTheme.colors.primaryVariant + ThemeColor.SECONDARY -> currentTheme.colors.secondary + ThemeColor.SECONDARY_VARIANT -> currentTheme.colors.secondaryVariant + ThemeColor.BACKGROUND -> currentTheme.colors.background + ThemeColor.SURFACE -> currentTheme.colors.surface + ThemeColor.TITLE -> currentTheme.appColors.title + ThemeColor.PRIMARY_VARIANT2 -> currentTheme.appColors.primaryVariant2 + ThemeColor.SENT_MESSAGE -> currentTheme.appColors.sentMessage + ThemeColor.SENT_QUOTE -> currentTheme.appColors.sentQuote + ThemeColor.RECEIVED_MESSAGE -> currentTheme.appColors.receivedMessage + ThemeColor.RECEIVED_QUOTE -> currentTheme.appColors.receivedQuote + } + AppearanceScope.ColorEditor( + name, + initialColor, + CurrentColors.collectAsState().value.base, + themeModeOverride.value.type, + themeModeOverride.value.type?.image, + currentTheme.wallpaper.background, + currentTheme.wallpaper.tint, + currentColors = { + ThemeManager.currentColors(null, themeModeOverride.value, chatModel.currentUser.value?.uiThemes, appPreferences.themeOverrides.get()) + }, + onColorChange = { color -> + preApplyGlobalIfNeeded(themeModeOverride.value.type) + ThemeManager.applyThemeColor(name, color, themeModeOverride) + withBGApi { save(applyToMode.value, themeModeOverride.value) } + } + ) + } + } + + val importWallpaperLauncher = rememberFileChooserLauncher(true) { to: URI? -> + if (to != null) { + val filename = saveWallpaperFile(to) + if (filename != null) { + // Delete only non-user image + if (!globalThemeUsed.value) { + removeWallpaperFile((themeModeOverride.value.type as? WallpaperType.Image)?.filename) + } + globalThemeUsed.value = false + onTypeChange(WallpaperType.Image(filename, 1f, WallpaperScaleType.FILL)) + } + } + } + + val currentColors = { type: WallpaperType? -> + ThemeManager.currentColors(type, if (type?.sameType(themeModeOverride.value.type) == true) themeModeOverride.value else null, chatModel.currentUser.value?.uiThemes, appPrefs.themeOverrides.get()) + } + + WallpaperPresetSelector( + selectedWallpaper = currentTheme.wallpaper.type, + activeBackgroundColor = currentTheme.wallpaper.background, + activeTintColor = currentTheme.wallpaper.tint, + baseTheme = CurrentColors.collectAsState().value.base, + currentColors = { type -> currentColors(type) }, + onChooseType = { type -> + when { + type is WallpaperType.Image && chatModel.remoteHostId() != null -> { /* do nothing */ } + type is WallpaperType.Image && ((themeModeOverride.value.type is WallpaperType.Image && !globalThemeUsed.value) || currentColors(type).wallpaper.type.image == null) -> { + withLongRunningApi { importWallpaperLauncher.launch("image/*") } + } + type is WallpaperType.Image -> { + if (!onTypeCopyFromSameTheme(currentColors(type).wallpaper.type)) { + withLongRunningApi { importWallpaperLauncher.launch("image/*") } + } + } + globalThemeUsed.value || themeModeOverride.value.type != type -> { + onTypeCopyFromSameTheme(type) + } + else -> { + onTypeChange(type) + } + } + }, + ) + + WallpaperSetupView( + themeModeOverride.value.type, + CurrentColors.collectAsState().value.base, + currentTheme.wallpaper, + currentTheme.appColors.sentMessage, + currentTheme.appColors.sentQuote, + currentTheme.appColors.receivedMessage, + currentTheme.appColors.receivedQuote, + editColor = editColor, + onTypeChange = onTypeChange, + ) + + SectionSpacer() + + if (!globalThemeUsed.value) { + ResetToGlobalThemeButton { + themeModeOverride.value = ThemeManager.defaultActiveTheme(chatModel.currentUser.value?.uiThemes, appPrefs.themeOverrides.get()) + globalThemeUsed.value = true + withBGApi { save(applyToMode.value, null) } + } + } + + SetDefaultThemeButton { + globalThemeUsed.value = false + val lightBase = DefaultTheme.LIGHT + val darkBase = if (CurrentColors.value.base != DefaultTheme.LIGHT) CurrentColors.value.base else if (appPrefs.systemDarkTheme.get() == DefaultTheme.DARK.themeName) DefaultTheme.DARK else if (appPrefs.systemDarkTheme.get() == DefaultTheme.BLACK.themeName) DefaultTheme.BLACK else DefaultTheme.SIMPLEX + val mode = themeModeOverride.value.mode + withBGApi { + // Saving for both modes in one place by changing mode once per save + if (applyToMode.value == null) { + val oppositeMode = if (mode == DefaultThemeMode.LIGHT) DefaultThemeMode.DARK else DefaultThemeMode.LIGHT + save(oppositeMode, ThemeModeOverride.withFilledAppDefaults(oppositeMode, if (oppositeMode == DefaultThemeMode.LIGHT) lightBase else darkBase)) + } + themeModeOverride.value = ThemeModeOverride.withFilledAppDefaults(mode, if (mode == DefaultThemeMode.LIGHT) lightBase else darkBase) + save(themeModeOverride.value.mode, themeModeOverride.value) + } + } + + KeyChangeEffect(theme.mode) { + themeModeOverride.value = theme + if (applyToMode.value != null) { + applyToMode.value = theme.mode + } + } + + // Applies updated global theme if current one tracks global theme + KeyChangeEffect(CurrentColors.collectAsState()) { + if (globalThemeUsed.value) { + themeModeOverride.value = ThemeManager.defaultActiveTheme(chatModel.currentUser.value?.uiThemes, appPrefs.themeOverrides.get()) + globalThemeUsed.value = true + } + } + + SectionSpacer() + + if (showMore) { + val values by remember { mutableStateOf( + listOf( + null to generalGetString(MR.strings.chat_theme_apply_to_all_modes), + DefaultThemeMode.LIGHT to generalGetString(MR.strings.chat_theme_apply_to_light_mode), + DefaultThemeMode.DARK to generalGetString(MR.strings.chat_theme_apply_to_dark_mode), + ) + ) + } + ExposedDropDownSettingRow( + generalGetString(MR.strings.chat_theme_apply_to_mode), + values, + applyToMode, + icon = null, + enabled = remember { mutableStateOf(true) }, + onSelected = { + applyToMode.value = it + if (it != null && it != CurrentColors.value.base.mode) { + val lightBase = DefaultTheme.LIGHT + val darkBase = if (CurrentColors.value.base != DefaultTheme.LIGHT) CurrentColors.value.base else if (appPrefs.systemDarkTheme.get() == DefaultTheme.DARK.themeName) DefaultTheme.DARK else if (appPrefs.systemDarkTheme.get() == DefaultTheme.BLACK.themeName) DefaultTheme.BLACK else DefaultTheme.SIMPLEX + ThemeManager.applyTheme(if (it == DefaultThemeMode.LIGHT) lightBase.themeName else darkBase.themeName) + } + } + ) + + SectionSpacer() + + AppearanceScope.CustomizeThemeColorsSection(currentTheme, editColor = editColor) + } else { + AdvancedSettingsButton { showMore = true } + } + + SectionBottomSpacer() + } +} + +@Composable +private fun ResetToGlobalThemeButton(onClick: () -> Unit) { + SectionItemView(onClick) { + Text(stringResource(MR.strings.chat_theme_reset_to_global_theme), color = MaterialTheme.colors.primary) + } +} + +@Composable +private fun SetDefaultThemeButton(onClick: () -> Unit) { + SectionItemView(onClick) { + Text(stringResource(MR.strings.chat_theme_set_default_theme), color = MaterialTheme.colors.primary) + } +} + +@Composable +private fun AdvancedSettingsButton(onClick: () -> Unit) { + SettingsActionItem( + painterResource(MR.images.ic_arrow_downward), + stringResource(MR.strings.wallpaper_advanced_settings), + click = onClick + ) +} diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Utils.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Utils.kt index 9a6e3a0f9a..4740280bb5 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Utils.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Utils.kt @@ -19,6 +19,7 @@ import kotlinx.serialization.encodeToString import java.io.* import java.net.URI import java.nio.file.Files +import java.nio.file.StandardCopyOption import java.text.SimpleDateFormat import java.util.* import java.util.concurrent.Executors @@ -280,6 +281,38 @@ fun saveFileFromUri(uri: URI, withAlertOnException: Boolean = true): CryptoFile? } } +fun saveWallpaperFile(uri: URI): String? { + val destFileName = generateNewFileName("wallpaper", "jpg", File(getWallpaperFilePath(""))) + val destFile = File(getWallpaperFilePath(destFileName)) + try { + val inputStream = uri.inputStream() + Files.copy(inputStream!!, destFile.toPath(), StandardCopyOption.REPLACE_EXISTING) + } catch (e: Exception) { + Log.e(TAG, "Error saving wallpaper file: ${e.stackTraceToString()}") + AlertManager.shared.showAlertMsg(generalGetString(MR.strings.error), e.stackTraceToString()) + return null + } + return destFile.name +} + +fun saveWallpaperFile(image: ImageBitmap): String { + val destFileName = generateNewFileName("wallpaper", "jpg", File(getWallpaperFilePath(""))) + val destFile = File(getWallpaperFilePath(destFileName)) + val dataResized = resizeImageToDataSize(image, false, maxDataSize = 5_000_000) + val output = FileOutputStream(destFile) + dataResized.use { + it.writeTo(output) + } + return destFile.name +} + +fun removeWallpaperFile(fileName: String? = null) { + File(getWallpaperFilePath("_")).parentFile.listFiles()?.forEach { + if (it.name == fileName) it.delete() + } + WallpaperType.cachedImages.remove(fileName) +} + fun createTmpFileAndDelete(onCreated: (File) -> T): T { val tmpFile = File(tmpDir, UUID.randomUUID().toString()) tmpFile.deleteOnExit() @@ -550,10 +583,33 @@ fun KeyChangeEffect( val initialKey = remember { key1 } val initialKey2 = remember { key2 } var anyChange by remember { mutableStateOf(false) } - LaunchedEffect(key1) { + LaunchedEffect(key1, key2) { if (anyChange || key1 != initialKey || key2 != initialKey2) { block() anyChange = true } } } + +/** + * Runs the [block] only after initial value of the [key1], or [key2], or [key3] changes, not after initial launch + * */ +@Composable +@NonRestartableComposable +fun KeyChangeEffect( + key1: Any?, + key2: Any?, + key3: Any?, + block: suspend CoroutineScope.() -> Unit +) { + val initialKey = remember { key1 } + val initialKey2 = remember { key2 } + val initialKey3 = remember { key3 } + var anyChange by remember { mutableStateOf(false) } + LaunchedEffect(key1, key2, key3) { + if (anyChange || key1 != initialKey || key2 != initialKey2 || key3 != initialKey3) { + block() + anyChange = true + } + } +} diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/localauth/LocalAuthView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/localauth/LocalAuthView.kt index 5a37c860a0..65e1864935 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/localauth/LocalAuthView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/localauth/LocalAuthView.kt @@ -34,7 +34,7 @@ fun LocalAuthView(m: ChatModel, authRequest: LocalAuthRequest) { } else { val r: LAResult = if (passcode.value == authRequest.password) { if (authRequest.selfDestruct && sdPassword != null && controller.ctrl == -1L) { - initChatControllerAndRunMigrations() + initChatControllerOnStart() } LAResult.Success } else { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateToDevice.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateToDevice.kt index 9d204ad42c..f3a992d451 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateToDevice.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateToDevice.kt @@ -669,7 +669,7 @@ private suspend fun MutableState.cleanUpOnBack(chatReceiver: if (state is MigrationToState.ArchiveImportFailed) { // Original database is not exist, nothing is set up correctly for showing to a user yet. Return to clean state deleteChatDatabaseFilesAndState() - initChatControllerAndRunMigrations() + initChatControllerOnStart() } else if (state is MigrationToState.DownloadProgress && state.ctrl != null) { stopArchiveDownloading(state.fileId, state.ctrl) } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Appearance.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Appearance.kt index 78e24e5e7e..ad7804de00 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Appearance.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Appearance.kt @@ -1,37 +1,52 @@ package chat.simplex.common.views.usersettings import SectionBottomSpacer +import SectionDividerSpaced import SectionItemView import SectionItemViewSpaceBetween import SectionSpacer import SectionView -import androidx.compose.foundation.Image +import androidx.compose.foundation.* import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.grid.* +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.* import androidx.compose.material.MaterialTheme.colors import androidx.compose.runtime.* +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip +import androidx.compose.ui.draw.* import androidx.compose.ui.graphics.* -import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalClipboardManager +import androidx.compose.ui.text.input.TextFieldValue +import androidx.compose.ui.unit.* import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource -import androidx.compose.ui.unit.dp import chat.simplex.common.model.* +import chat.simplex.common.model.ChatController.appPrefs import chat.simplex.common.ui.theme.* import chat.simplex.common.views.helpers.* import chat.simplex.common.model.ChatModel +import chat.simplex.common.model.ChatModel.controller import chat.simplex.common.platform.* +import chat.simplex.common.ui.theme.ThemeManager.colorFromReadableHex +import chat.simplex.common.ui.theme.ThemeManager.toReadableHex +import chat.simplex.common.views.chat.item.PreviewChatItemView import chat.simplex.res.MR -import com.godaddy.android.colorpicker.* +import com.godaddy.android.colorpicker.ClassicColorPicker +import com.godaddy.android.colorpicker.HsvColor +import kotlinx.coroutines.Job +import kotlinx.coroutines.delay +import kotlinx.datetime.Clock import kotlinx.serialization.encodeToString import java.net.URI import java.util.* import kotlin.collections.ArrayList +import kotlin.math.* @Composable -expect fun AppearanceView(m: ChatModel, showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit)) +expect fun AppearanceView(m: ChatModel) object AppearanceScope { @Composable @@ -55,6 +70,7 @@ object AppearanceScope { onValueChange = { val diff = it % 2.5f appPreferences.profileImageCornerRadius.set(it + (if (diff >= 1.25f) -diff + 2.5f else -diff)) + saveThemeToDatabase(null) }, colors = SliderDefaults.colors( activeTickColor = Color.Transparent, @@ -66,90 +82,424 @@ object AppearanceScope { } @Composable - fun ThemesSection( - systemDarkTheme: SharedPreference, - showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit), - editColor: (ThemeColor, Color) -> Unit + fun ChatThemePreview( + theme: DefaultTheme, + wallpaperImage: ImageBitmap?, + wallpaperType: WallpaperType?, + backgroundColor: Color? = MaterialTheme.wallpaper.background, + tintColor: Color? = MaterialTheme.wallpaper.tint, + withMessages: Boolean = true ) { - val currentTheme by CurrentColors.collectAsState() - SectionView(stringResource(MR.strings.settings_section_title_themes)) { - val darkTheme = isSystemInDarkTheme() - val state = remember { derivedStateOf { currentTheme.name } } - ThemeSelector(state) { - ThemeManager.applyTheme(it, darkTheme) - } - if (state.value == DefaultTheme.SYSTEM.name) { - DarkThemeSelector(remember { systemDarkTheme.state }) { - ThemeManager.changeDarkTheme(it, darkTheme) + val themeBackgroundColor = MaterialTheme.colors.background + val backgroundColor = backgroundColor ?: wallpaperType?.defaultBackgroundColor(theme, MaterialTheme.colors.background) + val tintColor = tintColor ?: wallpaperType?.defaultTintColor(theme) + Column(Modifier + .drawBehind { + if (wallpaperImage != null && wallpaperType != null && backgroundColor != null && tintColor != null) { + chatViewBackground(wallpaperImage, wallpaperType, backgroundColor, tintColor) + } else { + drawRect(themeBackgroundColor) } } + .padding(DEFAULT_PADDING_HALF) + ) { + if (withMessages) { + val alice = remember { ChatItem.getSampleData(1, CIDirection.DirectRcv(), Clock.System.now(), generalGetString(MR.strings.wallpaper_preview_hello_bob)) } + PreviewChatItemView(alice) + PreviewChatItemView( + ChatItem.getSampleData(2, CIDirection.DirectSnd(), Clock.System.now(), stringResource(MR.strings.wallpaper_preview_hello_alice), + quotedItem = CIQuote(alice.chatDir, alice.id, sentAt = alice.meta.itemTs, formattedText = alice.formattedText, content = MsgContent.MCText(alice.content.text)) + ) + ) + } else { + Box(Modifier.fillMaxSize()) + } } - SectionItemView(showSettingsModal { _ -> CustomizeThemeView(editColor) }) { Text(stringResource(MR.strings.customize_theme_title)) } } @Composable - fun CustomizeThemeView(editColor: (ThemeColor, Color) -> Unit) { + fun WallpaperPresetSelector( + selectedWallpaper: WallpaperType?, + baseTheme: DefaultTheme, + activeBackgroundColor: Color? = null, + activeTintColor: Color? = null, + currentColors: (WallpaperType?) -> ThemeManager.ActiveTheme, + onChooseType: (WallpaperType?) -> Unit, + ) { + val cornerRadius = 22 + + @Composable + fun Plus(tint: Color = MaterialTheme.colors.primary) { + Icon(painterResource(MR.images.ic_add), null, Modifier.size(25.dp), tint = tint) + } + + val backgrounds = PresetWallpaper.entries.toList() + + fun LazyGridScope.gridContent(width: Dp, height: Dp) { + @Composable + fun BackgroundItem(background: PresetWallpaper?) { + val checked = (background == null && (selectedWallpaper == null || selectedWallpaper == WallpaperType.Empty)) || selectedWallpaper?.samePreset(background) == true + Box( + Modifier + .size(width, height) + .clip(RoundedCornerShape(percent = cornerRadius)) + .border(1.dp, if (checked) MaterialTheme.colors.primary.copy(0.8f) else MaterialTheme.colors.onBackground.copy(if (isInDarkTheme()) 0.2f else 0.1f), RoundedCornerShape(percent = cornerRadius)) + .clickable { onChooseType(background?.toType(baseTheme)) }, + contentAlignment = Alignment.Center + ) { + if (background != null) { + val type = background.toType(baseTheme, if (checked) selectedWallpaper?.scale else null) + SimpleXThemeOverride(remember(background, selectedWallpaper, CurrentColors.collectAsState().value) { currentColors(type) }) { + ChatThemePreview( + baseTheme, + type.image, + type, + withMessages = false, + backgroundColor = if (checked) activeBackgroundColor ?: MaterialTheme.wallpaper.background else MaterialTheme.wallpaper.background, + tintColor = if (checked) activeTintColor ?: MaterialTheme.wallpaper.tint else MaterialTheme.wallpaper.tint + ) + } + } + } + } + + @Composable + fun OwnBackgroundItem(type: WallpaperType?) { + val overrides = remember(type, baseTheme, CurrentColors.collectAsState().value.wallpaper) { + currentColors(WallpaperType.Image("", null, null)) + } + val appWallpaper = overrides.wallpaper + val backgroundColor = appWallpaper.background + val tintColor = appWallpaper.tint + val wallpaperImage = appWallpaper.type.image + val checked = type is WallpaperType.Image && wallpaperImage != null + val remoteHostConnected = chatModel.remoteHostId != null + Box( + Modifier + .size(width, height) + .clip(RoundedCornerShape(percent = cornerRadius)) + .border(1.dp, if (type is WallpaperType.Image) MaterialTheme.colors.primary.copy(0.8f) else MaterialTheme.colors.onBackground.copy(0.1f), RoundedCornerShape(percent = cornerRadius)) + .clickable { onChooseType(WallpaperType.Image("", null, null)) }, + contentAlignment = Alignment.Center + ) { + + if (checked || wallpaperImage != null) { + ChatThemePreview( + baseTheme, + wallpaperImage, + if (checked) type else appWallpaper.type, + backgroundColor = if (checked) activeBackgroundColor ?: backgroundColor else backgroundColor, + tintColor = if (checked) activeTintColor ?: tintColor else tintColor, + withMessages = false + ) + } else if (remoteHostConnected) { + Plus(MaterialTheme.colors.error) + } else { + Plus() + } + } + } + + item { + BackgroundItem(null) + } + items(items = backgrounds) { background -> + BackgroundItem(background) + } + item { + OwnBackgroundItem(selectedWallpaper) + } + } + + SimpleXThemeOverride(remember(selectedWallpaper, CurrentColors.collectAsState().value) { currentColors(selectedWallpaper) }) { + ChatThemePreview( + baseTheme, + MaterialTheme.wallpaper.type.image, + selectedWallpaper, + backgroundColor = activeBackgroundColor ?: MaterialTheme.wallpaper.background, + tintColor = activeTintColor ?: MaterialTheme.wallpaper.tint, + ) + } + + if (appPlatform.isDesktop) { + val itemWidth = (DEFAULT_START_MODAL_WIDTH - DEFAULT_PADDING * 2 - DEFAULT_PADDING_HALF * 3) / 4 + val itemHeight = (DEFAULT_START_MODAL_WIDTH - DEFAULT_PADDING * 2) / 4 + val rows = ceil((PresetWallpaper.entries.size + 2) / 4f).roundToInt() + LazyVerticalGrid( + columns = GridCells.Fixed(4), + Modifier.height(itemHeight * rows + DEFAULT_PADDING_HALF * (rows - 1) + DEFAULT_PADDING * 2), + contentPadding = PaddingValues(DEFAULT_PADDING), + verticalArrangement = Arrangement.spacedBy(DEFAULT_PADDING_HALF), + horizontalArrangement = Arrangement.spacedBy(DEFAULT_PADDING_HALF), + ) { + gridContent(itemWidth, itemHeight) + } + } else { + LazyHorizontalGrid( + rows = GridCells.Fixed(1), + Modifier.height(80.dp + DEFAULT_PADDING * 2), + contentPadding = PaddingValues(DEFAULT_PADDING), + horizontalArrangement = Arrangement.spacedBy(DEFAULT_PADDING_HALF), + ) { + gridContent(80.dp, 80.dp) + } + } + } + + @Composable + fun ThemesSection(systemDarkTheme: SharedPreference) { + val currentTheme by CurrentColors.collectAsState() + val baseTheme = currentTheme.base + val wallpaperType = MaterialTheme.wallpaper.type + val themeUserDestination: MutableState?> = rememberSaveable(stateSaver = serializableSaver()) { + val currentUser = chatModel.currentUser.value + mutableStateOf( + if (currentUser?.uiThemes?.preferredMode(!currentTheme.colors.isLight) == null) null else currentUser.userId to currentUser.uiThemes + ) + } + val perUserTheme = remember(CurrentColors.collectAsState().value.base, chatModel.currentUser.value) { + mutableStateOf( + chatModel.currentUser.value?.uiThemes?.preferredMode(!CurrentColors.value.colors.isLight) ?: ThemeModeOverride() + ) + } + + fun updateThemeUserDestination() { + var (userId, themes) = themeUserDestination.value ?: return + themes = if (perUserTheme.value.mode == DefaultThemeMode.LIGHT) { + (themes ?: ThemeModeOverrides()).copy(light = perUserTheme.value) + } else { + (themes ?: ThemeModeOverrides()).copy(dark = perUserTheme.value) + } + themeUserDestination.value = userId to themes + } + + val onTypeCopyFromSameTheme = { type: WallpaperType? -> + if (themeUserDestination.value == null) { + ThemeManager.saveAndApplyWallpaper(baseTheme, type) + } else { + val wallpaperFiles = listOf(perUserTheme.value.wallpaper?.imageFile) + ThemeManager.copyFromSameThemeOverrides(type, null, perUserTheme) + val wallpaperFilesToDelete = wallpaperFiles - perUserTheme.value.wallpaper?.imageFile + wallpaperFilesToDelete.forEach(::removeWallpaperFile) + updateThemeUserDestination() + } + saveThemeToDatabase(themeUserDestination.value) + true + } + + val onTypeChange = { type: WallpaperType? -> + if (themeUserDestination.value == null) { + ThemeManager.saveAndApplyWallpaper(baseTheme, type) + } else { + ThemeManager.applyWallpaper(type, perUserTheme) + updateThemeUserDestination() + } + saveThemeToDatabase(themeUserDestination.value) + } + + val importWallpaperLauncher = rememberFileChooserLauncher(true) { to: URI? -> + if (to != null) { + val filename = saveWallpaperFile(to) + if (filename != null) { + if (themeUserDestination.value == null) { + removeWallpaperFile((currentTheme.wallpaper.type as? WallpaperType.Image)?.filename) + } else { + removeWallpaperFile((perUserTheme.value.type as? WallpaperType.Image)?.filename) + } + onTypeChange(WallpaperType.Image(filename, 1f, WallpaperScaleType.FILL)) + } + } + } + + val currentColors = { type: WallpaperType? -> + // If applying for : + // - all themes: no overrides needed + // - specific user: only user overrides for currently selected theme are needed, because they will NOT be copied when other wallpaper is selected + val perUserOverride = if (themeUserDestination.value == null) null else if (wallpaperType.sameType(type)) chatModel.currentUser.value?.uiThemes else null + ThemeManager.currentColors(type, null, perUserOverride, appPrefs.themeOverrides.get()) + } + + val onChooseType: (WallpaperType?) -> Unit = { type: WallpaperType? -> + when { + // don't have image in parent or already selected wallpaper with custom image + type is WallpaperType.Image && + ((wallpaperType is WallpaperType.Image && themeUserDestination.value?.second != null && chatModel.remoteHostId() == null) || + currentColors(type).wallpaper.type.image == null || + (currentColors(type).wallpaper.type.image != null && wallpaperType is WallpaperType.Image && themeUserDestination.value == null)) -> + withLongRunningApi { importWallpaperLauncher.launch("image/*") } + type is WallpaperType.Image && themeUserDestination.value == null -> onTypeChange(currentColors(type).wallpaper.type) + type is WallpaperType.Image && chatModel.remoteHostId() != null -> { /* do nothing when remote host connected */ } + type is WallpaperType.Image -> onTypeCopyFromSameTheme(currentColors(type).wallpaper.type) + (themeUserDestination.value != null && themeUserDestination.value?.second?.preferredMode(!CurrentColors.value.colors.isLight)?.type != type) || currentTheme.wallpaper.type != type -> onTypeCopyFromSameTheme(type) + else -> onTypeChange(type) + } + } + + SectionView(stringResource(MR.strings.settings_section_title_themes)) { + Spacer(Modifier.height(DEFAULT_PADDING_HALF)) + ThemeDestinationPicker(themeUserDestination) + Spacer(Modifier.height(DEFAULT_PADDING_HALF)) + + WallpaperPresetSelector( + selectedWallpaper = wallpaperType, + baseTheme = currentTheme.base, + currentColors = { type -> + currentColors(type) + }, + onChooseType = onChooseType, + ) + val type = MaterialTheme.wallpaper.type + if (type is WallpaperType.Image && (themeUserDestination.value == null || perUserTheme.value.wallpaper?.imageFile != null)) { + SectionItemView(disabled = chatModel.remoteHostId != null && themeUserDestination.value != null, click = { + if (themeUserDestination.value == null) { + val defaultActiveTheme = ThemeManager.defaultActiveTheme(appPrefs.themeOverrides.get()) + ThemeManager.saveAndApplyWallpaper(baseTheme, null) + ThemeManager.removeTheme(defaultActiveTheme?.themeId) + removeWallpaperFile(type.filename) + } else { + removeUserThemeModeOverrides(themeUserDestination, perUserTheme) + } + saveThemeToDatabase(themeUserDestination.value) + }) { + Text( + stringResource(MR.strings.theme_remove_image), + color = if (chatModel.remoteHostId != null && themeUserDestination.value != null) MaterialTheme.colors.secondary else MaterialTheme.colors.primary + ) + } + SectionSpacer() + } + + val state: State = remember(appPrefs.currentTheme.get()) { + derivedStateOf { + if (appPrefs.currentTheme.get() == DefaultTheme.SYSTEM_THEME_NAME) null else currentTheme.base.mode + } + } + ColorModeSelector(state) { + val newTheme = when (it) { + null -> DefaultTheme.SYSTEM_THEME_NAME + DefaultThemeMode.LIGHT -> DefaultTheme.LIGHT.themeName + DefaultThemeMode.DARK -> appPrefs.systemDarkTheme.get()!! + } + ThemeManager.applyTheme(newTheme) + saveThemeToDatabase(null) + } + + // Doesn't work on desktop when specified like remember { systemDarkTheme.state }, this is workaround + val darkModeState: State = remember(systemDarkTheme.get()) { derivedStateOf { systemDarkTheme.get() } } + DarkModeThemeSelector(darkModeState) { + ThemeManager.changeDarkTheme(it) + if (appPrefs.currentTheme.get() == DefaultTheme.SYSTEM_THEME_NAME) { + ThemeManager.applyTheme(appPrefs.currentTheme.get()!!) + } else if (appPrefs.currentTheme.get() != DefaultTheme.LIGHT.themeName) { + ThemeManager.applyTheme(appPrefs.systemDarkTheme.get()!!) + } + saveThemeToDatabase(null) + } + } + SectionItemView(click = { + val user = themeUserDestination.value + if (user == null) { + ModalManager.start.showModal { + CustomizeThemeView(onChooseType) + } + } else { + ModalManager.start.showModalCloseable { close -> + UserWallpaperEditorModal(chatModel.remoteHostId(), user.first, close) + } + } + }) { + Text(stringResource(MR.strings.customize_theme_title)) + } + } + + @Composable + fun CustomizeThemeView(onChooseType: (WallpaperType?) -> Unit) { ColumnWithScrollBar( Modifier.fillMaxWidth(), ) { val currentTheme by CurrentColors.collectAsState() AppBarTitle(stringResource(MR.strings.customize_theme_title)) + val wallpaperImage = MaterialTheme.wallpaper.type.image + val wallpaperType = MaterialTheme.wallpaper.type + val baseTheme = CurrentColors.collectAsState().value.base - SectionView(stringResource(MR.strings.theme_colors_section_title)) { - SectionItemViewSpaceBetween({ editColor(ThemeColor.PRIMARY, currentTheme.colors.primary) }) { - val title = generalGetString(MR.strings.color_primary) - Text(title) - Icon(painterResource(MR.images.ic_circle_filled), title, tint = colors.primary) - } - SectionItemViewSpaceBetween({ editColor(ThemeColor.PRIMARY_VARIANT, currentTheme.colors.primaryVariant) }) { - val title = generalGetString(MR.strings.color_primary_variant) - Text(title) - Icon(painterResource(MR.images.ic_circle_filled), title, tint = colors.primaryVariant) - } - SectionItemViewSpaceBetween({ editColor(ThemeColor.SECONDARY, currentTheme.colors.secondary) }) { - val title = generalGetString(MR.strings.color_secondary) - Text(title) - Icon(painterResource(MR.images.ic_circle_filled), title, tint = colors.secondary) - } - SectionItemViewSpaceBetween({ editColor(ThemeColor.SECONDARY_VARIANT, currentTheme.colors.secondaryVariant) }) { - val title = generalGetString(MR.strings.color_secondary_variant) - Text(title) - Icon(painterResource(MR.images.ic_circle_filled), title, tint = colors.secondaryVariant) - } - SectionItemViewSpaceBetween({ editColor(ThemeColor.BACKGROUND, currentTheme.colors.background) }) { - val title = generalGetString(MR.strings.color_background) - Text(title) - Icon(painterResource(MR.images.ic_circle_filled), title, tint = colors.background) - } - SectionItemViewSpaceBetween({ editColor(ThemeColor.SURFACE, currentTheme.colors.surface) }) { - val title = generalGetString(MR.strings.color_surface) - Text(title) - Icon(painterResource(MR.images.ic_circle_filled), title, tint = colors.surface) - } - SectionItemViewSpaceBetween({ editColor(ThemeColor.TITLE, currentTheme.appColors.title) }) { - val title = generalGetString(MR.strings.color_title) - Text(title) - Icon(painterResource(MR.images.ic_circle_filled), title, tint = currentTheme.appColors.title) - } - SectionItemViewSpaceBetween({ editColor(ThemeColor.SENT_MESSAGE, currentTheme.appColors.sentMessage) }) { - val title = generalGetString(MR.strings.color_sent_message) - Text(title) - Icon(painterResource(MR.images.ic_circle_filled), title, tint = currentTheme.appColors.sentMessage) - } - SectionItemViewSpaceBetween({ editColor(ThemeColor.RECEIVED_MESSAGE, currentTheme.appColors.receivedMessage) }) { - val title = generalGetString(MR.strings.color_received_message) - Text(title) - Icon(painterResource(MR.images.ic_circle_filled), title, tint = currentTheme.appColors.receivedMessage) - } + val editColor = { name: ThemeColor -> + editColor( + name, + wallpaperType, + wallpaperImage, + onColorChange = { color -> + ThemeManager.saveAndApplyThemeColor(baseTheme, name, color) + saveThemeToDatabase(null) + } + ) } - val isInDarkTheme = isInDarkTheme() - if (currentTheme.base.hasChangedAnyColor(currentTheme.colors, currentTheme.appColors)) { - SectionItemView({ ThemeManager.resetAllThemeColors(darkForSystemTheme = isInDarkTheme) }) { + + WallpaperPresetSelector( + selectedWallpaper = wallpaperType, + baseTheme = currentTheme.base, + currentColors = { type -> + ThemeManager.currentColors(type, null, null, appPrefs.themeOverrides.get()) + }, + onChooseType = onChooseType + ) + + val type = MaterialTheme.wallpaper.type + if (type is WallpaperType.Image) { + SectionItemView(disabled = chatModel.remoteHostId != null, click = { + val defaultActiveTheme = ThemeManager.defaultActiveTheme(appPrefs.themeOverrides.get()) + ThemeManager.saveAndApplyWallpaper(baseTheme, null) + ThemeManager.removeTheme(defaultActiveTheme?.themeId) + removeWallpaperFile(type.filename) + saveThemeToDatabase(null) + }) { + Text( + stringResource(MR.strings.theme_remove_image), + color = if (chatModel.remoteHostId == null) MaterialTheme.colors.primary else MaterialTheme.colors.secondary + ) + } + SectionSpacer() + } + + SectionView(stringResource(MR.strings.settings_section_title_chat_colors).uppercase()) { + WallpaperSetupView( + wallpaperType, + baseTheme, + MaterialTheme.wallpaper, + MaterialTheme.appColors.sentMessage, + MaterialTheme.appColors.sentQuote, + MaterialTheme.appColors.receivedMessage, + MaterialTheme.appColors.receivedQuote, + editColor = { name -> + editColor(name) + }, + onTypeChange = { type -> + ThemeManager.saveAndApplyWallpaper(baseTheme, type) + saveThemeToDatabase(null) + }, + ) + } + SectionDividerSpaced(maxTopPadding = true) + + CustomizeThemeColorsSection(currentTheme) { name -> + editColor(name) + } + + SectionSpacer() + + val currentOverrides = remember(currentTheme) { ThemeManager.defaultActiveTheme(appPrefs.themeOverrides.get()) } + val canResetColors = currentTheme.base.hasChangedAnyColor(currentOverrides) + if (canResetColors) { + SectionItemView({ + ThemeManager.resetAllThemeColors() + saveThemeToDatabase(null) + }) { Text(generalGetString(MR.strings.reset_color), color = colors.primary) } + SectionSpacer() } - SectionSpacer() + SectionView { val theme = remember { mutableStateOf(null as String?) } val exportThemeLauncher = rememberFileChooserLauncher(false) { to: URI? -> @@ -161,9 +511,11 @@ object AppearanceScope { } } SectionItemView({ - val overrides = ThemeManager.currentThemeOverridesForExport(isInDarkTheme) - theme.value = yaml.encodeToString(overrides) - withLongRunningApi { exportThemeLauncher.launch("simplex.theme")} + val overrides = ThemeManager.currentThemeOverridesForExport(null, null/*chatModel.currentUser.value?.uiThemes*/) + val lines = yaml.encodeToString(overrides).lines() + // Removing theme id without using custom serializer or data class + theme.value = lines.subList(1, lines.size).joinToString("\n") + withLongRunningApi { exportThemeLauncher.launch("simplex.theme") } }) { Text(generalGetString(MR.strings.export_theme), color = colors.primary) } @@ -171,7 +523,8 @@ object AppearanceScope { if (to != null) { val theme = getThemeFromUri(to) if (theme != null) { - ThemeManager.saveAndApplyThemeOverrides(theme, isInDarkTheme) + ThemeManager.saveAndApplyThemeOverrides(theme) + saveThemeToDatabase(null) } } } @@ -184,49 +537,318 @@ object AppearanceScope { } } - @Composable - fun ColorEditor( - name: ThemeColor, - initialColor: Color, - close: () -> Unit, - ) { - Column( - Modifier - .fillMaxWidth() - ) { - AppBarTitle(name.text) - var currentColor by remember { mutableStateOf(initialColor) } - ColorPicker(initialColor) { - currentColor = it + private var updateBackendJob: Job = Job() + private fun saveThemeToDatabase(themeUserDestination: Pair?) { + val remoteHostId = chatModel.remoteHostId() + val oldThemes = chatModel.currentUser.value?.uiThemes + if (themeUserDestination != null) { + // Update before save to make it work seamless + chatModel.updateCurrentUserUiThemes(remoteHostId, themeUserDestination.second) + } + updateBackendJob.cancel() + updateBackendJob = withBGApi { + delay(300) + if (themeUserDestination == null) { + controller.apiSaveAppSettings(AppSettings.current.prepareForExport()) + } else if (!controller.apiSetUserUIThemes(remoteHostId, themeUserDestination.first, themeUserDestination.second)) { + // If failed to apply for some reason return the old themes + chatModel.updateCurrentUserUiThemes(remoteHostId, oldThemes) } + } + } - SectionSpacer() - val isInDarkTheme = isInDarkTheme() - TextButton( - onClick = { - ThemeManager.saveAndApplyThemeColor(name, currentColor, isInDarkTheme) - close() - }, - Modifier.align(Alignment.CenterHorizontally), - colors = ButtonDefaults.textButtonColors(contentColor = currentColor) - ) { - Text(generalGetString(MR.strings.save_color)) + fun editColor(name: ThemeColor, wallpaperType: WallpaperType, wallpaperImage: ImageBitmap?, onColorChange: (Color?) -> Unit) { + ModalManager.start.showModal { + val baseTheme = CurrentColors.collectAsState().value.base + val wallpaperBackgroundColor = MaterialTheme.wallpaper.background ?: wallpaperType.defaultBackgroundColor(baseTheme, MaterialTheme.colors.background) + val wallpaperTintColor = MaterialTheme.wallpaper.tint ?: wallpaperType.defaultTintColor(baseTheme) + val initialColor: Color = when (name) { + ThemeColor.WALLPAPER_BACKGROUND -> wallpaperBackgroundColor + ThemeColor.WALLPAPER_TINT -> wallpaperTintColor + ThemeColor.PRIMARY -> MaterialTheme.colors.primary + ThemeColor.PRIMARY_VARIANT -> MaterialTheme.colors.primaryVariant + ThemeColor.SECONDARY -> MaterialTheme.colors.secondary + ThemeColor.SECONDARY_VARIANT -> MaterialTheme.colors.secondaryVariant + ThemeColor.BACKGROUND -> MaterialTheme.colors.background + ThemeColor.SURFACE -> MaterialTheme.colors.surface + ThemeColor.TITLE -> MaterialTheme.appColors.title + ThemeColor.PRIMARY_VARIANT2 -> MaterialTheme.appColors.primaryVariant2 + ThemeColor.SENT_MESSAGE -> MaterialTheme.appColors.sentMessage + ThemeColor.SENT_QUOTE -> MaterialTheme.appColors.sentQuote + ThemeColor.RECEIVED_MESSAGE -> MaterialTheme.appColors.receivedMessage + ThemeColor.RECEIVED_QUOTE -> MaterialTheme.appColors.receivedQuote + } + ColorEditor(name, initialColor, baseTheme, MaterialTheme.wallpaper.type, wallpaperImage, currentColors = { CurrentColors.value }, + onColorChange = onColorChange + ) + } + } + + @Composable + fun ModalData.UserWallpaperEditorModal(remoteHostId: Long?, userId: Long, close: () -> Unit) { + val themes = remember(chatModel.currentUser.value) { chatModel.currentUser.value?.uiThemes ?: ThemeModeOverrides() } + val globalThemeUsed = remember { stateGetOrPut("globalThemeUsed") { false } } + val initialTheme = remember(CurrentColors.collectAsState().value.base) { + val preferred = themes.preferredMode(!CurrentColors.value.colors.isLight) + globalThemeUsed.value = preferred == null + preferred ?: ThemeManager.defaultActiveTheme(chatModel.currentUser.value?.uiThemes, appPrefs.themeOverrides.get()) + } + UserWallpaperEditor( + initialTheme, + applyToMode = if (themes.light == themes.dark) null else initialTheme.mode, + globalThemeUsed = globalThemeUsed, + save = { applyToMode, newTheme -> + save(applyToMode, newTheme, themes, userId, remoteHostId) + }) + KeyChangeEffect(chatModel.currentUser.value?.userId, chatModel.remoteHostId) { + close() + } + } + + suspend fun save( + applyToMode: DefaultThemeMode?, + newTheme: ThemeModeOverride?, + themes: ThemeModeOverrides?, + userId: Long, + remoteHostId: Long? + ) { + val unchangedThemes: ThemeModeOverrides = themes ?: ThemeModeOverrides() + val wallpaperFiles = listOf(unchangedThemes.light?.wallpaper?.imageFile, unchangedThemes.dark?.wallpaper?.imageFile) + var changedThemes: ThemeModeOverrides? = unchangedThemes + val changed = newTheme?.copy(wallpaper = newTheme.wallpaper?.withFilledWallpaperPath()) + changedThemes = when (applyToMode) { + null -> changedThemes?.copy(light = changed?.copy(mode = DefaultThemeMode.LIGHT), dark = changed?.copy(mode = DefaultThemeMode.DARK)) + DefaultThemeMode.LIGHT -> changedThemes?.copy(light = changed?.copy(mode = applyToMode)) + DefaultThemeMode.DARK -> changedThemes?.copy(dark = changed?.copy(mode = applyToMode)) + } + changedThemes = if (changedThemes?.light != null || changedThemes?.dark != null) changedThemes else null + + val wallpaperFilesToDelete = wallpaperFiles - changedThemes?.light?.wallpaper?.imageFile - changedThemes?.dark?.wallpaper?.imageFile + wallpaperFilesToDelete.forEach(::removeWallpaperFile) + + val oldThemes = chatModel.currentUser.value?.uiThemes + // Update before save to make it work seamless + chatModel.updateCurrentUserUiThemes(remoteHostId, changedThemes) + updateBackendJob.cancel() + updateBackendJob = withBGApi { + delay(300) + if (!controller.apiSetUserUIThemes(remoteHostId, userId, changedThemes)) { + // If failed to apply for some reason return the old themes + chatModel.updateCurrentUserUiThemes(remoteHostId, oldThemes) } } } @Composable - fun ColorPicker(initialColor: Color, onColorChanged: (Color) -> Unit) { - ClassicColorPicker(modifier = Modifier - .fillMaxWidth() - .height(300.dp), - color = HsvColor.from(color = initialColor), showAlphaBar = true, - onColorChanged = { color: HsvColor -> - onColorChanged(color.toColor()) + fun ThemeDestinationPicker(themeUserDestination: MutableState?>) { + val themeUserDest = remember(themeUserDestination.value?.first) { mutableStateOf(themeUserDestination.value?.first) } + LaunchedEffect(themeUserDestination.value) { + if (themeUserDestination.value == null) { + // Easiest way to hide per-user customization. + // Otherwise, it would be needed to make global variable and to use it everywhere for making a decision to include these overrides into active theme constructing or not + chatModel.currentUser.value = chatModel.currentUser.value?.copy(uiThemes = null) + } else { + chatModel.updateCurrentUserUiThemes(chatModel.remoteHostId(), chatModel.users.firstOrNull { it.user.userId == chatModel.currentUser.value?.userId }?.user?.uiThemes) } - ) + } + DisposableEffect(Unit) { + onDispose { + // Skip when Appearance screen is not hidden yet + if (ModalManager.start.hasModalsOpen()) return@onDispose + // Restore user overrides from stored list of users + chatModel.updateCurrentUserUiThemes(chatModel.remoteHostId(), chatModel.users.firstOrNull { it.user.userId == chatModel.currentUser.value?.userId }?.user?.uiThemes) + themeUserDestination.value = if (chatModel.currentUser.value?.uiThemes == null) null else chatModel.currentUser.value?.userId!! to chatModel.currentUser.value?.uiThemes + } + } + + val values by remember(chatModel.users.toList()) { mutableStateOf( + listOf(null as Long? to generalGetString(MR.strings.theme_destination_all_profiles)) + + + chatModel.users.filter { it.user.activeUser || it.user.viewPwdHash == null }.map { + it.user.userId to it.user.chatViewName + }, + ) + } + if (values.any { it.first == themeUserDestination.value?.first }) { + ExposedDropDownSettingRow( + generalGetString(MR.strings.chat_theme_apply_to_mode), + values, + themeUserDest, + icon = null, + enabled = remember { mutableStateOf(true) }, + onSelected = { userId -> + themeUserDest.value = userId + if (userId != null) { + themeUserDestination.value = userId to chatModel.users.firstOrNull { it.user.userId == userId }?.user?.uiThemes + } else { + themeUserDestination.value = null + } + if (userId != null && userId != chatModel.currentUser.value?.userId) { + withBGApi { + controller.showProgressIfNeeded { + chatModel.controller.changeActiveUser(chatModel.remoteHostId(), userId, null) + } + } + } + } + ) + } else { + themeUserDestination.value = null + } } + @Composable + fun CustomizeThemeColorsSection(currentTheme: ThemeManager.ActiveTheme, editColor: (ThemeColor) -> Unit) { + SectionView(stringResource(MR.strings.theme_colors_section_title)) { + SectionItemViewSpaceBetween({ editColor(ThemeColor.PRIMARY) }) { + val title = generalGetString(MR.strings.color_primary) + Text(title) + Icon(painterResource(MR.images.ic_circle_filled), title, tint = currentTheme.colors.primary) + } + SectionItemViewSpaceBetween({ editColor(ThemeColor.PRIMARY_VARIANT) }) { + val title = generalGetString(MR.strings.color_primary_variant) + Text(title) + Icon(painterResource(MR.images.ic_circle_filled), title, tint = currentTheme.colors.primaryVariant) + } + SectionItemViewSpaceBetween({ editColor(ThemeColor.PRIMARY_VARIANT2) }) { + val title = generalGetString(MR.strings.color_primary_variant2) + Text(title) + Icon(painterResource(MR.images.ic_circle_filled), title, tint = currentTheme.appColors.primaryVariant2) + } + SectionItemViewSpaceBetween({ editColor(ThemeColor.SECONDARY) }) { + val title = generalGetString(MR.strings.color_secondary) + Text(title) + Icon(painterResource(MR.images.ic_circle_filled), title, tint = currentTheme.colors.secondary) + } + SectionItemViewSpaceBetween({ editColor(ThemeColor.SECONDARY_VARIANT) }) { + val title = generalGetString(MR.strings.color_secondary_variant) + Text(title) + Icon(painterResource(MR.images.ic_circle_filled), title, tint = currentTheme.colors.secondaryVariant) + } + SectionItemViewSpaceBetween({ editColor(ThemeColor.BACKGROUND) }) { + val title = generalGetString(MR.strings.color_background) + Text(title) + Icon(painterResource(MR.images.ic_circle_filled), title, tint = currentTheme.colors.background) + } + SectionItemViewSpaceBetween({ editColor(ThemeColor.SURFACE) }) { + val title = generalGetString(MR.strings.color_surface) + Text(title) + Icon(painterResource(MR.images.ic_circle_filled), title, tint = currentTheme.colors.surface) + } + SectionItemViewSpaceBetween({ editColor(ThemeColor.TITLE) }) { + val title = generalGetString(MR.strings.color_title) + Text(title) + Icon(painterResource(MR.images.ic_circle_filled), title, tint = currentTheme.appColors.title) + } + } + } + + @Composable + fun ColorEditor( + name: ThemeColor, + initialColor: Color, + theme: DefaultTheme, + wallpaperType: WallpaperType?, + wallpaperImage: ImageBitmap?, + previewBackgroundColor: Color? = MaterialTheme.wallpaper.background, + previewTintColor: Color? = MaterialTheme.wallpaper.tint, + currentColors: () -> ThemeManager.ActiveTheme, + onColorChange: (Color?) -> Unit, + ) { + ColumnWithScrollBar( + Modifier + .fillMaxWidth() + ) { + AppBarTitle(name.text) + + val supportedLiveChange = name in listOf(ThemeColor.SECONDARY, ThemeColor.BACKGROUND, ThemeColor.SURFACE, ThemeColor.RECEIVED_MESSAGE, ThemeColor.SENT_MESSAGE, ThemeColor.SENT_QUOTE, ThemeColor.WALLPAPER_BACKGROUND, ThemeColor.WALLPAPER_TINT) + if (supportedLiveChange) { + SimpleXThemeOverride(currentColors()) { + ChatThemePreview(theme, wallpaperImage, wallpaperType, previewBackgroundColor, previewTintColor) + } + SectionSpacer() + } + + var currentColor by remember { mutableStateOf(initialColor) } + val togglePicker = remember { mutableStateOf(false) } + Box(Modifier.padding(horizontal = DEFAULT_PADDING)) { + if (togglePicker.value) { + ColorPicker(currentColor, showAlphaBar = wallpaperType is WallpaperType.Image || currentColor.alpha < 1f) { + currentColor = it + onColorChange(currentColor) + } + } else { + ColorPicker(currentColor, showAlphaBar = wallpaperType is WallpaperType.Image || currentColor.alpha < 1f) { + currentColor = it + onColorChange(currentColor) + } + } + } + var allowReloadPicker by remember { mutableStateOf(false) } + KeyChangeEffect(wallpaperType) { + allowReloadPicker = true + } + KeyChangeEffect(initialColor) { + if (initialColor != currentColor && allowReloadPicker) { + currentColor = initialColor + togglePicker.value = !togglePicker.value + } + allowReloadPicker = false + } + val clipboard = LocalClipboardManager.current + val hexTrimmed = currentColor.toReadableHex().replaceFirst("#ff", "#") + val savedColor by remember(wallpaperType) { mutableStateOf(initialColor) } + + Row(Modifier.padding(horizontal = DEFAULT_PADDING, vertical = DEFAULT_PADDING_HALF).height(46.dp)) { + Box(Modifier.weight(1f).fillMaxHeight().background(savedColor).clickable { + currentColor = savedColor + onColorChange(currentColor) + togglePicker.value = !togglePicker.value + }) + Box(Modifier.weight(1f).fillMaxHeight().background(currentColor).clickable { + clipboard.shareText(hexTrimmed) + }) + } + if (appPrefs.developerTools.get()) { + Row(Modifier.fillMaxWidth().padding(start = DEFAULT_PADDING_HALF, end = DEFAULT_PADDING), horizontalArrangement = Arrangement.SpaceEvenly, verticalAlignment = Alignment.CenterVertically) { + val textFieldState = remember { mutableStateOf(TextFieldValue(hexTrimmed)) } + KeyChangeEffect(hexTrimmed) { + textFieldState.value = textFieldState.value.copy(hexTrimmed) + } + DefaultBasicTextField( + Modifier.fillMaxWidth(), + textFieldState, + leadingIcon = { + IconButton(onClick = { clipboard.shareText(hexTrimmed) }) { + Icon(painterResource(MR.images.ic_content_copy), generalGetString(MR.strings.copy_verb), Modifier.size(26.dp), tint = MaterialTheme.colors.primary) + } + }, + onValueChange = { value -> + val color = value.text.trim('#', ' ') + if (color.length == 6 || color.length == 8) { + currentColor = if (color.length == 6) ("ff$color").colorFromReadableHex() else color.colorFromReadableHex() + onColorChange(currentColor) + textFieldState.value = value.copy(currentColor.toReadableHex().replaceFirst("#ff", "#")) + togglePicker.value = !togglePicker.value + } else { + textFieldState.value = value + } + } + ) + } + } + SectionItemView({ + allowReloadPicker = true + onColorChange(null) + }) { + Text(generalGetString(MR.strings.reset_single_color), color = colors.primary) + } + SectionSpacer() + } + } + + + @Composable fun LangSelector(state: State, onSelected: (String) -> Unit) { // Should be the same as in app/build.gradle's `android.defaultConfig.resConfigs` @@ -254,7 +876,7 @@ object AppearanceScope { "uk" to "Українська", "zh-CN" to "简体中文" ) - val values by remember(ChatController.appPrefs.appLanguage.state.value) { mutableStateOf(supportedLanguages.map { it.key to it.value }) } + val values by remember(appPrefs.appLanguage.state.value) { mutableStateOf(supportedLanguages.map { it.key to it.value }) } ExposedDropDownSettingRow( generalGetString(MR.strings.settings_section_title_language).lowercase().replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.US) else it.toString() }, values, @@ -266,13 +888,18 @@ object AppearanceScope { } @Composable - private fun ThemeSelector(state: State, onSelected: (String) -> Unit) { - val darkTheme = chat.simplex.common.ui.theme.isSystemInDarkTheme() - val values by remember(ChatController.appPrefs.appLanguage.state.value) { - mutableStateOf(ThemeManager.allThemes(darkTheme).map { it.second.name to it.third }) + private fun ColorModeSelector(state: State, onSelected: (DefaultThemeMode?) -> Unit) { + val values by remember(appPrefs.appLanguage.state.value) { + mutableStateOf( + listOf( + null to generalGetString(MR.strings.color_mode_system), + DefaultThemeMode.LIGHT to generalGetString(MR.strings.color_mode_light), + DefaultThemeMode.DARK to generalGetString(MR.strings.color_mode_dark) + ) + ) } ExposedDropDownSettingRow( - generalGetString(MR.strings.theme), + generalGetString(MR.strings.color_mode), values, state, icon = null, @@ -282,15 +909,16 @@ object AppearanceScope { } @Composable - private fun DarkThemeSelector(state: State, onSelected: (String) -> Unit) { + private fun DarkModeThemeSelector(state: State, onSelected: (String) -> Unit) { val values by remember { val darkThemes = ArrayList>() - darkThemes.add(DefaultTheme.DARK.name to generalGetString(MR.strings.theme_dark)) - darkThemes.add(DefaultTheme.SIMPLEX.name to generalGetString(MR.strings.theme_simplex)) + darkThemes.add(DefaultTheme.DARK.themeName to generalGetString(MR.strings.theme_dark)) + darkThemes.add(DefaultTheme.SIMPLEX.themeName to generalGetString(MR.strings.theme_simplex)) + darkThemes.add(DefaultTheme.BLACK.themeName to generalGetString(MR.strings.theme_black)) mutableStateOf(darkThemes.toList()) } ExposedDropDownSettingRow( - generalGetString(MR.strings.dark_theme), + generalGetString(MR.strings.dark_mode_colors), values, state, icon = null, @@ -303,3 +931,109 @@ object AppearanceScope { //} } +@Composable +fun WallpaperSetupView( + wallpaperType: WallpaperType?, + theme: DefaultTheme, + initialWallpaper: AppWallpaper?, + initialSentColor: Color, + initialSentQuoteColor: Color, + initialReceivedColor: Color, + initialReceivedQuoteColor: Color, + editColor: (ThemeColor) -> Unit, + onTypeChange: (WallpaperType?) -> Unit, +) { + if (wallpaperType is WallpaperType.Image) { + val state = remember(wallpaperType.scaleType, initialWallpaper?.type) { mutableStateOf(wallpaperType.scaleType ?: (initialWallpaper?.type as? WallpaperType.Image)?.scaleType ?: WallpaperScaleType.FILL) } + val values = remember { + WallpaperScaleType.entries.map { it to generalGetString(it.text) } + } + ExposedDropDownSettingRow( + stringResource(MR.strings.wallpaper_scale), + values, + state, + onSelected = { scaleType -> + onTypeChange(wallpaperType.copy(scaleType = scaleType)) + } + ) + } + + if (wallpaperType is WallpaperType.Preset || (wallpaperType is WallpaperType.Image && wallpaperType.scaleType == WallpaperScaleType.REPEAT)) { + val state = remember(wallpaperType, initialWallpaper?.type?.scale) { mutableStateOf(wallpaperType.scale ?: initialWallpaper?.type?.scale ?: 1f) } + Row(Modifier.padding(horizontal = DEFAULT_PADDING), verticalAlignment = Alignment.CenterVertically) { + Text("${state.value}".substring(0, min("${state.value}".length, 4)), Modifier.width(50.dp)) + Slider( + state.value, + valueRange = 0.5f..2f, + onValueChange = { + if (wallpaperType is WallpaperType.Preset) { + onTypeChange(wallpaperType.copy(scale = it)) + } else if (wallpaperType is WallpaperType.Image) { + onTypeChange(wallpaperType.copy(scale = it)) + } + } + ) + } + } + + if (wallpaperType is WallpaperType.Preset || wallpaperType is WallpaperType.Image) { + val wallpaperBackgroundColor = initialWallpaper?.background ?: wallpaperType.defaultBackgroundColor(theme, MaterialTheme.colors.background) + SectionItemViewSpaceBetween({ editColor(ThemeColor.WALLPAPER_BACKGROUND) }) { + val title = generalGetString(MR.strings.color_wallpaper_background) + Text(title) + Icon(painterResource(MR.images.ic_circle_filled), title, tint = wallpaperBackgroundColor) + } + val wallpaperTintColor = initialWallpaper?.tint ?: wallpaperType.defaultTintColor(theme) + SectionItemViewSpaceBetween({ editColor(ThemeColor.WALLPAPER_TINT) }) { + val title = generalGetString(MR.strings.color_wallpaper_tint) + Text(title) + Icon(painterResource(MR.images.ic_circle_filled), title, tint = wallpaperTintColor) + } + SectionSpacer() + } + + SectionItemViewSpaceBetween({ editColor(ThemeColor.SENT_MESSAGE) }) { + val title = generalGetString(MR.strings.color_sent_message) + Text(title) + Icon(painterResource(MR.images.ic_circle_filled), title, tint = initialSentColor) + } + SectionItemViewSpaceBetween({ editColor(ThemeColor.SENT_QUOTE) }) { + val title = generalGetString(MR.strings.color_sent_quote) + Text(title) + Icon(painterResource(MR.images.ic_circle_filled), title, tint = initialSentQuoteColor) + } + SectionItemViewSpaceBetween({ editColor(ThemeColor.RECEIVED_MESSAGE) }) { + val title = generalGetString(MR.strings.color_received_message) + Text(title) + Icon(painterResource(MR.images.ic_circle_filled), title, tint = initialReceivedColor) + } + SectionItemViewSpaceBetween({ editColor(ThemeColor.RECEIVED_QUOTE) }) { + val title = generalGetString(MR.strings.color_received_quote) + Text(title) + Icon(painterResource(MR.images.ic_circle_filled), title, tint = initialReceivedQuoteColor) + } +} + +@Composable +private fun ColorPicker(initialColor: Color, showAlphaBar: Boolean, onColorChanged: (Color) -> Unit) { + ClassicColorPicker(modifier = Modifier + .fillMaxWidth() + .height(300.dp), + color = HsvColor.from(color = initialColor), + showAlphaBar = showAlphaBar, + onColorChanged = { color: HsvColor -> + onColorChanged(color.toColor()) + } + ) +} + +private fun removeUserThemeModeOverrides(themeUserDestination: MutableState?>, perUserTheme: MutableState) { + val dest = themeUserDestination.value ?: return + perUserTheme.value = ThemeModeOverride() + themeUserDestination.value = dest.first to null + val wallpaperFilesToDelete = listOf( + (chatModel.currentUser.value?.uiThemes?.light?.type as? WallpaperType.Image)?.filename, + (chatModel.currentUser.value?.uiThemes?.dark?.type as? WallpaperType.Image)?.filename + ) + wallpaperFilesToDelete.forEach(::removeWallpaperFile) +} diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.kt index 298eb39737..0b5033aca3 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.kt @@ -144,7 +144,7 @@ fun SettingsLayout( SettingsActionItem(painterResource(MR.images.ic_wifi_tethering), stringResource(MR.strings.network_and_servers), showSettingsModal { NetworkAndServersView() }, disabled = stopped, extraPadding = true) SettingsActionItem(painterResource(MR.images.ic_videocam), stringResource(MR.strings.settings_audio_video_calls), showSettingsModal { CallSettingsView(it, showModal) }, disabled = stopped, extraPadding = true) SettingsActionItem(painterResource(MR.images.ic_lock), stringResource(MR.strings.privacy_and_security), showSettingsModal { PrivacySettingsView(it, showSettingsModal, setPerformLA) }, disabled = stopped, extraPadding = true) - SettingsActionItem(painterResource(MR.images.ic_light_mode), stringResource(MR.strings.appearance_settings), showSettingsModal { AppearanceView(it, showSettingsModal) }, extraPadding = true) + SettingsActionItem(painterResource(MR.images.ic_light_mode), stringResource(MR.strings.appearance_settings), showSettingsModal { AppearanceView(it) }, extraPadding = true) DatabaseItem(encrypted, passphraseSaved, showSettingsModal { DatabaseView(it, showSettingsModal) }, stopped) } SectionDividerSpaced() diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/ar/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/ar/strings.xml index 52dd8e6479..0c4c4176a5 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/ar/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/ar/strings.xml @@ -847,7 +847,6 @@ افتح ملفات تعريف الدردشة اسحب الوصول حفظ الأرشيف - حفظ اللون كشف سيتم إيقاف استلام الملف. رفض diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml index 9308f5886e..b00f1a9438 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml @@ -746,7 +746,7 @@ To protect your IP address, private routing uses your SMP servers to deliver messages. Appearance Customize theme - THEME COLORS + INTERFACE COLORS App version App version: v%s App build: %s @@ -1072,6 +1072,9 @@ APP ICON THEMES Profile images + Chat theme + Profile theme + Chat colors MESSAGES AND FILES PRIVATE MESSAGE ROUTING CALLS @@ -1201,6 +1204,7 @@ Incompatible database version Confirm database upgrades Show console in new window + Show chat list in new window Invalid migration confirmation Upgrade and open chat Downgrade and open chat @@ -1543,23 +1547,30 @@ When you share an incognito profile with somebody, this profile will be used for the groups they invite you to. + System + Light + Dark System Light Dark SimpleX + Black System Theme + Color mode Dark theme - Save color + Dark mode colors Import theme Import theme error Make sure the file has correct YAML syntax. Export theme to have an example of the theme file structure. Export theme Reset colors + Reset color + All chat profiles Accent Additional accent Secondary @@ -1567,8 +1578,36 @@ Background Menus & alerts Title + Additional accent 2 Sent message + Sent reply Received message + Received reply + Wallpaper background + Wallpaper accent + Remove image + + + Cats + Flowers + Hearts + Kids + School + Travel + Good afternoon! + Good morning! + Scale + Repeat + Fill + Fit + Advanced settings + Reset to global theme + Set default theme + Apply to + All color modes + Light mode + Dark mode + You allow diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/bg/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/bg/strings.xml index c087e0d896..ca9070cbd6 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/bg/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/bg/strings.xml @@ -1150,7 +1150,6 @@ Отмени промените Запази Нулирай цветовете - Запази цвета Вторичен Избери За да започнете нов чат diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/cs/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/cs/strings.xml index cd642f8828..ccb703337c 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/cs/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/cs/strings.xml @@ -55,7 +55,6 @@ Aktualizovat nastavení sítě\? Inkognito Váš náhodný profil - Uložit barvu Obnovit barvu Zbarvení Povolujete diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/de/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/de/strings.xml index 6f4afec2f3..860759431a 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/de/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/de/strings.xml @@ -842,7 +842,6 @@ Dunkel Design - Farbe speichern Farben zurücksetzen Akzent diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/es/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/es/strings.xml index 54512aca34..85fcdceb6f 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/es/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/es/strings.xml @@ -607,7 +607,6 @@ secreto Abrir SimpleX Chat para aceptar llamada Restablecer valores por defecto - Guardar color Pendiente Notificaciones periódicas Guarda la contraseña de forma segura, NO podrás cambiarla si la pierdes. diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/fi/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/fi/strings.xml index 1434963263..62a01fdd64 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/fi/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/fi/strings.xml @@ -873,7 +873,6 @@ Kiitos käyttäjille – osallistu Weblaten kautta! Profiilin salasana Oletusvärit - Tallenna väri Estä ääniviestien lähettäminen. Lähetetyt viestit poistetaan asetetun ajan kuluttua. Aloita uusi keskustelu diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/fr/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/fr/strings.xml index 77f0abbf2d..a9008d4808 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/fr/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/fr/strings.xml @@ -783,7 +783,6 @@ Clair Sombre Thème - Enregistrer la couleur Réinitialisation des couleurs Principale Vous autorisez diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/hi/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/hi/strings.xml index 56dfb51e2e..61b9ad8de6 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/hi/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/hi/strings.xml @@ -69,7 +69,6 @@ स्वागत %1$s! शुरुआत भेजना - रंग बचाओ साझा करना अस्वीकार आवश्यक diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/hu/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/hu/strings.xml index e3a1f124aa..8bbe0c6e8e 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/hu/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/hu/strings.xml @@ -1196,7 +1196,6 @@ Kód beolvasása Port megnyitása a tűzfalon indítás… - Szín mentése Leállítás elküldve SOCKS proxy használata diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/wallpaper_cats@4x.png b/apps/multiplatform/common/src/commonMain/resources/MR/images/wallpaper_cats@4x.png new file mode 100644 index 0000000000000000000000000000000000000000..9bff3eb3d0c99f89786f8db543f45fe268a04908 GIT binary patch literal 51580 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ⅇ1T~!X`P2tAMF-_=ykJop zazV@cB_8WGO;5@&zpnK%2+Pq1_ z#K!BYNfG&HG%*CH5!D3LAppm=z-< zLYd^84TlvW+9~6KsJkF}-69UAn3D^XL4F?s-O{qeTI~4%*%dJi<&ArkYXp+ZZhiJ% zM37N}I+>9G0SS6-Q=S!LoItSp)*kQmoAMY^GKN&A3;;l{+xiE21*aiv&K*lW?sANQ zCC1Aj+dWKOz+{X*Emy?#9C#m%>awrE`aVk_+BDpnjpTW5zYV1sg8NpL3}Vqy#tOV* z3=F{%8_Gm`?L)U>;dWh$biaNJ9`O!+D=2SF`$+c+q??V#u}eNOk;nX>fq92M`J8O& z2quJW3DBGFW>m&xnLLVb2bD)C-vk%S$uZo{^o-nSf`GipA-~#VUILxIcPK{WQ5i$L zy=n8LcE6jlLN1k93g~!qPkcZ>ufhY%Zhskb?N@NgV&0N5vXf<3aJjCrWO>S@GbunW zZ`wFp7yM{8Mhmyddf`8^X@|KQ8OvdqJ`-Bnozn6V#(^fYw`ig**99AVejA;%DV=nf zHr=vs?(?>b`i)*SlXAm<+ntB6xir$4C2z&TZJ)>CS^Jio+NLkY%j1rB7p76(!vmua zVoDE%f-s88sOuVn*U7l}}cr%`ZW%=h%>{Sz_DtVO(W&F)(IrTdolj8($%5Z5W3E z!(r--ajXqj+Cz~8x7rmy1rKO#eLYckka!mUwQIbpJ~F805bl!*p^(SAsT(7VdRG~I z9)rpVhj{QUAvCl$YVxXH#E2lkCQz@id7bO>d;6ZgP#s zsLq4ZTW`1AHV%7_PI;g@*t9;+#CVPgs^pUKdMX~df0cIg!y3~@Up3e~>nvxhU4?j( zG=prqqi670c4eAtgjif!FOB#R+!rOEbamyM#ysCzsoT7&`zQhv!qElIR+|~#{%9E= z#k7_|%nU+Khj+~~gEfpVw-`!hC0dW7m>^;hV;q3k0=G38GYpDp2x8ozvG-&Ncf9tH zEJ1{Yw1GriMEQz-A|Oi}1=?C8|1xWsN;~qvpuEH2Y%duk06JD*`%J)Q9%CFwJS?T9 zGf;AId_9duN>d&g4bWzh_0+235Rh6zkU??>M$U7l$`=8{K=i}l?f6!OV1XY3WrPnG zsnfVC<@$vFq4#>Nevu0uOB?L^Ovdq)g|Kd&@^H=nqOGlycqUyDpTkC+mcRsl19uEmT}G7}?E43nN(HiPEG|`)oW=8@OYK$%oDusxqVRX?!Nz z+3Oi2V;R`*Vt{xU8neZ&*!H0IsBHh$Dsa6J4VL}EzjyA}G9Vlk~n z<hmArDP@Yph$TVUrnZo-fzMa)R$AeJcr^H=xz+zWPUx9HSG+X4eX!F zc*YChv3oI`^3vRaAMa6YptH6#xJD7Du>dYh+JHKW_D(_@V>?V*n%*o*)`Rv-$d_pg zxA;q5Tkz(?Q(7LZo=^``hw^g!N59HEFWNYJ)tIH<1;%K#+b1S$US07ft};sxZ5+6Y zxL3P%#W9w0$hr-1TGR8O1IAW_eu|6%f-F$|T-0_|_oE2t#){gBjgg%0G0Z&nj)XBR zOTq&NNQe%+3UA5NKg)AxVB_$!drIps4UD_1mR)3TUofI?JRv4oguuc0r0-WoTQkARFV+)^U=r>W}*Cy3&t(e?&9M5$JiFpA5{~dL9(q$eMs< zgb9q$2sveVuA^?gRRqpt)Ryolbd2AQe8=>`Xa8Py+ZY3>5W??E7N6+Cyf&qR<2j94 z@rpY}Q!B8Mu`;xey3%e=S7?|+QQbsIFY0+1L6emx29J1r81?s4r;HKdF2-L7NRnYD z2tF-=HQ28LzpY9hkr2em<^mnG4BeJrGUyBr9a`D^%FF$A`>daKAm+Hz@Em9Y%LM5ky5S6apq#o>}$G=`aVjUw~}yQ^9s3WlD*;qE(XC}Ub|ff znYE32eN|~HBPF!99?k3d;)UQf--iS+|Hfwhdx}%II2o)H`xEN^4a$DE72EpH^Y<=H z24`8~S=-@Q=?gCfr3(|m%*14{S|_-9-TRN~_3F!$!RF*k!LQJkfyYfB#XT@YK@b#a z>oJzD6zxylevbl%QM4h?80){k34P`fJ~g!|V-N`k0bzeat*N0K}LE!0DhNb7?WDraXAIgJa{Rd2pCWR~F zCZWam5QbHa1Ni(8kfq-tuByDqr^yTFgB;`F2YP-5`r-{f4X+y632qBG4St)ld1U4f z#KX!r%)kVH@IeL$)^G&{5~bBHB(ju{Cv9C`l4Ksr-)6Qu&)V}n1o{n|4uceAl-Or; zg|n(GEM+Ja?9vmZfIav z$dlX&M>6xUp0QG4x;c!jD#qLVu$noldRY&hf%aFRS<%9P0iyTvefA24HqO23oD}$? zou|Cl@okB>rpDP&|V%BUhwxgOcXOJfM9dW>$^is<#0aSS>hlOSovi$So0 z;>cm$RXWmr6bbHB8%OWzC}QniUKewM)Aj(6>y?9Zg0ZY8xB4zaBqri5DH1IGCa{>c zs7LNUF?o*qr&Kotjcl91l;^%|pGSQ)?q6PG1Fjr>Fw8S*7>3oJ3=pjLE6^geZO8zD z4%)0-v2n>O=~|X*)1GwkLS*yFWt?FN&Uub_&f8~ul_3K8Bf0A18C|3_#dDF7BEBfA zJ>Znfxk7wJ!U1{&7*9)rBZhg6G#dn)3!jaDejNY?5T4T*A9Fs&2b&@DDAt{U*dPHf(!&?zsKaPD{R6Mv{+;EUzA>B;#NWr&a>U2 z=ypbRAfrmco5#cnvQ?ChZp$5phHe}2edf}oOQ+AAIWzv*XP<4q|Ni?=iAPML#hrkz zA6$@-#?8Hv?1+#z77hA(F*6DkgV)REOL?{*l-w!Y`r!(%`^ z0{v&0jNFKg#l9+q+!{}?!}E}a0T5G1woay{**N5D1($xsJ|Em^)T$=XzSe|g{mL;F|s+EZo|F=SGFNnDxfI%|$#v5;(9~&Ec?eXKs zIj(O^O}+dIm7n6*G2S5O;DQVX329rSL5z;XCD38Hv0HAtmOJT-&XZ2w97wz=C8T?1 znjO}+iNi*~YZ0kFH%R!TF`&F5LOu*#MOk^|(Jpl%z9T@eCDl*52ouK4X!6AO)s6y3 z{J@dX>rk>C53B^yHTA}8b}yVZ9EP5}gU zhpcguzVx@6=;4*vGaSVDOQ|rhx&t{pNBShjbBBjErKDBoo! z($f?@bX^B%epeCkIXdq;I;^rQkqD(D^8{}bJ+_d{18qX`R4`)hBhO}K+}S*mW60iR z)xm9@b^@jGESa@t^Bv@h2jtY#r%zwWWHPV%zCXrq+}nQP{Od2D^?&@~kN=!HaZtCy zK#dTXrY@xqA@yCDJWXs^<3r6Ew`q!}L}_w^*;DYONbovzAe1;AlfI4{E>eCQh|8IK zG#0q~Ldg*67$;RBpY(dt)o$w%K}Zh~Y+5fX8KT(4V|HaJVTv`o$}t1$K;THxV<2>R zKpdl_+(V@uhqb{E1p$o38KfV}}c@`_X_@Bo8nxmVtRkIc?~ zgu|hfDvi8Z*w0Aa4>j`MV#u!Sm+woQu44~!!|p%haYC}d zPAVjiduh{-v3U8k-b?VQQ% zG(XDtej}63UhuP-*K#lBJ_Dpp>IHmW#pXxbooh5oI7q;14K=8#u%7IMm_?gWl_yy@ z9ls3|-D$_8NC2|Ze&$BXg&A&*^~pA)ktd?8$p-V3<+9@;G!gMX>kW~hQ+~j>g}oxB zvg?Rkl11>+Nian8KEB(}lXwrVb6U!@5mi-A!Q|7z zX-bF<(y~orom7LMr=WpK#)^a_vjw?_>+pEj4a|ZAUc5~i>>h8nr$)YHnS>+uaonTZ z5%={ZZM&g^yg4Q!_c6rph^F20^%^hlt*2KUV~-a`<_fSxy_SF0^MQ&w{I2mgv|z?D zwKG-<$bw=&4QcW!-61&pDc3D;++Te=<|cU-yX6~YJTOJHSF&wt3~;Y8(^sDvFQLk! z`*hCId|a=pHC|%$b3Jw%M2b92n3$N@Vj1Ssv7P3H25T{6J3D`o+4lYI%+5;<-@icJ zpYhWk5ik47E3drp!3Q6FqK83*Zh`^Dt}haX$u{J6$KAJ#aS|yF90fu~G9S;@BCn>T zc_N54NZj;T`Gmw(6|a0;Qjf^B>A+Azi4>JjamOz3&6T(x#}2f901}R2`ZkWiyLrO_ zkJt^>qh}eG7>)YC;8mhJJPI;QU3V?sGMxvpv=I-Ohr% zpNkEUs2w?g8+lE&(V40i2Tt6*$I`&Ft56BE4aOwx3O1tQAq>)GIblI5mV8E?og zo$$K|-j~2-i9FIP`_{c*+e&}yt+$@CC**@>vw1GFy&Y`r?7ZYe~P%880Y}imjV#9YNH$lCpIV{VJ9^;Q{;>p_e}T71^%H z;J{Fw)w3Byc&wmHh@nxJ^=|X&3hl%b58XJ1+x52+AJ1~rC0sa*AWvMCwj(#K-}~6u zuJ&85TYk+35f1k;L~bPcw_BN$9`E~X_HG?KS65#U{JFSKy4K=*bAjAif*Gg*;?}P* z&vS)#mM}&%Ntr-KEV_BV4EMsbjClBo%0K1#V>=UgK(?E{e=4)Hb85%;&rw!m&d&nKf56SZ z;x{xSBvvl-w9yW+l9^0ezna~$#uc_Ra>Jm=6SoSYZn*Kud-_s=q3;r3b<>jG5Stbw zI|T9V*K$bI8AaI62 zKKq=(#7U!bl&khz_NekhC&9ak3=Q{#L7y351)|1eY#Cf?m7>h^Ox8})r~psOw7wIC zp<+JrxnG?r={xVe_g)=C#5?8tm;6lT6~EEA$ns3X-`+k?{_(%`>Z{|~OcPX_w_Mv* zoO$iF*Usc zFKZvK!J2&*KcU2P$xn#eboc7}-ij&Tirl5_+`OZ@XC_e8H*CN`3HTOrujg(?KmOvg z@S}hO6dEN&`vqpcL1P?4oHtM0w&U6H6b3=SQi?oL5qVdDyQ)1(8h>v79`2iJ*Ot>b zgg2Iu4bzmZ+VT>v7?`V^0aCGX!@knD1!MT^Gw~TV9HXco8fX%BS2JSKAlW8qGTIBo zSCVO?em1b8G?5j>VYY3(A%{@F!vrtAZVWTV&ZJ<5mZ=7`#v9}HHWm0RWz9lvjoBr} zUC3CDum+S?I_Hsn@G9L|A@lune;^p2j!d=_;~Tuq`YLZl^2SYr-$UbpX33LsbJR62&nJBkq&t}iYGP1v z%k*)-!~Ty=_MdL~XU{fqe7woB%(<y<;^f2}UXKl%_NI=5W+%6OP6{C@Q265^^o?wu{jL&X zSO5#V{b_rEsKej@&!IUmX%u@yz@NMfSHQ^)cf9n{pLl7cM&2dm7ahm& zq)4e@kjRHBgQTkfmvGDYM#xue+vCiVFoZU3ebg}{1*zvz2L$;uA0U}z?uxrC)}_;i zH@l>bBwD1u;cHX&U%^5?|a+Zf9>+b<;iAadu!{-6MfW6yH=la zzzA~U@IgYKj@@Lox@d(>TCFICyj((VTI`Cix^es6(~db|k9?t&oV55Yq@M;OT zs>6g$?W5$U*;{jM5beZxtx#7*b!UCAh=)X9tF0je=Hv8sQ#{uZ@{1Utb41=z0t!)b z;(_kt8Tzd9>G{hZe&*}UaD6Xe=}V}L27wQ%(WdXI{pynJ)H3EM4C6Fdv~e44#x8q83jP>x*dT`( zm%$<6L(F*@+8lr3(-)XwY<|S^Id&g?CF6}{vbags@p^o}ao#Uvut>-)!($wG$5157hsxsdXNEjikQMLDzfQZdx9Sq7`GEM^vg=Kd4##W)p;<&o2$uiHMM~4BQ z!`9r^#2*O4tBMotxZFTF6=1%F_}P<3q{%mAEInm_psaO5Z>Vx7F~|#IH`g*ib1W@J z>WBJ_(DR7u@a7G=kF;OnXO#b->!uG8b%y#eiz*uL$mLv=G)9b&=O8BNuZ^cVd}*4Z zzS(HZeiLTss%PZEwmdDGW^%cfTl-N8XeKDW$1_da!==A@99c0S!X z_xSYVET^cR+HN$?WV7A{9bu*q%uIat^y!Z?ndU2*v9Yff!+@DAKD4fQr%)2Kv(Ov}mm7lNi)5_F%Mm(JVta%TP>8CbF%a>O(1{wx= z03Me#F8JyDThlfl@CL#uUPQf?85+Yp;}sNd^Xzq%VUK~cOdS>B-t<4EfFEz_PDvVC zlwc9hFxK~-#10DxP7T!9$B=@0pOO~5#W;jV zh-u9#XA79wup_u_yuC8(3U?72>{3NfgVWaY{5n_+z;sI*Y;LU*t_VUIBBEJYKM6(6 z`k><-J79>v>tn^AWCKL~h7F4-mL-b=8Q6B9$6lXF@X=N@Hs2tx`UVm8jchE4#wgNT z&~rZajI@oB7#4kKu)=IU#3-pqAP%y>z0@U{qVq^J`#p;G(_l0(;n{H07(-@xL~$rM zy$vxByphd=EU$6jGi_BCV^Cvl1qC5R*cyX6l{gO2ugvmjaa8h?c8mdn@}IRZ9Mx6$ zQ8-BZ!WU!tfm>GcOs~JLmS48d=%|pfM)L`atvC>x7Z~S1n{9ZF-^nz`uCOWf zCP?{K(;vI@=16Jg=kCdUY z|SNGurznu=M`3!chgSdJs!NPk+albHsof#4S4l7JT5Ou&F}K1-$C_PMm@74DVg%1 z>g=VSn9esCn|iC}0e!AW&=3ONj;WypHS1q&MUC#i#tp`hK3KTm(q?oJq_-pkHJM`Y z#7Uzp!RXTkb$1*oFJmP~+)}dKe$R0|6*J!O1|eTN0!B*ee!GrL19*TIx%iarV`B^+ zv|A|8JfCaZ9#I7xkHbh0rXgd+|Nq0STZhG7cn+ z7>}zqU3mr_Fm@`8cg==^LD$_&eHxpZWodl+yoOB~jpsW3Uhk#+p!2A0x!u8k#5(wc zVdCC}UF|5iar@mHJTaMqZwjdfTkELq{i;b#*Gw3Xhc+zFibifG+KnWaH6{UhD14*# zkzv{|Ra8IS_D|xyUOQ*mb0Q6P@LQp;0k+;W@^IPBqwz`noEtaDd(jd(vtYa(@_4kC z@=D!gEb(El`-~ho8?V0m?#I08@-BwQyLdk~GT!!Q4S(lDjQu~vmGCddE(R~<8qLNe zn?>Gk>}>rj7I1#*jg7ti$tRzD_Lbn`G?vTG=bwE1|C}B_eSXaMKHGToNT1;yN~qWC zk1tLJ`QWACH+#mCMJXR3oivT z)Vof-wX}REJ&ykU76Rh$(ZBD4m!+2{gD2qfzv%@>qwc$CDY!072G^itadIN~=Ed{D zS^ALUzAzb>xbLt#TYCk5i^1}{Dl=+0htVGW4N}4)iQqfIWKaXX zkt-mzxlymzkQXajGSYQeaG=C<^gD#^uhRFQlRSg>uS-_BZN3z+JfHEVi2G9)pBG;W zejU$5H5spZ;hQHPJ*r1;{$B1e0OnAJXE6YNvs-?_28=%dKYxGXrQmV>Q72s8%Iz1g zc>6*i(dGvb^YMKRZ~oR^^4$d%AYI*sE4-Zh>e zl+T)Gojx83&B9&2*F7^%gOg#wCH&)cEXF(FkIePWPW>A0Xydt)Cn$sQMV~9f>i2&2 z3il|*JIvPZk@v=a`45sVPau2{(o~zz%{XXz2-h$K7F93l5i}|!+i3XS4U+C8iL2p2` zW4-So75E`W$}Nkxpp z?fTge^*5&buC6N{BQFrX5EECmWTH$mNQmF_wd!4!9eqTGFYBIv`tj3?UN(D1;AGF8 z+s?lJ^2=W%;_EQaIj--oudhGMz5e>IH=6$Wrk{PNe9f`#zm(l+=pOz)9s$~P4Bq1b z)zLwLK$=KvU3h|7Q*kB6X7kq^vydtb9$K8nvzt5&Urwv@B*)2Pgu#|~`mjMiN9G~J zO|I|Y)NK3mL>M}-QPsxjN?d?2*GAlqcsI{s@68NUAL(N7gA;wTW%00e9;Q+saz^-OfYMRbnz90$pQ_L)M8vtDl1lgMk!9LMWeqtTf3 zvpZ8eJK1LDROVy8QP;?hojLPsk3Zl3{d4EWKjS+x-(VB!&*KpP29{fXtFcv^nwt7$ zOpoSU@4l;L8|2jUaNIB;#$|x7_XC%hm)VCtTD8jsuh|U)=9v=&TJJ_MuOKi(i!0%Q zzG_p}Nct-S2%%B2?dvKbf^w+aIKhO_(T@2tS3n+o5H6T`PG@}Yjs)c3Tj;+=y;iEe z3m<&9rT+?sP(m|U#@28`igzQ~kd!-2~1i@xf;Yt{=T;<#u(p=;mwq5Nqh{Uxt^=UAkvK4cz$*`!vvb-dM-SqjL@Zspsx+1 zdKn5VVa)7TH#E|cY83;cBdYHN@U+|JNxzq&08Ppq*muj&GVT!cH;2Qy{nMCdq7t}qlEu_f zb>nm&)3_sVGS4x4-Z?ut`4KBF5paFf$TY_Bgq+E;+4Q$hkB?sqyv%>yeBnHXTE^dL zZl4~b@C;$Q^I*g+KOjO+wRKHZJX|eC$6ey!~$XaiH@cfXD3bpbnfo@1D@(h7==rObX8Y2;w06|TWZtxVy~ODNC~z^`OWslB5&q?sV`{U=Cd{h# zD5+g$^i_E9dSlEhy)l)$iXbodG7bg>vv6*_g=`ERRGn${$heSqLLL$OHcVPR8z;CJ zzw(Go^4oxq?7oUr-f_yAO{y|-ZCtl&(%?zv6TH;(AQ|7!v-+_IPY3nJn{(Y@ z6s|S-ApHyaB|a9n2cA@Iy<6SKG`{)PTW{&mQ+*^?u>02L+J5`(w>SBi-G=>rwzc(t zZa14RlWCmSb|=T1ng5jMf8N;M`9X%wCB#1uL&AV@t>TG*L1!g+aZeRtR3n_znuJLs z;&W+f$v7z?W;t`M*K7$s74PHfMdW0?Q-NhhzD51UAlEGm?7T)o~JP=%h z>9FEPSKU9!6 zg$g=0#U?8htjRd{8JVWHJ4$Yx?&ES%GX6wA$D4}XKFE-Z`|3&lq~XHN-|b#r7F!RK ztZ94SE&p+f$0L&c)+?`^u|~))*zk0G+T7mWymay6MDua;0tUzy@A$rzJ)IpNYmULw z&%@9#pwH9Cn*}8VxtF5UhrP58n@elg@A7tx&5PpEXVVJ^uYG4QY6AiH(3U-}SJsXT z+Sek5B|LEo>*7A^$wmN6DDw-OS-#9U!c!SJtv9C+#tBv_1Zd&wHB8NH5hfkVL0+4t z=V|?ZPhsCLZ7_CLv#q7Mev1w?zXT?V-h89Q8XRf>KGvH9foY5f1<+NOk;3nm3=(*= z%6OQTK_dJ?OS88^hDp0@t7u>URh}_cVZ-NL+PUSz)mKFa$ZUB+#)u4&q%lIjWN^zf zI*Es9S$hoN{dolV2IuRnrsOxq2fP(BCRWJ1av0q7(c*Y)d+1e3;zRw1o(0Jv^$!}F*KYUfD|x#bo01pucvFoGk=FRxtFog_%V2=K zxc$i|U)?-?`U(cA31hFn{`#vsj~~B^v(<{00uM*W5!%dRwW@t-0YjJZ>}uH&tGKYV7V_IQt#@_V2a&b z{%#2k7?gA9#vR9dxjB<~NV+}|h__MX`7020uVZ6 zi7}FPj5nmJ&APyuCr^7k#QB$KUq2Jf@&FrJG1{)-S((E)(WlZ?Z=L$qb>+7KjyFw# z_#eD7!R;0BF-6%c7#~%XLB&o0+`PlSr=R+OVP4-55)T7^4g)KM{vmv_Xp|VUUY4gS z;2;t_x>C*@dIw*7+?yp1@T<3Ja^iKql~sf0d6c_8SuueklML7FyQ1>C?>B&>YR1`P z=9UMB9M6EizxNK>EZ}XrB1H^s%%9uC)&8f5J-~Q;&|NQ&o!G*lfr|*8`z4yQx$3pHJ%!h>14Ur8P&Yn}=xUZ$FNsZ0 zyIS0E?bcRWv38s}$0g(4C8FAnCoL23{2oTkO&QM`+cGsX+e)RB8v)AAjsIL-^njQP#X zPKNVB1X!cl^tZj{#muQwAFO%n|Ho&aZ~Yz?>Khk>i~kk9zQka?cIEuk-y!SQDEx1^ zYE#LP2X|fV$blIU0Ag0ng!ZaVh6wu~W;Ez+KFX|UCZ%VHTGU>Lb{YnVW{7gh+PJi< zgodnW&Ai-n#k*~}X~*dv#jXCEKE?)!Z)Y3F0Zt#`(glwJvs5X|O}sTz&~H_5@<^Zn zce+42M2F-BLTG89#WMS3ip;n-Fi7qlqRM@XO5qv<1Y-cjQ|?wk`*y&C5u)yWxBT7W zHI77k^BHnBy)x6B)7~L%Om6>pB~`eH@!YMdfyavn48F0NwJc|TyjBamOM<&ggOkW% z&8SoPK?YW@dwtY~a1+m%yENB5n&R4zvZ$H8g~!krnIi*4>3B<)_A;O)yQ$-$ZAFG8 z6tfVwlhyQ zH@3!_?>95eN5%+w>%I5>Z2a{2?*Qnlm%U4WJ99Sk3w%H3TsGtX&^J5gU6=-SFX0J|?lRq(mV%1C7G0|skAjc9 zG8lgKy+YT_Jtj!F)AlUmVh&i2R90y0zyl@leP=&hxZTqd2!}@2nOu}rhtjwRw;{`m zOIm6%_;L&Ff1jq*_Af;a!H%q0mTUk9edXG7_g5($ndCA1H?(vs75wn}ZRoP-#y_j~ z@^A`AqLumf3r0fhrQ6kI@K#2v?lLw(Z(d7Q$pSip{{-T(@%F~X$2c_J&t|jl&^Hry zcsu4DK3ezT*`1vi8|Th3A@g3#Y;Ci3yjfBn~+$Z$LYu)jt-*lMDr<(JYdknc3djn)2wu4NA)NB-m82PE*NJsb|ba+dWdHjt2yz$ zjBkvRtBn1Q@v67P^yU%$yh)yQwQpz9c$s9pXx~wF6fDPyB)L((%DNc?XGJ>ZhI)khjTOGGiS^h=6|i<(JQIZ*N~b)#T9B)7~eq zyz|aSAAId=|DNy4{L;(k&izZz&qSGzvk!M(eEO>#x%w9vAUZwu$b$$65G9CL!pg4= z>y*P$byNlxgV#$lL=*=clQKN$wp@1=2~`Bnie@dr7?(Qh_&IOT@7e680i30K&-!`S$Br!frMP#k9nV^ zsOB~XO2TuZSqXx6dadp~T~#&l%2PUPf`4&uz_RPitSIR<8kuxwD0Ckl9%2HAhx zhe2G8rvfh$9y0R^x~)?@WAD3N)hGIP1HQ7}VabIo>YM-oKmbWZK~#uboL@$Jd;E8+ zW03KZWz?tNmoWqf=`^xfOWzg9W@LAtbsVV8UfK{}HnNP(hSx+cFZ5DouRPcqXXW|q z2(Y`7?jz#j|Jsi}%0!)vJw6=BEgUbK_^vPCR|`^wH+nCTDK?uWxN_ zA;#=koE_DS>_Ka#LX2%t#AAK3fS{kTaVPbv!HY0nMj3@LW1F!s7}n`iKwM6JlhDz! z1dK67{%OS#L>mvf<(W;c=pF@8R9@YyJ_%yq_i}Q_Ylf)!;}+x}8Ek8)U(4$%#4^w~}QV@9d$OVO-9}3cLfhWdG%9aAlw}Yiz({#!DJM z6J-9!Zi>ELpDu84_3su}P3NHxeL**oedi1g}V7!U#Dvg%VrB3N5kxkhhE=Jizel zzHi=|3E0F23a~_cuRz(Vya1|4abjGQ_5*S(uq+^Vd8GJWgO+b>UA>k$M806JvhZs} zUlz6g3=T9njCVwqI^|LaBi&7n->aPgrM3GaoXeAiaDimrl&xROWzbcpTb2|zERUY{ z5JCT(ZTBEo*wGpv_hcB07BWE8w*%HEuU#a?3*Y8chw1`B20t3tz`TgDBSXZbE6+iK z#tU^74pR0oWi)P(OPb}*@Lim|`T@xN(c$X2f)oA?7(_>>VU;g^#Upu{%8Q(w}0K}oI02%AhE^sT7LXu#77Ca&%xD*zQU}i~{QDuxEtjxRT z>bv^PrN->~CV4&KB*T6KtH@Lj2E=W=1tpZl4V7128UV_xI`#{~rw_hW*M4~il-|K( zyaf>0wgo#%+>-%f+ftfvCA?sKh3Z@UGdtAbiOA+1^_8}@9^Vn<6@h;@Wf%%h&HS~0 zhxL@WFkIfqMwa70uZ3=G;Dv0U{XSTYcANQTNo> z_IQDZHg6i9r#$)z#R|4$mt#!H!| zf64Q`pKUb#Kiu{j|A@UH?|f0}Xz%nE2MVVM6lE6@33xmJp%f?gM!31@x`)nEY6C}Z zvYkOZt3SY-iy2i*FN?q)5#`ZGF-jGkd-zpa z--p2vF@i`&BJfShjjOm}!U`QVHgrzN19>3$>D&;lLATol&F0M{c#adrq(cPgv-W21bf9p!OaK+c61A7HNSUfh89 zgT`9bg&AQ#%`(h}?Wdcjdnp5!BUj`SPo_bSia+MvBfgqUliWZFhQ#alJd79vq9>CK z8T@;`Xb{uABJjlT$lDTSWRS1o?JW{rR+D+(!0FJJJD=5YwY~^cV4FX*FMj9|K!is-+4Q(V4UOLU-|Km ze=J1kbsI#~=mQ9n%Sy^>mr#+Qg)k+}G?VMA$`5fLQnrF6IzM{Icef~_kF}1i4w&8K zlmmf06)Uj1lrTsZeISR~0bi4qDnVlm5gm4w@n*Ftkg5U5m92(f&mPI3Iy14BdBk>-27G>l~u|uztn|B!Z;v4Ffv0i|+ z44+_>)-=&x~wXHA=I7fqQ1{*yt87i8WRr@a~m^t7Jg|F%J5 z({&Z>;IEqXIeVpLNcC)tP!8$dDZt&jM|}@C0b@MR_zKh7Ht@pVys8)mB;??e@qth>&W8*oxzW$z)u3yh`&I+fSa1Z|^kCX{oQh_S!2LD8H2T{a3DB zx_p{FBo(sh)!icrQaG|4X*^5A;I%y%bq`Z4BIH)3%wpzfrzh(f*0Ujg z#?1P3Dqf8lO=Q;WTNdapc<4tC!sReVR#CW97#Mfyp9~bAzC4f;6RdGxD>6<J3bTWJhW!C3t}Em*Yu_$y z$!lH{1>{>t0CsAV(5o(GspSh`jg$#G>KiIIq00u!W7ZZ_UbjCsepuI-XR7_ykC);; z%Z5rbhS*e2hNkT0wn3t2H^g`hRmYgmhVH?7k~~IU zH<@Itq|j*>VDaSnh71@IOEv?tKTr83`y5}J#MKjV`#w^)CZ;;6*}U<>q@)C|>EOU% z4;Ux+t++vJ^tgZ zvzbR{PM!HRpvjo&c@K>aBa09PB2&E~YEQFDW?Of;Z3}t>2OEF1i~#{^@rJjyf-vbr z{3n5ka1rs5nZ`QqiFsnCh#b%it^>jZ91Mtn%p5-&?y9h!EXnkYi|< z($Z~QOydgA)~lmq;^#0*G^PTZPu>rBy$Y*q1Fh1IML^i+;y&zxC+3HW5_I%D@=CMS zNY8G-0NK=7m$CwHVWNM>rmrr{U&edU2>RG%^*nTY*u{I*fgUE2qV1mN+lU7`3ia?1 z^OwHN9NFxexHG;(WNn_fvW*wqWQ#QRaiv#{mqu@3`n;uhK+khmBjobs*M2tZpZhjv zft>UG#wVvwpZ@)96UV2w?LYeJS8t4Enm_&E(FgBd4syTl?KJ-g1H^btEU-s$l_w+V z4Y5cAZ~Bz|Vv>jmBh9pnEXQcz-qL0}u6Km!VfKMG%*VVCzOydz`)yP8P$rL%mOFR7 zTX|W{nk6#BR(^eDG^e#j;wvck>JNV$)w-1(Rs5TmP-;FW119z*0IR+fTJn5PF7$N< zY{|l;Sp|lPXABhQ%c{bQ+}n_`V)GvL6)#r=thX_qstA-Sycmie@L<>h8#8*~E_TEn z!w2vyW2t-?(B5DV476S58!u6^9(ZAyxa;6znJ?q+GBlIuWjFouLk;c9}Z;0MadGIK%RfUke z`t=p)OM1w9r(WCfcIxZzuK&ZI%jGVOojdo}8$L}p{Ga%l%vZO!w*EDHM!ucRc$v4~ zS^xj2<;V{$6Cxo}U5FD>)H4wa04shN0YP$G z1_*6Nz0@xT^S3
$|rfOR^j-Su@b9@e#(AP@XfyfwE@S*yItwMctQYL7fQr3*Jk z>Em6XY*BGO-!DNi)_`x-b&o4;n87eGiW#Pk;Ia}RhJb4NYv~58Q@m1Kbm7pfLeJ_G zb(Fa^W#rY7QL41#6108`UUPVFYWjwRW)AWK*nSF5^+WhSE->!}2lTiK><5NbeZ{CO zvQhe4T03JBcnCYvWQ@R?&u%~&MeuJ)JV7sIeB4xTd0uq+L-*thl-4aM52!6MmWpxS z4aUhrxBSoJM~?yYP>Bgi4cT_9pVpbMmL=y9Z{FMQelZzS9qi32M9!Onz0|A88**u> zTV9v<81G+vpNKd87@y1WQc<_!J;ir5LS77l?|rB@srSkf$9N;gKj*6b>j33-l`X9!`kpSoeNY25Y!hJ;}1U>e|*0uJd%osF4uJj%GK z3uf*E*6r^h%w}bD(68$#xkHDLghV3z(|~CNu`Q1s;WHA zhe;X%KemZC+pYc>m!j*j4WbD+)#uBr^fAKgb{8dFa{FfndUxgBFl>bt2Pd&+pH$O_W3Z^u13iBzyJMD z`7X>qK6C2aFE*N6|9P`H{vxj)Y_s$67tsgb z)2Rek|2`8k&(l#j_RFP+#myO>m!5}TPN*HS=&cXutGndwj*v^dqcFO#A~J945@bE z<98FN55h6mJJ9T|KvW!koZ~jtHG15-p}j27tu2)Lh0pZ0^&OFD&$76x&Dg~fe%3=g z?kfBB)15SRUhRZvImOYBvYCb247%b)hzW0ERYq?yD4!ee7CFp4hLQEy^j(d-Hrn4I zS3VvKy_Q&_67w-D&-V)KJ(%aWX)IDL;^7vpd=V_Z`oAaN=YPLNw#if?;QXH`3CE){|r$sXx2QA2LEX9!9+q zB-!}HOVL34a@3ZV0DT!_oRoP;&_`8VM&NF`_0T#7@*H&3Cd#G#vTLlu(=+5dP+R-e ze-hI*9vO?%@MmD*XF^dlW5Px}zaCo*Fzo9X@NL?q0jfOwbTW2mf6%uknI{>@xX`4f zWXsA(7}SJJ292#(SII&2!p*=GL#Rs&p z23bh`fpClwRo7Jt3wQ$*QI65KLEc5&m?n+nh@UY|xQ6@&5`ZBG!)O*FSV{w_G_C|1 zYGxnuSXGoS1(h`jn6L|f;3i8Y5<_iZw!Z$!qbGRs4)2~0nI z);I!R(^kKl&GM?u2^cieGc_9}{7P=w=d>$ERnDCFo0hmw9Fye!Lh#Z{FK4pZoyp0` z4>+~GXG27tzxYz{_a`TU8@}(oiqWx&68s*(SJ&2~rHy)hd1JF)otO-2Y<7Ljz&ZnD zzcTq!@V6-QtNgzC@{7Tfk3O#dq!);Fr2NInAU_!d-=ywU9v}0(dEvz%_tB$zG!Xm2yWM&DXqh# zwIwS-tJM~hR;#T9t=3oxTH9+SXlceGXic|8q%|#zpf!?3(3+A}NNc6-+2+e`&Dqj9 zdzxVH&TeTWGWYueFHnJ(4}Y1+WRlEx4)ETKxN#%m#*KS#-1vFJ?`+f#Yai8qZ24mN zD(;kPKz$EC{;1Zre&7DX+P6OXxK^og@!X*7e@dBt01bXvU9WtFH{%yD&n6y@zhQyq zU&k_NxuV1dr19&eb?EswA78C)zWC?ipa#9a^M|z|-jbhvyH?W>`6V>>Q{T6cU607O zVi~Mw#5d~>*aRJC!7dsXa9*u7KH8{dcnLnEj-R__n6~(ea`t%tD>}h5%KP0T$}fDx zjZ)jC&R^NaG3>PWe_5;fQM}I(?4Qu)Gdth1d0F<4H)?-Ld4FoVkn7vQ5Q28Ps z_tvVF>*$IMeexC4&NXD^kC16w(B;`hribmPu0y6Zk^ldi@-8jEZ1dX3we27$nNFW4 z1M6Jm_vaWsKWEC`k$DRl_mz4gr4{u1GkGh9LFa9BO3;(i9rbiuzKijnvd9)){PX;uSHW+|C%Fc3L8e>i>8Zk5)g~Y#c-R3VLc`Z8wTygRlF`Zr3@{tPlRI2QFydOEu)5s-V;0r&Fb&Jv8;V(?ZnVsHnB{_yGn&E zbh^>9V%)rU^Im7GErPu!EIg9A9gizCY+nC8jExEU8BV(B^?0g#Uk^#{p6$uxDDf>n zR43lF&REiI;J5hMVUJ+WeKQnp-lY{Ey-f397m2t2PP@1UR5m?(Ge2|KY=}+_+ZuqXbN_s9*j?=<8wFh5a zUjz?z-lL8Sdq5V!xk?!MkMixnPn!WRuI0FXYL)q1;yOJAki|PF(3|-*^f83AWnEc< z?6?!<=P{rQ6kvJn{}u^Z?cg|L2c)8SIIEZ>3kORwVB1qpnqU_EqB1*$OQ!jTluKRu zB_8+vm=FDWx5~G~7MWU&X^MB!FMX}CW%rN&-`B5S=Eu7)g&-(%k9j`Xw;slMfoEHT zgbG}nXV|!ofkp}oO!EfcR=L=SHh!vTXaJAZZOZ^Y6W5BFYS6H|rb}EF!_qqq(pKRw z!Vqb?dC!&^1MC3?h>SL7%(VOghG`b^*1&qAs}B8^eSk7&wEZRF8!>HO$1d-Kkd6hB zcvl{x=vyjY+;6?V`!Azus|Y$guzS{C1F;6oi> zRT?LCG0w`{dct=tcqOcDS;xSFuX?mcHY?pli<93`2E(-f6w4Ush(f4x=7(#wit!iW z9YMQ|)xSd-AJS(AG=m4^jZane{UVg}vJ8wyxa>QrTrQ)FaLAGeaqv|JW0-JBoCC-+ zZ)>u&|L>SD_lctrf_Ic+A&0Ngw>Fd!PIV+@96uUYWqlk04P^Jsei-!u^%H*PMZa#v zojVN19#NKoqhhDRQ~GEOvhm^iqEoBWGIcCgcA@jah2A@Mz53+>6*-nF4?uBsX@oiz zcntDj7)*nm6`osOJ#kUk2E^I|zI61WQJ``IRLeMn$TidXOuEf9ALr;~a>Clh6YAXF zJ8L}z?bOFG8lcc0!%TOh_a()@?6c*h?8mHnnM&^fV~ z9&^Kxb@HX(Gwnk59=i#EJq`b}&JmN_JD?1qBPySTu9UT7W)r!$q<*9r&8S9%CXKNXuA* zM0_-S@N$?&mw3vkT7ooMS2&c^g!d!l!S=+mX&JHzAB@Ae>gR@od1Z@~eHsj%;!&BW zC*;KfBS-2y*BMPWF)r$Ko~F3cdIctDw@Iv%@g!04P0-c$u^ZI(ISv`*2(|B<$ zbD1xKeTOs~-1{lrBc7c8y)+-v)zkL~d)m9Sq4T%7JG$ybeCCHo$OT#bHMh}1+3_Hhb~78<|yZN-Wyj~1WniK&~6iac2VkK8*60D z8dZOa7nP4ehN;YpQto%99P*B`po$_!ZokayrQug97ld~Zh>W|tC=K+2$9`*js{^WR zEuY1gdEZ=Uieu4oq;RQziQ$%wdN(zQ%5+PFn{`KqjlK9qxG3j};brd;Hr|Uc8gUqH zkLm9Z)d}bZHX%(`k5Fk9@?^Fpr$s>oEIsn0Els`m?43V+2a;TF3(uJQcRa4+HpuEZ7QJ0I6Rq#-`bS3oyd#oHi_yKX*V zSBc}J_?hmGlgdj^4jLfIGYG$~p0Rmr_HtoR(5sfstL zQu%^T{r$MAnKIj%51_?Y(#h4$gndTYsNVEd%+mWi(2Sib3-6dImTB6%^PTj>qvu&> zN32k`FW9m3Bk~$hq(J-N0%V?(HojBkj$zQXPOjkgPPH18alA5nT3(BWTL$q$o8PkG z<9`PCfoY`?bo(Jj!Y`q#r_t`qSBv6Z1P=V)wSJ4hE(!xb)YwJ#IecGdw^VJ>-DHd6 zp9UwrpxrNRC!eRmU8Hc^mwxfLv&sa_HvAEG2F!xHj9Z)nC^;7?e~W>}zbW=9Sm$eH zkTger9)A03?J>I(gB+uOwou6KAPcf$ksN8i&)s=e#rxqphegu@=dQ>D2FFe1!y$S>(yhYkynBE`wC`RRT)=~VBhb?qnLmiQp$+{Ev8~Se(_^R%ThlXW{@9c1?u=DV<;?5Z3k-dLW zS*v`FoIb|)(gi#}^B!?|_uc-K=8?wFdd49z_rei<_E&D*wIOJoIkVeXZX3A6Cl*L1 z^JQbjtYV{pHPY-bg1*UfmY4PgyIT%e&(K2|Z-Z|; z)>BkFT93T9ogdcwK{~xKL(58>>q=_A$28t4$AFy=n>_Y~!?Jw_tXA(BcM3o4nGw3v zMEz;;FDp7VDJ69eac>elV_0MC(}ODFSRK+T<`r;X0d? z_H47;qmw=%toQpPJYdNMy*|j*Oggmc-gaUM0ogwJ^iJNLcX>vy=h~& z!H#!FmgO@oOnrmgcdf-SIX^8;9$w>qj4u-X6~NF9+vvCkFTD_u|5@fxWltJ5m zj5nO;HgR=zO5UgSsDFj_r5LRNh{V7n&N@~OE&NB^`wNog;eM$rES1_@t;12GsdX?>-7#`2T^*}uN zV$}yQX*XAbGS0+hBh#=u1|o3UIb48o(JJq)i3Ge@7Sc6hxQZVkSXb%9utn~8Ha0!1 zZ5Av_)BV}^h4C0|;D=M-$Kj0V`_pI{)5@T6QEm)d#U0mL25lzjU|!%xu8&-g&?=MG zC{m~5Hl!Q5$I6Mf>cUO6*ZA_3S8*b)hOp~1YS>uMh2B$_;Kwy7> zcf!|JW52LZK+A?SEP%h0ukwq72Ks*kere}&!GVB+`-yx6E%uUi2vg~R+}Pm&z%PSW zZX{n?&$-+0z!PN2)Wnw&$0(r8j56z36vOAeI|!z4eK`-VEdIh7A!#8cY&0q~C=eXMAj$8$DpM5* zbUQ{&@YJe&b=JkL;>3zRtTO+Oa^1Iq`0Zkd+*8>TeuLj`5s!_H74wZ%3AKQ!i%-Ue zL2eY&7{@hH9+fKFWFJg{9i>?E-w`fe1B;mDNzHRO4^3_)ZOj_DkEeoEN2&)IE-vcc()RR3@O9TgPR}Y8wQCvkhc)E+xaXSsy7>4)t%I&7%WzUPil%=}}VX)O`n>T$9UT+uq zh4)N8qVFmXCTLVFKe!yc?En2?cGG^7#*2skcOXm}e)&9`0`z~q3fXL^;aX*2vx0uKJGv~eH4`S9BO@D|1Fko)3=RB4;_g^xvW( zKgU}9t#K(uoTFoYt_}PbSmFalKR*E`5S#T3zd>m_5B5cxhV>+0$CFtNXS&QaCWpZO zsE9vJmp+60!!q2$V1VpV=HI|9qm<7f!4)QT&zc$Z~6>Q*UC(sP@2Y{@Kd!kl|BtHG$~JSY z?tpp1JoFD;r-E&?P5ML2GY`+Q@#NKwQGXMNaT)90Ng$!6gQ{hB_>{g>0=q#ZQtPmBNf4{M*% zk1BDk*fhAy@NXyp|J{b>ODij7w{nXnS$I9jH@Tkt$^7W6e@vEqo2F>B}EyHk5( z{ZD;|z;#`>xLlvRTfz4tQp2!nTZSv7U3e5>+yWM#;~j9P4+4A)^G-e;aiw9ip2@3K z|Ks|2v?lX`<58J4>WF?CZY}a+J~AB4^Pm`>z7yX9XDtm|#j|;9rHA^}>$fd?Ss7Q6 z*CIF~-9p<^F6(Uj@#{$QMQ|(&BkpC>EDLWP%F@hgSJJdiGYuxvstoU&4zu0tALmsL z^6HxBdFA&mzr8f4f!1 z<>x$GQSk_aD?7O9gIktSb8Hkw^txmxm<8}5RGkQu%8bz3;Ge1Z)7H?nwzgK;kU3-+ z@~TnRyG7SRAr9AE0uvtdwF7S7mD%gXc;E31ZRK?-i#~Cfc|(h5cpz?owMR@a9b~8QGRmT+hMcLz$ z1LaO$=3tD_ciYqYsPeNowQ5+*Gxkq#x|`?*`M01+pZKi^Q@q=^$+Kg)ylt5=4t5Ch zgP{+L824Y8t4AK&whUz=L zz;kFo?%|3HK-0sxz%>NNGjXKhF-_SW_gA+pycovk?FTGK+9Z5XjN`qu>svRf+mYF+ z?~Aopm1n>EpfX(lJv%Ho#@aPACAd}+l;<6GCsDfFtlhaoS!$HUZxLLlF8#_{Wk|VP z@HB3Rm1I5xNh}xJ*Pdd8`SsrCfM+p@?T)Z>&BY#JcVqZ6cRMeu*q<(w<|MGzg%$V> z=vwzV;^5KmCRGS_etsCka;}^juZTz!o8_y_+|(X*B8y-`bU1l z=(3Xx`F)A-o_ZF8xTVt(0vgyF{P_SSa%TNx(Ym}XaM0~w8Tl9MHEyda2MDq@1o`Sg zc>5{;M%Z{KO`U$)z)*S0)I`^*-Wa#&9e&zG4)hm=PvI;x1Ffwx{;+JyU2tdiE7G~^ zD&u|=p1O%nc|qLaG+JqNAV(^|mhQZC@Zs7Hc=axLA0uyi|MP8iZEkDL4+r&IF9^um+WT{9ImT6u`nBP1EGNX=unD;hZ92)U=5e-osnaG|ZhhHjdBfRmGiO#vr)) zgEu6FJ?(QC5s)9{s7GAkxmsDs>k{hgHZM-lb6O(ci-^wfF7sFEbBwTWlg)E}!!$dM zB3zHXH0&&%p_Kx|xzD=zrNC=r30h5Fa>Knr{(t@51`*K zdXR=sd(P8OrQ5W0??ZSTSVRS=;m%a&ZIsT@yf%_Pwv%arueuXt#x(RXa+)^^+G&{} zxAiE8cEy89cnCX|s1RWO1Rc@F6Edj)HucqX@M9&%GZn5ZLcX%h{O;fpK0r3L{W*XE z-dE%K)4YC}WmR=aiMlFlkErb&wnT>cMGn z%Z5Xu%WD<|WQI6r7nlI1w&4}(xUhPJ`8Cx3TFG8=;Zi{#JD%a}>e-!@?@8jqJU+rx zMx|WgTn!kobrM|Xl?LS|{T|X`4)`5H?$F`sEE)xS(5bda2RUtdaaD#hBxu*Bd5bRy zy=r9`-wg|Gh!GOYY1pzCJh8G4ylCDUBEdDC3+0fmWUbHyzC7Og(>5B2;qttf+=U#2 zF3erwhzoo>Dxb1~=?15-Ol?Ek)`3M?+RL!{6o6m!B0ut21$e!!0f7u{xt`5FjzZk< z$bwmz>}ME)e)i&Cs_-0?AQwtKrV*d{J3z$Hyhnb1lr9(@w5y8!E>j)1l#vmB+8sXG zMSk9&7QaZiWrqyPKSOz5T^qwZVh?g zcQ4N~sWJtV(svXy`EMSS-?N*pxqi~}OhTOQ?a~Oz=?9%_5}T`5Mp6kMjS(8Z%W0m2 zs^^PfVFq{>tCpq1O09_0IM2M`G2lmthq=+xG$#zCh(kMkm9-Rf{wF!Z3{QyeT#`YD z8z=`FhK6eYY_&X-K$nP#Lxr8Sd2>YAWLI> zynmoPVQrjwV=#9KZ^St7A^){W&tMwwvt>XAy-f2j!Yul(l1Hxef^5sD@u!u27EaS3 zBdlsFtxWK6q)uj9# zwScOo-Ivy(q2rp40gU9d}H0D8QOd183Uibnq4Z9V7 zrYN~kqCu$=^799+yGhyy!${gE9*CY#% z!>$s9m2SsA{4j1O%3DV;b?NAFVcChldbv#bRt1~$MqhkXp{IM5drN^0KSo{;i!b9M zRr-nxSToaj0bloHlHq0a?g3$sG=O8+o4#vsAw)AqZwlRBS{~Z)FnvGGvmC0_&n6PJdy%$CZ%;=7b@Ld@ROI!BlHGGlcGA5%)N9rBp zXx!&(uPP5YZSxtf+dc5tZM-;do~9?=AjF~2uv)zo>O*i<;&TfBzC1G(v#p!05$aisb#M*H-~Sqq z!sr@@`-;#|xM!m%T)j+9;{IN0*H=t?R(D6u;C_j+yIahIzIv?~mcB!iIxt_RVP($@ zM0Q||+If5HEKBefjCPV8qM%eRL*&{PGNoxea;}r}w6EuK(I>Vsgzjg*KAF;z?)enV zUCJK%S)t%HVM4vC?2=)srw||3Eod}r5KAL=g_P1k9Pr4oojS^Can zb8OIl|oI=pZKq%K( zzwn6QTRH5Q_B3c0;m{_a4{VplZt~n=)ZLFCyW{k3xq&gRuy*m%u@jq$+OoSwl2=7OQ; zW%=lWqYN$65Z{ey2`d$pG5+%Y<|&{+i*1L3YboqBZr^;#7At}L49|JeZrkU0S%;i2 zbq#y)(~)=MBW9niZ+!O-E!y#Y;u+e+@Hch0ylI)r$`R^RvRzXlUaWsHJ-D5|su#o0 z>)pI9!y@?!OMRYlt1SY5S{P*Dqm$y04?j)#>LhrsPs-Ic^&a=p{4~{LbfCdh{`yA!EJuQCOaN8Ds*!5=_)AV`V9_5}WbEu0lZN^EcDW0=_#_)RguiUb3 z(c*~r4WX%y8`6A{Co_YOy`Wl&iO%4kE{M?Wow_L?04wv zE&8}Sf3DK5Rr+w|Xq)J%eUj0lryi?pPdwtERknF?xwoJ_56<|!o_Y@)?cZG_&6|S3 zquhkA+G+l@jSEpXX`B6$ug&V!bNVNXQ{eFVP(#uWLo%IG2UjLO4NDFpex-xkCpEQ8q_lrC$9U@KTgEYN$p$-i` z%(#@NCB8J@B* zVZq&zHf8ZK%z7`9e}q5FJA;Au@5(L1t~Hlgu^1f@`C7xW?(-Y^&5#_<@Jh}IwGVz* zah|nKPz|q#cQ2XbIpJEQnF0CLC0%fdGMaXTm62aprmr%Zgqe5PLiU8UAuZthG12Ay z;!%JRa&Ns_dCJQDw_^0bx+A?B1NjvejO$sB5mx>LHn@l5oG~LMg;*0l-6hQL3k4wv zoI3{O)$s*O4}Gy8G0OWgMzAKs#c`tr*}o2>$QX5|_ajEbXPN=X;e|eZw#{Ro-??2X z4(iumHp6^PT8DH?r(Gs5`o`fbUYmw1j@T#Saa*vyp&~v!%)`iM!mN#sQh%6xKzh0H z)5$#?%?UinX4>n8Vd6mMPDCSr2V}J~5jf{1cx+DLU7{QrS+sKlXqV?IzZ$>M>s-dh4vK2&P@RH>6E`e;Ukrgy(UBE)^IeqfC|R8rwKW`_QuxH{&la|1B7<4U@bezlR9; zO}Ne}o+k18QOM6ga~bu9DL^~DyxigV7IO6r%?-s2k0*!uy!J+}v2Bsh3&ianw zV?AeHDmL458j$hC36qtnze@nDvm8EpWG&!e6ai zEz(;4Q)VJ3A6=Id4u)%kFSz08sL$y)x3Td12x;pa(+hfeT~G?31Uh&FnisTq$BLEm z^0CMn0rEW_lsbk*9iI14zBc^oXtWcPIf~;Pku1LJ6(l~qBRm!My%=|%cl)E|rzpqz z6ybGFn|zESzekz+)5@jMhCJFO{$?4B`15{W7JYVMthp(E)p?1`j?rU@v zCri@?S((l-#+DMG^SzBjgKA5v5(Q#oCY^7yp$HxfX^`eOpFj20b#vE zxi@0jdGANYh+*Ef_B46!Fb_w^6YUZvc0lUvPAUs9id&rX|jWnF{S~=hXXesdI{ zeTKB>n=8N>=bZC@gKS<@IR6GW_JHTXIwz~bt1mT}8eaBn`PY~}rM{!1vI{`=Yw~y_^(z!*;a5CF z*A@mo1t2`*Az+UXXEPW0#w;{+U#~6yMQNu6$)hG76!6eH?{$og2d~!|+_3`%{Sl0l zT&{L=m|$Q}9O{N4W85;AI5C3M6=!zA%UyX;oq--2vXy>_f$Tw>eh20T#?!f;=W$jQ zUAYmGGr}IOp@~(%F+ZOzgBsGAlx*byPd~*zuT-}_qogO^18qjfIoWjc+%DvxU`EE&H4nz zP2CXO?KG8f%=JHGC4DRJ!*N$v08_bZa2M$DBE@l@&z6HS^_)h+O|S5NNk?l?#tg;P zMCNQ`JYAhuChLm}{Hk6gM)jL0fjtbb`w>3$VFp)a1F8sfk~`UkDPR;#FcxT!gVd86 zaE?y2t(^qF)5+&?Nq_31A>!9xJJ~;GGmSnKD&^`eTQ=!MR?5urrJleTzEAi7ncfCQ zV|Wk&cn^o6Vf6Uvf)})FFj8XtvUhmu<+5p(fv4;l@L}zUeGFw?b3hDlE={jx@;z_Z zl^Y?E5wK1r;P{I3U(WNPe?|d52cAhob6+es~-P;0gMo6y-PVL zUMP2shcD^a9-L!c-unwWWbYCY6wHk5Z^N6V$1^kXa?5MSI?J!Z!y_Hs;QhR>2ajc> z3DGsznZ$RDfGj?r*FB$xx?@?*lP2qW_o6PAyUpVh--{PCO24WR9&aLeSOjKK!!FO%jp zuz4T3g`98Zv^#_k`p|xm$EE0Nyku!Wd=9dagS|BTNjI)@95jO8>F_~fBsvu%K2~Rj zwu-32J?GbZ*bEtuTv=Ei3D5D7QW8WIxYhiE{ zqHK81V)%z^qYsdEbC`v0PD9bJ+Y14&5QwQ6zfFVysq8X9yUlu>A$7i+%e;`2BYf&U zma8#)>+LsWSbKMmHgQURJiP;djZeVV$RRG^z*y;2tCdF>C%X>zz&nWeyjL0g!MnHN z>pF(VHF!7X8}BLj%x4tmCSLldGlAZsNM%25RF{UfN9g;sjp4J_rL3ZgD>XuF7?kb) zyn<fZlPc-8>N}-o-?oa-RF7RdH&QagR&~Jx ztGl$C90e^pUmBPN&Y4#NJFHs(&)OoJSB~?FSMgVWzc?Ldm5VlUG^=YlC=+ob6#4{t zK1u@y_!1*yUmV136E{c&g3QNg=5_)T(idRrFlaND14iwp@iF}JelaKz4G^XkI>izN z<-r#;tE`RE3y=$+UEU8O51B@#$jE$1I}dnnA(XG`DYH)_$m;ImaGHlaO1&(_eBY;c zY2@NfzGro7nR=TJZ^Bc2OZ(8eJuhv{2Ssv6gAirxcdo9{?@I?E^YASiuSW@aQ00`~ zxn%^l<+kH8oq;@h%wW&yl6q?B27Pc;*&|%Vc`z-XAp6*s%cANpQ}0PykI)xpe9I+; zjnC>iWa<(9A;`@b{AxetT6}w_~E;i)*D^4y6f8?*W9yRfAP=5 z!6I0PT#LYM{9)~fdP4yJY7zLi9p=SwIN12Owz=_9?N4949RA`o_1UP^e#D}}zm7P> z{q0&!W8;hGhuPm=-Kf3%_@i3u+keQHqOVlGKzRI!JimzW(EMv*zWq_{HsJ@R|4yye z1jpC^l(z@X-h5rH{5AM~227v$R_&wO7SGQjp3D2ip#VJbIl_H&<7(}5+P?nrRd@}a z;Jra9hX|g3N84s7u^Iy60d4#6d6tcN!kW;&P5H-XV84Jz4&@_+{WXNu_Z9l4lYfM{ zyuP6TeW^oVy9aF+l7BI!@X&c5-TM>nKcAJJwhP;lf&FZa6EaX9zeJJuXvd$DcEJ1R zwEF{|pUuJ(^Ir5G@_k*o#h~S{7D zf8SQdO9Ny=13HI(kBr}Cslv}OK!P{QcDBENXQMWZdSDja&Ml5|IUUhiB*Pqb7i;$s zX=WZ_tIKy0obMWp4efQBdP&=|^w7PT;`Uuwr-Rb)nAXlmoG$usG5T$jCcJAw$MAR; z9(*oxy}T|s1!(VDv51D*H_PH^Z_k3L7t{Fe6bJqFNRLWc{AF190N_G0avH6qy&ub* z)&|mEnMog=+XlddL+z&JwQRWUKdoHTaGjNWmqszqyj;ile3`uEdw%VR^KHD_r>V2+ zXzFFV6AS&; zTD9_XT)ux3EptZx+dhjY79K_R0Qdg?TC`we{JVU&&R(afBO{4A7Va@TTDy8gVw~@e zM!vmKyU8eam*@R7U#(qmUH|qU)IM?4zX$-4w^$_KdtgK=1wv zderr_Q?Jj`K8jA*P?obG_(P`2svmt^!;Mz?BRpu&tgF*9cU>6GCu;(FiS zrCqFZkv_D?Biy5RV|;qYl0CM@Be)!2h12>bI<4s(Ik6U?7xOSZbIjL>s+P@Di;EKx z8^j%J@3b73&liUR3K|!t#Ws#5qpicJC!G_P@0h}Ki?7?bGv686xZ`F&e{NJ>g(;q6 zycF@iZ+AzKQO2F7?)E(lzCGmQlPZT-9idpRu#nKTJj>vvooe|Sl^}PQNt?pj-tdA4 z+O^W~MV_h4W2T7j6?v|hR?h`>yhmLdtV60qxkCCKXt6Ck@%Q5n9KAs(xnX=y@u{a+ zQ_?M6k23PUdtl|0vc8bwd7GbYGy1EGh}{{}mHrI;+YBc9oQUkP63Xt;ZdRT#PI_gu zJPi$KpR>7e;k03t=W#)!xme+K7BEg*NEBgUYB|$m<@Cl4qX&1~j`@Mh}d=i3Lf**m-F`x3TRP)6lki9wG<7hWvuj zf-syWST$T==+eb!McnWEyKQ>3UfDsh=y6a8K4gtX@4V<@A7vr(9)pPcG0(ME2&pOx z4#AWvxFGleN_iwVU^G$#Z-_&j^ywz`nUDt&|NC}_ZYtdImeZ5gU%J{>4lu%VGJsna zCo-VT$oJTexn=Rp8t}}*wMhAeNsXLn%!RZ$9n2$!FOc8V#lheVhFNOR%)<9J#c6yY z+rLD2?5F)S>Q?&s00VD}{#r-3^pQc0YQ9iCt*6Ec@59sTVvL~GUqLxm!_l%o#AWXk zi;Jkf{`S?{<7p%ESPET&y3a^6Fii}Pcc%@A)79I;jnpZpRnk(15JLx z@0Yk%ohHe`JG7BL(CSw()hCP+u0z+)2s`HT1YVcyza?($Viyl>cb%!V4|yIh3X{&b zZVwa&k^aUr_3|qgd40~J8Zl zJQLyo<^S(-2_K|WU1jN46{ZWCd=K$f`q_c-!yp;x%9bZ$KDhx>O$`u@QFbEex}BJQ zqs@moFJ4Z~KtNpHzd^9O0K6aRd6K(R1$c^oA#X_I+SS^h4POpVWU%6{ zIGC(lkpFY&`-uBW7w^V0yotNU6?OU?o$wMPqvn(hwETg~DB#I|L70PwX0=-R5pw7= zoU_&jfeMsB41pX!@8QJ2y@t)P~0E}$l099frzPXOgFDp+uZMKNXZ zh6Q}dLdj`x?`pW#taNf8{GxSKNd)7iB!O**W!ox7>BS(fUJN&kGVG+`w6E=U3|1I| z7hbfS;(Q;T8HIY@#&dbPSl^t_d&TfK`EDEQ=}gO@5k)lOfB$$*-|Y%csVRfv0<3dhL8e`T%miL`Y)6(fMp zSU6f^F%e`w?s3p#A#IC`NUg8%dYIx?+(-kx79W@u9^;$N1* zM*J)k`J?^G`V+jJKLzg> zv(nCrqb#4FR-P)C>E}N<=@xxt$bj^}r7TlD5a!`8)bKCQYMUq&&Z&KHI0EZHn`vJ!{0dfdHESS+!cpDBp*8WPc1#eF#rILvMG{ z=|BI@$F&a$`wVZ0-Y9=J`27X^_u*+|IyhHz=>egzE-V_BVZ@4ZvD<+7L0Nnnrp1L| z9+oW_O5tFrV`~}G_;>wTZwNGRL(?qQRfb|sh$q(`!AMmX1?F@g!#LVtPP(6_i|NA% zg9S-N+B4EhQF=v@(aAACwl`KG;s0lI;W-b1!8qa zjrQ>?y*-{;>B|%Pgm!pV;JL8Y3kcU}woXcml^7u!7*u5DNvSdwm2Q?PvSQ&E?F_kL z(@zOg#PzPfBgDdKm2~X=GCIg?c&HjM(N*U5uICIlFl?G3f&lR_GwC`OX0{)T;I`6* z#?n^&dAoKZt*5~z@ER%Y2*0Yk2H2`sZWqgDed9NQiO+%;6HIvzG~)D21o6$3 z&P8zH*hcvH$}4sRtX1}i-(-Gv-*$AdXq68i78Ozv$L0IQrhsis-)hr8hX~{^@iHBH z;;f~{;Plw>YqWENR|jYJr!DLk4}H}Zr`VK=IBUjsy)p)pd_0j59AwGty_VWVMzRpAgr z*KWOR3vaQa`6zt6U9=egzP!s^xe!w+2CFtQmox~Yfb~j^5!WX1nPCXFt2F*i9-kI1 zT;ruJ(*qr!<2B7o61*?3Cb#tFhK!!CET)flaJOOTm2UNd2lv=M_T;RLkkCmv&Kyao z;_pMtm(*uiy~2p$2(JKig^u^j>Kp4F?=)8p!{X^8f;iCjsPbjVi^ZxqsXA%f+Fxi( zx6vtFF0Z$o0`@V#ZK8o`RqU@Qg#m+tEv6c(^W>9b8g zn~;gq;4fl$E=%^VBwLs*r?O2RQ+7sOZWx1}I);k%_0t_;0GiW5r^6uB5k0bMqa@&6 z_RoSZlEwuonktflc-uT+;%I5i?0ahyKtvnL>KV}TucSp!D84d@6sZtVVk__({Km6 zGi?GL_ol(ba9|z)Kjw4mApOhmTQA#Fn3z7jhkP&lK}wQ$?peNo2il8PjDFj33a^Zx zrr`kp-ZJph@XQJi^*94wU8dZ?miD7rz>`z+9E zy3plHweoDy#cdLSInd8$eLG-QS>Dw+7i_s@3cA*@WM44azE`&3QTn-{jrbn%Jr-TL z&3EA9QojMjXybEe)TC{%19$B^e^9Ib)Bnvk8~82|3llx@@gSuk>D=b~SLwnwcp_sv z;-3>Y0V|)d*z3D2kp1v9TTgQy_z!p>O6!=G?UIAHh%GXW{T|-rW#Tnih5pr>r7-e*=&IEXA|x zXSULAzh0~SjG}~v?5n~*t!`!b5p6$a@&3|shdjQ9mM%_xQik_!3$xwvX53*~=2t8_ z{aKJpc$0X3W?j(7n{3PPb9dXeZKm$d21=6^%%(MFd%Tchu>y(wBF?5ELpHj zzO!KI?{9o@r*h2o4)jfFvhZa)K)Z$3G%k$v4Fgi8T9n;-IU-H0D@D6O+!N)uC#S~6 z#m23g4)FKsuV5vzWt36b7S_^lw35V1c|CjoM|{n2_bOj$9scv=Xid2M8jt);2cEyc zO7km^e+0hq0Y~D)5_22Yk5N7f@|9ZD=KU^QZr4RI_0qc7`3V0Z4gMkCrk_o-UR7+s zZ84AfB;9JAkH~+C6?~v&jD>uwy3YEDSCvm_r#jyg_#ydyjbPiuYw`=dCgyKGoPVV^ zTyJx`z7+~AgYUQsmKyF!wWiRU7r*1!H)b(NN1qvPd zb>%a^xgakyQvFXDAb&<3GV{P|v;*Be=xHuro4!)5{6`GD0d4VpetH%g^tZ~g^jx-n zm+EPT(hG^Q__2q~(O>;N!Atio4wG~J(kEe^iC@))7pKXB6yGYI z*D%ln7ukH;LY_(Yi&!{^=g;?Q3g{@U(5d>0`e z(gwX72K^k67-`M13!5y${jG8&$nTHw?B?=Y7(F7$st4%e8qbFj&q?dV%*bjkw>`-? zFn)^>o$h>(oUT;YDm_NWLzLgf5;+aE$`sl~e5|nUVYT010@r&7ihI5nEnAHW-Wx3B z>f1)sh>^El6Zf2O`_teI2e+SfwjKIKIPmnZd{EhR9R-GD2cfqCA2^@*VC_|9KlPkg z9=##pIEJT)*LQG-EsF5OOLhn}%V16#mV17-LVC8%V&v-WIq`+J<1Rw$DP?{ZjSPmO zdm2t6r4D-t!+lP?&3w0RD2Gj82foj{@R)QkLNr9ez5!^RG5zKas3vo@dI@jEeCOf1 zjK8=Pa4~syg2j-wJzlqKY0b*|YZ`yn&rJDDlxJ3c@OPWO(w+rl-0Stw$F5V|na0Wl z9(I?Zn)c{(!6P{lSMrkg%^l7bxm6PVRtG7|ksXcfFnbs)qBr~1dcN><6j+4@b$QBH z@1%Q4x|h7x`7I=~fGfRLW`u~{!f|W)oL-K?U$fOL4O`?n?=<~IU@u|5p@8iG&vapw z4oc}N%<@E+ng&UPO5L$2vM1=WY}(epm_|lKc{VX>I?NwW?ewnhXYTh7jGZNEYZy2! z($`S_7DANF={C*lY zYnsS(7(gxn*ASW7PAR_2=Zi@JcyUNOj@{#Tg~jW4ut;5isbi2|gLku8 z1qywNKD*BO7Qppq!N#}`kUItua- zcko{)Y$Ruq*$kN6c+iP$q7J~Zu*LfzrakF>rAElKLi~rXTc4iHMW;i0>;1ctCDxuDgMvfp`)!mm~VG71S>q{BgGc#$3g`v8#r zC;%eNw7YPBQm;RRj<$b$8r-`c4$btO?I19pL6SjPeRb!T8NFq&Zz4>OBd+mH^6oF2 zf7;)dO?wvb^mP^218|S|yqJ$|rqU;TSd1&aD=Qep?Bi`+m_DR&fb=E&ApScH6x#IB zUHayJT=!r;l*0knj_bnk$SmYBDVFbTcxN!#DV7tS8#0j0Vz^(KYpF{ zV^9EVsN<7uo-bl-zwgyNZF&4~Ca?NcG_E@{tli%_fLxBqNJ0)7{||Oi@n$uY1wQS z+9G%zf}x&9mObM|#lUPUONj22ffU2^yb{)q;n25DzI7CBgR(u!y#n_4=P2W6#NUsw z@54Rs1MRe~`M|H0hOP4XT#OJ49Nae}3wNgC(Jjs5yxuA+d5P;d1?Y@*n5%m{=9>`L zd6t3Yod?7J{<7Q^G+DInGbc{tHH?o&Jizh_}_gekj=SAkSz+ctur zSq8JJuw3bHV3c+7h76D49nF0n3pPOGtNQyeYRJj}sI~_9e)US_x$*FKBb|1ko=(j) z;(W6P8%lK>kI_xxF~T}{LOMP#bD1w|Ltf5HWBX9&M@P&7W9(R*Tc(|t?oG!_Ck89h zsE0z^x8N!xZei3K=**g%b=nT&uZ@D)_FMxDz;L(~3Z@TVJ)~{g$fmA546gQ@u2)(9 z@Xr1;#a#v;!!XP)TstBMx*GPh#Z%g%i>KibS>)904f=t{(TDb0RH1x2_iH~-snK?4*1$HnK<}&h3 zDPU(+IJ1mo=E;T%cHFCuFxz=Yo+y_J+R=47g`xq1Q0xuzrSi;#!s}IvNKpKb<9u_D zZ;#RWE#n>OS3Hq$&O+gcE4_oO#yd9T^o#b}!8QGW{BDxRoxJY#=_xKoOsE^}<+>Ou zc->OTPbx4C5#MREO^sily{KPL&zsxI1o=twmcoSqT*ZNgGlLBS+}u~uKza*Xh1bj@xe z@LiyISXJp9F%MSwU{5)Qw=)!>=EBL_w8>Z@Mp|H*9!y)L8eypQ2FmnU8%AnqfE15Q zwtZ2;8F@}MGF7~^K?j9$9mSDFd}no+C&68%UXGHQ7$h0*<4Yc8)HW=R$^socWUM-S z^ekRY0q|tOv-FyeI3AApUO@`2_Yt_6a0*H4tsvHIy#pPZyx+1gMAyRTeywsFeDzR3 zkEBkfAVOIF2kbTi{vZuYpB;_j0cmUSn4fWLj7Bj$C;DWX=1n|1XsKdQguL}gxlV}D zY*avaiNh^tT^cygPlK~k5R&%i%hKjGSo1lO58!l&*QY)g-_ zsf=RAi|#HdraRB~yzfoT65hY7hl)B6(HA}2*M2~s*(JOR9WoOW?3%8J^rr{(rF%t$ z_FekYp7?|<#$Ud_Sqhx15n@#xk-$iUoVhdrdchiIw1{Q=5GKjaizJab5oBEys&2qB zgQ_s>$OyEfX@dT|%6S&~AOJel(GK21Vf7KtTMBGOmk*2i+3|Cwwn^M`gun(g>lfXc zrVB!1G(9smQ1Y-{+Si>egChPsT^)MwQHFgKLjOGZ!2Hb*T6l_J=6iZ6yw=t#kKl!C zWA`ya4KKz%(BBQLsquoF?!1Lb>HI!>ag3#^f4^G6JOWsljF~fGmJcH=I{GOxHMYj z8Ai^bzLt@44Wkif85sq4p-YR$e*WIUn0k)K<4%w(i4j8bvh`-6&*RbS)6W|bkGP7L z`D3Wm@$L;EQ%F~YIm>qq5scHO(@HE>y+7?kZt%-?b;Q!yS(fLlapyE{OLt_>ZTjC$ z`p}R8RF8hsPxIHi0+<7a;LWrj+y2$j*I*Bj@4>iF(_B7Z3<{jP5n{Dru8dn7rm4YD zn=qIk&*>6&ZWjvY0m`n5f+=Or+)D3LMwO$+$Ws*b{<#(K95T`nv3>~p2GV?k4!#i- z-e_0K^}GlQ+ZVXD4=^CRhC#bF21wuM^wOw9DcsQA9m7KyyIu5rIpUAu>0KBVG)h2a zQbD;-9l@vRR{ab=)XH$muaL=eKUx?R8UzPdaQ$O|^vmEU!q{1Z0K97$Lh(ji^cuV# z`I#Y%;5?o6Kz#YLEAnrVq^3}1nC_NB4U$Ye$<^gNmOaX*@i11381^F%%i%HjkW_xA z%^#-iVHnE19dV13=Qn1QkiSNep1Mvfll6x_E#A{G*W6SruQc!nO@^FvFvI{H#cAp8Mu!Pj*9u^aChVd6q`Hs`gvFp^z!`zQGm93a~BL^2kxJD z2@oJ1gz!RJQ*$P6;x$;<6?)$FIZb|f{kjo{LYLDD(z-bQhTdh`3g9M=)uGWR@pgbK`*JSQuWpbQ>#5ctCp%sB6vh zaTd9NA2QGwuc3gnfj7yoO53!-QNvrZ#o==M;v+sxpYeFd_w&A@F~T&&CdN=5-rA%e zh0n96#^rgJ>muZ5TT+hxMJUT<8Rk>qjT#~Ii?@0R6+m$3m5k(P<)$kXq4rK1B5A#I zWt#>adq(IzfsXC9S79oxcC=o(#;9W-B~}Z@2-7vdC=m6SC=iZaLD@04%ZT5P&t(yS zG@Cqkxsq zInVdw`+3}1&*842efX$Be*KuI9!hzyB&-v|FkTKLeDSWEK88U;r)Q4wr?kc3c#!fY zdA9I`wqsiR31L(7iEw9qcN&5`{PoT{uS@)w6gUeCAp72*OJPfeUnQfmznJSdwg z(37NpSJEheopO2o0SEu!?Lfg^$D^T9(%^mHIFzUBd&&g7hRTB@(xK>_3d>Tupr|*? z(xotG_Us`&)$%Es6XjX0Y(tlz9ICkU-6_OqbqD1Z6uL$PcsI$@uNmLMkaL@?U(`K7 z;kBmGK|?0MVJt-Y&2nu*>I53S3fPc?!HYo)Cow3U0g*aCuUVQYf4dkWWFUu%9X9PMXKtk`5z6 z1?z92D|kOxV2P4&>utZ7$TmU|UMq&5*E=Vr>IrGADnD>-u{NP)y%?SAzW-+NDTWwI z()zk(G{9h3xGnkK6xujFu!G`jk*2TFqLKu);d_L6#=^~6JPF-*@w7}#AB43aRg|^f zkHf56tb1PeS~2{r-yPv&tZuuu;Zr;x)-%>k`ViMn%YX;13muw-bz(T{Jcbp#bnzXd z!xMVP7e@^?UDXTe80S3Qs9yTC!@f7VT2$@ zqHwu;5;B=S3MKD&RGtLE&yJdt;9F&yP&YgfD7-Ky>;hBpzo2{vjBtn3R?x4q4D)bN z#-M<8lcOld0zRg*4wTm;l5e66hcW!T?=0#YU?}XaB46u-VK9_m7)du6scUdNaq%hB zdJSmNq^@^R{Joq$k1#;S$I_b~1?hahU-Z49k%7|N7bY%<)u?lNrHV52+=W@?4tb8Y z2WJs3Uq9k;__uPmevBI5HH^rAtk}m9r+9!K+tl6lLR5*1?Uwu>NuRQB^spwQ1AnxD zY4Z!0o(Vl9aj`gbc6y{{B%Zm$5frdJgZ5Z38Kw~K}x`8LyO z7-99OG8nnfl+B*+m)9i)E-7$w3cMFa2!bSxz7Do}IT*Vi_@pRHXN#@{HwFiFzOr z8t6bpL-}6nR;SFncn2OvxbwQ(jw}wXuOdG>)}}_6xHJ%{W9Af#?;Zk&+PzM8P9cP~ z9VpeNE_Lo|T*PS?*Uw-?jn4zI47L@# zwQV}-7|Io=WWI5CjKZfBIvDQxdK1>5)Ohb^hu`#Nj3sw$b<^bJ=X6atqk^_dqb{E> zDR4=F6HwrtH$sBIW}3Ln#hubiVTMrLV=com?}oyPQR!HqDfB+QR_~)Q_g&0~u%3Eo zRGP;spB0cOwgVLx!umG#Jczppa-lpRKYu;*wSKtcw{xS!b3eLgX^@cLX!?OepipAB zEJM6(6GpNP)`dKGT}TW^snno<*R+(g?b?zUcaHaCyDv_fH%3BcT9qk=N7rXB+9wMS z`CpaAs2VJ^r`HpvT8 z-_Phb-2%E(z49TfZQ8z*^JoV}-lYFv1KX2e>ZJgFLN+ zfr%*?4H`Wc6tHF?g@cdkK2N(MF8a7U*@K z(gA?R$O}Cn(HNmWdZOzM%S(Ru@Jh5b0(fqlzj!cQE2j6E-)KsPZQ(IYxb%XaFVgq) z+4S+9e40fg*s#=4(J(R})|%Ami(7QPXIMrp!a6Cgi1YIPZc@O0dX@vaBGu$M!Za{y z@MGO)W9jAT|c{+mM51CSR0rgFO7xG%akfmBtp%h*;jHAl2(3^!?p`ze( zbi?`tw+H%BrEQFuyJhKU+^4kpu!>?paQ4e!&MJ(2yNp&9f^7w!7kPEfkFYudaT@_$ zqaH61-j2>DXh3;;fclFD$!+TT5~l6vxQtrr3Puno8$$Dk(DHsv9Kx%W2I1XY!NjQX z-A`;|KxHw&GGLhWX^Zi^e~dfJd!TDIeD$_{ntZC(1p}Drg)M|a7S}02020W`(^1C3d2*TcSTru!h_LD53?dJOr6Q^v{SYa?h^pXpSEvI z%A>p~F9#1;G>YM&HbGqsl&2WYp6j#Eed6p8+e_oX^Z_5h`BmpWh%fQJo-ag=?`8ME zugR_%VFGP1lGAb53~@J_kL!|$GKl%jX5l?aoC=;g zUZsvxr!8!ArWx&9ftPX~*4r4SkJv4<$C{Fdv7FLKAPs_5B zx8cLsuJ&R3uW8`1is7~yMuZ-?cC4TIledP(n70Ey&Sk-%yY3F22%Gc#cFZ$|U*6w+ z3cyEgc<(B0fA2K4&3RCH>h}FU^848$UdeGfJb@bQ4B|E^j|-~<|DUEzXPNfQjSxGf z6^I@GEGrXn(-^^}jIg~E1r-8k^dYP&ZYt)-9qlQ!Vwz>|3NVCK|19cd`Sa0Kt-^>b zTDxf(Rc!opzp2#12%7s7gz;3vA<*SjU~G3?bm!H7o6 zA-orPJ)+~>9lcHdGs@_q99t3pWbEqSq9VIUio`NuY&P+VY{9>MzXn@obQYDjvV!Mxx4-bfAT2V#5_6nnRbZmbxmQ?1nWwuCO#k|YjqryL0$FP1K>mJ z@}%&Qhf+Sp_-I%8ZU_cU=9(3R>zH4nK_L$Lg}yPg{RmHukfz3-eO3Vto@?ao!FyvE zo*$5>22K{sqfuJieS|@`hwwavXS-uK4~u(Uxdok{ssv*A<^BDkfPCw8=1KKSK2T^> z`QrS%fm=$|nC?ox&MPU$SO=!?7wMUS+Sy!@2)KcJbk^&1?k$AE{jBigVd#l<|&f5Vn2jHdNqd|2XMln}yT5 z1;qnU(d&^5){Lm0$^c=#B`)XTy%#U&)r(=2YdgRnK}jzT-C~4(kaxCVd>BkS?=osE zb@v-zyi|m**MnkhQ1qH@R)nD~&(+0k=f`{SU|M;KVnq+o^e6v*s~#uoLAfQ$rk0!d zX=6GK5W~tY4nPZW#pyp`O%EMk;_=90S`42SXRF+e@7~GRH8n2U?ZBv7dgpTzE zqDMzoj0WPz;up<(RdAI3Y%V%#hYsC~jeyddaIv0EuEFK%_clC~tR0DcCASXKJXNZW z#G(*0PPa7#aY5w)`?fN4DP(bsK?n{*HtQ``Qfwz#sV0!6*yUV#jw;*=GofYxMcfBLC;1tTP6G0j6LASdxophrE-DU(C zltc_K-eXzZIg+lmv0g{NXWfK;IV5>BT+{TXRZ*d2=62FF-ASKAel9#7P3dJP#dF^2 zD0dw)*3FlL%siEKvrvY9(SR((&wN!;)2HshM#GtaNn}vw)vz$RhcR)j%+L@V`QUma zJuml*d}_UDe~sL>d23wo+{wM3VX97J#VI9F4e9&ODd$boz%woJBYa)p8~7(0A<;0A zf3flpqxUf6m+-XjxjfOsnu(7fd9ux!JY77NuFraa!dZ9}D~`+S-KGFKrlY|>OKt_; zD#+9#Rphnx{P05JhUkD}>+AxaIa5K(TGxr7n=?N8c&=;higk+biv6>^YAJFJ5IZtq zx6<%cJljZ7NF>iw4G{Cxigbh)m0lDst0>P&a5(j%&?N1kEPZYqg*Xic7<@~(X+qsN z>NMom_ot9X_|~TxBe_L=3@$MDt4c$|L4yVc7GJnR+-M{@)c}#kxZpP(wWd~k#6c&m z=_aSF0~G~0kB!W&2XPhRYI&Vv@-w-c2lTpsR{VM(*jE>z+ zQR{tRMR_+W{xt41&*H^8?5N0T^zaRiMLZe^-k;bvas%3(F)j1+vTXFxHhE^`QRhB% z0dLG_1U32xG)&>ppB)gD(lv#D6VJK)-U)d-W#@Gi>Q(d6y769mq`vX1xB{IyOtHec zq$=kxsdT~X+MgTrzq)x)j?SzBmoOLc(lCWj4yng3LS^yPg- zZ$5Sj%%OBI<0;_Am;42Qo3};^yz-p*XR*!8;-dm$&D4GPwndsggP(4gqO4Rl z#FZN$u7&DR-bV`ed{mtQ8~99vooAw6uJ73}@RkShwaV(6m!sjJfHF9ZzF!7+5yR|1l-I4`6?pFmdAjewkvi9$nx=mo zz>nA9yNR_%^Xd|4ry)-tm^sM9XeZz6^sl?p*)bRI1=_ z72`|a(H!Yzxl~Mq`J1@ta4S1jeFE{67ikAA@1mSFL~i*$1@w&uN4mo=F08hk$J%CE z0rNUpuU>@7M^1ImH<8u(Wq1tl#`tCK@JtVd?}?%f+I3<&FweV9`GaQ!W91tBeLoMc z#CZ8rp3opR3?9*=5eyLw4ys*w4&R0KAHdZ#tjVuVIi2bwnkzY@1r!>zL+W)CqpE4N zb*A4bOZvzajggl;TQ+&xgWNXZzlY?#DSUe6Fgt{8@N>7%zIg}(u9o+Uc1bU2=R)Dm zw6aNS;{5gaRcr_P!Xsp@E9FmhmJalPfU&G$d(S>E{%KcUjxKcWudy?Xw3`fo?oETg zNa4zG%3Y_98X|4@a7RNrDWmnO^RAKQAmR|d{E``i!*nVNkhm_yDH?foALFK(;F);* z^m`)%4_J-6`=qa9@Hu#XNI%=20G{(=THBqDR0H(p9Po)~y@ncDpy-qLa3YeI>ZgDF z$A9vl|M4IHp65|VEkewB2eE50oYJ^e1U0TKQ#xgvMKPz|Swe>h`|@oFM_N?$83LtS zEXTZe(}LsfJh(JogXbjEI4O?!EVCfAMmrql%+o_t=chMmtZUG4{Jofnt9Vyv7&dR} zCAK35P!F3R2vGAP=?&WOi8zXMLJ)Ki1TEuCub@U-HR*KEW_6AT9}KRw3d4iryHLy< z+w0gO;XI#nTcB!Ly;OM2r|#q)hGQLR1odYArBxWwj_4lRSp*o%9nk$)H(Fq6sG#G{?)(wpZ?(={^5Tokio;rE;3naod=E3pg=BGYo9E~V3Cgv5IXs2 z)H1`OpOw$2xcG`6S(^n3SUNLK)mT`4XYqgSUn;okBadk&FxTzaTysB*Mh}c^o2yDK7KxBSAj3 zbCK6=6u@DXt+^CsfWon}?UWgT=2=`*WWH&+d_S)X8n#htJGrMJJFk3a2}V_CF>NV|;{<vPrlLkfR6_nZT$9gPe;V3$II>K_rbjdY=gEAc_ev{`pam0WCjm+=@VIu zFWxC?__hr4Znuobi}2_9u5rWwpcec1N%9Udz$qQq6D1z3X}F{Zbbre4iL{>vw@5ex z!KYzlJ~A{1w0({CzFjsTUIgD+!AK*P3WS64Vjjp6kF2-`?N{c_NsJG7Piiy=SuV}x z>&VN}ZBZIo_Go~}=gMUJP^v>>oyzX1!9#z3gp9gdgsWcv@2}rD`rznS;QzW9IqjWF zO{`wF@flU@Ei+0ij;g2SRTfTVCJm4&-@+(MTNdVsfbzFuqm{v=VJdVOsMM-U;pRPS zywP!I<{M~@qk&P@jadds5ZHJQaFK?Cou=h2zF-JoID`(2Y0LXYQ6L1kN_fDk@969lb+veAv+Ps@g4aNA`UuSlafXBg6Av=kMT!V`LQ7j3UJztcV|JWy)8 zD5^WlO#7WS-(q^{tza>H*^y`w*LlA~!?qrasI;sLJlM1x+>d!k18XBE$uRf8aU zgHD6fHiFi!mzlX!$fZGY7G^b7Oiu_)B3HeMTnwO{fj}R2%Y)afQ4`2FP9M23+_A#3D4Je75IyE?)vp z^FqR$eM&V3!l)U+%RWZ}~}r{zJ}GXzkb_`x)oG#o*jW zEX3_1!=&-?S;pbnU%$>3n4rY-0aJB>sR$$UP@fITsb?cIJYG(5p!5%&pZWWL9DQE^ zg>bAb5VSj_-#1;bW~-HM#8JGPr|_u(qE()cMqe=U4AVQsbou)cMf4QUV`VU$Hg>^b z&F7e2L#wj3czeZktGJ_MVkSHQ06+jqL_t)1Iw+I?cR+~0K3`FOOj~qOD)(1`cTpVD z0^W0dLK9_q;k_TldRhMJ@0jvq>ml;uxr*b;@4^xEZDCa`@;J(582LByHhk^65Dk`K zsMr?Z(-;eD!88u5)yh7+-vCvO_s#04U)Kn8rUlxsU+@u6nUN1nGg^1Ls}wY6xP~>`Bw3^LeiO?cdvDZg~h^eM@Q@M%@Ws9~6-J=1Lx6w|800g;)M?Zy~@(gcM4i+!cX|{{r5EN0D zHg5vb5zb3@`r4~XgU5mI=Y6SAsOv2{SsNkv9NM;v-kMdHDW|PdFYf%vd&jX_n@OZ+M{02;Jdcvkbe<=PTz&EJHvxr!{vR# zMc4emOyem3Bl&w%=?z+hM5BX@Yzi0>Pg9fnb%N-=yKQW)s^&_naMx4@5E zrqYi)V@wk-+CoFfMfV#aYy{Vi@nv^E_l~i@iL!iA7XPNga5u*^yIw+vk4Q5d7U<-9bZnsVn8BGU0zPiU!8A2s{(tt~CPyM4eE$@rJ}nH9P%>pDKNyXLuqqD)O%?>j&rxv&@KafBxM4`FqcwKmUo| zI5^{|fTNvRL73S4x z)Go|(ElGkktU$Mm_)xf=VwjAL_1rStXPK!8<2zYv7&@KOv|}KzE<0)-mBE&U*~w7G zj&ahHysAYw!x4gzm(RucvwEj2DS6kSfxM|P(m)Y5pxaIsckH5px<8erLUB|N|3k0q zbd2YQ4%1W;+B`wtckn>yJ#|}rEvCaLNb$<0ynD?2WkaHQnB%5zOcozOWUcP@Bsz*C##y`iEe zvuhX#ZQ?e7ZOhMjUZWj?J3TA6Jo*fntvn22Lzijth6?aq>aVx(`Vin5zEH$)AQs=z z(cr3->Gh)&&yhB5(bEv2Ej@^92O7JU>h84oC{pN{(e?N3s7*&3xt{1r9*2XM&^NrU z+i_WhNgZV+LCot8Jr8*skK2%UXbdbEIr1D3GwnIU{N~ z^$kY9IWFBv#c2THJ=i@i{;V!7>emogMvrjMZ_ApL4|q~w9?2{!W!!Btqn-lvDeFEQ zMfML$5^m_yz=%dbK0;+HUU4G$HJGWDkB`qPEsU5R`l|+$mcm5XvO9vJRXs3T#(6`i z&l)&_a#_ZBwKF*nmvo{Wb!mn0HBf>YBq?;?fj*sC+7cA`EqH4vuT`d<+O(rv>^kS6 zzO$A=C2WV1(P=2TG&6t^Zn&c;adTm;@Vyqi7Ax>W9r=)tFT;mj==oH7VvMa3z7DSk zgTnO65ilADH{r)mk*5yEb1&emur4GCdZtF&7V%DJHOMW6##P|9`AFR($`}-^UJLNu zApRCy@4z~$E)623zM>}fQQ&jOnbuAF} z>=L#&ufoBv!6<}wPml{U*eK(HQTb(byGt2A#gOS>B>4eFJ?Go`G`#naw=UCZj^10) z{Ly(a(xJ76XadjOrO#M{#x;$FvgtVMLA^BI)F01z);M;-zsA>YR_EvNZCC=~J9w`F zvj+S#c&mvxG%`GujED6ihQZ4u{b5-(9yAoek&2(7z_)QtN7na^g+ct{9^3^47kUr zZ{lavO}~Vji*-7yFrAIuVOm3`4xWt2RK@a;mqMN9!!=BxZ_6-gjZlYY-}Bc`7~xR9 z?Mcj?PZOUrX1;-Oxf;W~Qxv@+`JnJ@IGw_k7=cdHt)9mB^Khq(mZxr6GzQ_RYbb_? zv}+9|LDRnZsGKl^tM5jxCCI!$2dq6HuEYCVYj_Om=0kp3Zzv+PcbWyodjaCjt2_fQ zuELY+kV&_2I8_q*KIUCs-xXS(<<^G&eK-Si7Ycoqv>VX6g%WpKD@^U7I5*(20Essx zC9hyWKwau9-|-{X-XUvRklhr=0j`>uvB?ex7|rc9uL&5*9uF(CH_6 z23w*A4>T5&u>PYviuTZ~0k5}NuJ9NhvyD>H*DR;THhQ5)hu!g=tGAqlO$$ynu98Os z9`3={SLo2Y89zSggO2_ezjA~DGQ<(`dh8XH01RAV?=ghv@N@oF8XZZn7+LgC2(@CSnepLy6Hg)J5K-(P z>G%ex8y3?Z^_{xZtjIL!6FL_x*^Oynr-5Ol7#08pCAE9F40dQ3B+l<82x2d;nV`|* zsCmtWnkYffIEalMvNkPk)F~^+s5k^V&?270d4TN#He=(o`2~H6Ud$r5S88mBgy}1qkTy5 zhtCX?miV03fdL!&`1mXxFq&HNecV0P6GhSa54rCMiKEP$A(Jxlxl+VQcuM$<7%p6V zKCgFpx{YD+gtBf?#)*mo`fsCj9-^r4pVvCgS}u6J32#1zU$^sV37^Xa?*4_r%xLf` zFY<-IYKTBq(#*IIJoMw*19Z%jBw;(QaCi=p!8LfxLD8-wYWWi5qk?hLWz=ah@r}F? zmpC8@>#xA`6yrwYqcbwmDMp0O0GIe#O<_wwXmp*na_3BCT0+SF0qzfKk6=SRsh{G3Z=%bGWGLc3&Rv~PU+|f2 z6!FkT%>@0PpHgvvgwDSmVd9;-+@Y_yXV0I%jUydlsc((%g~);m3W?7`;6e9zN0sbKRW^ zb_~!@`coO*QJs7~sf~$3tPvJG2q;ZYBi+cuV9C}AYvjXhbjsSzhsEbC?od0zjKMIG z3GF;0eDQ91Xsfgs9^b*=9|_XYpdhvY?Zmiv2Z!q&N-qR&*Lv#>u`GTnU4fuJJG?*i zy)@xD3#8u8SBI79MbA!IQBgciyk0HpxG~e>v@&GpBupB>5BKRLHc?cLiqhj0P2OGP zI~4HG74WR^tMcnu^AlOhs4_1{FQ)Sz`eY0cc&nZd7Y`ya z^wCG;$la`^?YKl@bo=BBp!=*`Z$OAoA;fmZRFe}HAVQ^B>p`%B@4+^A3n1mM%<)o& zMtS5hLh-JEcVZbdRuZP7j#}?n!hnZSQnWH-c)ZhoVcKE=?+n)S-Ycdj$g^WSaei5} z9bsb_O#Lh$<}>}fd*(|UU899gu8~h;xqxqZr+qaD(|mkcNFa+?(=j{SktucS2Cyk-U4*na1Naj z#`96_cb@7uO-YX@FnDDA2G~ zudKnN8VVjjc3*chdh0X76J*MrWS${%pZG8(%zF#E@1P88Ojlfk&&;z*ybEF#rafTN zoMF);>r&nYx}wJt9L~=_n|9Q1x|6un*(m?JCxQDYIPI`#3k~gwhDb8QLSEWuU??7? zT=Px?-_`Os^{S!oRtXD-*I_iN6B>D#;!-uA2;OfO%Vt@Sr+abHYK)in=}+qnus32@fYmF)pfZN#@5tSB zmjwl~j&iJHEj@t{zIR~op^xkk7A`U#QYHxWDuu2hu$kEI6;vx<9TH>UM& zddjiJW2zy;ee9(R5QW~sy06LXBbc)a+OW4gTTz{g6y_eO{KsZ`Mv<9YHF$97knT?^ z20X6k;I@Vc?NK}HPHa+nr;WE>z&5EcD;gOQj(bXh_E<3a%#IbMu$Ar(SBL_JZ#8(&2%Jm) z=Fy4-BE1Qk>Pf4Nk&k7%31REtXz{_Lrx*fNl;17N?ZIcwNyvcP#E5z@32w^xDzvHx zSS$r-(?w~uV_G|96zU!5(TZW-r9o2gcx0XVP9Dx@M}=i8$;AOvKSTg_c+>*!2~Yi0 zz`B&14aS3fEjNQwu{1O88*#@3ve~<&lRTDp)3ugX;ap9;(ByeRXT=H z)-u@h9){B0&={uOJ@jpBQh99yXnTE;mGpG94`~-iJ#TIOV|}TUa(sh2HBfl&YDit6 zjDp^pR6ml2DL#1ZI(j8#7f}}+2MMP&gQo)zE7KY-O$}A@xQEfPOWv1B)88_kR6a%5 zx;^!V?qyxiq*){FfcI&mb<#FT^BGEZC+i41xjJ~5*{U+bK&(bM;?&og7J7qgp9)ehJ=r3J9gDyK~L6=yLle)t{L-J}J;g_H{&67b!2hYeFk1c*9 zFAdtzx8@)+dex!bz!)LAgPz&SfsK8Po{oeKAgmos1ws^9zRr2~QD)_8jI^ggZE@cb3Hs2-zJ$`N>@94n;J_S`6Y!QCQtsM}Y?B4`TY)&&^w>;>JEe%1E9g8m34;e{k$o}L(7b>=Ujd~8sg>D}hgy^*t{k=9#K}fe# z<}uE2*Tn%JHyCI?hYoFY@K(_v7KY;VcPKIdr;l;>>0NNhuQOf9;w|;QeGPbSAb%ZX zuaQR*`htTny>oj~9>+35@|hm>Swcdby9oS4DzzQApce2+sFgyPM6IFNKUE>|c>Pdi zSx16$Xqe7?xIM~#+$LW^xp34p)?Ixv^mGteIU1BVjHpaSqo(ftCe9Ju1`WEE#|B+o z53>`)f)$I44(9B}uz1JwbUDi-232GT6tdgnHU@#74tc~2nzkr&Jt%KZ1EkE3Hm^In zg*nIKMOd7Q8I+qOtug_#XbP%3e88O^v8d-JnQcOw-$qG1p*-9!hi$1K`0;c=*AjvQyU@2J#)MK(kk#!)x278I0VP`pVNP0(Wm=sj`Q> z1fC0N{pOJ}kCDy&zWRatP4A0I(tEAnqQ7-=4R}2rO}!t$Uk0uPoi#?>PWb@1mca5X zVGWK8@4Nc3fW2Jxs;X6gPld z^_?c}jY~5wZW;CO`nhp1ryWPzyX#8BH!aH>9hkyvSIXjwVd_Xai3Z`FVqAQOj~nn@ z2iS*t3DFhzjDyBcxp}UadG*k#TjV{n@nIV+zGmGO#ykdg!}@{iKKZu58!lj!T|ML1 z`L*~mz5VUPYiT0HDF9>)co!lz5ZY_Sd2r)V6k7B(o>PnDGm7QOA|p)H%GwA)8@P;S ztwu0Fu+km5&6;)^cQ|B6^vlIpNc!5;HDZCw&XD~=G!ja7e#zMduaL}P?Jp2Sho&%Da@ckW(zHJPE z9=K~S4i0wVQKx}A7zQgmH$cAuE!*bfs2n5jK6zDWp9X23=>b8}c1Y&0qQOF3)91z4 z?ArQ8+V#13<kl4ebUIeH zna4Xl7Lqw9R(GMR8=xKN$8oqvr1SUSy%&Y4Oub%8M^H$ z<#@#N)YrK%LSkttyw;qC$f2_mP(a~Z0>teAue z4)M@fDx`_7q?l%2cZ9Pg^TH%;7tEpPR>8eTy`xfWn3oI&tZ|*}y~aHlU8ME2Sywji zK%WicPvXit3Ykx(y#eDl#^saI^%gMA0^E?{730JY-d*aE#;~{jPMuQP?k2pcAz~Zq z9SAfWS2vXdg03Fv!uw6yc(*trAD8|t;~1${k>97W4Dv2~?G$9qumg5Vq13jZ!;rk{ z!NXYalMNe@M$l{%BVmuuwQgE3jc@qfMaxa)9vX$bpp(;uE%I8^hzY=YD_E)TGjWYL zcmaP(x$Z9EUBQ6aVj$FzU+KVyK2M>+LegNgBn!c7Qs;eeL_5zzm$K-zDS6!=ia5m= z^q9w=KcOu5Pm5=4V>&gbsXRNylUi43?+$#w#g2-*^Q=C2HEKScC(h&Il3(eQ?9AtK z(cuq{Ef|MTLxg;5%83R!uz_D=nxKO#c#isutykdx!37QVm^c_%LqcvNvmNU(02qGg z^4b~>I@((h#-k-Yxl|Y;YcTDm!UGY~d``yc$|{D-^vpRoA>I{~kl%xF1k=o?o#t7^ z$Eak{SIZ?r6agQ8FvfQLKR^uukoUk9L9q%HH+}aE$?|qZ@rQv9GEpY(Q{n6fNv!I zb12qmZ%6CO$Kff+aY)WE4)4S!Y`Q`b{2s=0p2IXtS&{6xGb4H{>-6Q38g|B^DIL8Y z&?Rj9#TZ$Krhci_flLGCb_K)uuFvG7!RNtgo90Q}mTQf&oiVrIv4H`E>}|MMFY+^T z=G0@2^sS=a5m#0=w+Pq3`wUAle6gA+r(Eaig*3mTT%n9C5~OS?29btudK5fmX}}#1 zoV-E&Rfy|7Ns`KE=qC-#k!@XuZ`Lq9J!O5xta#=PuZ-t)7aqOG@}v2v-(3?zd}C6+ z(iiW=6KJVdVn;rn)PC|X_&peI=01@8!h%=wJC!Zw$jte?B!tr~bY3$p$RpWcDr1(K znNA}Hh2}o)nHz4FyygvS*}-YO(|O~b2A=|@1s-874=y&hN2-+57^i{9Na$&q5ot$J zCXhuzj(NQ8cSqRN!FF5a*PWz9r4P#IGnCN=$MiqIdr(Iq`Hi3!>EDXW&Kv{kh8+`z zsUM?DJ-(fK)u=#~5pCQ~+uQGZAyX?xx;vz~%E+$ad%X03L<1e3tHE0ykkr%|!R_xE zA6Mlmd5APU^3lt<(ohLw1Z@c~e!L`g^!fpC4-6~2Lf#1r z^1zQc_R3(+GAtNW4Disa9r$NEE}k7%ChJ~kCl|B(?H(8H*0QuNa&Kqy-94?kQ#3p1 z&+x8X9ao35h(q7G>#z+iQuEInA@T{d*K@r+sci7?Cj1%}@uDZfd0iOtpGMvsm7e^X z45-^j^?qr{(8f2+GuB~LUdIWCXU^wkrTHMyb(sCC3R^*#rlcgBS@7)~VdTduj7ZDj(K+rY_mQ7fz|_OVr;U7lG(b$FhY-H0XzlEGdNrT2 z0bzPD?MmL5{^H)JfG)))b_}4b*P!FT>rteS!WcRlB7l2VjCcNVi8*A#J26h&=@jnD z2>+JdgW(8I@6cgZQ1W-jmEX=Ii%%omX)61e=REEzRPgv4Tz2+!-Yan@T9EmY=@%13 z14KN^aW;UsZ5#s%r)(N@0Jn(luiap=t6mY~{n#UhP7hB~)eaN-x4^LtecP0wih(gW zGGE<8C(y8L#BZ72Jh>TG*BH^z$-<1T$m1F~Ja+h<+bf&i?ZyI1N1m(8eeYbw!?m(F z`7}O={t() z4odrw8#r%(2up|WNZhq!J$Z(A*d`ddfu0z@s|hFkqQFyvs~QOy4y$@W)CJO?G#jRo zhZBx+*XZ!wOGAWF=XG?(W0Pn$f&n#o$_vz0y37ZW}2k*AQvFAf&QF(P~hW`&|Vr8K>&q= z=|YE*wdWwIqty7~Xp#=%L41GL?y>IKeNgXrt)7$WBX2NozR4gXjOc=4kZrXsru_+C z3U;ovBkg?0Xz-A-6f{+)`5xj)xt$p*ZPO$FE|~UUzB;4GaPlrj#x;x!chcM=soNTR z=Ih+K#s%?p4UyQ<>ejXc#@MLAlNv^$V-~+g3VCb%c!KIPV7JgSd&a#BmvqtapcAbm zbJ|inFS@AznIdY<3*SlNfyY3Ae1#`uH^Rtw@TL7(xWL(>{_5XO zKcxI0xF-GOGX~zPPU*nQSK!eeWte(_GCF$|JY9_U3LZ<>Sh zTUD16Rl&l3 zU>E^@_bA|@)2ss5%aT{UC)vSwKC9T}Gk9#zy9NmcM2lxV0Kuz=VX_eo6VsqKZe!#; zp}fu7k84lT+)l2nObyc494VrI1|5ZI&+4K$*4?eL4#whuY^6}1=jcg2MS)(xxj^^| z#+@D38l&HBI9XL?}C^y1F^aJ-`VI&R`HYKaUYnGt8-&1=b(Yu5CST1T`^W z;X*6AQp8N8V0B;P5o?({l& zJZHr07UHh?VJx|#-Lh^_PDjpzZ-^LwaUG8WC^UCgwWF7#Y_zS%1EX{go@kq!ZN;c^ z4R1*!zRP30Z}`qu+x4GkUz!F~1Nf=oUhA2k()IALWI`UofIgN|5%e!~zo$7Ql!TU=m*R(!I$v+rS z?lws(H3tje2(oY#Tql(#7@aidq>l5X@}Cy3ZG$n_i|`uL@bZ?^hcRs2-8Q7dAM&c{ z-6xHF9PlO@nYs5-_)G_H*5K2->NDUP!m4Y@WAfpLWR$^o^cwQK<(e({?jg^!7*(Pf zx}eFsb>T+5Hfmq=X)1?zi>kx5akL2|D-1)I?rW5CgFtt}v{4eRAT$^jc|Z+Cy$i;x zIQN(P?qZ%BD*im|Nk50Wc)kRlGn7NzVyOIwMS6BTA&zwcDEA%fhY+6VmbH_vv-r`E z)tHYouwI1KVwiW|33rR%P)sflK(G;D{I()VgdBSpF*FKB}h{%+J7V5~ z^BGpNg;=6N4}oQV+ckB8DHb1=;I?H|X`%)e%B|g@-4} zc`w2raF&+o#buvLn;a@*gq`LNo!*@*Flf&5EY?iLQw+O!pPd3)-r2~nA_Jm)@8Ax1 zgt-M@c8VB@>e@CkZ5HRqGca`)7Q>54PxRd~Va?y5Q)^C>QC8N5=@6Vc9drdH)5^l9 zL2>3VmR(miZRkq(3P$2CG|-LTv`!c#!648hz$orI%D%aTmxyGJt_O-}9u)~53G)Bh zZrUy4(=ei3H4N2;apYg6!|i|DB?G4XzK5ML2I*OW2|HOd#iw3Nl~#Pu->H8OzOB=7 zd$`#k%1*+O9{Fv=`Wi+jvO!qew&q!v_$rUx45l?eaGDSO?WvY?`?%RspPJqj*S?4g zoGC$m=jaJ^p87jS$1TUC^iF3~lB0WiCgGoFy!;0~y=|NDTH-k~v*KsEWtVoS(j29- z$724{@M1o;XIwu*xthsh<*{XpaC$YAFW$?&8o9M78txdr!gk;fKZ8)`xykQH7yZM# zbE#ZeII~q&BNY^ir&|_x5jGnIFy?yD`UV}o5fl^!CSv2cMkkk|#5)M# zy5S)#8y!Trv%1>}AyB3K63aw+tAGDL;Ts~XJ3tvX_%%bieMTrrmL{i zFF>D%)_n%Fa|g8yl+!a^#>(v6Gd?0hWxxcMR9Zn0T&NPra+jxU#P6142D)#tNakU;C>W2%yp~S9)#7gx_6G8c}YS?%_!nK z3Xq*-3CO6RUJ$4(78a_S9z6HN<&W~-ak?mTXNGSITS%}4_T+Ha8mqp=w?l~aiC#rJFk`P}xleln}=Z@lm1*P=`t5#GDTiS;Eu&4-`W zvvL?b7p?_KD);!^;rBF8yJ^Z6I!eB^HL6}3ql|dvi_f4@Z5o{OhM_Hv)tS$`Jk#KF zs)F`-pm9G9d>M>-2YI+z7MF#|v+0=lH&LwhS?V7M8PCMIk#EmnP;eZ7J}f5I<3Tyr z<2y#l4sff!Co%AdcjW)wxX>ZDphkOCZBSZvh|N*)ClPLAF21g;iJSaW*FmV@P9m?< z#)%>E0L36Z2las&JGc+u&^Xr#z{Fu5kSZD^3idb<0Ir#x5eYv!hc9 z2UgLUT_foV9aG97CMiW!ArI=6FDp%2MHroaQrXw@ap&<_!vXK$b(BU5O`dVD#&SA} zDt0`qk7!f>8~JeS4F7tf>7)FJP8jI8ZAV@-He(*s+);iF;WQ>g`H#}xePkcwc!1eZDFsg3<^-&`L8JYRcV-ac=Dyg`1i#o!qEb?s-&M07R z`Wg!Uv943gI}5(^2&-@?WOU$7e~yf0R61w$VSj#}@K!9laVY$HJ}kz~^9~QREf)qx zTtsRoGj!QLl*R7_ZQ2o2rts-@7xh`rQ9^Aei4f}n*a~$W!g~H*UB(oW}L#eArQ+?f9i@f?L=&%ILj9 zo3?znGm`eUF-$g;Cq~53g7mCjL-oj)3z_W4;YFZRb=s+ip&SgM2uE3(@bl1U5x6wa zF#?_OJs4l=zTMQRl%e`cgM9lIi<%iAZgp-HStS|zRPfSShbb1XWBcE{&=T`D-rxxv8V2IcRNUjt)67xGQ>ph?|&yIaUF z$-kqpiz_rZHtP;cQ%-j^z);X`CBH^-&c$``x>92_ zoKpT81qxe)G1S&=Tk7ja5~W#Q4~24P2FO(n)DSSkA9QMvU5hCzcZ%IvcwKq)vtP__ zO47Qh)1md1eb%Y49w(ilc<&x4?HlDZt6ZRmeGOaEi*hiw{_ut#zfFKbf2ph$J$@MU zE?l+0?BtO-7>Kf>E&*2~#1BbcKE-s;(- zTFWS^gUlsgp6O!c7RvQ*dE|UUQBaP;!^o-(vyF$0-NrMc;?qz`i*SU8PiL#}-li!W z%MG0ae>nY;uNO*X6S_Rehn>c=^hHtbp{Vzu`MSnorqnu?mrf^4-B7k|K!=ny(fz5H zO64l?O>vz@ndg;<^`U;%Jig2`a?>#Cw~ey#!&E)mO^-t}gY6KPlGe2t9gRoa_4O>S zl6BOkx1+C}1YKMR3VIEtp7n@%XLqNE(imnrP@K==yLWWLU>y5Jo|o@m)<)%5vMF3TaE*!6QNCw$5m)o zr~E0;L)UQ(kccS5TekzlQ1}!>zYEb@k!}%gmV40UcuT?KiLI`s=**J-U4_Nq?ZTI< z)K5?IV6im@$jqK)+YMe$G+<(%sZoh>@fa~O+N%f5u5#r|o~}Vwn64q}%^(|LJI*!H z2>HEg^+)ety7b?`82>2w{*V5*y}$XZ|D6oag-1jpF~Z%nV;MyRVVJw>F)A-AvQbHn z8$Mu?QHX40igg#o@er8X!trj0=i;(86#LWH%P3XWRG=K|FoezAIgWsv$0=MryiO~4 z4c6U$8S}HF*8nLpbc{dAyL7b^rBiE>j|#g%c@7xK$MSe8<|;6TTa?HrJ-s^2qiUR_ zM#M{HiBedL@7$~WLb`;`kh<;^)8t@J^^p#~cPV$65i7;O@GUpYZO zb_M`Pc$j2_EGL(~^$(K$92nEt7k{ZYwk(hRt7P<>2A5Q zGDA9X=fWFv&wLcZBy>olVh7(@j&Z-PX+~m0i9ad4OpTT=)W{^-6rw(o;D0#|LqdZqA`;fw*`YvqTqAuy7`rrn} zIIHHvtskAu4P@^QJgX-q@S=1!4~(5g9{wbr{mlGAPR{sN%;iJ*TNH{+;U zoOVnaf%|;;?(ba*YlwRA-au!;gYr~D*fZMBsnIqxZ^(ONDSsIFk!Hnowlihu z&Vu7KV5JNCe<&-bhcVn*LxEGih>te9PdjXqB=CY^(8IGrG(>KrCp+YMPZ}AQN6ouN z`HeE3N|CrM?8#v2^{JT5N;wS^M@lrr`hiQc4R8(A0U0ui_`gZss~G)tUdyJ}1UuDB{g6$aH?nrG(C!=X)nL8TsTOELW|S2+&t2^5 zg6=nSAu~PNM)Xsw)OS;_u!*GuD(fx-cRloX$?#F;4QUvkzf2Fkp2Ao6&;!kU+^o;= z?8s~R;QjZne)+|hy}$aazv{kv`En1b{`t4wd+$5nuYUjUk4$w65fIAJSc9y3{8o9b zmSr212=NeFqMrB_%Jq^tbOhe#Nf}1w4+?z>qeA$E)yx@VOhSJq@fu6Idi`O1Jfg_9 z(Wzc4T`crSKH98PEVB|GEM{ zRl+#{Sze3?>7VA&Iod0hBRh*=Ee{u;mtOUEm4Q!Bhi=?0=%A~;UZfdH%jv7AmC+$mmb`(UzxwVO%&3vxQOQ zAwxYo7)sH|mn1Y)-|e>pA=e?a-zwS4!_4d1P7g|4l^Q7F9%b8JPAXF|GQxS2cJEDF z78!$1voS6FHw{j2g?vF1IKL8^&@#p+0y{09BJ16p`$J4N!l)9HGX#b{SR^SqM>eD z9?#^`E4g$K%9YaR9m@-nuK+ULrk-8ArcW@~9(djl)qK;g&=GpcOI!JL@i`bO@#Tp3 zQAWtOmXqcG?5p2>^~K)a-m?!r_~3gS;&kxE=P#Zomy+Ln>s#OYz3+bayFd8bzx~@^ z9x>k|Cquy25?8Tn-81TfVA}}Bkn$9{3J2@|Dg=B8^R3H>5PN%wz(+1cKOy+sO14RP zwwPyqbQE-yC!IN6QVAXF%<10o1S%jprBuPPsxDYmdH8I*6JMdp4$X18xDF#^3#C<4 z$%13oG}%?9eJ`s>_c`l@=Usk17mG!JQEg~mz*G@3M_w)pb^6dLwP(a#C*1%?#5J$G zois-AI{2CqCwaPFoLrG27rY7@$CYFj(q7LgjUJbiAO^({3*urU7Nd+#qTeZKek&$5g^Op^Ueiwmz`{`KGd=4U_t@sEE%!vB=G zU!GLKM&XT?7tE9bQxy)k+J^W1g(B)g+#Zax>z%kmFnRb{pUFS$4xqvAW{o&2iVOHT zQh@fTfi8&#h^Xn59D%ib_EMlwM0FmUzUMDGP*3G-iATkWx59RnZ^DJ}H%PA$n`S{1 zZ&`YAgf#HtHS+1gn|eaJ6A>H(KsiCFtdi#@M);QHRtcBMig9FB$FrcK-Q?LauOxjp zx@9%K?5Z;2)(g0W!GCjU5u*h;1IM$|P}bD3VS6ntRBCh*ZZm#FQ3q{CeABsq%F~eU z6^s-N$sPt(qpUI)VWTM!yi5Hl@N_iPaEu)$ys=y6T^xp-(_6x~gGTK7$#{4}Pb9ew zc%+!KI)eepEoA0)f$v=dv7r%roYR4e`OWff*)Xy$|Lo6CMt4McQid@`E>pG+GPO;< zJ11H1Lq^C7qrQcurGNDK=U?Fj*?T6DUcY|5ym+wiqOyPKb6#J3#dT?M(X<$eXR}>5 zQ#K=+DRxFMQf-9ZUf88PmW?lSZ09m=*{VDw3-Dk@!j z(~E1E0vZ>tzlfn3oznR3U7n#ss^!D7XTOb7_1X3yZCoWj=z#6GenJOLTpI7 z>oy_Tv7%Lr@Z}*-XCA3jp^J3p`LO(R!XkD$-l72#K;WMi9>xt`I{7rG^_(zeO8N8h zHutPEd9sd`KV(pXr@!el#`_w#4!?O{$sr?T`Qz{Z@zT=L%in$ZciouV;{HCJ=fQ_B z7hi_+K^7JkezW|+2fzRE#~=UTH^2GKUq-m|c!#LHlPDJ!X>A&dGzcRjbQs$XZBQ0R zXyDNObwKCzAZz@IMTIF&cgyj_5}iGO9U=-c7|gLWi?72}Ogp~k?t?anVYUnH6kjX0 z1t?u5-sIl!-AG1R4`wk$Nb45B26MP=I{3OcPV36@zQa0=6%^-fr;n(HTm9p4SL_4y?yGhhzIAjl@M>>Ehz?zN{&p zd0rS~oq6K>CgBQRkiIvsX1(F9TE4xDv{2_^_<;hD|b4o9LQ;FRNPsHE5FN}oYOK(C-7O~1 zMrd^aen5f0VKgjI=Fd^?8Y7X$#Uzy=-2KiZJrwy34#*6SPM!pKHpVK-JZyNTo$_H> zJJgFtM=(S%OlYqI+H0g&1jW6M+^hm~>RXfpPgR&w>QDQm`FddtcNRS1vcHAe1+#;A zXy&19J;S6QoyhHUH|^<$-X{&-zelVM>o~2IR;v<;`H$~$E+Cl#ilsmBX`99jo7ul&$6>&QlDUifCg zlgV3mmNahxZ1VNTAHP3jguM63C;#BR#YtFxc>6i+K zm3{vGkH3#zNc~A5xFp_BSeCk)`EgPzbg~$w}njayHg`!?AoLyy_@FB*DhvjvQLy_O3zM&H# zOpj38=^4(MXc(WrFt)001*PNJ!s}zb>-qSL=eL{!N&lmPwDAT!q9Ho+Vza4GhU{JTJ@RipJH0v@+rludjZG1Du648BFM;3l@I%i`sl)#_hr%vi zj!Xf)AbUyj(SV)wf>f55Km6UxuYQdeDW%D&+c`fP0yTp6;DCRd}W8Y@yg6ZCwQS) zds+Dgxls17JEyoP)3U-}Yj|viJ`@Iy>yB#U`VsMg;(i&=FR*}>k@5r9Ij!n89%Op) z@J>(wSqL)Yxhdl+Eg?mk;Y34h`|J-qR|L#C`EzPJutJ{PFTvl@BgM!w-W2 zp%-L%Vfm9UzWCyWQ!T}02M3Ew{_^4buNPiky7a9j4>HS#f0LfIs1puL!;SA8`yD^^ zU93OxEf~5{3?KKdKmg}s6@vZBKh=Z{cQOev}qtTtT*?2cxpD6UcEVB%`#d)Xq9Bf#Za+H z-%~jNQq4y|t2Fca+|u>#V!)U_+>wW3ntb|;=XaO_Oy}wS4K-v6hkNg&Yb$@FD<4H3 zJZ^r-xL#<#rrdV0Hx3_i*2wh4kc^B=a}gIPko@xFU%sC#zgpSf-)DzCSJ)B5H)0lE zetF0XLiBqqNW}&@_$nmN{_u=^PS^_!mrMEZZ`!jRliL(AHg=g;)Rq54;~-knTF}H@ zLowH8p-ouWw@|q^DqSw$74mvG3+{IicAx~9{u)dn#Cl3Yy&TzM;20e4hL@dV@QP8r zYaoVzd6Di2&AJAso`9^AZ{Sh5XQyw6UuKLJ@tpL#hKQpzJB5T3Qdz)t8&6s&vw7FJ ztRMAk70Y6s^lC^0jFgR`_@uJN!qhDdVsKuE-ox>y(D4kF=i=pDPyi!9FRmY=^E{SE z@}FTRUO4!%On%Gq#Y5;8^g}XT2CGp6eE70*S$qsDm5~^EaUVqiP61i^fR%F}9PBT? z&KOZ0oKKMs1qn8RM?%ap%a`+xC+VNmDjwos}?H-4eeB0#qg}NeG{G= z#Y=w-lyFE-F&&+7n-2Xm7U->Fc(#LkmQL9_`E2hmhwl|N&%>0NMwxu1Qgv;MiwZTC z5PWw$99lbKT{X;v=L$z%3$J0teG@OpV9LpO4D6O8#>^PIXL`fEUtHfj3fT4jZOj<2!l zvUqjE#WhC?{PwrMy~M!$+pm&W`(IbS{<{TszWi8Y;_Lmd|DrUXh06C|RbDOdotXbP z6rUs?a&T(ct~(U|O@EqZlgUb9UhKL=-Bw;Zxg^SMk2C&s)-tYQ5G}^P?7!9kh zmfo!IkZyQER`Ld6q=g0x9cL%LdtX?rbX~w1!)UTn1!P+aV>>h5Q5!X~63(eQybkM@ z#WbgRk)^y)T8B`c{ueT9u}m(q!_e5E*xeZBop(RV*mhk>u^!Mqcv>(-^s1ERmB)4Q zd_jSEQUI9`Q-*pS_14LsUgM@j)dw2Z?1l|G z(|pt4zy0lRFTQ@gaOu^nSNktsy!dMI!w)|CQ(Z) zFTVJ*eEhe+^{txkgs0vwE)Ht4V?!A~@AaOR(WA$8d8N9eN95!0RQI0$wl_r6vNS7~ ztN#@DcuLYCPgEJ~C)Mh&SfusOp6~U3S{DDVhJCV9{mOdNQC6PqrXB04BEbOpS1jWF zS7r5H`A)TgQTPbD4%Rw-r&|4rk^Mi-({E*^x_Y@<{j)rr_&&Z|U8ViHzv=aU`rVc4 z9{B!S(v`M5{P0uSW*t1B>780fO;%sQKmQz_v;2d6gVN=rR4ml}m(Xn;n6-~rsx|7q z%ln^v0wI3$+g_Td+sen)e};ilAx%PE>++@P@cR85ydQt|@kiC<^2gQp$z~#-=J8%U zUr^vU6p+V}yMKcWvPLv~_oc>Q>>37hgYf@p6mI3gbjZd}f&U|T`d`4$|I8nJzQ%y$ zrwkyP!sT(e>ulvC;HuRdA6KjY3VGONFw)M$Ts)7bz(*f_^sR$eFFxLXiN;>2{AMXh zUbB{H^tHdgP%5FM_8t|r>c)2Ky z?PYf+0={DaPBAd;aSvmy6RU;+vH@+I@x6GbKRq;ZcO*}nRP(S*(WDiQFDI;*4|m-} ze0OAp(PP@MbuWhJ?|Q0?C(PfeUD5zr)X6*MSw-;MXzUILFLem?H@KXR(J&#PGYI4X z#e9qDCD$meJJpnr^BIp&Z>g~RrU-NKenEkgqCn>D?1~>R#yT?FoF=c#d)Efm-^9y& z7;JiG(-n-A+Y=L90F0slD!6|wlx@F_k=);7Ys`lS6}}=dd@V05T)IRMedNUzDF9V# zFm(`w7&huo$EmCDkzNs9iDhtfY&CEm>MYA(4GRL5>l{bHy^G-(1yAW%Z(27y(vj;x zh=;6IZara3F5?DQ*16UO0r7#k==kUz+PikbMVc+}*Ya`k*?5eBjre{VcgqzP&a!AW zyKi8uri?*$iuqe^jE!*Qx(1UjZM`NKcu(TuR_f3$Tjx@?E2)V8;{D_(K+`#eupT<# zlgs9F?fWzE6%NflPz4eq_-Sv)6|-@AsFv&d*7*1sqERx6dIaVMX$X!Voj50+nk z^~K9ytE-?zv<5qwx=Rj@lQjG4DRM1*7&Fx3mDy1!$`AjT9o|_ znrM~L=lyAL31i;O(U(pMOpD`fg$r}TeBUHYHE{ODxQ`36L1dM!b)Su>>yU9V0)_?( z-jShb+mj~P$QB?UIyT+-pWtZ$rpn`V`3&VSx0k_JgYy{mnDG8I-3|3{jnS&{@by#6 z?z4CJb;~+ps0<7l4J_j?uG6Og?QsWfewER`3)DTgC>o7t$z!Kah&MT&xO}0P8|c~% zvh2Re_Tp(83UD@v)(5QmvTuZpn^wWq@ez<;l4xk_?!x{;?cmj`g^`O{rzy!87?gBv z@pWZQmp7&D7WaYM(S%NVp;8NIa4o|WJ1WRAXiq+hT`{<%Yh;wpl9{f0;9FYO93LJO zKXdInSlkctcpT*vX_1d#;@b)CThE7`)w6A6`o6W803eq zUcY`n_w`)CJl1UG%P(HMDt=?849B!#G7XI3r|nyeRO`6GQTY103`&KrueyChYQn{vl#=A{^SKSjQg2Wg9Dz66;LIMj}Ln0NVEy~6?m4|+UA1L>-#C`p3XZzLHq zJ+?6t;3DG46j=B>rel(1|6pk;`QU>O_^%}Ui|^6hv+$i?HV*3JXCcVtunqTb|8{Vc z`|nk&Ke}}3gBM@F`n%mDmm-%?ra;&p;+%P^OFby*Ts)6mJp>pZ9>(QS(tE{@W@u4T zHnqWm!Uy9l;o&Ui^JXWAF%X!)q#mW2sN4~lP3GKhPe|i7$rc8e-|lz}vJPt?c7wNp zGa3@U)?4;ngwjk;D3H;=-(Kiq7#c!{@EcfN8|A)4pfC)-2`=f3@?YNaXGwy!Aj26MT1t-9}q} zYln6|l(vZL;{E6pSbWXa=f(aZa~T#FKkKoo^PZ=DkG4!Rn8A&9?Bv^V5b+IpK%d^% zh;vX|(34MJ^$&q;j3ou93^N_6$8e*}5fJHO^^Kg{jXo}-MP;f7Z$(6 zHr)>wKm6#!Z)1&ogtvp;wqN`%PoNLq|MnGp>90Qj^7H>M3t#@ucRv0n3klwn%Ko2z z{`u#}KB(-I%T?zu|0Ub}+U$lJY?sWJgKdz1%@(Tvj#26lS&{rd=HrUbY=`W!^=j+m zkE`|Scd9pd-YLSIl|g#2op$x(Z&%+hZUG&Y<|M*D zVQ(FVz!i$~{}l1F&GakyENs6uj;*O{OkDm{`X7R&t?3kOk4`ZzzPp8&?EX1hbib01 z4Hp+%0oUCgScW&IJ&QYKOp%>+Wapn##(%nyRKBK7{}<~)+pQ2@*Fy=vrDst-^Hg@A zTkov$KaG6hnGLp^xAJ+(D{i;`UbXs1k(X$rwKD!=m$md6xn19pKJENJpi?%;tIoXw zo_A(FnfyV0w&YpX+SNP*h}~e1pj$^evi1ItJ{h5h7&xqhDfsV^ixqV7qkQ|Ehi4a)vwhet#Osv(4sE;ck2+kp4ri%%BYm(N4&HzN z{e??O^6kpv;-#g(`J2D_zkmGWAOGOJ#l?RJkPA?wH{@HFE-k!x_44HxG4Us#eDa4& z%S+YY_I~?k&p&@Y@Q%dzS?@MB3cgil$ro`k8mrRTHj3e+-cg(lyb|@(9(h|AbmUzR zy1@!(V^L+B5luG>uQJN^v+s4nFJo!@jfD>7d_w$WrMggg9_x#MwBz%6xa*P8+cBvu z)VHZS6u8bL*prHPD|68gQmxjL)|>6FYi^1mQ4(dntsggllxVt1P10Wu)1qWA0?< zYP6=o0|86jj^onGKz8spRG!hsrI|-u*1&c0tudvwW@ke=E{mIQj&u=#Mh4T*juStp z%9qnWr-D0WAUg&O#P+n=qVRT#Z6d9*^tSVf3b^=D(51!A;;N;QC4nkA+SX~NX$+AD zu-D+ruwd1Wv`B}NEWS}ej?m$cRrE!Rwn&SWcSOr{P`w!LdoWNE7PO;u%UtMXY2L;# zjc5%A+|a$jkg>cXLvj@KF!~5XV`%C(PG@7>^v_lRa7SDGli-l0E9Who_*KB$a#9;DKN@;L>Se zi!dmp9l~nG@Y8s=dXA zTINf5gse0C5xzd_95@!SR{I^on#9$nLUu%;gtaRwsr3gpZY_V!E?#LLS+s8(=h!IT=oKgHsQ}JWpVFf7<34qRbYB?hdxSq+-A*F z-SG2XU)Ke)*5&HYchl>Xbue&)|Eqbuw%p$ZSc~;RSG5H1L+n*Ab(YrG0xo+t`)<;-QC=1dtBOkx@u5j#)0-l4hEAx*&iW+kr7%*4U<^#aU!4#i zqQz%jaA|)EKi5X3Q5K>hk}13DB>o?T>s<_|O`bYHp>FA@`ek(M72~0;o#<6$sZ)$Q zPwyBWy7uqr4fc1iRH<5LJC?{habfAGayyXIkRNL_WE1Pz0A^*Hh3j-;(|Kh_73?hx z*RZuu%J}Ns*8mU5ChfjUAG%R2thyCFv=+nlmKFOy!cx7_^v{RV$8@J~Kll&W9q;|c zU;M{tgoF>#X^6b|`o*6wE-(L=AHM(I>IawJ|AWil{q}#ppCl{|dHL^WGC(90tB3Qh zp<=}xLE=WzC8qFIi}CRtf~~HY&RNG7p-XB$`&{<>Ym(iq%@2Kz4bjuE5RQfFMbX0sX+`2fItN}%vHAa;^ z)GhOfpfJ9X-Vj~M(CCoo2qUzKJ6z>BQXfcnrgVGI_Ye$i+RnF&o(7dRZs}Y3@Uwho zH(V`xL<7%Yz&a?S-VgMQ$&*=UvO21q>I|lKS4SBQ8Xn;4%7fS<*QDzxTroVOXByux z?&psJwkN#5#(6`nSUTQQf&;I>Pd&n`F;4!X{~Ww$;Z^vdkuVcMx)2vnNA@1mp29sC zA_F7D3^g)-@vC3_^ouXP{)Jz-`})Ppzx=A#`?tURfYaou=YXc~ zjf2e&_F5kYbDTI8If7Vf{E0VA5246s%|jyt~Zyw4z8Px{)J5?1qZ=%p*Zi^pxuELMHSIW+fZ`!(*HdUKVre3}z{#t}H; z`uwY}|K!)d`SrgU5j{58&Xi8IF%~Ensqo=?-$Kch?#V_;mkL@A#puU_$~{INyAbsm zWqM#XslVX{_1vTGp(LHSd-&6M_b>9e#7WK;45Uh6HGC$TLK`sNszk zG;dg!Jbn#WMw_jC*tE|XuBPxT__G6TWNE8(iXL>9;w5Ylw}CRKvRJH6e1Om3-kBTp zeN1JXf(?TbXk)v2GLed|!|%`q?OPaV>qNBl3{?8wgAD;`s~YsXh4#{j@!9Z{UzKxR z{NP}R=Wx+U*Bs>J+ZKFvjT6#!PWvn&3xx-;*Dqc9zXmFN(O?SpipJNdGGe22smCF2 zl31;uMg_9jEYIa|D0=d8o=%4$E<(UMkrl($ zL*To?x{|9APT7EGIv6JnWVD7+{2<1i)V<6Id5^EwRhWPI`Y4%NdAuM8Qf8L)j*L-O zP2Gs&rf_D#smm87bYI+-3&OhoWJn>+g736oWh(L-tEf(^EHNMGR)zWPH2MszvgeXf z!wP+v+4r~c!Z;oJ-V4H+QeW#ea(nJ9_0;16yuWbC{cwW>wu_#Gi8ft49nk@0Tf~gQt=|gjTou zA-s9<{wdEbVFR5j;XU;|Uf`?o{2Y(T(FZpX*%9tbOc75?rXiwnjA5_|Y^MxfzG4(x z7FE%^M#M8{k(L4!0z>DMYo9{&#p@|kK;tuO`a@wJZ?Q?b0>x)KQ$J+)-s-{+aDvN50TaT5#}WBha7&tSN**oe(?VLuc_oO zj*=k=*Qv-r+0252&Y;1!Qxv*mUn(FP$tj_>$RsQyBG2!b3;tsl@GU~1KtRh4lzmu4 zY6p@#l0BS&x}Q{T&bvx>D&XwR8*dRGtkIJ<(jEp)AECZQ+|Hk%wv7AF&O>DNmJhh22spz&j{XM|e%re^x~9 zob~~OL2;Xh@gXm^pN6!&d$KEZ9@0gj&I^?TcSHcMTl>^6I}kh_Ym+h#i}wM71{)(` zlgd`H9i<}%+SFf?#Q@P`(vf~6^SOvPH43;OUjt+T4_?qq{ri2qA1evoS&iqctp>8g zz^NPgfVS-71zR0eVB!&-!8K@ejhg)8Wf#6C3;@RR-vG_g9}XEI2a7Mh&mz>99IJXH zBLo9vb(H&XQZXegm3~yLGz1`kYS<+d47w_R3tTWoUg+N{>{oLy`OPNjz)=@8VR@dk{ zsXX#{Da~*7Ek44+B+D!3`lkurL9rUJH$VYF!{UN6UChm^BoO)wMIvb zH{h9djYf%ZDq5URkLKlV&F4MsGezuaKzU6{1Kn;X@Z%_0>e4LYSOzydtjBjE|7w76 z_6nfGbS&b$ct0Hq1Ow!Nbv!I^mq%?E+IW@R-BsGai|69ytCnWqvE^AKlJFo)roo7* z3RAosoG)c-B$<|RYB&`}{!(7@@XC&c5WIBnB>T)mMhJySzWVaZFJ@VYnlCud$k)-Y z%ylhIY7q29YP_D_#k$cd|}i=wkpFRlp`2u#S9JxA>mK<6H9`y)uFK1Z#f zGvauJ;N2<;<=iWIRtQ~-aZuSoxwTHR2>F%vDn=Jt(yRmJsFKa5M#4d3bhv}5QsMOy zCH;f7(pk%?af1Qihu8=6xMn6LRqN*Xg`7nH3*K zLKC8Fkj|f!PbErG*g{Ez?`&%ss2qPBe4#dA3Y>>yywMtSVXh0>H& zN5%2zwpuUcun%G?V8B4<_8nFcS%4W@P)zSfK*X1dOs3`N?{HJ9+jW?*n(6W z6@L-lr+^BNLv0St#ZOD0%p+ApNo>Q+?P=2q2UFG&mJ|W=tGxDJ2ek3iqfYb9lJ~m~ zYiFPE(L_3*+b3C9JPu~s`DyO*aEu{ z4CpO!W-@;d1%K6N!{E=FN*#J!LAmbE%A?{q?nP15ad)RRM9fd)jv?-4I;HJcmsk#P zRne8}Og|mOok%e*-b3eIsocwSWg5fZraNtSPcK(EXJ~g=-$R2Mx?%&K)01|nzc{b; zlm{>h+(Z%judHqB$V;6nb$mxB`*W?&Q`<2wKR)Z#0JbJU@`Q5D9=Wd!O$AbgCRe8=#+xW-X{cC0QP<9rp`rRGQz2Di*FJ|wJ0twD3Env2-9rsaTMa^+faQVAK>9^pg_Bo4GL%?S} zinPD=@7U&%6x-G~uzAF(xUx}` zuJS6%?=wex$nlOkfePlG3B_%2>wAH&S%rouXNFScW@Qb55L(JrlCe!`P>)p}`o5FhFujY|y=4V4hT zP`Sr0t=o$UUkv7(W`@Z}-2C2I>bsXl2|Txoaoq4dq2KjB&ui{RNU*RViV6sV93ULJ zVbfU)Edfzpeo&~9OZ!MeWIw4iP+~_X22{Pc#!~N^BEN z){4l5S*%nZ6Gzlsubpw&P)SGEAL9@g;(qe`{qr7BIV)7~8PS7$p@~~*!=Q@#^HAAJ z7Q+V|51q{bJ#W!|dw7xdin8ShnbiL5tURGtZ(=9wR0s~Aq;GTcH`SHt>~L0ubvO@G zq4q6!Y{EK)X)57~%NoAGp6Jx$G-VkDV?RfodNDqudqa6a&kd&43T@s2{!V7(H#A6< zH^Q3y0xtNZiJnoq3wi0DL$f{kB^wop=8!OpZ6hvLV%t1!K>+w?LzX>SL&(`Yv305 z8%ejPDUY24JkdzrjcDgOpM(WWk`b)zm-99bF+ z?%;FAp_$b)!~voQq?)z;HJ;Nr9Yb7I9Q2uW`0`WN)rc3E+9IEifOocx*XX1lU3Y*G z2m63j@x!}WSvwvE$b~pB z&AAP2g4zg_9ZE-jK#ASwxk?*^Icf~WGzuL2aHMH5MvFZ<*#Yn5it&wp#C7U|-Wo)B zo-9>%@Md*vJLGMh_PK>j)y{HMoAFV-*hr4PFk(|!ZOCvb!cF@Qk3E|fR=8jo|7F^k zCCwyQ^$f=L#w56Wyma8*-;jPnkJV_)r*s0>iJN?73lU8Ra5_1`Xb9S@N85}BINcb! zjM*+a@D^=RCslX0l&1r&Ot8+vbC|Z^|C$CQlqT-V`!1&>JWB_D8gS_LD=!JFO;``@d;wtUwB!RRr64QIbuv#{1{^1&xGCJi)#!8ppyn%lXhri^c)FI+dCiG zpna}jcsvjgBc=!A--3xf*>cM;EqsNFcfag8q->3!=0ZS@{7si>@V{*^VdTQp8FY74 zlpZQShZ5~ChS7Mc9N13KKa8Lb!OkfFe$WFm^_6f4linK=bf!);0uX+yj)*!G3~$#6 zRN2q%lD{z;KAjgr4wb4^`g8eHm6MTgIVrmm2bqG8&B$!>xbxirANGh+sTd69(%sE%BiU(Gv)cs` z_K^2=42BJi85gZ?k&Y;Ibft0&o%~1~glwW)cO0-_n7Dpy3!QQo67~WgEFo9qiGgz$ zZ%h?ufcS0!^FTU>%#ZLlS0e=LYVQbTC{02K)~3SuhlERqd8Zt%6`IR8U8c$J zyu+Yq9JxHjpxYQ(RumQVZyBG-fzzbXxJ(V7_myy7Pf(73nRceZO{d*O=B>k2@Z)gO z2~Vwu;BD8gw8r6^H7+w694(&Bm7SIeO=mI$^Myss!l;;@>MA4fdOq%qo~z_L&>^#w zVN$;o>zX7?VQO&g^G%hcZ^+r9(;?rZvo-I*M;K?xe3hirUJ(qDt;`U)ih;UG9a6m^l=Y#OMRxf?$6D}UKs&r4b;1vzhn|;)hE8^WNd6nN zwd(-&poZzgj4pS8(^_$DNISzDZ*|Ma;NEGWn|U1{0j9an)d(>|3x3qX!~zGai?81% zN!U84`)CIuxs9yBDq{58(JsoBQog&Pp(>TTN5k^XN@ZIzl6VGRuT%5pG_{upfRhi> zOrWMoHWiEpk)!yjfZt&tX^bHe4xGXONk>&xC4qA3^*e-kgtR)e1^9~(glgzVl2czdY?e!Ur*4bai*tt@xWo7i^a%~M{%2v~0pglXvm38r* zbsw!|;$h)?8Up()Q$W^t=_l_2avwb6sDZ!6;JZm(ACljWIEnX6nYJ=&e1a#E!D16x z=n+?=uB#d_cs;h1%{<-m&z1++`{enU@Z0&gX`jh|eiwytLCY$Q)SMNoM1jZ}9xkZs zK-f@u2|@>0=huV4z2sFTjf;0?%_G9&QE6y37MU`}U)uXfF%} zn6gVdx(-OUe`<>0$zqQ`kI&(eM}|#%iI+}y^SG|RY4bbpa44Z>p0=aPD;%`mD2s=r z%G}Ir7s_xI!{i&LfF7b8w^?A`D8`q)V}z_D-@W6=w{-%yo}cZqJn~^Ga%j`Yht2C* z0}p-m4Ezt~ffL%?0pHaH7SN8Pj~%Ov5*J_hkK~T9K{wM0q3~BJPfBOB#a&u?^%&_s zCvKOHs2ks}&TsEk0Z(RC(9CX~EkE_tG&3yQ@&q0sb zVY7yAT;2h$QgJHmp1KsHa0@+LA@8+djNoBZUMifEg^}{~b$_Wr7o7KzxzE7=i27Z_ zxC!UTP(Hn43C2jv=^Xh9m?l4`TmlV(%r1a`p>OO=Qzy#_+$wo)F1%)`!<3%SJnp%A zLbQsoLn;m0woFbJHZGL06m|DV0L ziH>8*4l^qOu=QU5vG7{smRnMzXg%BV_{r}V1XnX&0oZv*aOIg53Onyu zTzbXA&R!8%Sz58MlNUNHoHKKdC6C2KtKCOE-D(zF-Rge*NMOD%Dx+RjBI_4bMUan) zQ^?GS8xc2d+ zwQT!=xlu61I6A;KI$)3Rb}??!cld9!GQlBx!8JYQ0@g`!5Y8zKbX8M*g_1v*q^%H_ z-mWIx>q&y~Hn`2*#ez*196tfh?9w7WVPsFoL)0N1c8xUvtq7Bipzlf_T?LI;F|D{EG3m2_3l84=w0CRJMxg ze79^p78nKxoZj0}H^PUmvCwF&#xximY4Sy-%W(%s=~>z`9q2b`s}0(%r7@xbjltfw zuJmR5$jw8H)P3@QhQV@x{5=5v4EPPo3l|2>nL3rU8X#KM~3Rf)|BVW(&Wi!(KLk%qCwwX`wb4JrPkNzsq z!OpGD!0{=#xrqF5-o~iq%M za6=-@AFeSJU~YW_+Ltotu%xyXGSq|*HW7e<`9!R2M-f{H%rVdDusjSWI(3u|WADxC z`W%)2yBeqRn{;}Ej&>)VWKrRlCoXp9Mwc1$glCSZ;~sc4X2NBHMawE*6nJZ<{HILh zLST}##a1{@1YORG+c%ik;%^v`8dsUsF6ulp5KsSwCt&O zkr%%UGaz@v@>9l$YxzTF!)P0W#7_Ed7Dv?bE^%1P?Ml&LbD?I$fYH926)y1xqyB#9 z$7noV<%n_8^waTN^`{X)-NK^FnCC2a`ykqLdz!SNtxHQagC0L zjMWG~g;#3uPz{5mO(!mIy(GRy+aFO+J;_@%&2#80*l^1DU4Hou9lxf>x`>{`|kO_X{N0R4$5mr)@fqJ=;{DL3 zOb?*bCYm15s4D3u z)U%t9oAnu7Urm!1_#He=t!dKaVKcntAAc3-py9EJf#DfIdN>YwhXsN$dr};zz#mOu zx8buBXcUYJ>DV_qR)}?a4g-g5CNet2BY%-^XC+~G&Xm{OjS$Pn+PjbC*P!AX)T)Cr zI)$Nb!wg$QAHv*I3kv!48$Gi`WyaPlOoi~eXf8D7l=S*afnNth&GjYo?jYaQMuZL? zv)rBp|7?B0$f=l^k1|B3R*moTxSJ=6vcqqC+RhAJ(VWGA5pO%?VfdpjYAS9z>c%jb zWrmASu5(N$EgRYjJ64CQ zO^m;4g>@*TZ&UwvguBXJI~!8838btVI3!t4VW zy+N0b=NU!aos@4(2&_}8cj?Sc+xC5$a>v1vXRq$PgRs(Z@WyBTMoWHzQ}-FcALl#u zoMBmYkV$;S_^d9a28eu#oNSSO!!oA1pzY0R;PZoM(?No&g9>C?qj^1_7waxk)_!!s ztwT6f7?gSGN5@^$=#ZzmcbSSgq>uIJ_rrW%@!32u5Z3?d#fzcx5n-=#hb}LtO}{WB zBqE~MA`p%J$*liq#qeqF5}Xn7z^G25VjZ8LtftzxjRm-aF*Fk%)8PC*zz(y*mtHsK z`Ilbi^(=65I`q~?q;I<#$iD|HX^2#&F+?(N$PV~7C#?f|Vw1s&iu=-~+@q*n{hwZn zdMf9&1KQJDIXPg2$NS@Ld=S{Vy$cElU%_K+By|525ECVT~9* zk302fFfyOG?)ft1Cunh0De1YK+Mz?P2i{o;i+49&PgX|b%mCSeAFSV07j&spPJ60E z0NW4hwZKrW@%oY}q*DxywzM9V7s;x`YqYpXw8Gu#mkQf*Q*P}WteyFSMgJHf^^0uL zGvSvmrfoX(mmZ&RsXTOjDC1J12?NN}HBM~|#Hp{6rkpyDu?b{4Ttqu#0fzuEqT3{@ zU5wT`h9Mf08X__QMAAKcx0u(5_sbMuBs6xB@#R$W4N>4LbN;y4d@)>3Zb1>Tux*Oc zR4Uiv$_x?Zv_9z~V>=E#V9Kn|lT<`K!LF-T5!O7=jaB5nU5tAh@6_u7<+dlSmpGzB zn{?by%kYJ+P3XE;7RNNiuA^l-yQd7=rdsEr5%Vc)GRpFuHH@aHV%S_vQ}<$7`Lwoe zKOWtVQE@+em)|s4`X6(olXPmTW4!#3H$Vbjgyr+@=bL*Fj?R3aB?nXYAz9w7Ty~cp z$-fpnB&(I12}=+#SZ?AO@$1Q*FX-gSqkAb40iXUJhS5re^TooV)U*u7u*?AIdUt#8 zu>6Ll9~Z8-WgJW~e&I$)Xte2+XA#E=E~d?N$l)*uN<%}0^(Q0u;Wjnaq*^J#mRfuDh6})0hOuX<^hu>a)0|bdvNK zE&KGE9>BI!2A{CtkWT0*KRprQNRvYI3X50oGKhY}a}D|*#Q1S{c1QRX+M4-{gPkOv z4#zE~CzHUAf)OX{6Q|!2rr3+R9eL^C1$vIxpQMUXS3}JPf`G?MXweo;`&OFG= zuu&HVUGU=ER?#K*;aN$PaWHsR|md1%8|PQUH(eq4n0 zeZ{Gtq;ik@fkqgsB;2AKjfR)xHTEm_W%@Ie7#NMCZDCS(FodHc{mK;FqU)Ur==fp~V1#Mn z&TUkN3KH@DD%Xiu5LCT*sd$aM7!B2dIT{BS<1?e>MSNe>9Z$rOZ8~ni5X*=DP6>GK zg&*IVq&}hDVtVgR!xTHGeEhPXSKWoA+j_#wwn2Zo3!*VJ3FnV61+hhZy9|cT)vc{t z7(TrX1L#U=G7*2{<|of?S-!J`(aCl(h%U9$w0Y@WN6$aR=uBf;Wmi4G`z?MhP(5M_ z(C2vR+0mQSG$43cxg#&T>DlN`-@G+IG*o7p(xcut%|o8HP5JoT9dRK1jCvdz?)xN{ z`k3~v1N)M@21l3n^?*CqT{`7*X^BF{N2W>Pr$^|LR(>!L>c_DPWroS5x?kRATBpqL;3qp@C*9xn~hwXBRu!|V@M z@mc`i9G52O{}7hg&~n<{n|e>j54O<3qToq$aG% zUaJBjc(9pRZc!!Wo_y(4d=l<%1%Tku4kIvq$yF59@B{kVm^s~B=Yukup{{f>_Di-xOCYbn2TkvcQ^@dE1G?{-CZD~$ zlI0afwdjBsF`l>@&o`$riep;u=IuS^@AEt^24ouQ>A1WsU(YTbiw4^c@JD57Fd%Dh zkViV)(I-jc6|ggvceBp-Gw9z4+g|aoxvL`2*OafUyPK$4R_?4}(i3@`Xo@GpvmI!G zcTXPRxtX;|)$rIp(5g7))&<7~eNO|p8gQxiWP$;0teXIjKybhGqWQ1NMLC365Gi{tZt#sWTGw9mGSYHd*$i~okl)xk4*G4~VMHuxe;kMmlc*8@-4$*IS zsDGWGi()iHcGYVbBNyn}V2l_QudJ*#@BYFi4J$pvWQTwh`lQ_3l<|P}IYfW@KGn5w zBSdW2+0v9rz<;Xg5G#yuK#TDe1H^L)ZcbJEIRk_4ux(dYo^P8os#9l|8FxY1!*E*U z6}FL`F;eRb28`dBG-F5K2+V;a_GsXkR$;54R55(^Ce16tg%MxRBQo(pb{ZgzppFsZ zEy_HMd3l%rxWy6Ij_(L=9ie?f_+mcmO~z%HG5~$6WpP&tqe@kjQhJpV&2Vqlbs%;=ePI(hvXVTGekddN1T=Yjn1`K=&j1h^yO?$M_1nCSp>6TOuZ{v5t;(7wls z-jVZQkUS&qOnyU_(lTQtmg}9iNWJkp;ukJ;DE;)USvQ}o#f%ntmx&|d0={VZ91WZhe#L+0g;HwRCi#(FS+?-vChhWy zpQC~oMHrPA?bL|j3Ly1sqntVj{U$=&BJLT2JFo^R!Y|-HmcOkNF7M})mYt2B+LOZ1 z8%~;%=Uv)t4|={FMoZfD$kE;TTIB(H#H-7%in857o^}lIN)nW_7m7CAr~IcvC5b%I zA@5{jex9%#*A$@q9{~QaEJhuW*KZgOu59EFyGP(GHb|fltoHg!u>7f z5*OP0G41&XFIXuZMC4PZkm!VKw5ba!yH1q?-=rSfw67mvdn_CVQ;!#XDO~awe6?Xd zL{*iKeE;LSU!XM(Pwp}N^&;!|Q^MwUg#pq=t&-;_pEIMUo)z?xT`(uW4s8qh17pe) zb`NRuhnWtm@_a~sHEAIaGf;d?e{=_frb^!K40}x9^K_MC>#5)KglQAvw=_UBMlg7G z*OH1~DsKSiGKSW$X%}&&sNSw47WGo*>8u8bc`d~Vu^<_b+kF_K3G<~gli_6-6|B)= zJ36|Xr7Hs)2-5mYs4M&mC@(zGA88nv)Ab@(d?*sgc)}S z@WgzE8Q*l`XY%zmY40|2SAz~i4G}uFX0gul0mecd{brA;mtS# zJ{YpVH6ndY%lmx>6?J&)4kwYGvKudrdC&FE+8+6vI=>{}b$&1DfltA$F|Hizq46Oz z(BIrAO=_RVfI}T;9ct9!4#yds!Lu$kebxXxmhQ8HOtch?eu2u)|>H5sm;gF!r7d%S)j}po8$1!Dwuh8YTsgiS4dYg76-| zw<^MgwI!WmD&A%I#xNAkCZz4e_fdD0*p3Ql6wET?Bc2N}Bkd{{@& ze=a=83#54-gBjtr@VZ7LEe7ZBU*?++eM`^CR}0V3p?cK1Oo&Fc435t5A@Z&+9mvNi z7--atX*4YLKE!wL&^r|u^z!b-T1CUCQOqX~KkKt)BzS*U*|^wWFV^M(QTHJZvmce+W!6OF0fxTxp`b}|$e3pbh3AOtIduulHEH_m z3TNBWraRDQYxNCV z)TfT%xATB13G%rO1D>%ud@~)h)i0lR+Gol>q8>Y>n+V@g`NMC1N2L~(*eKX#$3@wY zk5Ir*Tr^1=o}eQ($Kj%3iGtr72bYhx)8V}uX`y@CvuPkv)$ly*yq>epr+t@eWn zqnHQy$3>r`4AE|czYh1z6X60$y@@w9=3_gQ;b$B=^Gw4f@C5CX^cEoR(q0-OVQm9_ z$w_5}wQF?T`TP>5c3u}`IA2cIH#sd4JQncMK|cPf&kR1pvIKD5&Eu8NSH45ex52dz zKg)mJ6?VQv!&(oBdMKvXXmDn zqxr`A8%|!qBWXG^Xo1%e^lcC~;Kl3ZKKuW-VuXlptQe0i-;0-4Jx0nS!rS>c2vMVf z?j<&mA2VXr_c&`ZpMD~_2= zJ!AUJVE9aB0*{>Swh3?C6E4f=uAMUJmEm2( z11xuB*MUcp!5LM0W$}CF!(jLk^8K(BaE3th2A|%p6xLp7NTG95>gS?&-#3E}qF;k2 z51cZ_Fxx{GLc2NW!HDX6K**~W(IDMkB?;5vG3e4Ax}2IuI%3GB0LbHe7&uLW!!z}5 z65a@dfZn2UHsQ#M-}dtY2@)hxinDNM}&2WkMp86l@~v?pt~cEF*07_ z<#=UUT-_Ut%GXf}jZ7dzmKq=^kairYgun&;Q!z5{TN&mdv{NnCwTMbEqB%bU#dcVX zyUy=HAFyx^g?$IbRmmL%b-U@?!dhWQ0anCi zo;bYhc01o$uYOD?w@n?7=b86cEw7-UlghuBf4F|VzFw{WcD34tZ~ivY;%2qlK^S*v z$D>cytAB{R{#qkK-m)!zd%gOfQ4Zf_PW181pLaXq*X^DF`w?w)hc^1p$aD3RZ&&}F z%5512h`5ViwOZYw{C2EM{=R;*S|1iCTu?%cxZX7bMBHsm>UPBMG3{_hP}M5&(*yEH zD9wKR5;pRZM`+($bnqf>wlw-{w&r5@>Fe4-<4%(_>b*`&C@XBzjL$tp9ueqzU99F+cmuG zlJ3xQ^OJ8@Kl<6v=iBcf$MWz00d9Yyez7d^4t>lDXNsihzl%75vu*x|w0WNwH6omb zLAPxJcMo1YMW6i#+WU_gfE|5Ot=3jvS3alj{2l1iHZSW+z5m#E=>g2Y!EkwuA@JFE zs?}eML+FdD)h%?S;OfmbbUH;}?veI?CG83CCkb1Qc|J7Xt6bRq*Z+d~wEl)N%2I2< zJfm~eizpL|wn@H;?y*JW|5eCSVWlHkhhNfIUzAkS1#0o#yZnSuhb?;udkdJ&kTwI- zs9@2YUuhm#=m+c(F5P2CV0!6zZZ69JiTGpmv~|nI_jnh7UAytU>@Lplq5)E@i*4ot zITY_>Mv-mXvj{WnJ!@y0fAC_ocbYJow0-HY9~+C}?F>RK_YGVcZXs1C*yh~bez}*q z%!eZ5lm#BU0{}er@?;$R(2U-41kD-;t$SVXgJ+uk$9_F*a3$dj~BunKU`C?#JgEo2tE0&`nCof53g1VGb zGw!O_J7I)ewUYBp58*fG;er~56N??Sg&~0Vz-H=@4!Vbv}AfF#Xa}O8s<}l@$hh4-o3Zsou49X#&ze;125kfuu ze$s9}&Aa|geLK`)eVTfxbnTSwgz`L*KtHEGRJi8n0#&~>I!)g5hLv~SeV4H73?8o8 z34r?mKMpI?dN@rXzYK%9&f$2g_NjM&{X-ttAnWX+ls?o?gXTg9P3wqfhXL z^iGr^&7nEXHU^Z!y znLN!&AA%_KE4=#vOcA3_JOyr;xF#(&{k>$hRhiB)+sRzw^ zxm}C(69~^qUB%ju%SMSVK7>AphO78djN5&f4-ZSHfQAC2@Mc-Tw2ccV9|oDu0PqqG zwrg2J!bp=k6@!OmeM8W$WQH2KWZki1o<3 z9#$AV^?J_A5X1QC5Z*W3fpZOFH|otYLqr{m;n$zC*65?`R$2bjhJ7$Xrlr`D;KOLG zw?%nLCB7TQs5r39U67cUURg~Q>fn}TM-9qv zPj8fSvy|n*Lhi27UD+;6`!>R?Cq~tPo0Tb|D!6p>_^7BHEphr}BOm_0Jlk$rU25a% zq>-t@g(T7`TpDwPKa!Sq27#A2d6d!O*`n5d#j-!#%PA0y13I`|+YSIS9o5Lk$>SIZ zHwS=tp)H%kI(R!;JWEH#G{fF+VCXW)IU5!~Yq+`wx!t!8`8;^_NP&C#wLFGtoJCpA z83KKo4?BsnjN;U+gQvCEUm7IR4n24)mPa`qo}KD@9O+dwM1+ll81X<}wlM@xVjfqy ze=tI(qn?X#`U-5iq|-qMA!D&oS!X(3PVWyi%wLoF`K6BdF%0yAG%yreSmj3uQ7Vka z0`2r!vF6eg1EoI#D8|Qkz?^3eTW&);#E5HlzvKaLg#9rF$b$UvPae_%})Q?mQOze4{#kLfU;U&ZHm zPZ*e>FN;Q6zaPV!*a4;%_?|P8A|7Rii24xR9$?@MOcBMhX1RYbLZ+aa3^N7zl|e)2 zkqo-rubk;SoB=}UarX}uPK6;>1tz|yRj$woWB4#*5n=0F`!W5ydJp_ap^n6<1oO2;o({t47GJ(a@WiF9Av^1%enM+Fzr&0aYaMK zGElBt(Hj%tu5w3(eYmEffCPg_N|pXJ`Ah;E87{iWCQ0+Y!bo#FhDa0ZX;`2QuEiLR zpoZ}X~k9Vz&DrrZkHbeo!Ye{ZvWP*$Z=OwcCG9mkHfj27=p7~2!i^jr+9 zPw0>sxyAU%Bfe|2`nmTQ=N*MzX8>@J5Bu=E917T0bgb=ZN(-H6A%Ro18l85c=z?14 zJPRkaGXa;mgc@Mnh(k69j=tuO}eRRJMJcox5M#z*zq!CnRccx4> zGkD?||0UZoXU^~)O=!mu=jb&C==>XmZAF6uISoQ)r+a}*QN=T?stDw%Mnn+qVL-WX z;n=_bBwLue>$cF~k;&GIP+pDvo=uuxF6%2ls=Sgfr?9m8Cf`?b z+if*8$f8d>;#2d;!fHO3UBN)hc~FGM2tNtoSpuePTAo*PGDQCmO zly|30HZ!;i6Dz!qT$L)=nKORJ5+Yz)`4yCcUyp1%ckh-(M+3}>HfWQbSS2j^4wicw z-;4L?>U5!^#tgKr6=C9gP(sYlq6C7wUIQp||E3X!xNvY*mS10a#P~(uQMivY1sfF5 zr?{V?!NWzDdtLIkJ;24qcbi3=GP$|Dh?hl%w3p{l9A!rB9_+OVZ}^qdW-*@+@5`Y8 zyj(VFpQ>4sGaxfQv-MqUyi(rD3TUx)myD|N5XmYYR<^q>*mMxnOyhAJe|xUXTX-BG47YMa@1 z-{h-AyCS{b_PZyb(jkpr-!lS9<&X}X)6Fk;mdJ^RnjJV;&=}EhSKfonkf(Rwk>7pS zXV~E{+W?7GQ_txYaXT^Ihx_4~GmXNaGy_^;;VqA+zJhv{shLq%(2Y3&bzqOq37$gq zq4mzi_t%FI9=;e4PDlCpc|EUv?|a|-_(wnb(Lc;9!}mQOc)LrZ9M^uob}#*#^mrNd zRbgU?Y*SWi8RcEqGNgSTH{I+hBOJqGCxZ*Ijq5d`Q%MakyX=^7X@*tcnX+mD*FunM zD6n9V&_VgptWA{Ay5V$Sp1j!1;QQGURV8j4g>@45^Apx}x+im84&dBRIOhk-Z{rnu z3eFpR-TCgEv%mJ)QTG#+@;wl3=8<)@NSg)aiQLv=9PkfR@bTTdMv85m51aHkqW$;;^JH};$nA@~_ z{SRt2&)aZqQ3`Eb_`VdmEyJ-GR)&jH!|-rDt50toQ_mwQAY$>K60!t~NqGH6mR~os1z&It7&su@QMfXB0 zH6Q-IJ}0;nsdCl&DI9k47z%be;Zjghs$E95<5zAc;ftL2?R2u_F^@D%t>7UE9TXo; zgub3Z@|^Z=MS+iLYy-R~kKl*nXn+_e93A38_6>`Gb4;_Sdp1JqV2wRqR2kPfUufM1 zzs(XH`}DWd4ZNe*s<6;dua|}#P1h~SV`Na|1AyegL*C2q7@5biA~TPjMo5#zj+aKi z5fAAE??2F65W|*rXF$=^6CqtEEz|W2be7wr43J`8%8Wbh!qhI)t#OKX79J?(z36wh z)lx<~mXjIVhJ_2#RpWDZ@8;jFqvs$=vn1&m-q0g>ir|ec*SKA*g}8%x7$6vVuE8tf z6i{0Et&59~c>0D76T+~ z*CpCc_yIq6BzQ!4dxD|{Kr%iECwLkGPaVOh*H#{po0^>p?BCVkM)N1uAyx{S)R3ts z!f9L+{|WCd_8|@&q0{FZ5Ek``Nz8+C)(#RGPW1P^7l0m`RMn4@ArP|hd=z` zuksNeo<~#Q4T~WiAtMAW8Dcc_)ngs$p%m)m)HXMn18a4k&aukt!ppbJw|U`lXrq{R z5Re`5KrwDg0}TU}C`_&aQp)6cyy+me=!{y1;av%5hK$?)&(uwa{98=@bTxMLKp{6> zK9hZE@u#>Dw;7BV%78z@{(tTsGo4!QqON7|;k39*FATCfq+5?^q5B4WdzQVwL^+*~ zYlE0}*xkA#56Z|UFm2&zYYo$|h1&du`E;Xp2N!b(zG(vT!tZi`-wqw~Sl%(u{H6DV z_e8^24}*L~+v8xko|l~gBk1RO?7&w;#JaZ)*8_oW%Ny3IvIhUwpkFG?GOnzw`;4G> z!l?WrY(+oykV4B3ZJUHCr40i@L{YbJ}vdtc*33!N(UD7hfmxtr{URd1fhTiK!sMl?iuynF0{Y z9(4zwE<*iSp#|>#DA;+#q2StCS^ey=gpXmQT6(rT<K%^l*K;z7IbRtWTjO^qO)yk7FV zrNII&ef}k^N~hNb&qtuWa6?2yuG2-`A7ON)ah_S+GQ*^w?t z-)*l->UVf*up#dGQ38Gp@5nQ@TL|X4SF~V_Ns9<986Xl$cKY!0>cdi z_FhnukCKG_KQ5u77Y7L%<{I%f&|J|2yOJo0oNr^EP? zGMeyX1Jbu?WG9ci0irX)R&pi7(|y>sjEZE#J%uSpq)8j;+;T84<{ z++0-dBt3(znP6m~TuykcN_UMq?hTE+Xp}(1J!se^tUV3y$`k032j)wgxnru=X4yA( zEF&5qwi)lvfd_-c_en2gUT?u;jLnW|!ayn8jdg>1fydG>>r8#NDR_M--Ov}%z@me)HCKV&i!SS3%Rd@w^1vE~H~e=S8LFdiZqsMP>U0@2 zouZG9qTw7P7J1kEhCy^{8DSv(rc&pz#jk&@tzKNL@ca62e({U-i;q9P`NhV@S>^2P z$3VJJ&#B*OCMXNT5C!h& ztp;6E3qg4}r`Ps5e`)d3x$ZzW5ANE?$GywXEF3(7EB7$GQWjPDrPEh=1Eg>1>wV}= zQK@jN{JN&mV8Lie^E80Tn<(u)!W#K-pCPl}u2drv<0X8@2PGYN5d)*4Q2|&mj%|D3 z4$h%D=}fajnR~b*4}Avj3;qsq|LYOa-7RkK{iVXA{(eO74o1cvk9s_J;7@lY>_dQH z1YmU7PL)iC_Uzd8F3{n(2!0mnF3hki(0!xUS?iq_(uU^i!onvVJwJC)R0E_8Sr1(f@37EEfg)h&J z&~adXyas;JSQ2;M!$lc814n1ahy~u!r}gA@Z(W4+4gBWzQVEm^tv-O8Kf z<;6wv`NhTgFMey~;&Wi;>IJb(Pq&0=cMwuL111(~Z3V`-cwxnN93}DIF)T3m`Eo}U zmOJfbJ@ACwr{mWUxnHc;wD}E#xBpt{t-RNTUBmF{U%q2eK3!p*2uku+KceJ8*c)G< zc(TKtP|&p;*h@xouN=+s>;BjO-g7zU;@|2cit?c*a-PO^WYpylV>K-zM^#n2Rrs#! zHd~b^hRNeR9CVE9?U{6WEu~ z_Fx$OP+YCmBrF(jpvAhveTt#@nt_4_AV#8#_zv>?Gc2!sxHw|Cd^wdyW5QcC_^M`J z)NKp+z-PRMa`WjI`KMoW6-5Syy-1ns!o{Yo7IaqKl!_#|NQ5LgmZa)+3j{-zUuxdzyCPf4hQ`MDetQiI-&i?Qd596|~!f=KmJ> z2KuwksQeFM60!)30lT^T=PEURn<%Vp(lq(~F=gB$pYG58{>%1?Wi0b9UAvZ&^-sR@&1&UmKkudyp0-PAy9YO`)juQa zQvL#_O}n1aS^n`SH>=yUMe^Irhn(fS^8(vz_vsmNZVJm(IeWd%KM3N>W5FhS^dM1r@ zwEYwLnCBDI3YWhOlV5@Rh~KO4e49pDt^5u3}c!$GedbioZek7X*En4=Z-LtZa`hILWeBJQ=r|KbqE#&W z=ZvZj7m3@fc{|!;M9^8JM(EJT@NX|T&KNi@YjJOYdsLaw1u-hQF0wTQ+pVnd%(SPn#;KS zg^Zlgo({-~o6U#>V+H^Vs+cD_OP^mdkXa^*O!lY(b|VJot~$)elmIhdt9>M4R2 zPbjR^2$1H|3q!1itklYoBK%n~+zy5I(0jN~T~Ep9aS_J%&@LP0)0t)P%Lt=BbquB; z)8L=xd2Jcxe`U*9?d?8qR=yA8j%y3tltYrEa{tV}A6-*S`4q*Voq8nU8sW zv3kSJhjY6WOb>2?DOxaVn$MU;g$H&JH3URPHVy>atRK0<<1qr=WpuxZ61f2Oq4B`G z@Bb{izYV)imx`16+;?h(hB%n>;Zf448eF2dNO3W@>HPe%;Vo%PxuGLQaqM7a9z(kW z6i552^f7PpX!)azV32@=^TBP}^)b<*?TBCcg>t+}2jR7$S&~ zuu()bC~`U+X*jMvS^N=s`1^28Nr6m8JlDfx=8tHfFfyVI?#8VCpf`ZIWHn37?NfV`VY625r6n>Wy78RPDjgJBzXU%~6a*onLh7h zc-Dz;MVMvY;pszg4AU-UkFt%`EWI;DZjcy`J>{I5Uk^HNoSmDOMU>K{J( z=%a7GezWq;8y6R^e)-E^{$e2I6<<6ENCO069$@^KEhC8r0=*yK`8r??L!_Z{LD{D$ zkq4wdjPbxXdEboh*YPgiSmF0MGh$!npCgV{=&_A*J#$w`7(HI}jJq&mW0wxJODOv@ zh0l(4j%A0eteYb%Pt>z4jIC$3)x67@BtQBHnK;q?M<+923>k;9>bDQ}!8h=aaPXn) zk}fM;Gy2jSGD-0tV6H#``G`(@7X#!o+QhXo?R<9fn0f=RMxFQu?O8KETQ|1lvoPp` z6W5uYxtS&+FZT1NX173jCw5n!;;sA7E3}z zuVd7;_TxpKGQP}tu=4j87yq#Go8NpZNs`~XczxsNKl#Z|=Ke7|7eOYyFaBL3hk}gq zKVg&_6bnkH=EroRazRN6(uoOu!OeQ@FY&Y`|&OU*P!U7C_>Ak%=@(2-kgmst2g$#fkMR~Yv=20M-dD%jNWs02WYUx&O!?O!48=zr( z^xK3yQaZs?jDkHIi@0#XlP9!uA1;PZdjFK^B8{X7Z#ftub>As#hlQCfpS>uyivHSx zcV6^D-p+sJkviXkPJ3k-1X|%875{uZX==vBFzQo7pEN40F&pIp5uPo}P3c7PZcKk2 z@79C%b84w!dtFBy-({Qv&)~Jp*CEeSS@_EsZ+}mF9QnTT@y8$EI8TzBZ&u#Cx%lYf zqksPUzyCYm{qA?a5rL<#l+MQ(>$? zR08H}SpUMx?LS}h2NeVLxSM$lo?NQSg!q%LN{9NuydaHp<2xvi3ezr6P!^BzOx%}d z6J|FzFw5*4TfKSdx#c}BBMj8Q2hzq)OPbK3RrHF`aW$C6tGKfzb{^&j%`{@$!}4Z< zUFuXC`8Bb1@A2CRX5TAJhnxQss5r+=xd(8EsUw)%mE2h%}|7G=$}&a9B#QeM?n z@{k^`tlmp0_p4Bdg8&A{2l=|@X{>IB_Qx?E`P!s8I=-)b?fm=`7NdS=<$Pt0d z;0J^xrhixN*257Uo!`l<#t3@l0cj7-%X;et;TGrZQ$V1wtRT27DuLb9?=_uG5i2}9hTu3T+q}3W6!fDn!%Xq88jL-O}%sS zYRs!Fk7b8ZO=ZXh!_UGG`djy9<8jsUf{f@DVM;;ck*ivgXBU?)#|a=utTVIT!XO(e zvpckXley?k!uK5cUcet~y@Sh2vKk(wLJiZ6-1AU@xA@{H(|Ma39vqk#7Cg!);9QHc znNPFGXWLmrNClt$w&YEwtXfV#D2qj207sAZ?t2F@+&00n8}U>I)H87!Du(CpmO)4U zR0Cw3rzD^5Iy~D(4CEeSq&~V1_`J(F{L|mf4Fuq!68^8o`k|+5F>vLoKo@L3`4)!A>YMYg(MF>$nDqgIcME0RAoCs*ub{rU2K-lY%^ z|8btOi!khw+PT(S`7{yn7^XJ`W2Q9!2(#?FL`B&-da4a8J9v0rhf(%@Mossi!*e=~ z4s~{3`?ycTk_^nB^nPS3&_;zrx;CTy-4gJ(7NjA9;%m|gJfhRKT^D+Vh0C0ps_{`Q zNP`%Ti7_yjD8pC_xh;=_uNBeA0kJBvQ@R7CTi*RmA1CLz;kKe{HVc?!c|y`OFN* zZtA7UM=a=BBY;83cEYw=>gUH5+cz-Uz%BfsRf90yew*qUXwgI-4%!d;e9rpq*XFJFr8m4=}@n z`o%S8kymEO;+;w&zvxtehmQ0hB2L&UXb(LdoT2Q{Kqib zb3`tU$`&Eb6HE9hh2JhI8=0H77_iKxKYY_g!5)_3pwU9yj=W8W{!n-ncSBgRtD?9! zdrd6OP6{Ad>i0jL%;1H z7k3aCJzbCU^|1Yg`xK)WdC&vmp>>ZnWHdxbbC3AomCf?ZCog@rQ+5i^NEK&ZztQgD zG~QxDl<`*Nm15ky--98I?j17#IkH^HS6#(8L!WHHA1|OsgLH>sac@$2gwE(!>P@CP=lvFQ_Ei)OSuDS?v39pK0D=L*H$kxG8dqgt>quwj2&+oR z7d|}1`j`zm7)LcWpk9yzrgKtZwYX6xZH&C|ZrF9Z>=7PI6qJw@xL~yS0$lyC|0Zpq?7adHXKmaj+F$=d02{n?`TR9i^=%a6-<9{QZUKLd3cPGBWpDKjTShs_HyaGp;Q>#}eQ1MG=LYS<2Rkdx zRkZ}XK-dmXO@1SQxbLt66an34aSQ> zEgxJD3Rhw=S7 z-W3LLUrHy4K0TACP>vdM8}bRf7p4hic$8xsVbE&d8AdBQbUP{)wMS2Og+l;ZrsuIw zd&Bb=Jl$4NFN+Uj+13|BtM0mm7=}{l8)Jrnzn$>Y7(eQ6y{YSV!a~j*To*n&a^#!~ zduxw+Hz>RXuFfad(LEmfyaA3UoGVnL9jXkVypA|O=O!9#-xpvy)axFPL)%d}FFF!E z8hgFB-v7u4PKNLSnv|6v2awRG2JIgKvs(tYtT1?FV_aF{jBy+IWE^ZUJ{X{^FJmD3 zP}*YLJ;-QW1YP*Me6cJ~oRzUW^g_eu=uz@He>qhSAGnUL&pYx4^15AF%YD;~Db|&h zuYK(=|J#rM+fP6G;)`#*IY0l##rfLLKlI8w2L;+EAa?YIUsc zR_thvli3rtit$r9lwNdVeh%II9pyYGSvLZj9tBXRPPG`es5?beF_xY&>O9s3D*lTq zE1xg*->0K#P;MjET`x%D^iL8#S6<7*U$0|Sxl*7r?U+Sh&Wn4K9 zox1jV_*#ca^GC0ChQUHJb@Od_VON7p9v=o<7H<1!7#8VR274XCked^lesfY>fURKw zx8S!;_^&@8MIO&4&10T$;v)~vGtW_Zm6eB{E#oKk(aXROS%&c4p34Y|JhgW7=1qYw z&R17&zBym{=Ed6i5B~C}e>u@vAqpRzWf#QyQ!lXs6x38`vyUddjN$Q4d;=?VC%(tK zm9$f#vvq~G3Z(SXI}p4R*{9S?f#wjXHK#%Y-_{(mnkk)8q>8a~^yJZV5*x`pAO@2J}0als3$XZ;;PXgok&# z=WCT`dg4jhz7X_qxq5^`UrS)NV1yAJ!K|`t@O$ zF13?q5TT2GDGQDJWl!;t;oTXLqy-;tW2|fe(;fyF_=b)bH*uo~hezPJY^154a$qtn z&v}RIl}UQjoK$=I!H_b6UfIS|)Eb7H^h7V4eUPVNaHGOmpxH)Nc7SP*g1ZiJw0j4) zVI5pX@lXZQ=>c&G^2|J4SI`dM~R?+ckPYVwoEM@j2daF#f?y zco^RuK%<-;9Huc0-Qo$V?Uldyi@*5dfBx=wzy6z*m2a;w6_fl!;^I{F_+(e+u56S+ zBls-}-Uji{%HlH@Yd=b*2vfLn)(^3@`w=A%3JD{W0}Y*$=(z;JTs22P;L@B+h7)9> z!iS-6C5&vH`iV(wM8ay))KLoIo51eH`0IFwIgi12bJ4hABnD$Al+!yyrV1ZzPilam zSW?p7b`B$dVU*lVdWSo;Lnp*&8=8kLiP9%c6rH_NA8@N-ojpmTf_c(hlTgMpfl z$`Jlm7lNpVswv!a%>u$}hh0 zjqj|!e*F#RabCV&`~2_ofMw6*>9+Lkb z2!;z+{YX;d%b3wmjsj5zb<)?sBOMJreJobyCio8!Zu(p%OCb$lbY0)CPy*8NUV8Rr zo$N3mqt)z~BQ$@=`;$?lVd3896}(_0rrhR*o5rk4nf%%qA8a)by8w13%|9Etc}7J# zkmk$phBOIpXNGY*4He4`1{%e9)!sAL0gnN?D&_ki0_XD&pgME8U)sM%+eM zh6__LPc?Ei`ZcBoM*0jK7%lJi(`n4~){97ockXhaLk)=ag?v1Xc47~pG?V|bfl?l&iJz&<*2))^)WydWCz=sZ zdcyyusRLi&{Xj1qqhoeTfe56ZbCka~EPhepdJ<^c=Zng}m@m2_c$tgg4C2B7Xh0s` zd^v5X+!YOZAsb#nx z2lzm5nF~_yK)bsU{%zeeBVvGO#ghSx13C|mJS@eHbx%ygJwaZY)bCjOgmk?#Rl3ye zG3op{uv!p})jIcBx?z0F|*lib?&Dw|| zU3REYG5@Q+t9%iHjjQG}D!oD;3=l>v8X#FG(57Cg=>k1j9|9g71mY;4m$Xgr)R-Q) zUc2N0uER4s6_$ZU@KWF|r31bjcw+iOk5Qzxm`nh5K#IS*qx4eWZHu_jI>x`{`+6*& zdb?(+wxY-B0)rf-B)&1ec+cv!V>;si?I!RZvb*oQ9yiuowR{G)DnEvio&hsnmWk5w z8!;891$>_|tC^D_KaWXVwX-c|g6GTuQX0bpFR|W=G#hkAc7_dcM`<1c^YSXA{8+{! z?i!=uS-0aHW`Ib02Zh$DKDAK zc#h7g@vf1{({h%2M&4u~>$xnuf$q@%&5f`)*a1QRNB^^3ws>6GU7PT2JjeN4UTDkEFhn4-q+S=MLR=eG={V&McUsNj0%#>dy{DT_XFIlsY z32Oi(%>CqdaOb^%Nwq?ofQAN)_n0GbTAF@yA-cF@)J*rx8?r~@#!MLuNo4&H&?n+s ztizBbQw0Yj%)@^exyFXF6Uci(H0&68c>vrFnfHYy76gtBM#FkZRPK&|(-`-*@8}H` z-m7Kdp;0z#S*C@DHRfv4P~4$u8uL>zYH*_fDsiqe#x3(MZt&!QVaKRr7sdGkd|UtZ ztl(`-s7LOSpXhXVb3sl)gpLTsro48M&3lxgJadFl`0{YdW02*1x=Ejr^DR9MbY>mM z+d)StQ+8G}=Q(NF5l&gAey)|N6V{I5-W_$R*z@gbed$<_plv7OiMMwT1MSE*Fx_>z zpk+9D5(D%g>XBi%+5Q+Qq5Xv=X@jr}PJwNh23@jCo7+Ab^QmF+%HCVND=QkOc1-H| zG{Vg7ju8;sgzV*$cJ>=6BI_JCY1^FyuL*TK5Fa|mBm0=LGy@s*UaH=x(>CpW3x1f0 zH=&VUkXqS^%_U`AIf(K!=I@cwsePx5Iysvp%G1cf$1H_A03ltSVo#t;o#z(6OPBP9 z{6W|Dh_up@B@gkSk%72+{WE znYlDT$v>kr_>9rRXHjw3=veS=>XTZY0!D-0&PFvgf;(k+Ku5RLr6~7j=3NH!Ho_2Q z&+cfyjk0Gc6G3|j4Ijm{Y}*~=E7}GH{ZwOwp9=#UD#{4ItUENV=F5UFbdf7}r}^;W zbKng;Cdl5MVjO(-7#`X~k#{kA``dLL1(UBMno`~?=2P}gb{*1h87HnQy~VzJWv~kk z!(&PvZ$pPZ{pfV-biyrYQjcXTcL}3D^^^D-&VXSb1BTZHbhxqL8Sb_z%KnjFh^R+~ zWdpxHqHUk$>yUpoUC_zw1{&vG)o8aPp64QLYDd|W!}Ub<*`T)J7}?HlaWl}FnsF6tCl+debwC$94( zIG_`1&Qc&B`}FOj2jbbGrScqkZOV#tijJDjuxRv`>{3)DkfF9MNVZ85@|7hl6M<}X_79#8qBuWPs1L1>Oa>; zFmD>XiDF)-to?pjGd_r)`6%EOl)kjeH-=si1u16Fylq%KnAIzd;bnJdx=UwKff=9E zL2j49EISN?$_}r+>~d!Lr78_;z} z6YvjY{{VWfni?*$cbu#}?89eAAx&Y_A{2C8zn8KO| z9u8RGtz+}D9nb+3IsAf#DH~PpF+jW7?}rNDdTTKHT}c1HdR16_EXc~rZ@%__e|+PD zkJoWN$octCzwygoPIOvo%s(T}NG4IRfln|%CTi%Y0HUQ7%d+v~bGXxK$1s$zF5g=N z@pF916!(FI)EH4gX_3bA^F(I)@$s1g3(dNDc%SoL5Yy8s3?A2>S(?Rk z`S;KkJw@ZlE}`rf=9Pz8)-%fc87{m_o!YX>ze+h8A_&rb+U?OFT=pt;?T`?ntw>wH zqp?WdE7k?x=&*ah>7b&5U5~J|{Zl&FDw^Y!VdBb&FOBiKaNQw6upWsT;ksM<@rDKY z%M6#8Zq~azZzrfskaab7Ftg@2YdYkjZQ3|OhCZq9UeXm+yXR<*qu@7DsFehqucHAH zj6>>@Z?j%42LA^Ge#rQ#q7dbsxBj5ZrheOY5zp7RK|96IdVd5;41XkZYxY0D$@ z(=HynJ;3^XuQD|+W6;4q{L=5IcyEuYmu0WvK^tZi%ZH@*yHC9nhn?olrg&HW>PLU| zv(MkGeiLE5`9+fa!~gS>pLkf=R2LNwbL0}Pm@o(dif|f1?thhXwW2Fj114NSh+y{k z&T-8ho;H%|nk!E31N(5ZoZCfReKGs*)7bu{DGR5h4nfTdlb&6!t@=f*6p;5im#Ti9;2 z^DPV!JL{U+$2QTRwzDEQ&Xq2d_wrTK8zaBap}vZSrud>LHiQ%3gi#i;d%5hwf|767A!f`L@bS(+BZ z=Jl=&n^$gxoG+`2a=)wRQzcAib7W^cud?TwPr|o@hHb&k3ZgB;G!m}~Q!EE%0-xPJM`+bn;<7!((1S zb|-CP4Ofh^J>c&b^PA_ph#{AjbC}OpkB9>#cvJ74yCq#zJYb+{WJd!#pLW`3+B_Xd z!Ub*bisyu^tet-cPXf*mydhJZmKqDQ zU<7v;p$+cLNCX&n8_b8PArPsf!7ioIboRxq;ZPoGihjNMd!3V z4wtLO2gQd+O3%?%^STb{H6B&qp`)gqfotjO+=jE(>3IDoMh$WD_Izu12eE zOM6#o=V$QKDR?*OVDzY^;)UYUy&8l*;wcRIY{DykyzU-+R?|p;mp5H`&xmV)4`aHk z+{Im)(a5pP8ZPIUAI~)nDD+5UK;|RBobHr+Z~?6{J*5t*ST+L(g2OiArw**LwJQc) zzl%kD!;qpX^1)N&{+Kpz1K5@BW$<=rgqOx?u)#~W&4XX?0tc6SSw`@eYir7)t{NsD z)Frmp)Y+LnpU6Ry{AWj>pVG*~R{ri+ zzxvhK(^B&p6`wU4?0Eecm<>(5)_SW5H}<_(;hJy|)pHOARM`?}0_q18L^)Vp)~mE}5;EowSwr(HVOyxpf;ceqMLV zZZm2-&3QvAmW|>)L-lM+Pw6nP@)nT~I^)cC%ID2%=qxo#sl!9-iGHkWQ03wB&j~yO zpBxwSiZH~xJ8(yO$Rm6l(6w<->6F8f@fvbr;L+<7yD{Co?}1-10wysU@?~2u@M|(4 zej3vf5TQ*S64Mce#7s_ zTvJcQm`U-nK#Y+C8tybJun02p9T#BO`W1n+!h@nGzzW6Z8&m|>^vekMF5YRpJ(O`v z+*O23pB&~J%y2zE*@(s0iLNk;L%Aq0CNNJsQk46BI?Szk8Y6+xnD$91?|t!rlo2`7 zkUH+7D9+%$E!s?P!W}wtrw#9vrCUT8GSZ?G4O5j7FUo17U=L$?;C0&pf$zv-CGvvr zUNtWG>UME~oqR}wiM)8doM!v)0L1}DOdXAJ-@$9HiZzxI?|i7P#dDo{-h+SlLwIkb zdjLHbT6V6Dd4^V<=y9F4OkFjmT7G-Q&T zL1>#{jNGT3Q`$)Wsqq|6dM-;p&oFTDP|P~s;;l*ZwXe_!1MmCM;2@8*M&0?<%JRt! ztN4M`b$DbKc;>+q5VHuDPV%n`LE*8*==-7^l$(p6l{ZJ`R5KwA5w{TU$9l|K@KhmH+Sj z_3Kvz!rSw^WEvXh2|4agldA;4y_3oe+4pHu8oFv8RtSMp`O1(U1ufnc=+Hll-uHLq zqQTw!y%VNkc;?Wcog(hgBc;xv{>8Xa?<%U*-jUqR$W)n&`M!+9h^fK+{~jG^$Ife- zZJ5#<2J;i=d!%h6q;Avhj>6}CipvD69qS}LZKwFY=(}an`BZEN9s}JO-JfuH(al`h z#s!>^l`fq{7dh&G5jPkcIb~ovJ7n5ZZ^}_FpM^apjI>qY7v)f@eAM_NaV^U`YxBLbxELl+x*I6I7w;GzTNu)|bBDpnRxv)lqoW*5_W8{4jQ=CZ z((aVoq;Jq0aT|l+U|hi(4CuM=9UQ$w!rKAbp<{i$;JIO#v|<`?zw(BU9co}OC799J z=z)vylmLHie&GVAx_N?Esy>}%J)Ahek1t}L@os0%K)miClKdO!Sr4eJ^SlQQni1|Q zck^?HU8q~hR3G8$j#^n6>Jg2!e4KRw=Q|p0#c8G)n=z8G$2b}jd1S^t%WNp87Io=J07foHF`p zx>aG=lzR~fv}sXV?x){Kl1d$zO@fY@7Py<9^*XwI{$I7{yihHx?zB}rNG~W?d5N~ZW%($K zM+H3GkGqpqC@XE^QZc?qNVFoMtJZfBOs`3dsdHB)%9hS78~mjXs) zlDIa6`XYDtm6Z{o?_`wnsvHkR9yzAoJI2E=(tW_ti0K%)w)q(47VoVX_BQYEOaokN z;M_n4UeE!a43obs+(B2rZduq)z77~5kLWaa(S;2>&kbOv;s^Pd{QOlI9PG%`JYMiO z@dAC?tL~z6(hXe5LKVZKnGdu)42Lj1HIKDRPN&e$73ie5CFqcRdD-(Nnn+g+T}hfo zc*8VIG@4>qyrZ9jXDYsXr|;%^{rdYKVTou7@%G>O&CLjrSd6aRN)(I<@}BsDxf-zp zmC!Jq9*{Q3wX6&sV%2vugoyRO{^6k2W%xC}#NUtCJ*$k_CPrOPFcj**xA{$cK`Xr> zPlqLdcVw(q_N!UPw&GL>jl0;aMXV+fnwl`c^6E3|bo z2?n^{w}jDZCg<{ErA$#7KJP1|UpwlUdFTJO^Fxj|>C{?fc*qlaykZ<)vLkq8kM~9l zi+5e|qdX-MZkhM2(`#4{+mB9P51<~|0fWTv%6xI-%aJ$WdT{s9VH@!Omj;3#q2uFh z=)WU6!cFskbrsX;<})v|gG6fK_)1Y|FSH}#T~#mx}r*($D`*&(g8 zymY}MVdqWWV~#BAO>5OPY_<`1v@wSovLM27j05kNC~a z0Eq=(3<1zB%IUaY7kFfK; z!-94Ip8nWzd;P^)rKV?wPR{M*x0PXFTw~B(Bp&&CQSJdhcRlrKl#hR3pJ@lrA!^0? zDbw)6zy^RAM_Y7ho6?Rc!o0cA8AV9J#Jb zS&4X4_fz{B246e*PBzBRa+huzBzgqslpivvtKw~bUe?!5l0W$E!>f1luvhVdNS}OO zK8tUlWif(xc?8t15q2GzH(7)yy8uCB1E$s6RGk#^|_3OXmTe?4a zb8+$i@g-e%$IRUb5h0LwzHFe3th!9Nxmx+01kzo}CnQtB)(=L;Sl(f!KK{8_2^hHPD;!P|qN8 z(XmD-l`6lpSUX0*?wScZVob*gtdAJ!syNaJv!HtwJ@CwOlb_J_@?D^8HVi&s=U8 zI2*{>adGE~nP+A8@yQoRTorH16AdMGIrZMl$ItQ{%3G;8r4{?+Koj$#oX#Y9ephv9XU z-&QzjRl`UjxvY#PP5%MzdQ%`_dd$u{C|uT3C=1BOow5;~%E#$8cf{~mCEe3ijF+p7 zs3xV3cp=;C=zuUFaYX2kwOuKBs03>oL;3vZFdqb6fX769^KtWfPTo^*h~885=2o6g z(i1(Jz$=IOaGz}-ZtCcL-{WOxgN}V3-{1D#I>_(T?NE2aqx<;@s2>z(X1mclXR;QJU{8<4qM%#Sg+(@LFUxbN20 zei1qE0&_$^5T-WDU@edEOZk_Jei@Qd=h+>)IqrR_sU;{lPu5P?mq@YMcw(6QoT z9nfWGZWFez$m3pomajQ@?=xYIGrd3f$z3H*Hy_cd2QRvPi_h|c2TvyK2%>M%7zqox zi+PWGS4V5ez~XzMIgxRY&s%))Z0g-fF)G8y7QwN})W#-pwLGlPl(#v|m?^^g z9{XhKdnd++H9*-{uVYxeOCRb}k7aWY2jdae62}NPaOWE_=S=lF%@0UdxfVXcti67d zd<)Ef{Q2jfFJvkv78LJR8pOL=pSb@H(jTNpf52iGm}@hGdBMot1C+X)+E__gGf|-e zD9k2}@tMpc9BH;mzg}E59LsrM?=qwd3!&j>Hs~bvbjk}?;5&Oc5_9!7jN2T_=rhz# z0h*MCGi1NiB#e|iW9AtOIz^TqIMOH}(51dL{G4}i2R9sD(eW?U0LkMs#PA7&65!ea zR&NgOb)V@Fs>u69{2tOy`7gl$BFR%oB#$kuoGH<|GPp(sb*eeihJJ4E99uVN-uS01 zctl6H&>La<@|6*}Vg^(}ubm!&hqLGaJ3b8A@I4^v^&CUwP?RvzQaWwD>0LY~&IE)@ z8c=4-GVOFpvxB$bIk2Zrr{sA=+`_?yoXJAsTOk9y*3dgYHPp*^#Q(5ktq`9t2mGt_ zm!bXa_viz+08jHtX4#;jETS`xV?LJ2do{jaxe_g_9+ESx{4%KIje5Nxgtd{W zrx>%&pQm}4Yw?VNv#s#Z);L_MZ%DC@WfL9ITojIu@Zg0G%5|SICX%Z~;WF=h)fwdJ zZ{jO65_cv}uwcMofM7Idb(y*}JZ_tD085`E9|c+0NV79fFmUC8e8yQ>cZJu;Cr;0j zYpwQ3vw?y3D!^l?VW_11j%UTseDL(uxTX9`FXZ};vOyVL0l@vJ6mYUY55TPULBYTO z>_aApv8;StFn~5{FX>mpTAX}b{+WJipXt|Q;L{im?FPIchOfO&k{|ux?Cj?}|Nrd0 zO>7)VmggBB4C*8GL8mh7qid_0q3+zRZVVQR+z)JFfrXeDU{P}tb(-E2L#LTNF?8C# z(RrJjLZ{uEg16~YhE7|9Jt#E50@auuD2N57tG23}&hE;d`sgYKGb{B;GWPekFbi3D zxJP(=kfO5a0_FDc?Afzt&z?PdW^QrnYh^mU4pX%kCQnF#cgqSwEaKcF#>E{I5{Vg&2;oUs8(UEFb<6w-!9mVYv!k}1R&{$ZP{s;YL zBDsr_*6$(g_#K^OiUgBYe#ITkO6H%Hc%aog9*H7bZqW4Dr;F8xKJB{er{xJt=rKNY zs7?pMG{Iy(;BUaHmb?YX;4X@1Bzz{KcaQ&buu_m^DZ4699$(N0#4l%GC&CtOJFORejXp@fCdr+=q@wN z6NE+gden!ZdMB&V@KIXcSxVDgB(z6|B_kc`az+zLx{jYYD*vN0Ok6s^*5(@g+)BeL zrz*y<43W*VYKW+PD6Dl9Qic8x;Y#-(WMr`bSSnzBY1AgkKO zN#aqwbfIuTmz2Ge?U*!z&eQU9Kmv!5=+JJYtpq0PhgO)({^Ich-_Ucn2ov$CPcZpg z@fK3;Ay!3@bwE(jxWsuDtYZz3To2`B$UNfE)YOMAF@_^+h|KM`8FCRn21v%4JREXu zpj024vsB*J5;Cw$&XB@zXvI$y`$OcU;}ogkSI;1M!nT)AzH2KY6Nke!mp7ND(bv5L z>QoBOhUme=_XNX3XTKis-eX18noE5rj70qd|5io2R&>1kd}JK9tT(rxcEaSm*XXqf zP~U6Pouwf%WEd~E!BZW9C&s9+kspnKF^l9s{p0eQWE63YN5Rf34>_tpd)?v-^+rFr zn@!uU9?=B9H2x=fLW(&fW5^Rj-F5g<1);0IAft%%XK9tl03m(g>nrO4$uvNOr$`6s zK&r;f`STufK!ZW6H=Sib>#dmy7$x2<71oRFqxvqf_oaDEuJ>uj0}T*de|J#eaUR+= z5Y>M1BDqS)Q{IP>ArchLL9nu){w~5A$TBi9DjzXk56lg=tPbh=j!zFOp|PK_O0fjJ z?FLiS$PbEMI5FG;`1cG&D`j%x56V?v5SU-czR8|D6HgsCZiF(8sl1~}=zWl1$sIg< zbj+SUMo3-bahE>~J@Y9jX;HuzYVyvhjk-$w#F_h^R$zF^r>*czA09MjX@)gG*3gU5 zNIU`Ok2r{_aW)c;%p>|zx@jETH2KnVYQJCB@jz_}g2Fo4q4Hh2gEd<*iEV6`m-VL2 z?uz$T%F2dOQ_12ee8jm;K#iS)DC>Qtif^%oujd>-zM7yS2xcF-E zKa+TFgd{ohp2f{%g5uL;qVL=hhRjQR&U(|-7FOkZW<^}&H%$Vwqdvrj570KWq1*f z$(PdD^z%+CtiF<0#!cFKONQxld2CvKz2XJN*k@8`e)_u%8@bbupW%7K-JI%063^jn zOU8)|60Q>0=dX`c_Fd9`*6P-zHLo$ONt^L-z_j`lUAR52t@18tf~8A_#)V&2eTi)D zjDz#b~(WS+wP?OK_4&KA2yR z;AL2IW~&LGn+}NdGJ5MXz96~@?dvis19XcX2jkwwpZ?QNzjBfD_c;g73I|vfv>9~U z7y`P)>h>tQkayi7@IW4rG$9{Vc2u5lN#V%NJ__!n@}x-NLydNQq5%#$QZljHn^vck z3cOlL%k$G%?!3Lm+Rq?N`7K^e6vj0RogdXu?UX7G?y{5)mW7Rr$5VM3;qEB81E(CJa`&O_NEzk;-$(WD^F!uH*G)E#+9)X^H{iXc#`>6hK9!*ho#gO#_cn7!F_F0`eoH-ytcc3+B9K!*5)(e zieFYVfm@4~vW!H+&s@IxhcYrSBH&_|uD9{ba6U~73>oLZZAd@+FfL5qxfjGS?9SQ2YRAG^}AnzR(h5;Klz=8IX9#)ub%n+lOzb;t$p{h6t>=e zKJAI@#8+kFT=(<-P{T6Nw2dXt5?jh;8EJV867g5CGVD}#LRm2rzxt8>kQXo-#ec!k z?<=EVrp;rEq<<~C!{K=tbbdqI?*o%LHp(h6+YWw`w_l%lM*CNj<<%$X*eYA&GPs{g zj>T&}DK4aW|2}4G#-4wQg-h_f0@2QU=mE|7bIyV3IUoT;K<_Xp-Ip2#+;9h+M_Dph zas9K>Xah5J(_r3OnKa$tXeG;NvIh6Tgi0rgCNs{s=}?F9hPW?wGJ)rmL4EqPSO$o` zbQze8`CMH;tNsa94eiUSdadfzCzOj7PkY2Gwly*hE4ISS4ldL=kZhfk#2{R4U-D|`WFQhNq7*SdsN_kfVPxKj+19Hvj z6H63;en!59Fh5Ky$e;;J7$^wwEi88J>FeT(rl)|@iVdV`prox74GqVvkP|C|fx>f$ zK)2|vf~qwKbR$u~FQaS%?t$?KvMZz&27|il;zMr~1ZlVU(>wE#;?BxM*~#dukl)fO z2;Mi+6jN6DNz>Jj?8mRE9CY>X3o*Z8A->bcfA@>tWUmz&eX%uZ9j65^d6)MHMLhCg zrTSS4oe9URzL9aWEu%9p7@ykSiBF5>vtAFZ&_v&ulujnMG6r=#s+^U*0T}U~?lE76 zAp5!;b32Jch9zn8NTx0ZlJJwno$>7(0?2(0J=0oCzTu(q zo@NA5rbC;zM;#QG;VlEi(WZKortxa~Fj=*U)28$1oCA|_Kr3}tf#!=GlxHL(Aq#_q zPx*4&A>enlr;niSNdb>@v$A>&`*@39m_(F>4nCO!fqj@03TRM4^NF}$lO&5TGSaem zDt^M3Oj>lY9}4Sc5^pjN?{v7XoJ?0-hEC8kWK1?nBr=}{rvc9)O$P$a-ZA^fQdo9! z-c(!R`)&S==R;mE!fn#yIaE6{3V1Z+kgtp%$SZ^Q zWd}W4$LQ!dR5IQnbtXedh6nYnJDf6tFdo)iTyMO1t9U;eewqu5PRXx$;u|3HiWIqj zM7(scY439*B#kTQX_*|*M8M!%MuFClt^Q!hERd3+K_&$(WzD|gs*Di?x#ENJNn=br zbZKsz!NsMhQP}sUrNQCJ`|h$ADsMnu_-WvzY;Xmv8@`M{z~q<7cN9U}Hy|?6y!Dt2 zff$~81|acRK#{Bw$#`((1VGgi*kB3ve6s|SU57K!l13}w2 zP4tcNR1IW$`YDkdP z&dBR0kMo$o|F^uS6o$YKO0n8UFvoxl3mIN0qdOQLb*-u}KFUF0{x+bcLfr$GAkDG* z=}{%WNC>7sAn3*dGPeDvT-K*mCx&>1aDRn5J)!3%(>TBo3Na+bdX1UPM*uPm<+0NC zhX9qvYha8heO{07V;Ho3LzD$Z)5kAbke6qE+O*-M_eDB>V7#;NOyZW&qA|<()nYJK zzIdwf3+)45kz`pver|;L+&INB9VL%KgoXX!6sw)7DhZ_~i>+>>%Qpib75{&_?gVfA{+vSg;ie6XzuL0X zK~J+q0UxMOcZJ-OVdnQYe2}8skg}V$zPXf3C}vG)v*HyWQ0jN(6=BO$=UHz`SImm{ zy!L@1J2B*CrtFxFe1}2+RB4gre zG!RgTsV=#Rk!2Jx3b^Nrzlp)I4sXg1REHF)|CWptZNs?q(|qHBh+)G?_E&}WJf)5@ zMux)uN9`uf)QuNI=R(T;%;5m68vP`VyfkRh;nLmqm^>o-BVE5~vFh^Y{gx8b>g;d- z!R%M>K}w(RoYL2gnvXF?3#1S5Y2I{Cw6Lm=t-1Bns875=rVDOy zp*S+w!~^sQecV$Y|1E88nl^3f%#;2ifwwTJbzAu0}>*2o;u2$hu~y2%)j%l zCe%sWyl}*CVjLH?CoMM(yc962{XNQ-U3tcXCf-%zT@4PGewuIVfjE&#PXk#iX&y~v z9sh0;4Sd>u%bk{&K`_b)2|N$d2>z&^As6cicx82@r1)zhw>PCA$H31en<{k(uqtGH z%DRdXrqlK@QMEzu6M57pX3>Dbz}SuW+rW5ObJwoRFh&`#O;Wk^fRwuW5G8((@{x3c z7AEol`nc3a=?BRLvUmG@YsTl!_;B~=t^V+#O&@f*U3tW3qdt5xEU%mv1;L2hi<4z$ ziBq3BtS!179)*#KT^FC%TVq-W#X%nmr({s)vN$&rBmbLhOW%^WQt5)xm|%RG8&N6S znuZR<|NJ>=4rtYbB3Y8cp%c|{5sIieiOcGwX&i^2Nw1>Q&*R|cl`kv%3j@p(NmJY)ny#||!MdEjDr(L!04RR`nXHuUJz;X+`)R1!Z)3&+tQW1jLdqS_8N zcvI;7{PVa<+hy$3&=U>eQ@(xc9+3#Ih`c6y&KPy&&)?}BkfEMDN5RCYpLcj5U#wF=JRbUN6q=w@D`KiDU7TKq})>~@*iSoR7tOkXV4I` zDA+*$11qbs;HG`fjgVMy}<3=#1Eh>vLm(kItog4CuD2)lA&MWfyk0B;QL>@Bz!t}r`x~UbNCu;I6 z!$ZSsu|xV8`O>+zneSmy->4r>i_K~W_1$xZ2<<2!}xHte=Us=m{neUQwW(fG~fpwCXvq1K7YFk8OWSdM4g3lS?Am9Jvy%@;kPRs zV~otHno~z3z9OLUX;iGb=&RcdfLqkptCKHe7=)jpup_OIPlFD>4keP%}+atFh+X+#zq-ph(Sw=7v9SovZ)DM zvVm7-o%~PdNyDG;`8gh@$CG#{2Y76MV`CsKK_JePh71pq_4R@Im0f{QcSy4;lx-8O zeoR}5Z~M69D#tL3`C&&HB6s~f;W&Q=Ie-kCu>-GqD|hbvKxV3gP}9dwoB!0;H$*U$ zo6}Q1zNFd)-x|&v%h(eyyNo}{q~Ys$EcqbbYa>L$g+?gHRnWex z;{L`hVG2DllC9FMT=%`SCU3jE8F-Bxb)@H%`uFJx!n0B4YWBQee zhl%DX3iqa~RQ(DsJJ9kee63)m-*Ux62p;bFHWB8 z@26j&U|`h2QH2;Y_S1->o6WWj)oJ^!tp$pPm?o3F}#txJk48^ zR&8pUwu!aHD%nc~_!=Y{eSBPyN4kyTO}8a{Vn9Q^7FmD>?n7aU}Y{X@noN z5}fz@Ve+Q|Z@m&H*cv9>&#(~nd1lDF;;KSnw#f^bh^q{a2rGS;3F^~X`pw}U_crHx zg85(3?AOagTaX+j<%RS$vR2`RRzh+m%Md&8%g!^*B&RF+V~5kauphbjNxx-?s16xF zw0#{pxJld1gAux^^D*=8bBvqHVd5T!UXA(xSHIxVNbN%(3wl9k!XD7hdy-@H&l-B8 zootf~5xjm4`aJUUH=4Uabp zh1yXbUa1uyW}abihg4vU95asiOcd5v=UGP{Tsn{noc{FGG$AvA4{d282W82IftvC^ z&RUcy+8$Nh8lr+reXQrEsl^BYwNxMyA=Ml_Ms918<19F(5Pm5feX=Np zX_OSoOm5ke?zjw+PAplxp{@Nr?31X7RpcgaX>%pK@Y~hQBfiME>FQ(4VwaV0-}|9H z&_O=(yY$-@e2*RMyxxYco&m5uFPv$3Yl%%fjW#0Ut40?qXPulqI5`XJz5ChG8 zR)nQrW}vrG4Eo`;r&3y)Oa-Eqh~IeO(nQ99f24ux=Ox41Zjq}P1rX_zNgd#!j@$Bn zfToj#f8XQcO)%nz(`Id-ndmVT;eX_C1-*l1>Wa`yi}7x)y100)?HMMBr|LKLi_4qG zTXZ2WI?y(9qL@crb~4Zb#qv0O$aJQR6?62{V(&|i{nUCGGsyKb@e?CtTYaAjcgl%6 zzd&E~4X;vfArUd=wjiZ1Bh!!t?j~(sODikmf^DGvag(+3(M7et!)PA$dnB$7;3H&w zS>7g>mi89^>C-Lr&1N!R`UhijC_M@1;*u@tKhdd+;KsGdl{(;30V1%qGKUwB$6URk=6791FNX?$_=s13PzZO|`Y5MYmgUCZlo4#$R-V+~NA&N3E+?9#>@2VWlZ__-S#abj+hx+`Z!ZlN8g4;@R?0i4*>;~6 z_^(BR&P&wY7-fh{Hq7{v=Yro?*;X0kXM-`=^vh2gHn=(WlxD=ryTJij<9*4C*U~x` z93!AkKdf>XcYPGFwqF8n(}fo`A5Qh4^R|=eK8zp6a9hK0srzXzES@6sBk6Fk=kIe4 z%!>nG8zaOqM3%jb5w=Kn7?@FVP-&nkoyqDMla{`B-gap^U!v6&xWY6;#CSj0eo+|| zf=;}`@maGLx9Sw*IwzAFPnBr>ivS!&TxGh>v#w6rN(pSJ0uve=|?aCO|)N3YQ6 z|5;Q-oR!!BXPAKOP}LBx5-?LoC1c3-P08ITBw9qF*TSTsB$NzJ)1+Cp7d5F5HJ*9zkX8of0mkCJdC|w>b!#@9<>eKxQLr0Bey`&nhE0+AsMAI^!gt|h^58t<50eAIA5ybX>T3+N3T@tJb^X*`TBbc;7}1gY-wkXAtWj_%%bnJg&N9#y&NLnf3Wu=caY3X@y8aAb^*vdS8R1O-f+ z+Te?ob`~CJ*P-f1$ZH#Kz*dqb__FIC*!A;ez>xQ;pOy^k@G6s5LmmY26r*|rK0W4q zQ|1Ji#BtJbP0Idwv;FyudPDx27*c!mXGFK9%FeX(Ik}NHR5Bs`P=GOcy)A~HJ;T}2 zC3?*huu#EhdMdm&Y2c;0S^Y=LiCglKQ;t%gJN(Ps+HAti=q$Knncmlj4{B3Dv%>dnCg&ZjCfGnQdTCGZ9 za$eyHM#wfsNCO?yc5q*(w^ekjI$JYMyWm;xYnCG3lw;if@Cu%`vTzwA1Q#(1cU3Sb z__cz(Qg|$~l&z1;)TgbLp3xHfdGA9Qen-fazP7mUCPB3cFV7PWK=u!5y0+N%em2es zk)eXDKE(*UbJmOx*A~5Lj}`-NteR~Yl$N|!`uws#7X32QhN((lyXkHT{Z5WPQ{IzT zO8D5;eMI=)INTp=8_oNQMmS4&SzX^5J%QI0PfmvkU%wLEOvCx7WemgK0b%KqI0*w@ zW2_{{p}Ztniy#?CI^3IvPxw_9e5Sq0`p)C$95^Wsd~LU5Mls9|!bTEC3WGdt&qx{7 zP|lyqJ7Nd+(2aXqv9PLUsKtXOunc6L!P{(Ni z06+jqL_t)q+|AHlGZWt?#@v0~T+0O58D)S7v8-ei_P(n`Zevz^2c+L}X`|k@KaGnW zxKBsHp2a-)6CqyO28-C5dH^$?Lgzm1@1)VofUdyfgJd2!%w)&}bvx*-()DY&E#XhX zo~5`yR!tjv?c0Fv`n>1_ulWQPp675nW67^GCWi8Df;??(*&5mmUe1tp zONFL0V(gfy3S5Q;=?#KUFmSe&<{oVutGsj!Fhkc5h%c0nWt97dj0_OUMBu48TzTKL zeB>2x^-){~ecju4K0Zp#B=5M1+wmIyz4ud*r`|=uC zxU)C4Ix=N?r_LK}^XO1tJWg5pb-r(5nl5+nXU<(cj(!8*yUU}4(H2SZXeFMfyj`*H zpj@?05QEDoW+sbU^vi%ddK4YAdT>VJKCL{pU0wm|yMr+zW8*R5UF7XRGDo-opVk7- zwiqu5arm?XY*~4vne#5EaRHI)JE>=$D|ROGb&TAbjQ6qIPNt+u~Sp1^Y+{hD$BIXHhD2Q)}E5HUh@pGb{Esg11Fz8%mlH~3kl>Qbk> z7%polG^Gy>bXU*U;cX^Ft@4-zQ9h}P*&1hem=r5TwzV8D&3TZVmw)N(0$UF)@l5v` z*n0JQJUhh{MLUYODD%0TXBkz;Y39L;(0D$i%#-I_M93LD>oO1iAU`$6Sc5UvnFXK5 zFtS{D)NmXS10Wqxa`fPgClio$K@yAg4bdTgQHBIF(lMRenO*-=NQuR_lsNfu{FCa z&zy`CZPSAH34DGkWQ5P3Gr|G&{k;3++z6p_;j7sTW^g~oh`2-2^0<|eTiK{n@CrOI zGQz<=l!y+7)n<_y;Z*r~clInaWtBy7u92s&Po#`=S4zi*L$~tww_Gg0bg1srES!G2 zIY5aq=nmXbUK4@7h}e>$I0>)q1Tpn_7N4&3@Vn!HolG@6+S5`YIkNH-O@hP8?jUTUKxbX?WKj zj5}Z;ehEA&Z42;=lU}l z^zqqwXrv}G?Om6#vK201VR!V_4TLBi6IOg)k6|o^2S&$Z2Dk1P(LQ-=6n@buSO#Si zqh%deqxtkx?$5Lp$S7QXo|G%D%XLlOE?w?)6xxA{Q*ZO6c;V`pL=Q$!*Tn- zXe(jtBO?T*XKsabt39{Bj>P(O8pi zNp4yAW!%I|nskxTJ!X4Lakj&Xcs{cxV)eIl#I%#B%Coq6L_G~>Z1}Vx#{*syCh(yx zm^4{udvhQCvJG8JcpVPVH#i>BzcBLKk6vt^#x|bXExtK}%Cvh87$gETw%1_R60bD{LIZSJ1T4@ecYss z!yWr6U<6|g9iz%=mEnJ~=NlgCC^vvc;YiDa7b90^%4Y?#3Lne78I^pq#v+kZeQ9i*=U^##(y(=a^xmD>O`3>YHGcoKfzaq)&pW+~11 zn|EFB3qJKh3FFY-M^i`UI!W1?wk_}62$2P^2I(|--bTp%h*{M~ga`*ljXp=cn-`xHvu+F3`I5Y4riJ^M&ox;&wEWew zmEBvuf-@`5QtvMh;IFQ4}h_=^X=hs1}ScbNW{u4(!@XWn(ZZ}_B#(c6*eR#+Z17ISl1 z1S7le_W50>^Wz&~SXsUvt}ZQyzwGd&Q6!<s*W7mcBUT2@B;2U@jis={uavfgOZPP}as00sG$9IRZFg_< z;j>YAmA4dzKaud$p4K>6@dLQ+8_VG*@UIF#ev-w%ak!MP_RzK`;Cl(~ojheGfeFL# zFSzfb{ktzZao%#vOQBY5KVAq5zmx}vHcFZOx#Q1=%i$j_Ukksz|3&8~Nu2V!EQeu@ z{{EHAhX(!D&(0(?B=M%jrNqHqU0yb_{6pwoMWO%5H$YSldH*GCIDn?;!)xJ7(Ss4Z z$Heh(;rWl1_u=*M4(*#e|I_F`3u%a5$e8}&jcef#G`8roHQp;H$piW!rk*Nw{3yu- z>i*Y^TIb#WOiA)2N{u^eE*}X;j7<$+4*G_ewC$M6WQ4Na4Gx@`U*a8 zOn#^HSB%>~XRD=3zTl1gz}H_<*Iyu)w>dcfP_U{8o%@$;i#CwIZ-es@GI*JV)W6~I z?2iC>nMI4A&P~#la5?;!wBdi@?*~Cp_&$fB13W%IhJXJK8q{9%_tA~;65FcZMo+2T zKcFqKqs7PR!sx-6@L#CB(gaHzRzC_u@iCKEf}Qn&z8^w=le&NO(e-fS`f|9FmnVMR z%vtNS_nz?h>F--u^Fk5Nkmdx9RrK!1y^D9(RXS3*5W{c2_p#a zXG}_WCn;w5hw*}dWL|(Y4xi}9IBUqTLojq-f-(BWmCKtysnH@Z7U@EBuTsA=pS?8pP#2O?r(YedGiV<^@#8qdX5UKr{O8<*VmKJRe6L- z+gKjn25 zkJ^5Jn;z+CBgE{B-iAq^;{M)*N2#BSQf?#Qvrd?{f`acG4pX*X12)7^ zXwng7;jl`xrSPl|?R=<-ZPcN;WF3}&HRy;ilJq%iGYK;)ZngIGAx5q6sOdnx*pnqi~J;P(NgWhX6T;tx72l~GZpUaeQyM-fLKH6f9C|?_a zqvPjkEYn``Xq?R&r`AbhIvN!7@2;e%q{-nJY~-sjAVs=d*bNAU{F7r zM+S&wkVw=^neKmZo~_3Yph$y}j*q0ktfj8Tnny|lMW^emKSQ_$qkb>if^QQ3iL7tvuQ_X1b;9$Syh{Wp^2m&$mlafJRDN1s5jUVqml7gu`0dj4mdwyz z_rqhxBVqHHt|M~~ zJ=jwZQoknhIy81PA&Yi&%54Z~Ohb(1!766Ict}LDt9Jo;F<++eeun3F&tGg^%WWpL+$ufKPqBc)lP%UZg1Krhw|z5mH4*rBxSw z(9UbDvM7$6E>+q0aV$Ho;Vs)ten=n>nB|L%LI*na`^*_3t|e|TO5il8Q4BIhoo3qL4JMwXf2Hd#Y@Kh7Uwx4&Z;hctx z?T7nP0Jxf07(BY2_5MlIiab`>HrPAqdfo^8jLVQ4KjS2=8q3I1MdL*Mq)K05!I>~JW)xkN5kny*{xea4n zP}x54I|d9z+gx;TtU%;;iJRzu}gDr zvSdI-;9CLTLss%tmpAR3KHjm$M;E@v!Xw(zH+R6lH3n~(%*XiZaPH(pAL@vyLv{D% z6GN(H+tC_TxjaAUoydn_@m2QY?@L&1K@J)|y_$RJ)3~3;L1yHpoF-3wm@xr#=-Ga3 z<03T_+0z-3GK|?T@uN`X@0IndwyOn<421geqKpg%5&7#FA8YK>-#06U1@8Y~i-W^7 zw-}Hi`OBc2YJyMW76Z4+z>m`MrcJ{W(xNR@%GW2w0na)pww*kdyZ8$I0SYos)`OC0 zGI@LkNbZyTNgM<5ZsF!Ye9jRoE7dup9f?j8?-6&{j0Bo6(@ai>-aw~3ePDk3MX3Ch z^Mt5R6dYx{l2rk+)UZlC63oI8+iILA$bvuZblsZDgdIVnR_6NcTM54Ikg}m~9y*ZT+}rHz_mDbKv88FT#P@D!u2^DuW9C zv|O5Y0+5Y0;&qoc>HEwZA+ABTV;e3m3!j0iyF+&QTPA!5Lxk^!h%;ywIHanfEUwgrm;>?IQ}eMj?>L1O@zQ z77T5BI4iFlZnn>2bjyH}R$f|~P1j2Az?J_)dF!)r44bCfD;YyxSLx5TR>ut3vSeA? zi{2!5HdwH^2w5!SQTXhTU+JYeYebvLNo7=J z7#z|y(lK?F!_(0=zpJuHpGr54c`Q#_fa%XX(4ei0Rq$3x5YP05f;_qdhJjbsm6O+F z#YEhH`~o#_4Hr$mweTR#$e!|K5F>l?Jg;G(Y%(7A&!UP|`=v`yQ?wIK)=q4D33FF#anf&};z!|QUgi1^FmuAu%XX}ogzdEW1h5t3|-CTY_2*MATWc}pG?F+f-W zY>0_c)JhL96!gYGxkG_Ef8~C`DFW6=s54kP^Y()D$?=qSKP_hf+32v6899M7pf*6) z7=?0HW5~zN#Mz)W*s6M*2S*YHl;T6v{+Vno!dQ{srj9Cn zTEf8DQr#xg{>S*y)0?zBp1>-0r@iQqZDoMy5XlO%z~mkZ%=8mj+2PXfTZsmN!;{rzpuSK_4(A# zduxOwTP#-?gF$OpI}nZUQ?}2`2HU#Zja!JLuA~XHG-l zrOc`zs!xNAHg=>alFCWAln$S6rmi-UmCa$_Pbg*3u$tPCGL&-DDj&D+CabKw^o_QC zw0bmsW)x;`)e|SlIZJWfnrZu}JrBA}zaYf$=@G9j43O0JXDP#Z&@e3yR>hLH)K#Kz zs&AQKLiH`@wc=6rux(Ibl6{&6qdLf6Qy%X5B`!_cnfDeIvKpx`P>@xP6TBlM4}bb} z($1K;j6``b^gA+@0*ZpRuOKTr?;#MuO#BF^@vJbpfpgg)VDLa^nQ(04_CI++@EY{f zv;aU4Mn23e;c45DRj1JhrNX-8K8ag-$9T0F4^!#FtU9yOS-=`kcT%pP%XmYQu4Zzkc-ay-kRGVMvo*gV=XcOyiD1j6(;@T7In0Kg0pR)w1kxPaA$e#vo-iM8s` zK~I_Szq^2ef>E-CGO5Tz!q$L3>C9A^uKcLCbzP1EnJLc*JW6{;Iy-4Z*uCl~Eiajd zj%%Ta*GR7?^Cpd>VD5oShv=5*u^r-f)lOD+_nE{VaRJg6lg}OcNABx;lj5HRUa~@4 z??7KcZf0=l5S)IYwgXM=G#Pe%G)ujHSth9(tGyNYGIZ~W52t!DRP-gsI(&MXMw<_R z8ew?Uq@LUSWv=*{l;b?BLzH)gHVI$kT?(cPKOP?Yk{A(aY8yQBRA4 z_&$d%WdvqbgHa5!-V(W)+6cB3r5O571|Rk2dT>kjUD&w_ct9xpl{CSCZ}Nf+9iZ}x z4g`${gUN0namt9Lrjp3l>IoMDb4I6T3~9VSEP%HCuUWEi z**=ZQZ)L$uk}g_|SA>JC^nKZu)!}@s=)&!IFIHceNBo1%mW}pbEJkX;t|QxzF;b)p zQ}rQ6dF%?gFz?QrMPtD9^Bl|s?-0GM^L(jBx3-;_LsmJrc6S1tGlLpg=3ugTtgw&J z%pck+wf!jG12ZJg;<*+Ge%ZN%kv}HxGGncqcbhP8z0h1mPKMgzl^@`R(ycs%1c&mx za+$%YjSxDgtU-@b=^XYBVGR*rlqwx$+>w?*2$r`(2e$N+>{=1aaM=ks2|dY*PW5xB z@&R6rEv=4t>&K?r$(B;LImjeKKasT2RyD@n^VafCa@U^1&c3I8NGbcies zo<7sy*h%WaZ5(U2O$dG%tLU;6afL9V+w7YrfSB6NCxMRW5<=)!9V%%1V-&0x|tx|-@XG8gnRkO$; zt}nD=rKLS&$pA{rnroWs0ik5U$b;xB`Cqg2Y71?pyXd?A!A)($C>ZNBKNMpBeX(hyPc7puf*tQf0mvI&5tgKmbsOK7FnO z?&=suHs=((caNaESMP0~&NWLVrERYrY} zK8h%-L)5wz`rf#DM&TRC!@&9ZKg896G#k-;&Rm<`*0cgS(~zslAB1*Yf{0LzJn3vF z%{DbOT`i^|a@n%a%3#u?@7z}vKsgnxTXky`Q^kDx_W|V|A}IQ?snor5z_cnbOk?8J z-tIQ5ur_7Othhs}GR{N8%A2R@4;CMzbz*nhOcG0`191G6|vw^ ziZ!dWJ9cFhQNEQ2M;eUjub{A7XNZ$g?dN>WY)FY4PM%tM~|>-85LGIhj_! zp=Wk|16%oCy|Los9#fwTGtTCLZwdGoM&wfu&j1RWZa$G_ZqZGn+dhD!k9IvE{hpt9 zl40o5HnF*jD!Bk;-f5O}O#}uUGQXds!|>p6cz#hj+fS=9P?(Rp7;`~k(Oi1D4Zn;| zN#e?iTfTh?jS(^>FX7Ob%PO0eF4~Y!BWr2-+D7Fgg3SE1GI`P_HbPjHOTitWEFVI1 zs2?#xNt8*GwJw2MR+zsIe{Y}O_wLIyB&H!coMi+J!(;s|5TStEO>w^=yaSi+I2dch zR0G}nfic6M+<1d^SzsDhp`#7cw4bPnoUA57-KNtb4sE5Db9J4iH-p&RU`qS9k^>@1 zr-X@i-^QYCB=Zz!wW@wPe=G+ym@xu!^TQ7QI%A;*tF;1+b&ySbw|S|!G*;5w*AxpG z{AJ`aN-g*f5@i%IaW0`CpXy78MaDFGbCq#ZE)+R$cf`4b-oEs}7^3|HpE3G8F%vSz z39Ig>YO`RCN0RmlPL~Vn&Dh@68~Am`?bbVJ{!CTMyMs<#Wen<5+BST;skY99bb`Y4 z8`ZrvSTyNDgVBRoXe@k$5ukG~Gp(*Iu9&)-s!x3>!wA`lt>Lb`p$7xn7$RxjG2vvg z-Im^FvW9awju7}J4=0}M(-E<7l-HSlbv<&##XyBZh`t4zLIu47=d4qGjwxLSBL z++O9V(06d56L9gy^=?-lxa%)qFY#Up9QcxORxI2)o*;eZ6}weID;% z#6?u|!2hms1Z)weDZf#4A%At`N^ayfhM_zV5%BsOcqDsF47$B{PYWR6wBm`}SYhz5 zNdXNMnlgf-UPUQBp0cZOe`(%6cpyV$$oP@$BF7c*G<;lIsMG(CMW@lnWP;;i zvOTWMi1Fq?#=g~W)MxIvvD-79v4s)~0uvb_C`(yF_c`zs zPg0jU19;u|XgZ%&pH||Z1i_#n4B_;=BHf~a-2-L`S5~f1wIn1kEf!vcrOba@XgksJ z-aZ>QO+q(=zrjSjhSHWo8ZunJt*le@ph(pkIGL+< zoiU_8tH9Rz8+gc@`k=l+golcLYH8g1h}Bjm!?I+L_R3p)5HJqJFVT%WxA|MA+_ozR zY@37RkC+epbP5mo0sW}oH(MH|BLQ_^F^xR$bQ8(R02mQ^MreI&f} zTSmE=k|#1kU}~9$HPdPoBTy_A&&mufoEo-|_u?Sn#z$6ZEpUiga_=r-7_6n?^U^fn z8pP{No(0_A`YHC7m!BO(p}9;1=BX4Or>t8H0{u*QJ{%6g8G4IwH z?k3^jVY9zFO=hOVb?}$L)Nol?`kN@i9Vvd&BA5QYzTuTTNLAWcpQa5crly&^@d#in zSHaP8c!U?3i(I__wqMjJpFQ~D{664h0s3WclF25Coe67|A7Y${4^|!{@exH`g@%|h z+BdW?{5xcY(gCVZo>R7ED+)`lRF0w9C?RJkI-OD2Ql8S$5w|fwwiVBMSRL0iab@M7 zRJx&0cMfrA7MiP*)T6CA7Ie2MbJLdV@ZM*EwMQSc2y0SN+Q6f}g=cHWDF%q>0r-hu zK=S3bFBtO;K-vzkwq4M_jpP{+SKjt(O?bg0V?_N`x9JWn^Nj(r#$qU>JrR8?JSy9f zfdj70{t^uNA@HHXeg&#qd4Ad?VU0!fe*}(-e}+PM!K1$xf96rUtr1nmAZZm!g|f!E zGl-eX+RQ6``UH>8eW0BJ`nG9tI&=eX#>pB9nP1}#0FQ`JrMxXQKq7&uPSU0|L`L#8 z&<*A3&&YD=Mc$^C-Ui2qWcg_j=#)2>o(ztPS8BgoO8?}#$3Q)mdjSkB6CHP#B~9=#yfCpB>!IYw+X& zJijlwhgW?W^zmyfkym5Iwd<$P8dl#*QECG4w@C8h#Zc&oZu&cw?ooKGj5H`;h6j;g zjj{XI3)E1WzK~hOy3k|mF?9i3p&zPB7Y=x&m1kderMPAADc?O-K4)4ywJPqS z%g{;p^YDu17}q?C{1eK>te|5i^xSmY^14A+=kaQ3v}!Vfo_boI(#VT|i3s+}a}XLm zyh>l)gs!0jsVbv~_Qkwv(BM3bA1>ikr^Xyn=k{rZFfW2GOih~w=g(wQTCz6yV~{fO1YqR01|T6QAXX+&Ce?D z9&1FdVwg27ewQ`LTlJYoG|+$jxDtgIn)Jm{jcBB_oKGhUPW)p2-bv!H=dbrWou71ggiXv2!|=}XQur?rs2^hC zzodiy+}5j~)-2cA9E)lV1`xN$A~v!xrMNa{fM4;T$U64Qd9P=?kY zk177%XRE(HTn;~7z7~f2Uvz%rHwZrd=tdY;Z(I+*Pk2bU)PKv%p}s)+cTVxcx-vMl za{o)=68;;@;lEl6!>6$LrPAJ~M+OLT+(Is%&Vz2r+0t^@4hn_8{P0@%Q)K+xOzOY< z-4~rWiJv~Hz}x?UpUK`z=FJ+XUw--Fjquyo!%!qm)Gv$|Eil%Qm-e)Ds8WqncoAbr zM1;3}T%t)d`e_OS*K}zgg`qANH02Px5IOxftp1zA?O@~qDI%Y4W$MyT`mK7=Td#B` z2y#a9*Nh`{=0Z^TGqz9u3Z2;yZ^U29_S-UwX5o-bVYED?&L3sLqHBK${(tN8Wr!Z5 zr>Vy9TJ@n1UWV7hb!d2s4r~+u1Q~5H4tC&i?Z#5LLf()*5Kfg>8PR{^Mpy<<75H^z z{UA-or61_We*xSN@qWn*-KTAtG-%Ci3v&1pIs8GI971Q=>2=rEN#Bw`n;5BZ2{h|k@sUiFDtC}B=I;{+Wlu~x{SUbkTC~8$-6WO zuwb#KYu3UVDyqT4Kv^{z?7LyBY|Hv(8)t(-)IljXe1$>h$bF^GF#GAigbJJTDgOn5 zIbj^7WThs_?Tf`}@IgyMK+s-=MiW;2>;A~<$BNgL=zVX7YqOLnt54n4a*woqxe&TUH(-KmC0Ozl=bs_e-4MuF+lJa=loz=6X3EZ6v?G|E*>ncMvJl~o=bqK%bRIS;H4Lpy3o`qfZi zKK0?m2PPLC;4Itpec}VZ5UX@~bo4eWFntB*9pn`b$sAs!rms%~f6|W(5bA9~pZJ^k z$iStKSCIvs6RBnbj>(`eHo1jTZ~q&Gd{2pY5L(;32;WCGTHd=}gEnX!^PaIFqhCJ*GcQrC1ef;Vp^|g4ObDV^Jc|Xkj+22X<(@>r?kz zKC>^=Xi%D&7Yc=27^EF!{U&|Tp%c_Mz5ZeQkv`e>`!o%gjM}WeQ(LXh>dQ$Qj!DxD z?aXN^r+E$j4g5;6k596U?xh)TCw}g~c_tm{!S%x3LKC?jyY=mr8yQULYt6U)c`jKP z154+As>$?ZTrz+ztR>SGPs1S@VLaSUn-kJ-WTj2)32}(*p`2SN)-puYl`h361`%|Y z-$SLl#|}{KrM9i{BF{-g{s!^X#=Ela4Sa=g%f&~%CFsyYb-jl{9dUpyS3R!GyL#Id z!ySbBCJlH7pY=N{T45NT(*H(zt4*{qhA$2B;xu|m)}=c-A7aibBw@13IXDR$VSV8- z(4Q_JMcKqSTqE9aY45{Z?Pg^gs(s^lFs?l)fjdcKhB4A8(Rn%y=a;8CDGj-0TYkD| zppUA4+O%P+oyq`FeWHWaVFksrK8Zo3aukomPu>HMl(uvQGF+$a`T}7YfPE&YWhR?~ zt}xj*X|SWx9%LCH zmcEEdSN9NAN8uWm#{?|z*fJB>eQ=rfk19jmWq7jU!(f!H!k?znq)RaJHt5TH4h92B zdZSKJvjEZL!&ulPE(5_lz(&N&z{y}qH7p%I_qK*t%f+X8t4_*wMMPS8XepC5mM>{# zN2U3+iw4Q7=?mTW5?BvE2pC&tQYjr4`usHT$Tt18ovcIrr_3GrcoW(ux*0r)D=jWw zfV-TQr!*F>4f1Pa$ACRRp2l0~AL2LTv5Jf~vg*y7K9vz7V*Df-Lo}VZ3S2!8tbr*O0tBS@BT2== zlO%1q@thLiI9@t3Y&%-S^`{kxluG7r321;ZsjLaVTODiQFbTveKkAVeh5hWiSuny) z-TC_@3(-4Bmw_PKVTDn~GmxN3b>KlsmEmrn^zzpaJ;UKTAEdgX%hDgCp_{5FZ z6=U}?vUWd__mrU$y~BCWjgk?nR`-aOMZcHz%zA1AkMYkOb36i*;Szj^b7ubl3| z>kyCUgF=u#FIhP@G>d)==vBs*@Hd33U&m~Lf$`*{GP=KK*w+2@WSBW!3xpc!Q8JJC z0DiRt*aGqtr@)?Uk}8*yP%WC!nAjenK-SZ0Rlby%l!)>*ScyyFhl(TcQZ{DKigOA3 z{B_MAXBc=t>Bn7q@4c(Cc^}n9oexxR-ZJk3PJE@kpE=%6LxU7K?c5wyR&_Z3v$``z z$tZZO1YG}(ggfK>9Ywp9k(uNJzDLPA%E*5*&BcK?W5~tz7Oy1-e%hpAwFNnNG-_bHyisw{#+V+^iQ*ykulwahlhS$1%hG>T zpVbLvm+1F{OLK3@0qtt=H-O*e&+^X01GQt8I!2WhFT@}I`g2wmywRP&!Mi7RY)F6a zPQn+-r0UD6BP%_P2hdZ6elvE`%GrJ!+h=LxPG!|MK3=ukkIxb=PFk1(cW^T|)lr2K zD<)igNf(qArbpdUVFedZWGpe5)Wrgn+YjTZBLgJh42djDts(+e+B)yS;mC*JyE}re z@`${lEY(FlPq8{D5nc@bf_S4pg-`U+VOS^w~A5;_Oy(yEWu;z3eie4t`b&_U8o zrD4JMy&^u03nSF>lq{?NTw2zfz74bT&U(6$5f0SR+{{5dt_>W{)0h}kC_zD!WjbF1 z^UI~{x-UY1DvO})K}$TYuB?3ODkDd_Rk**}&4QgIU2?^kkL?OBN|P_~5V)pXzIr?S zqKWah>)tLs?Je2oGr+3yybG%gsF^?+C(=6$y{*5t$;kO1=Wxn7LDRqv()vYh(is<4 zgLM^J;5TB>Gdi15g9mqyxb3+_djyw;RB2>s;@d=*n$MHP$1GSsUFDeY9-*NQ&`^<| z$JR@YdoA|-H2PpkD{|fkraqgg`lNTDy>Do#9~jSTz}0*l3QHI0d;xg&sDEZ-#J1n` ztL6*gPUC@vlUL60I!V{8aZTbHJK*1Tb5<5kXi>kH<4 ztnw~h!{qO$&zBE+&OH!JcGgal&>@zwW$HAj#8R4Kr|@mu+KDLX;^)s zRA>b3nW;>ncaMm`haR#ga(9BiIfP_%Lh<__ee}Usmo6>7dGqGguYUC_eTIi_pZ_CX zFyLco9B`*jTay%sgqrfLG#uhNMvw7;&`(QgFfNVpRArDfTzu4I~t(yjXAFnz!P%_6&#U|2bhgxjP8YiefyxGzS2hXHWSB=50^Kr@xZuS zr#=}1bCIKD-FEE8r0aedc{sI=+SLKX;!$DeXP>`4py!u`7i-W|N9Jk_poX897RHEf z%E*z@q>j+Rh`)sOcdCz8ytJ{ERw+E!_^2ySlNf!eZH7!xwxyO890}xx7vxI zXkT4F1RDE!qr!eUjZygebO4@%xhycsej4@cDNbKB>B=fN#wSVo?VrDV0zy=tF~7~vIfbl@8LGw)Qfb>3wj*aY{;L(i^0=8LimyEk~G zdqNjadsA)?vPRCG!UN0}xZZxS;9dGjy0%jrmhQA_CQh5&2tjC)0;7gWP#6#amQ*Qy06e%^gRbBD{WU8>m6x)JQw-}#aEn*Se2YQ4itOIv z?LlZ^6z?=ha0uoy24{1|HW0`1xVWOpz&L;KfaSDt#{2geA$|oP=aR~~m z$#m)|m+a3zxIC@?EFWD`>RbGm;!MpPlL((z`E0Y60oGUO>JwI!c0%%z5_Ym+ z4I3lJ@F7ls`O%QR$ei%aoWUo*wm^sXKJXeZv5#aPVYLl$)q(O_9(;y2yj{#^pE!8< zydpe~KE`m%@L8UR-onfnYG!lrYr-xLMOFM1h+Lzh+%w1aXM<-q)+!B zXbQ#eeCInCOQq7q!~MgB!nH!-`Sa(8SFc`u^^0Hpg59B>p>eplSn9rcbLCC3c=5u8 z3x^+l^wIG@{nI~vMZP9K@lCj7luT`y=$mw`WhwAY@edyK`3K&q9|WzvzzP%ujWi^x zhkCbY$Yxr8KMiYTf@dzYC+ai(MVfdnYKmNd_r1mA#l_!z@teQ3>AdFh?9YM)`8E>^ z-lZ0VHsJql6tt7oNVw_e2w{=T_jzUH9`CMAYXPP|^Uz0Tr3}s$q-`5!XdHBys9OMZ zd_27p@92LB(ufdkbkveowvG}ElvrU+g5r_dt9aJ4aAdyfXr<&kr5%%(tL-PLIFs~g z@?jz#_-zrvpaRXxQDK@deYvi%zc5pL+@rR1OZ*TWzaH)ufkr+&c@YljPFUPP)~Y^E z>#kQ?OX;Hw5onB{wXVL>qcCYz3>@>@Kq~J))Fs1Nb3g+)o$DF656XwtgwMp*Ag$`B z_rq*UF@E#`!Q+0~2?S_USz{DFZx#3_&y)~A|5Bcls5y3-VyXfCat3>bdX!BCjgX(v3BKoS%xL(ru zX5Ox)L(i59>d788L{_gE6xNk!2{wqtUsbr(SUm{0L!Es7BsA*+*7JOCYh|D*4J@Z#vjH>l%MaPjrw>o-C7>f&Pe z=;-JT#>rRz_>ceiRpIA9KR){IcV8C{55L5z-d$K&kkPXA-S2+)@Y1DA#|H-o+=)`W zO!}9=A5cRVvH>Y|fBy5IOC{$vOyFmvHZvd|(cw+peA@#QPZ7~q3JcxBGy3T^t8dXa z@W{Xm-f(BdVnMFAkZu?d<^kXw5z!AnH7Mr!1mC!R{o^ZFm;O82^Le-1{SRM#_0>1R z%U5sFCl`+wKP>(Bx4-=f6(UKR|Dd2}tnixrfhR+J%7aDxL*AVi(0KfiWnGy*)Q0xe}_Knyg`N?3>QR&Occ6Lr)<(N3{FaM zIyzk4>MQyvVgk~H-83{5-~N&?>6=LCGW7NJqANS<4NHuCA>{{5nD=~GymxEhi(H!c z2fv@$c%Ltdi+|7%I#|7Bh=^w2coH00`f5=gY4?MKF=>LUYJ#QC25?F%*nZm4M1ptc zHu}qyg_Mqi5uE=p4~S1@+rm#*7(Uj?lLzK0)ySH$m}Sppu=5A7@3QF!Xx>$V<7QZkB*ODEgW5VL3&VJd~*r-t9V1+0Q%8|VsSY*KK?C+ z$uR~=_x0=7*IvDP6%hXtkBYW#bsqIyoj`HK3(flIb(XgJ5Cda_Pdt3TFSN}I#X1VB1qf0ADL^I5*_?&VAm)ykzUO?d@z3JCu_yH6gCc?8DNQi@cQvEZ(@EM0bi& zu*i3tai03AtlDMt1Y5VN#~C9&eq^>KLndIW3!Xjf9u;(nU;jDAAd!xsuDG8#dq4_5 z^>K%h(RU98KwBfdWiY}bea#9tIgM5yn(19pLPzi#Ki@YPGC> z@DCKK--OpMBbt+jh}xh-mrAFv-!z3*ZPVH44#Op3?o^NY7MWb-`$9K<=jnr-?@LivGczi1K@e^nr7|)V< z`11(-txQtDa@wMF6#QxAO=X0LFbSmI>IjgOSyfjsD3sn89CaLW zZ%*s0^N4C-=}=EiWhH0~8fT0=QyP=!D*re6lWSMM%zJ=Bl2FMrCd6B#&42)|S6hxV#F+OB~9A7+sanub;BwoSW@rpcblp{zl zlsLG$1Wb{?>*OsQA0J=-<~P5&`0HQ)x&z#6gNOg}JgI{`PeBhxJSVygE~6N|tbR~~ zgoyqgO3@4{D>BT(9%E*n1<@*sLt}LBTou2tA9E1rZ;KZ%{`ChuFS;+j(7Bw8#fv{J zEfy}r-`{@t;fEiW7K;C65EQ!f+kZisFZh!f>Te>?2#T+cfvZ#M_p;g|-XgQQ>2ysi zASp{=)z8Vt7|t${Vv_r+Rjy_gNVuVT#6RHL4tCsIWq^snSw@j-Raz%0jfQcka_5VF zCY3vQJr3~jq{@}#q+2pSzo3a|$EQhch1Lzpq@$Y&(fqQuh_GXOpZt4@+jcb+)}#9M z24~ExCLH2t5S;9t6{<6JGFJwVwnZRC9)<{kTR~s#DIE`mp_di$E^U{wmb-tzXN(W( ztx$f;ZM_Ju|7ap*+%^3)!W~x^6IBx))kteO81z+(QBfsccWHWO8X`RdrAGVwL##1H zBII_>e5QF^XwdIv=73eVE9E2X5nafo6!6cG<-&uZzgGF3w0-%=5WpW7VY9s8XjnGkJH&{ z<LRo;=GH%@g1@Ca@e0TZM}44%*d?!m z0H?{~;?lRi^)1!aAuqQ_1X$BpURs5$YLMeW%A6Dh??3QQtH}rO{H~uqDlEkT{~Hu- zi_bnR0;mJ5k4S6z=`L&ykegaHxwI+Y#s3y>?tknV4!-g5{KbnGZTjTD!pQh8xc>%2 z@$h(|DC3S#BD>$?0-?*Vj*g!G@|VAiIY4~<%Ec?6@RijEuMQ9Y18Jt8^Ux$A1MXAW zR7KXxX=MVshY7P1B z>#aD(&cK&+N+-J`ej%q_d4DW?BzSP1s3Dd%nTsa(I9gnM+BZ#+@v)BnyQv8pnb;bI z3puR7--d&cKBbQgzm+DQ!5f!t-jXx;xIU0*Bhmxt9CJ^LZ}^a2SGukw*B4#3y;^Ll zF7u_74s{b=(d5Uwz(jtVva%2m001wRNklD&@+IfYV{614E^W^5Fb$uT z*D86fw0zQxP7>W2`Tb-WS>S8+6HX|=ygvJ*!Q)(#!X`o2OoE_pJM16#4x-l8k#w5b z`*oHkN>0hK6c@s`jSx$L)ew{#M8 zguDSpa2O*pO2X^cuOEK##TTO2a~kKPSc4SE778GeGJz)z@hGdb6aaiQUmIn?WTm6L zBKlCgj(ixZ>o9q2(GL&k&n?B3Z|ds(DB;t27$Ee;|M*WIT>YQ_xDfomUwrk&|HThL zen~Ynr_km6%@-IU&*AkY;ukMnyL5=B>hQ+Z8{fbD!L`!s7cc(LU;O&lpObflq4Lib zFE0FZ4C0qB-@N&I(sCOiz?uh{ZP?(zOEL@IJ1F8$vs~k@fD{k|tA;$sN~80Q0b=uw z5uH_!g~|OA9;?iw+=X%iLVs1aL^3HgM-{Ph(U%R{e+%W+ANwk67b_jf8T4wxZOU*_ zp2oc>_%0Z=Q(?8$jRoqBNvhK?Ro+d-1v}3Nlsd$%aZvFm=Xult&AQ2X zmBrY4fcHq-7^-g^ZpxMMf-L!P;vZ!jej0c+;Q?tameQ0-k6k*0YLBFlq@jA8!9iP1 zf4MSB#{kp<=LvateLgrnC7ig5)rZXMvmdfYe%gjNj)*zEk)tN4^q2b)4{6h`UqET} znc<;$iHqSn! z93CDVy(zseUMaFkQ{Z69E6%oF5ZtBGaq0P2Z@&5+li|@~cX9bb>B5y8g&WUf^SfnO z-Mxoqm8^BM{#X0p2ni^mFAvSRg%6s;x$ zw|aFjZt~Dp1)iA>-l;wMZkI+(RhPr-y}KBJy9*Z=|2=zJmzNi=|4-qyYc#9yi!ZI`ms7pzYwl>+?edhUlMMt`G((kF#|dSYk?M|lvugw)OsxXH5dst6xIW{wq(*fPbcU9{_Vi% zm6-bfqu>1IH_x?gg69Hm3qpjZR_iU zDvklPha#%>6XzG`@|DXk`Rm|0(&6CZl`B`SUcP+!dl)1CV(H42Up;^Q`aivV`7*fr z!3TeSe0cPq7fZ!&Jb(54cfs?c->iK5yZ^kn7?jwO`A`2C$Dc!%yjhIH{D$7BrpT)Y zvH*EC{2v9ICl6eR_}djzo-*TLWGKpL7zdX(Ujza>v~NDDyxN2!Hoqn1;27(hjP(N- z_ut4{%a13+k~upWM!=fOlc*yixud)!yyTa@s;a-xHQUMjS>p~rG(}86&7Wml&X%l4 ze9?r3o?9hPce=20FveX&!Kof_!GeY>YY&FkT-?2Z(Kgn=syHpp!MisGMvVoB&PT~B z6}$8zm$7N<1^u&)K6rHGT|ntz&gdH(%{A_D8BgxNh|xjQ9klsP=7mE`npYg z0M5rTOBf@xX^qKN5>J}(>BBhs{Is<2xG|bmW}38_jSvhFt;}^u>^4F>w?wQ~Lr8_O;1vefGh@{7LvywMjJUh2Z#*%UhlY7m9!U>eY+?_(kW%=Xg!b zWpeamPMa-3d?|QOpPSHV438ZXiK7{Pdmx9Y2zBt7@W~0 z<&%m{1_)aQ8tYraljda`haXwcR?8-E_l;~8%tYSIDyM#uAtJrwZy994Pnz!JKy_e@ zRBd^~cdbk{G1;`x%i9lnzknSjd1PTGdPx^D4hH%f9SZ8fNzx$=bod-S;CqPD(j2^d z>uW}x&mn%#rD;;4-D|`T2KDlRI?2w&r_AOy3)ljx=Z|u6`$v${!SX0 z4!`o~r_jaE`a8`CK}O9p!1%0&sKE$S;qV9#$UpQZHaGcUHGjfty{WQvhECW=D5a{y zMgE$sZp9Uj7!T`DG$0U>IalZSBk{tDW92bM0(5RDNUXZKh5R2x0siv3yfii#~ZyJ0UKF^tbb0&l^^$( zM+JQ^9H|ewtNORUcsp050%a!_(cd4u{_@Lj9v2qBaa26IP%4zV#f!x+xC@G_o&Hh% z!eDRXio793=cl&DSVT&Bi}iGeS9VO|Jysa=eUkLzn|;e2bdXL2!J>6VqHp> zMN6BNcaxOh?7EVDaKuznwUvjI=)7!IUZ_0gN%UV}`YlP-mZ?fomCX~KJZ!w>wZUYa zwaaUZl2&($04b6nh}+;YnA^GJ^F5pc4j^0x!vQ5)Y}DYK)2F*n_piHu{p;VY8x1L` z+KsSLb%LP5J!9u!0uw+4#zka#SHyji_B^nhj=v_j3IR#1A_7Fji1NhmbrtfbA=C8Z z>l^VV=6AR5bFVhydV5nxA@vut3k&~wesS?9^X2mYn_pS_+1%pd&+jeV`>U!~pGMa8 zET0rR`x0d04I>Qt1E>)C!m~_w∾hIk&Lzmv`sy{g;`!*+0KMJNrKAyM{Gm?;MNG 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 O000000Hy}1^@s6%hunD00009a7bBm000XU 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⋘j&jG_)GH2D>b9x5o(+@Q)W#9@v2D(MsM|IW@;v=x7;kj;Zm1oEC9U`BAoKw7SF6yd-SE^zz(K{xwIVJ@t4Y6w-2&tO_M*Jrn* z_5Q{cxa>BU0vgZbl~pw^cCkTi<0*{`5i3aMcAo@+U8Zo#bf{e*2f=ZU#2-PO`7fCE zx1_};{J&|R`$G%)ksZZalGnBk7I-OG>xJsB!#S+DV1*Tq&Qp##CjlmE?)DbiNg7#iI7E)>r-?^}d^rT2ixDwlYWya+`W zd-FLyH+duYetmUg=zEwD`bLs_cE_&UPkK3@WJhp7yDUbNx__2}zCZQ@pUlO`1I#DL z70?Uyjs@m5|Lu#J?#FO@LmgoZTF5_t-hfX?*rYFYLUqUAH}T24wdqwBIs5#TI3g=0 zspr^R2!;8}mO3FLmbl3TIyf%;=mgsckA`FjTqxY)5H@W>cz8LMZ4N z6dCgEq%exldj&17cqCRbmUD|$ZniJZt>>9`#RB))`o1X6#~JxjpdY4+Ls@QHa?gHb z*X@>Fn0t2Fej8}n$@<8+64yKj*yTBDs!5ConBDfXe3=aE)?R<^?j9^EOjpUE=leAq zKm*zkPv3YbSARuY^ew2y-^b< zY$Zws@oWeG~L5)|OL(bn0M%C>5O@OaQGN+g_R@*LSwQ zOiTf~^$2#Y5f4$+Scp~`-blMXfS>*Cm9wo+sBXpg^`&N2#c&7plc�ugkh`a;^12 zESA^fa+k`DzdPGl#PEz&gd8f0uIP`@1&;eW5ns`qPSm}l4b6_iQ=(}*?Xfd1@D5fv zq7eSP{kINYf?J<3Zz^dcfgZ3Zzc^{B4JFQ33QW5~blK8Fdvvx**s_bEBRqA(vvEmJ z4!hyNB%Ty@MM;;LN%FYwa~vVqrLe_8w;w3f@%+BuyREUX6Zd*NLN)2&nm3B!r8rho z!kgDh7uPQZZm4c+%O*y7kl(K@IAui;9_vwF7J#ETu7OZ!2c@T^lk44LVykAaryM8W zjs0ysgr^T~wFW>rFYfj6+pTiMtq}gEj{dUoyyOwxxnJ=9wd{2lEX*GvAoP!PwIS)Y zy}#EDDzwX%9@?84%kEn*p-hvl;=eY1m4Y>bHOshMF^MN-!-LE`ucMpf(H9XlBY6q- z3voZh{a#q)Hh$;t>N48xYpJgfN9>?JLGI2uR-I=6;jhW1>z7G%qut|KwK0)`g~3Xp zw9fYvU6&HeT`jJ2LM)b-bGI`*if+Q*J}+A1ycCQC3%}Q3D_OlgCp=-i0h^&J)agMU~@K}xbBbwYW56wAG*}0H^#|3hV}*k z6?sJ$ko^tq3ZR)!Vz3(@rEH)aiwyi`tK1kxdlts%wP<_qA9x=nSJu|yyU6chc&0d; zF#jms6PWr6HKdMkKcldY;a4a9p5! zd@I8a#WSZ+&YPP3kLVrZnB30uJ^tp@fAY==Z#pa1S7m|94ST0TS|8A%q9Ae zmoYtg?%h;gg9>qtWKVnwuz&AYSPNWcMb1HCxA(p=P9E5>G+?9RrM@=0Z%qRIfw!{_ z94a%zx#tqvINk}$SlJ@0e%r7;DKwr8{*L8!#t6HQD(lNw>IQFipUGXv&*WrH!aRim z(AkpG-ANi;=ZB8vaLz<*Zt^;;nFeIl<^#&7xdk~FO~i>gj~03pz%w>(rh18og6}(O z-qn|$CLQH$f9<;DdE3c;7z$4>DJYxDzSVVwVyP|bb_D?GWUE#=$zj(ZQ2BKn zz~&+`RI{mB@ryn{X_Y6Qi|zz=X-jQleEbaKo>7zl-8lSgp*;>!02A&qEQ>5B=u39L zuTrRI{N{ z^WZW6n2EOc+;GB(#d2o_%!Qt7FyAA~e%0Z;kcrXsPW*7z;y6O#HT4`*UPd{e`o=1T z?(VfET@}7Z{tYNt6K7v@&+Ye&y>f*t&9VgQ;eA(XG_CXt2wcj8NaeiqIg;!@X$k`Rr#t`D9pmp3`(78xMaLyH`*))S7n@ ztfRn*q=wuFmDHEoVxyQLdI)fmdf zk6N(O@#MR0Lb>N!rU*16)P5rN0@u7kkCS}dkG(UJ%EdgSNTc!>a2z- zV}aLaEJ@9>)mK?qyQS_G=H!;z!*s9)NdBxtKC>p^^F+;e%~m>EzYiijfY>x_f6rEZ zB38$+5X6g~y5AMFtdt&tj~)n#8r#l_y>9e?2S zesa!qrRKzk-bp4CQ4#8!b#s$K`GZjq^|l1OLjB?bU3R15{9{oo%%_e+ zmI+0Oxr90J;C~R$!Q^eM4ZHks`SL(IV_)px;ZMD8h;Gf91})e%{2~ zmz=2Sa&pDqQM}Mfe_T_NSa8UBmd4uGv`E^^a^Z3vErQW!R2v$0^QUO_r;}k zjF7+yq#SgEOH?XCJ=er?R}(~k{<(-y&q_j>}ey|&-e1?>4!a9Y?wsdyQlgGnkvRs#9n_IA1RyB~{HH*B3trRaVQ zp35oFn(a8!>?lH4<}kno>4)4_qH!XXRVR zirU+%8se!3KBoN6#OU|dp=)yAtZr*Cyrj!^8H9(D=NkL6dW8DboQZNmn9G-IE@2K} zYx&DCP055NyYbAb5K(8j-5FbaCl6MU*~_^ob`b#wD?{`oPg z4f0BmReM!98~xeRetbZM+YiK<1+-b)or=f$wV?;Zp1vs<#9wKRgc z5Ic@Z5R1hHj^?TMKw0O?wI?yq23dDeefE0{Q)5|Sj^~#pSSc)nN3r}A={uhh5R1Og z^C2#l24=W7Kq?40HzimE3yc$r#TGe2af*dVxU)DQXA zKrO|0?srIqZY9ulpqxd4{^0I70CBMtMGEGD8E9XIYLQD!0?g^VoG>TIfjz6c-Js%j z57$!k8BY|R_gPz0*}xv%D@0r@g`a2J=7E^!##4Pyf3yCw8^NT4CDIBX1M#;*N2}bp z$5VZZW~-bUSNTiTtg<%dz^^v5@g(YA1foogp}g2Jih&nJtuK`c9KGi!;r>HwG5wD1 zn*=5i>ROoFB@v$&5ax(jEC+vHok7hK3d4r|Ett`GHEygB0ZYtCCGF7JF!~wXTG!es}a7 zKb7wB7OVV?cI#JT@DDQPp4lDNY(;|`n;0!e zK}UGFu`Ah$V^AZ^x3B>6=arRzWWO$z(dyiDER}o-&saS;2L$sT@cqMyX49~F3YdtL zD{ph=A=K6xBe(d^pSRHo=0rHu+Qa)~*j(^Zu*I6ZE6cviV^`=?1JHV}1(}~37L^#h zM?0vFZOr{~Wll-?TA#t50+mQ_puXGOUR+lK)gB3y2~T_hm(Kp00`@{{0lps2{V;V> zoCOp>I-?jv1=K-Hw#G#CwzBojx)h09ZR46^@Re4j z^aYol*}@!I;wVYi=O)KYbXS<)7Q(#FD#sof7^6pJiN24W;}%)$8Fen)dz4WHlm(B+ zmcrcXpMHUZTMIul?S~_Fe!#5InaCvAN4d@;(`wIF4)%TB_!62yXeGj&(KZ3k2_=?C zS1&wc8aR_oQnQ)TF3l#I*)q9m7JaFWlbTd0dVk(~|L zGOw1M5yfgO*2v_wJFtZ@Ca&!oV&#u|?B(7m@jY1ki+0Ma5d45@)ekDA7@m9&RTuqh z=DcGaGjpH(T0hydkeA>8aO8xrq3U`39<&&EAxp5yzGh&_!9{0&fOxH0jq zF?o*OA0$qC>m2``=Zm@NRi!uoB5Af#H3-*8vE@E=Qp5`JmzB) zIR(;C_t4t{a$x&QekX}nyTqjJdK<1K0p$3u7iKE|E@f}SDxQC4x63`|_w830h|Foh z3MDfru1Bih7uq7vvP-Bc*^{+%o(tBTQ^k=LmRq)bW1lbw8Y7=P$9dpvbg1c}uD@p{ z%8gErGuz8+Aou$JYTmzhd~I8Pr(*N95$J>6z|PB&2|KXqpJ@J6&I+^t!d zBb=m|7fZgJPNL7G36)uW5AQal`Ded`@NvPDfN!FZQ293Z@c;hbUqhZPpX1I66^(9> z>X{rD6%KqoJMbsgN}!ASZ=OsKOI)ub(8=R4{8+X??+z6*QFtj>b55~RKU;KbH#cx0 zZuj3j@1KH_685qt@vZ2d*^=~z+w45wnHH_J^B8iuKa4D0i$PxWT7d2n*>qrFe`<`u z<@+9?Y$jr2^IoAowJ^`hzVjRKPeO`6$A%a02u7e&DU5>UF!`7nA;=99;KmjC|GT9G zJ5MlQ*m7z@oLlRth+gMbHfD7{^csKETGLIuc{5g!u~qRJ$|g1&p40{@+hf7MXN$`` zMsV3D+%JJRDzsvsj{~&M4(t)ZcWeds&s58!IF*j%{E8LyBqeSfL$!im0@a}# ztm$FnizWpZzNmw`ibd5Q_F6Fz1N|A3h3RBgnh$OD`?nhwrHQ6>d_TjLe{< z7|~gx#hO)sTh_J}%n8!^OF?VeI?`{5f#@UUL=kIu zUM{G(i&m>5!W9`(m{(dpjsZ_E5dkQ%5+0pLY%-3Bf7vRyKf8Kh8d8=!_ z;XFo&+x>UPBmt|^_0!=SKc{jRmnF<@c2Rg=O1uIIAWJv<5CoEP@sByMbt z(KseOWB4Jk!e5>%P)KZQ2+oTHuy=e*5}5}i=uM6TS%u$uz3M6~o#(&W`_&cfmPUoy z#OvjpdR)@`k+t_W*WC9Jw=%79u}c?x0+iF`n~NT}J?oX{yIZ!{@g3Z>T#v3p4b@y{5DDvD<-)CO9&-I_x z_lDx&hD65iUO#e381vV5;L^F)f9HcGYeES0Qgh5QOv1T>mB7hnyvkpKK`!^oaqA{` z!Z2a(Z+4F`S(liwk@jT2D<_^NGKd8e<3h1t700V#ehNjgn;(By5t6xp%!T?5Oaw=1 z?)AJx;+N}TP{8>BS;=EpsQhLC46eJT=uzCSUXDER$M!RcIB2zt7=`2TNE zdeCARKK7?l6oP}}#ykI)Rt`uBQ#zMruPWXTA_UrUvS(PqPKs{~)$82n|K2#+?{0Fc zd2cpAja*{q7%89&9hJVS!GWHcl-KQ{3j8i{)_HSVLJ0I#4lb7`7<@@lW;$f&N zlJh0|VJx|vuwytg2tkjiyw5D~@e@PIg%H!uMF8Z-Dn(8RCGaKU zI4IbYuF0Mq&Xa)8i^Xwpv0ZIA&ueuX7dnmu|M!OTqUu4Vd-ad!x@tX+XDiS-k%?e) z7l%6q4ahe<7Z{iUTXs zI_V8WO*(@6df>ZV&Rb}`UtHk!Up>bmk{NQpf2*8>asw{CN)IK={n6Lh3+-}W1z4*q zwVIyvuYECO5@bzpCsxf)J`*jUgk-y{20|-Fwp;opnt}YnE7Y-7=k@hr&GBHKBwcG= z)w)Kff^>OTX0vd;wwc53B)B z`B`}JNY+EK$PRN~*WD-+KX^9Pp`{T&iSA%}Z_j*8EKT4psYeGECa zBI=BZ@0?WHQGxrGjp(3<$HnRquQ2zQv6(Q5ff2f|IaXd}r1Qh{MR=j#b$36f*Lo8| z2=rCC+*y+fvZ+_z)B{#6*|=LsFOl;Rsx+nL+!+>hbfZFMnlH;$%8ODspBL; z#1aPIpeH8r+Uyl>d;xGX{anZWFQUHkz<6gF!^?ab^5mC*y_ika??*Y!sF?=cZgi zwX<5y!L`->f{B|pJeGIPvETG9w>_H}x~DUgnu_Hr0Hl?*gQttQSQ_GTwX?M`9=fPv zgw{y@V&bz+XoZfakEYIyh$A|c$AyLX&&NWzWes{Mv{@6KZ@&!chs#pd2%ZFD^LO7QHolLEShbGO z3R;6DNec=Le93n(7S(1$SF7|sH6Wvg7jDT<=l8Tw25M@2hh$LeM5vM(?4&&(i-EGZ zWByCQ0%dhtsNdYgU_3uqMtXhyeT2*3C0#?g_1R6N%(^yAstWQ=TYFU)fbjy|&hU#1 zttN{6o8RbpSAj_)q8dCyU-~Z)0gU3!mFEz6zDurOt#X|^)O;&MES68IOH*LT7a)bc zAVFE|zn1&RLgGPK3-6KCB}9g=W2JxMY|B##MxjxF2+OF%UIC6lGU$(dXj(ljj@_B>0T4=ck3ttWR=^B>FD;v zh!6t(FX-Q}AcnH!fYulVphgkscrCYcx_Sme3bLTyiW5U3mV3F|IX)(1uzOe+@TD{f zTAP4Yy0rc`(9p(rZD5zAocKFWUYv!#cUFgL93$Vy-V^^*2j_{z{O1uS;{50Wc7MMC zNn=dz>_IffO*sHw4tHwpul7Zu5WvTLfGFVZRPcQOAcmQH1)tICQz)-Nj+=*2RIyQdc60*IsZ&;9)=5c)z)?I>Tm$f zdwvyqdCE26HRwL}a= zKrxmDO#YT%;VHsyve0W1s8k88JMJkb&m;@T9>*+i(xTKE#@AnW5Dl*{H?d0V}((KlW<%f zEU=p$K@)o{)~tfV0H0T`0PcYr)wnda#u|UYRG?{>WAgYYGtVhMDHLL`uWwb*3T@R& z59y(h*n+Qw+Q^fc6vihl(7|D>;+vmVHbdUvKmSBGRyjH6ljabrNS>UOSak(Y3szPv z^o8sVei~H*QjksJkdQoa}qM!%Z8!?Jv`NV+=VySG{{1qXQ^8ZHhnpKb+JXwLx8|Nmh9P-1yAq03KC zUJ*5`z%g110O}VVvImzghjzz<0%{&JSdb$G zO|DcFLU+|uVmXHOLR#sYsdAV2{aZBjPzZE(`+P*#kAC^_L(6Z^F3wwRx!KtgV9hHP zt9rXME5{gW>7O3ty;^lbTPS#b<75I|ob$dCSEqi_UnlGRJunGQZ|b_*r=SnDEmcG4 zp-519NCt`eM zZEnXJU7|m;cHT6vO6$`ylS zdD4~qH0$^~g2xgjZyrSHl5xRrLu8P9nBe+ag1CRo%L)Rz+KcXPHW3ltlec``a^6$= zJETng`4bg(e8*?=B4uS8P0*CC9XKk)y|0_U6(<%x!c@Tb*cded$&*5Z=UWBkSlhx% zuXQNU`-U#}axhSu{Vfv}V7;D8PGB-;SLs@5gU>pLVNk`=7%P$Pv6(PjGL3UXB9@1D z3Bw7uL=4Ypg}1bg#@mlE)_M&S+^*ODQo+u>2|;OH{bW%%-^EZBg1GKdTk_~Jz;`jX zcJoQ{8(Ym&&v~do6mi}*j~!c>D3CTa$GT<`lj(#x!L@v2SS#!j($yy;>+nfF?l2_9 zpR2lY$jaT`5X&g$l}$a{qK1DhvO`UmrP8|HhfZY0JN50=+>L;OAZxvW39kD)>3YioxxvM? z#V{V1K<%2*rHz6T^AmzMJkeCabo_)?=%y!W%WevscFZuooor_aw>3Uu z{A0#`G6$vj5D3~>9D5aojmfHTtn4|l*eG|JDNgxb<{~3Gig415`2a>c2+57>1rL@> z9@wwIqg7kI)yajM0$G1Y&+%}7tHu?EBZffWMgn+W>DsWq{lkZ2F4R{?ML7yGhB>7E zyo4&2`nT;}0xjX((}I-y0rAW?LGE|z*mtpiOs0rM7K zz(8=_Zb^!n_wlb>O zJ&3=rb^PueN(Swo$tjEgCuAPQu_vi14F0~c`%X>%@BEij|4ZbHT^R&MJj6}qS*~n4#n{9W zW>umyysumSj@;`Q`bPOi9`v~GSm<&`7taxzFcf3TG52Xi1Cruesl*yS>_t3t%xeI+Y+_$CsqRJ z#ir7TK~}0K78kVndqxaY??v2UbbQCT`I7)xK&QXOU^woKLMs-l6(AAL2~B`g#E{2K zdUHbxboNdh+qCSCNP+T1f@fTN6-paNe(x3ZJ@$mL^CcjxE7#>dNa4}PwCChr0w-{; zkgJTJyf8JQwITm>e#1Zqt#MS{@|3(q9E#^v!jG-$SX8py`6Pc&$(dgJy13die zgTOCmELNp3AxzvZKW|zavs=H#o`~f^o*XZb(zJ{o`_~194KsEG>pC5!TB6B#LkyOO`X3H>aTlxG4cKyW&s1W9PL?(Id;0(ca{zn)=#KlQ&CE*lSyj)-Z)5Ah8--~gO$CzcVn+=k(md52C zmVy0_*5m`}cb>?(5@_Jek9gx4jL@cf^xrrjzk#-a(KCMONs8%R!@3mE)eX{8S>U=G zVs?n5Nnnarz_&kj&8KtxRVT+y1(5_AEQUJ;))u#%8ky;HZYL4;>eb-MZ)#0)tIV$> zl2D!b?kYd`daFr#!bxsEq6-@qf|HZ>nk!Ez1D{HMF>Dz(971uJ=Kew-3?52xv_fsOQO3Q;C-r*x|LuM4b=)@7_E0DPqq~C8 z6-2JUbOn|xuv~#9H{f*xucZpIsvvR&p)2sF0wWbO-R2OWu6aLL;b>M-*xy4L@U^tw zF&y{ZZq70u;|EM#E&#CQ`eATj*RtnpTRuXtzw}IeL<%Npiu&8HA>1#-c5sgYlWNG= z-UoQ1z__-ydhNEny4%>=36xxIl8RlACLY^`gqq@5<8w@sT0$*wZAFc^_q|E6Y;^3z zXLFbX?3+;IcX&i-B-Tym<#d!Q_|GK z_VNw{X8hXoV(w5rf-{?emk#{*MICP)Ey9D%$&yS@5GFm3ZuT zeqvk-GqHmiUL>~kn{0lj+U4WNKXsJ@S#`FHe|{_4dVNNcp~u!koH!i}GFSM@73q{0$}^>i}G%Q^;B4TDB8g@2KD_ia+tt=clrmlO!bwz;Gb zZo)ip_SibW`BZ-qVOd~V|D;%&40P{_`pw8mjBku*-J927f~ zVR>k2nOBKtHbK>7lC%&g+6kTRO$i(DZ)r1-5{t>II&!m=&9gX+rWN$uz)g3`LWG=* zYh#3PM<^EXIZuF5107v~U|OaU``->C;#qL`;V|_f7OT$S`CjvjpD@kqT!hXT7nMo) z`mKEFQb-8w4f8z1)vG617X8ljs2NPn14BA($=bL9CcL7XrSS+hPsQIt&}+loFVN{r z2k`|3HaW)RvXfA>u}k5x3W`CkA#IQa|MMrtopR_|IGmE3=p`@DR(d-ey5hyGtfyA0 z)&)nwea~^zlYqyVTU4kQrU(060p5F}xSqtpm(kW!VF22?t>F#JfTVsib9i2hJkllz z8El`hK*m<~@JPUuanCO^X)zx6s>OOg*9#KWMQRPQ6xvFcwvdp==P1c`Wb)&G5E=M; zG*g-xTcqXY@C?KbNGT;=31S|LA2za+;c|G&`1$j{@_v}VQaB;7d-_IrdWZo}bm9vQ zFOf=7w0+#=HUAH4YZh^?-SGgJTl71$_qKnv1;$CiI!GK7bj^JpRr;=Dp$}mgn&q-9 zHr!y|#Z$E~L`*8{5b#|%fGyBpEMyVdmc+A_Ucnj5(ZgMjDO42#R)?Lboi z2s@=k*NS_cSTbBlRFjRy!mBFrWEd7@VVcva>ak-o9)TJcJxsB}$AB&0KY0B*Sx+p^@5K9X$Wp(LXwD^gst5;%+_ zJMqnh0%Q**Ydl~29&I6hJ{NU!mZrv~pmsM0&;Ik2(C=Xl)%~oDS#Z2# zQQYp&%CHS5e_?ShfY@LK&cwclhT;&)aiuGG#w_S8cby@8ef`=I>Z$l#4uOI7erz$+ zy@O3FP%4kQUrmU*eVYSZho}Mn`aE!>;{gn>J1sQN0^I;v4(mjqR}dJSZ}Cp-deW|T z4OuBfeeWL?u#W&R>l%CLQmB(+k?iHa@^>GBS_fkWx~YhH4uu7V#njds8;MwO-{ZCk z%3e0`dTi@FK>W``&XB{11d?Zr$770FhJ+LD3LZy)u06N$oQv~}C1KT}3rig*yiAn) z7a{?(JnQab)@3$b56=bmkw~9aa=)ocJ@KkJE{P}yqQH=*Z9ld^z~U|4G6MC zjirdzLJrSBD6xGWJZ@-rQ#{v+IxDkptqNHx`0Q4GauDTsbuBq21`-V|dMmz9Vd88< z(sB_psb%RbvugSiXulv7L>Obc zS!*IzOgT>Ryn~}IZ3rL;%kzB_@$>2Qwxk%KLUdtWC-th%`8RcuC*({%k;5}4!Er4= zdDpLm!>QuXD}5r$a)eu5eyXWleHX= zbv`Krn7teLK&4i8(5>y9Yhs~u1#QAT5DU|m;I#0Jx&T?ENl(0VN+PyE*N1KI3Z`Hq z)hw~#SxZ!?vfPU0?Ck7Sc}$al=30P?&l#ME_ zkyTAa`vIEdT%%;sNeXlcJ7f@?e8fXjXlN0bZ2< z|EhQX{P~ZL{msa{YzaFIMM(GL9_oe|vliCJ0`{2HRVxd6E;`)sh#*NpYk-y4PmKiF z8Dp+97K@f2x^L@V*j4DNqGTqf#>oDjKYaf!43WZh1WTxX}fA)s_?a zz8A`L<;j4Pt1I!$)VSy6_BBkj&OO5X9w&AX&ikh4U^X}TNXuCPQ8C^QeQqsb2fS`< z`jdljKXrsoLQRTif$qSmi(a&Gj<|*{!H&q`1b7-c=F%kZTyH{?pFij?FOSBh(~zcm%r}{ z0)hvP)y1uo^TPm?TI0!<-+(yGy+1*?$Grt(3>bW)V^2< z_V&3+%{d;nB-}fdVlogW8!j!e*atr5EF+=SeZQe_9w!Q8xoPISrJyC}LKuybdKN$b zZHzH8`daOdf=AAkP!JFep-!Hao3_sf7wE0-C&H>-mj-YS55B%ejcEj7UY*P7k~P*! zXE!Ulg)-+Y%DyBnWySkaKyL~qXQa;O6${4Pa}IYQ8Xb1qj%^&5eHrzMo%D*);l@G@SGH9qd0-4LnA$E z2WH&LG3Ns)mOR)U-Ej@)VED+XJS>B*(A|K!G~k@R4wP?`NSz8>*M*fTYFerTbbdf1 z51{S_>Rx{rCa+1}>$TUZs5}>ihdR8?v-S&wI;lUyGY7P?Hn@;_8Vac4Ul!cV^u1_= z5&CrHAS|!3rZV;S9dG$^L%|vx<7cH|-*D9x#jg1H5m2b}M3maTnl*7y+fEX*n4fbl z#15vxjzKr`=5Ib8Ci}|VC}V7fGQ3`i?Hxn}umA6b+{sX8`INmN7P`k(1Q4;I%bI9dqsx{3 zjHWX6xWT8#-~Af&4J#LwrWz=jP2S_lR=ST^#v$g&plP8Tn2=-9KJKxxq>C^Hs)~&E z%xo@HSD-kixein? zWTx^i!~(#c0rPutl3&3{=tZiAzUFe_{G^2%E?!ibkUC$(b5Sy9Ibkv0%;Wp?;aKOa zw44lZo|WSl!*;LB{}U8?fEE}f%*9Z=On%87hPbp+S-Mqm5e+KLah}>S;KeE;5ygPC9p_ic-&tb$s6I0=pNgni^) z4^Thkq@x^!q8N7%=@|P`sPEu}SiueA8;n4&lVczI>VF=yRXjeX>9w688}VBcS71kz)|9Qzq;pktoCzMGpAaDBs&->~l-%kSXW zFiL&~wjny>f)WJ_fq#brnHS(FK+`RBJK5^kvd~G3=o6L^ow#L?iS1>rHA)mS=v=ti zQc3F_maAs|rIZV2d5+JHrX2KspaoVAUL$Dng}*5u^4+3l4Rq0!$b^3@KF3`P`H7B0 zmln(E&}X_yk!4&I0-$jFJY$dN`dKMH_p!WBn52Z`^>E^IKR9@tN>9=QYycQ8EwAmt z@x*29f{&4TFX!S#--joa2V=5aolKmxH9? zor3%OF#b-i$WO3gXcj~JzI~pv7~|Z<1X!J%gBjzr;NNmSLdNGxc{^iI$0w~+pdv&$ z3AcsaaqlT372BIqc&eNkJN}&N+>-F)J{Q~PY>Gl_z5iD|W(_cvGw>IyElr^kaDB3?)lMRq4)w~ z0CW$izt<$qm|TO(i|iH07Ny0KvMcfmHWpuJ!i_IrQxcC(iWH1!NDqr+s*R9o zC@z4kdQ=K>CSu9q=|Zk4F_i9E;Q4Z0jspcXv6U%Xy(s7BO`s&$qaF`N5vMsH)(c?g z&!}NvYK2S;&R|(|CP$CA(8 ^Z)|4C4&STFWaJnQ}0kqNOgc_iq@1ioO+Nndqgs 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

+5`yQPfmA6l@GW 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%0ARdlYN~d!R-;I)|YM z+h|8V??Ey#w1tj9t=b5%bl`U`cp=q&y~_uvfH;Kjmw0gOZcoLo2M7lg9M$~@xhS#L z{f-5mdHBeh_u#89b==*9dU!XKG_sg_zvn>?rojmB0d{x#o8jw z^~aE=)E3UV;()XHudMx4doBqyXg_hEUy6NCMVJG7M9g2`UW=%c$9s55awYx>YK=4&r9iN(Ph0cO z*fU~hL^|XkBg;;tQi7J!#aJ&2Kfms}{-)C50>^>A?havYXk1hA-l585cZEC&Z8sEf z4@9{t@6r8}5#|Vc@%{_e0zIEpZ)0x9(}se2TxUR@0bE0|>H`(eH$ZD=`}d0imH3;fm;sc5KRX-+`&BGA3&+4@vdJxk$LI&sg%)B77rN@86nxh}w2$&P?qCFj z7HWiH1|#wehM%ZIn2RjuR$=bTfTskXeM87o_HGJpZ844AUqRlZ^0Vc+ui%NGsN3`M zj^ZC!3wD3(6rM6D(>&GNbvVYK1N!Ke0Clczx1W7?`WsElf&+TtW6X|m|bs#H=cK2PU5|otkZrYEhc7>{~ZE@!yfNEZ<$Q?TzqaX z-q*=--gAD4ICyQ16rU zVnDKPHovO2isDxoi7G5bab$U)@HgF_7+vok>N#>T;(Hg>+#M&h+i+ZCOqAzDo{1F9 zJs_ceKDBR0!0U3|?l{&$3-m!oVH^v629i1!wRh?eb-7i!FGzC$P8QjLLqGzdVV5%G zFc*@Mk7-VmW*qv~vPh)@K*E0tl-Lg6qu8GTZ-ot50sGT=|Gjp_`Qqj1LL_&wI~h{z zFVn)c*$`%YX;CCNf+?%t=v<)5{YncAeH<4abYpij0FF+^i3oY`2ah}ES};nUZ!yI2 zvM&Wfx<%3_AMkl~gfpkYWX7j3R7o(6URD4S>6Fj**J@0ohpkjrST3wLPvc~}E3usp z`9iQd^cYB}0gP^n!Mo03MgtffGrGCCWdfO7Xm(Ok5D=_1NUL)XGvINB-uMQw)}HPA zCXvH5sQLt2PzD2A-I=rd;0W^+Y<4&*vuWpY$4Rw^KFyZy;ag5F+=+L#Bh0B$#t)z| zo54I>Xax_I|BwnQBLymvUK4wwA%0Wn- z(Egolfow*)-Teu=Q;u0DLJp|%I0=Ey*g?&OJdNOlC=b7jJ-U+(TPH}Y@BkCR^rASy zGUu(30%E+CO!TJN=ZgBK`Ns+!3*#5tdKe7z=_X%fk}&|TH4Y=|cBu-8H5Rw{C zBF)qRmR4Iu@gD?6;&1=h-9Uzf^G(Z1>V1|9@PN4ZTZ=fAIhS002ov JPDHLkV1n0f`U(I5 literal 0 HcmV?d00001 diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/wallpaper_kids@4x.png b/apps/multiplatform/common/src/commonMain/resources/MR/images/wallpaper_kids@4x.png new file mode 100644 index 0000000000000000000000000000000000000000..f5f15d3643e170195d00317b12edf16c4657b716 GIT binary patch literal 171840 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

afh#-7FOIpY&$N4FrbR%HATA*=X)fAv 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

llw55LGCg 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 literal 0 HcmV?d00001 diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/wallpaper_school@4x.png b/apps/multiplatform/common/src/commonMain/resources/MR/images/wallpaper_school@4x.png new file mode 100644 index 0000000000000000000000000000000000000000..f6e1cce38315d6ababea563acebd8623bef01dd4 GIT binary patch literal 238390 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

8Fp|G%`i#`IxmGgX0WZ4R_jsLQ-YRo;{c^BK0| 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

m4vRaDjH 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�Gub`ybx+Az{0u+&I3 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 literal 0 HcmV?d00001 diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/wallpaper_travel@4x.png b/apps/multiplatform/common/src/commonMain/resources/MR/images/wallpaper_travel@4x.png new file mode 100644 index 0000000000000000000000000000000000000000..64ec1373312855069a0f079ea1f8bf6cf55f0955 GIT binary patch literal 80606 zcmW(+XFQzE*N*6IwP1r?1kr1VUf074K}hrx5kU~Wmla``1dC`9y-W1yy>Ei((R*9H zEmm9m`oACMH*?RYnYm}qxz2U26Q!@KNln2*aqr$eYAvX`!M%F~r~hkYBzH3dlS`lP zI&wFtspq|WlnnoC1ozU?fp?Pxo(7s~_sWOZw(mZO>{Xwu-n&eC8!~TDi%QYes2G$gtqJzf1?xPzF zboy@p;vND0+poBsQGYOWftzeKPrvBLz3Puo=Wmkp^$uke&)W-_F}UOU)3y4V-S+m= z?Ls{G3KLdOih#^zK0aAEzdZLt6?Cp~R2azO8Q0b}-GJs9q|HirZP;I~a_s|9uF&oc zZj`j$NwVGugD@ty(>Z)HFvoEDoEiHO3ul{WuZympb{_=5IOv`zr zHm~LrXwh9jhVAOMlZ~rH`3!$}z4qfl@%-W=wprdwLOAX`76Y-vIIiAs_2o#E+g{g- zYFAvsi}McLKyH!2oDD*dbd6*FP2`R+5(-xyv`6?KLA_Vajw0df!nrojAU*Vc9UiuC z86520!YaGY13x@(wKdnb(ejD5RXq%vg0=U~g+tO`3cqe&SOyh^pV#-VKFLMl=twXB z9g}fQDZMr;YI)f|Vw=t|B}S@{D?};sWyFy-tBL(A1Y}U1-ui- z{7^Q?$aot`nw~m=x87)279(%RC*Pi!UyZ>wWkFjsPRp(1O3AP z&J6LFdN|yK$@t|FbB#Rb&%Evn7Uq?!mPT}W@?dRvOF4O%1NqpS1ul5tNiE2%u84(_ z@d^nP8Mp8>mX3y)vbQ1MRwwG^&#Usw|h za{)Qe5_g0xKi8W>I&9k9o-ENXG&9zSR5Y~kAvF7?tgrAlsSQbK@6asMv6 zJ}IU)I%a3SB9iXWc02y_lhXo}yU{m}+Mcrd-%>TcgM?FD56M?FvO{ZN1s<)M?`Pyn zzaS$QomIHo<<)7Dw*jNyYqhGqqB0q?&fS7fB3JA{NX0ij+}KmB-*xrUiid(6a^S?r ziA-kV6=y@K+)p;^e!pan$e><_uz?e=)PwO6^rct=ic=$tc$^HXcy)9ACmZC6^p11= zP}%Q-IqGKp$U*&UE@Y1L98L2T4G=#S#MwL1mP)mm-SQ?N{=zYX~_rlhU+c$D(( zNii#9m`gO-_5e)s3^w3V(ZsbZkqy406k!L!!w=jZX1fQJEjMA&@SuqdTQaEZUR%x} zs#N4V3)KI2MoyTpnv!pDbq4K79p{RD1P4VZ{7YM^r+kmw0_>4l(N(L4P5{ojYUl*P z5s+aWqK%JPdCUVkwANpI*?r_=^^Sk(IiyYaXcj*#{rgx(dfMGH<8O*<`FLY*)jIrJ zJ;|%vrk0~n3}iQVK%1bbS9nz-rC({oxH{;(xxbrP9rt~$_Q(|f^9J|XYy2dQOlIrh z`#@4@DCXo1lu&Ldr`@`uY@@(O*f1kgc zU-@w#`;*_A^>KrhjV!SP$kVvFYh}c@9DiG&T(R^j^mZQ2*rOSK8`CflNGYC9uA zUI*6+8jcCOxe<-=*Y4|m;NZs32C&UXEj}uFa#Bd)Oc~}#kf#AaNR1l)>s}KRE#9^I z3+rvyu>!C8_kWzUL?=iQy&jqg2Fc1LYHa{Ve(vcn%>@6^UxUsaSu@}_#%Z4>MftnTj_*NT>+7~p@+%OAtZNQ>m70*#3e zkcT{%$#+F3>;*ZNraTs~bK-DV<*wRYlcbmYM-}mxcUXt0#nONVD&5(1i&vb~R1uK2 z=vLnF^Oae{^pb!{{mrgg^rbQ#VUYRl=PdPQaeeze}ys3^_&%!1Wod`LN^4bR#g0?W9#`TW#v zZ}H8=ouSOyuaaFEWD*O%e269|muKrcqG_Ot)7i5%ck1A5>*yE3{}qO48D1S$MA~eb zdkQW4$N!Mc=EPe~`RJ2$TM5t<^ zw?nJ=gWa^v*uuKu?15kJX+AgkybbFosGB}*eQ@wejK8c^)gnvgDc<}yKBenY0r~R8 zIpPr5=B|s{6~&=Zw+#ZauaaG(Cggj(U%M0uG#_HVJPc-K8*GHFC^YQuX7_zzfmPs+ zZ}9Zc^KTvlSlOF5Lo=Aq>?X{2j^{e@U#Ne6Gi1Kw=Mbx1)=0q8*`*xY>0j$gwsQQE zfhMTgIPok^liMw`-XHXaPl=;E=j*(D;&J_Lo8d_-5WI_+Q+!hlU-|F3$UxEk69QKn zfkY=n{Ig1=+K9O+;rRmU*-jBhr=hBj2VX@n=~v)Ry^Y%A7`0X%?(?-aeP(1ma|qUi zSAF2t&_0hF7KHz}tguz-{LoQHW0Sj8cVoD%^@yvkTNv*8BfSgYF3T-lhuJ*~nnL5l zH(qC*C`tK6AIev5@YM(hQq3KR-7I{qx^OI8-}DhJ<9bCml5pZHKNwiZ0~}SbknTR{uxWj#AZ_0*HzdwAyaB@4^DcdPE%{ zj?xOsDY;5T@MW<&?oPm&^vCyBNyMyHMqqu*|2*uWvj-!Gv|N4GVl)7E)RhaYVm5FB z3uPA+Od4O|uzj{kAf8)_KYOuY{p)7w+O}NzmbeN@Cc-!qVoDw6Qfkr6WuEkp3(iWT zkUNzdv#$N@q$jrBOC~>g);OIc&{Gewp}*nSs>Q#4>He`~9e4Ei#nYJ#Y~r8L6B7C7 zfV29UGEmi#A8TgQq~+Y`n6jZiTdwp)bdIjSAYF`8`0ES#O}VV}Ki!zLsQ|1TGbC$| zL?WP6fcfc(3~5Fq@5V-z0jz)WrEKZ2y{C&~-fNX;5wbp*csb-UWiB=>U~4vty|TPu z*$v3IpmL_!qiWPuNpmrtfG1rQJex>(G4P+T#o33$>y`?raIW?z3L$cfGD*h!tp3yV zVbG3w4rx-eDbQ*-3+Cid->9ciQ^KcWDJDH7%E|Q|n=)f5Dlt&6V$<^=IC$tJz@ojV z{3OTo5-+vMis>RE1y%JJ2BI80B7f{SPO%$a;=&s0HP6WZG}h2)(w;G+O*v~SWxR`1X$y6jvV=O4JQMKYVM)W|xOsVX)As-7xZYAhJX`oRX&f{W zPiGjSHSZ~m)t&)1iWx979@DX|e99HKk;UwrHDwQEi>Ed1uZpLOkU;iNpjqji>BO(|PYfPWIZ*oV5;0q(h*v!TPigN6 zuNVj@W?;F!|D2G$Avy$2ksk;;c)NjV$uCLH-2AB%OZfewcOB&7!fYB8HMcMagW{@G zf3hSzwoZo)tqJzY=2Tvl4?8UVg*sRXzUL-exjzzO5$y7o zQ0%?LMiPVE476V~;&d(g&!jE#xc;BxNyClwq+{^K+uybEa*R(>Muk4m#`yiG!t!_g z@JCPW!dpZfAc@NlHmi^69ePue>Tc_^NR3z0z^Y*h=A7>TT}UNNmpfZ z4`4f139*e`p-;oh19riSZ1qlP-$;34eE7NdW@t^w=l0bWw@6lwnuXaEYd1xQg_NVn zOV^%+y+Fq@dF6BYe5d2fwC3n}2<8skP3^VgZYpk-eX%K%V|PAaM0~VSb!|Oua^jUP z(eZ|awc9jrUe+t|YM0L=SyL^(IB~@ajm{-Ex%rm~YC4%?w>120f-%?agZBM{PI#Pg zx-0rBIqspq%e7mAsuCVq?0dS1#eJXhqiTQ9cE?3&Y+YNoLYKt zCdT8szqMz*wO2k_4aE&3hz#cc@)+rbhreDZ0IHh41IOPQb(yDqH4GGp1i0@9#D4H_ zm{Z{e(yXNnd6w5L=jbENqlfovRb)lfT+6!{X|oENx0OA+S)~CD&mMxeDUJ4yXRmrK zWYY02@4)U0h^%0kZXAos><1-woRoYBa{SYMzu3TbTQHG3tWUmV7_swcNQ&oNn`ba| zoVJ6XPOSAXsz=ix*F6s>R*+R{_|E`27v-@R(9U930NRz>qr4=XrHU<}jjk8;Cl56m z!lJCJza*-g{sFBHwTVZJOQ?9h-ffDo69nF}z2jf4)O@y;hWMU#zyCgGB*~C$G<~b_ z&$FAm*c$aE6NiXbFn|KivV4PgNy2s>XILXsX;hmWtG%o$MQSq5={saqP#WasgYHSj z10aPWynH@#Vli)iihH#LDh&Ejg=zf79~p4NP>4#q^c2YzSMtWu`$?+P)kpvw3${!b zAJLZxFukHMGleIj)DTo9rR1t|M`3m&bpbv0#27T(gfwqa=dyaUL6YME!jYzp~rAkaC_o$w@I+wWFxW*-G^a zK5+f)p|Za3V+I&3`FG3LeWZG_Q zC6xV0YsX;1vDz2(A(>d7>k7NE`@$O)Jc#j5n>OrN4tSNnjB5k^Y;l8kf;YWCE}IIO zB}yb587Q$;^<+Q()~Dq;fqVH0FlA_w-rvMztd{%D#vs=@3bhx&vOLdVW4GVO2J3MH zki$i}={+-7=Eu@$ru!~srEBoT%30z;mU}>=k{7R|q?EC5hL&F6ypZCMdurPhZqXMQ z2i1J56L)<^Te+;L)bawkvxU z7w@UeKx7vds7;n?G=UE15E(F)=_y{4Hy|@;{fR&P+X%1&DLq~@49{9pem(Dm_Sm#t zQS$WKe<0_)%33FL5e8u1=f~{y=AKo67Jsh57!Q-#6qCf>m|z z24|vDS6LBNt?eDZA03mA^ZH+vEE06nmb4bW<5obJpomGoc}95pa-sV+?@x8r zhjH|uHKKyG6BP=yAzA<;SD5o;sAhD?m>{!y(Wm%OaS30O4-;}!T!cTkUZw>1ik4VD7_w2`XYX;g%`IM_Pdk2UXC9;8J8Xo=S~Ay;9${-@!S>*f^AJAUpSDMLw* zI8QH}B)b2K%iiCi_}JHNyJE#N9G$u*KG-Y###|RfEhi;oO`JmgPuM7gXjkCY(8dW; zLxKp93884wecWIF;-!YUB`ov0!Wr6DsJ*G7j@mh;<_+(zbLut{PdfO8dWt1p{jgH? z7YdmA#Pfa4gKWp?S-=6y@9sQsCS&5Y=Hqg5zIG`+^5%Ez2UXNLyBBUl7Vm)p&-F@`Ok{hDk$@+)ZCSS( z?+m;Kt(F95G(rG>D3OF+ydevDM;ho^A0+puHzc;^NjOa29fHSkbx;~ujt4F z7c~4A+$CqBqa7OMz_a|#3ahrnGU_`7c||ifot!+l9YQkc`n?S6&T!i zZY3wp_#Py0G29kg`#SFvIuvrnvaE0%#k|vvgi6o+7;2p;pi@m}jus=b5FzSzYnjA( za%S;3;66}?B^d6ASKy?R0_)XwF_GW&Rd;Av+lj#LgbA+#UWR)z4r=xs0m?el#E!v$ z-LA8Z+0G;ApJh773rjapG2N7TS87;dmw3V|WMiJPUz^cZz7&`SXmw*zC)+!Bjspa?a!r9cmxM=hcss*hkmRA89 zW2dOJ`OGu&u}$+zp-Nx^w28T;r>1HeedG~T&`}%N# ztRYr^NlIm-<=uajb-_$lZo$Zcl1DFFvpr4GUv{WF-DQ|_ejR$>6o|_v!nTUKH@0b2 z-#b`*js4{YRPxavwA2q-D|0^#q8N1yDtStU%gjkf(0pKMxszK)wj|E=)! zLrH~V-W(TxdlKqhnC?Glog%ct7Jg8v)al(&+Io-R1$xxKk*T|iNRb_fm$GcRg|i@l zHMtyOG=~>*E5qCYCL_d}5^A?NZw4ds%I8#l~{ajyNQCVx6q_*hL{fI2mx>4-c;prPE&Je)M_F2WF8{Jzr1i*wqIsS>c@Ak! zUUwJjzGANNw?GGB{enx0c*O4Vn*-C6H^lB3RWWaWzV*P)>MX7FPo(+byh%Z)Iu8JL zKXDKE=u%N})85YeerTjjRO7qoi8DXplf0>=Tx!5}#o}ljLyaxs#9&Mt_Cch|)Bo9S z!5XXE!)NDUG?%C9O%)J+MfhgRVtCX9rgjCSO_{4XV5hL#ZFJ)C+Tjg&WgTB0MOt%5 zb1HguRwB<#hFA+O?d?{^IQTqu$Y+^c{)bLlHC5zKt=KE?rH6(ks+;>Bd#65zA-vqm z>bK$pydKbM0Mv|_d|7>`!IPgrtSx|&?62t}z48z8ZJoxa--&4NBxGQr% z8$e^;1a#_$n6^$!(RK?ct*QFA6V5{>qev&0zqnwV0|0IAy8&c^<$Lli>}QH3<mP(LmMB~kQ0K$<-ooCns z^Vd`8>obmaJaxZl*AhjT`xw`K1GOUiLpRfrJJ&`YIouhm8kg{0;7vwL^6&Osws#xT zlh6gFWCz7o^B(qrZ;yPCr=uFi4an}JD#nuaIW8#&b~+eOg;TK}AYo_v@x(%yMB(p4 z+l@>^?2iTO>j=-+i1V#`ibk%n#67po`vWg<<0~?5Lm3H@C+FTkfmJ}shtx1sUHF}o zgF$5_YcE@LnV_oNs4m#B{Fk$0JJwZNsTg<03=KQM|95?lbd`(Vwm|HUh z_pK{bCerpO)n03!!_1v+owWvky7DA;iCUi7m)igSnASk+Jwtehl#2ejNtun2n(mIk zDfh0T0n%9GV8N!?`5dT0O0-61Dod3|N)@G$eVcg&81J!qWYbC-Q#`4}N9TXLV22GB zse#a<-VDvJ0O7aIr*`wh4Q-M%P!hI*(6vs7S<-aC*wT~JB|?MVecG5sBmGOt$%t&7 zMFG)y&yxul{&V%Q*36iApenaC66h~%iKX6t{6|||<-O3)^3_|Kp?|MWc4b9)=KRyY z%5(LX?K2HZ2066;`s9RcA=05te)?Lc1lftjPLli0xrx@UTDyI75+{HNrmNwNmPZa| z7)}q~e+?R9dFlK1p^$y462boWds)ABYv*};&Nf)K&HVB)Mwe; zdqr8elt>dH{MX_Rwtw5{?uH;6L=Nzb`ijxkS``kdM%)}FzM!t z^gB)fhE}XizNxprq4($*t_N+U5@71w$nADp`y!RPcwEPsS}&brM5371_)JBAair!! zSc8t5jQX&%2-HB{bC4^c%gj@K;3|4N7sB#Rnd!&wX86|By)(DJGQvEdabJ5oOERO+ zLo$Qbf&IdDuF!5#-&7jpCo$i`7Af8vqmif%tzxzEvkfy~5~lg6ea&pdW-Dr3#XFUz zoNF^j6Y0=WA+CHbgOf;sm`fIr9Jn7vhBy6&n3JFWChQ{*L1I+yu3KPB+3$PQS6{nr z<^#;tHYphCmtY66Lc58}Y0HTbKQDd!%+)Sp>xosrH7LfK=P{`hS`Hoq1{CpZXtPZU zC}c9Q$4zj2F`rpz&LQC0`ggNhSNZ%iT=;k%WTv43b(Z(`fk)I^!*2)r%>A}qgK}a5 z3iEF3?w2F9PD=cZ;@li1IDtpBZ+F3tru z3@)mLpNk`nV=FSe9bxhdqP+uUAFW!tR%9|7iHSym@q0k64NcBreihruWm`|#M&&gH z_=15K6wO4fteEV%ho@Io-g?U@gwU+v&ZH&%w>V<^kZAON%Ud!71E0Hut=xklshBd~ z7F&L{KIskpKZ6A9mQK`sQ7OVzX6fpKpiqvljP=VLl2{~li7%A8;-;$K&}J_r z?Br*8g=)JQcvPtlo=|5zr!q9+Lk-1}4@BY`+kK`|#yM{vpvA*QWI*320sAJajAXeT z4i9a?jhW56U!xOyV_-E;30IL{TGl{CY6$lYHZf!n(FO{8Dgzk>?B;gcwfZy?iFEQO z1GUUQ#cS?pcE&+3+adr(PoNhLx#yNDK|k{ItY{)GcKwE(LX*`y2 z$}buIn5e`K=P)!Ahd?Qi>0(2Ch`U3|a%A^kBPXtQAD6#S9f&Emk!Eyc(R}Fz4f*-zB|%q^qL8_p~8om*d+~e03p;W3>#F z2)pp1g~VYQ5Fb#AQ(uP4dOw9#O)BCvd|GoJbY;+36jIl$MYu}IaX?F509rhbCA@Hm z?`O)YtaRO~c0|5xI}Pj@iDa(vHzVkFbB+b|duqF-@v%u4dLWL33-jVHEdZwdd3LAw zT&nHJ-Z(5M5kqRWvOPQLuK*i%baMZJF6r^8&N@O_|NA{3swxJKkFc6iiit_I0buB zYb0s(*I%pT-m7&lqU~$i#}$?(88$&F)QAfo(WECx|7TJ0kKx*;v5=P|hQ*48x^9@c z=PQenCiU=F@Tb8C!*l2D90Gxpves(rH-m@AZwx*xdmi2!fAVG`H1o1VID zh%3^f<9628oNQ;5xwZb^#+&l0oAbnAV}C^{Y@$l{@MN#eZ|O9>xg(g>5#^Zh$rTXk34=A{<#;6Ha<~bnB6p z#R!N8vQ2*Ke~FlIbNR^8FJ_lQbZ+un54Y+r=O#j;E;@FG2423&`T@R5wXE2uE4?OB zLOcbD*AF61n0<`TOcc))P}g*G@*rFICys-x%BHjLm!){u>l=dc_6fgde$m+a%%Z)U ziWL`D4Njj(@MRlb4=J0K3L1+QdLH7_&@JiH5bgFAa@GIb%ukpM$Z~&HbIh%5`Njo? zvV$b)3C2_QJ8k(o1g4J#5MWc`t(y!xIj5FcXh2Z}$C>0XG2+7fWRgH;66ywx`6M-( zb1-dsR3$KpqQ5bE{e1xn?o?eAvQf5a&?&u?>#55$)P0a#S=(mtI}as?>i|tm%1_+s zN8pG(n3C9~di#G5g~I~)-?otujdIA;js>9RA`;e3PBqZqShAv&jTKz~~bPYTzNEDi(FzKRA_U78R_$xS%YL6ZCbvQ|az4B)2cv7AJeQ9uj@+)5B z#v|elP)r)E?Bgmo^PL4b{LLAu+{zb$0d!0I_(wx9Asrv{l^!KjE~3HW^S(|yBQ|M~ zXS1$A7VMAIOj`6MDE9+hIv9)z@mo*rsr6?u;aPJ8JkuL6S$q4%P6jlLfCtIujMKVJ zGfiH_{*l+-nNg3UiL8b`~?|tcWPd32aQGTBSF5Xc8{L<{87y>4Xh2_o5hX5vgKJK=xv(yS& zOxXnaRzcdM3h${(uJY&6L@1n=J3ep-F2#ODd@LyI95vUx|GVy#5lQ|-mxPac2d#WtKCZ~c@Vct)Z^-cd)%@d8Xh?MzT%GFq7 zKq(JsJLMPYIQhOdo=rPtJ|y?p3wrME9l4uH1DzV?`N`gzrg)bvv9aV|JN4>G)Sh8h z&sC0)_KnFl_CXH(7u6zP+OBnI;>I3DjQ&s9OlL^$RgVo|9=80t;O4W}^Fhwr^Zk^i zu_c)H5*@@48_6JjipPKUr)3Mrz((2#JxcRxLuO-Pcj}=TSo;GvoIV$Qh0MfXT=FgJ z_FQw`e0x*3PtfM&%O=JdYx0Joy@zyX0}Q!)cw@Zv z*(jpz#<=CvvL7ClLaAz|oCMJbeFYZ%Pt>XPn<$6Gc7T5rd%PD(kE;@XnL#^U-4o4Vk_}&RhO2tkE zmFZm{Ppa4#W5G=bcWi%kqE~R!q^&dm(uZo=it<1z2a9uDzhaFJqzg=>-Uf*G+#1NR z)1u{D5A}c7@9u70A0|f3skIV`8(f4>n8P}o>p##{4jG`0XxVm(u1ruT#2d0|mkjAN z!^MXS^lV-p9Y^G0>0=ccWZpZ6g!y9GVi{Sm!!-JJ0SEA1sI^c+o~Q*TET_6CJy<0LRLc z%)-1ZYG}NN{CiMzQdQJ|A`}2}QuwJsv!7XK78^DW(O;T(v`L8(@jq0f3wz0_1)HZx z(47XY4%oMSbDD?FP_=rQkO;TuXMYgCy=m6G3iwwRHO3We6E5YIE{k={rIH88y&y)D zO50Ys5Of=xQ;em23s+iLL(lLok3Qw~AnOO0f+a^{L{7at{puIU~_5p6TrhxM; zCm-vDM8Xo+{w_$DCPB)(6k_qn3rd~%bD@$y^|7~^K!6qR!=#%wgU1!P&l_Nik{i?BIwSVo2Y8&wo}jb(v?eO|M<_=Y{}N^gA=G!*E^LI;kCA2!U=>; z#E>kR1sCHAB+eufCQa(JIqr6$2&N?sU+JTF{_Vp5EWG2-dE^S~SLhKINYRWs?m38S zYa2ByyrUMYLatgN@>SZ_9}W~1RwNfcEq>~s{k|qoHPs6wnOKk0fVQpH#Kjm0vh^=| zlY=3{4c#&yWfRHC`2w$7^bQ(*BRx|va-v^I8XxSa5GG@(A_8}gX(BZ)5(g<(=V$HC zDp9c?HGdHHoqmPf@W=~dcyJyc9OS*g28S2%Ephk87lb2Dgv$1`CIAB{Z!lR+^u?&Dm4W>E+soKR~uK&7YJdO0>;C4t* zS)nEAYDe=P3*xl3zhfDdD#Kj$@s=l%L!HJ>;Zq)7+jY9J375-GnVg_z(?E2+?aL+u-X6qkiEi2#b6qtYb-yIFscFSmYw-6Zk#(J$9W_!cu=WcjTYr+AM0(RH!4p>UR5w} zP6ZqC_+v4kYT0#L+w`&IU5kN6!HQDit{%1bjPU{QovM~|gG}BS6GER)XH@oGbAGAg zoU)u5v_mwsC49~CnoA*9hbjzc_P470qA;T|JDa}d3e87?yz23U%1;I~3+PLUrtG>* z+J>l_HtLynhgG9So*nqN61me;Y_5Q-gzFaMg&67@ZU5cxY@s#`+hB+|+2lPbnOFFB zDBROBd@^$6R69bvp*aIwWXeCI+-yp@mHTtDm^)t)J+yb-(t>cofFYs_EMD4qQUs8K z1MztfOo+&R?c1dHlwXFXd5x(K=>f9LU6O!|iT!w-0JA?fxLqc=K4HQQ-e2`buo`AB^q4VsPo*z+FU?Xr>@f**kux<7`tdcvWWK1lN( zp2uMW{K~W&N1V;bu*Gj-n0Mqv5LX<@s7XjyfNnU)8I}3^;3Q9$a@kgFONfZVjun@; zxufX|Ix$Hy$t=s{q%Q9;8={(CF=pqj#>{(nPq8$Vfwrl2bh>B8MgL)^{`Lz;8KF-c zjNFsg1o6uchYE=sQAhvE0tWMRegH;SovEcL;O$@ct^&M@5fj#8lGzHI*!b+*pvR2= z2n{}|ji=go)K1cvFq@%p(KmnryYZYdYBOHJBE#^5_}F-k3~SJAlqF{Kg?MwU$flKa zVL5k*BA$Gss$Fwl^edNj7@c}!z4!GfEc5frT8`IHU>N621p)F>xxg{SVKdCr!cC40 z{=MtvQ?|m^5SD;OT>;_lO*fg4tYN8~?$c?B;n}NdGJ5{6x|^XFE9AfO16HN z4~>1cNhQ6A0%h%EE9O=d67?tG@o8bzVPAq7^N6OJB4wu5SigaeG^A)0-V30 zR@7+|75@YMuI<`m0*pT4<~s#oIH6N-yt=$2)mh>W=%=2(I2KV=`9a1umUZk2m1dV4 zgdlR5Wi*ifWt*@!l&;YX#M1`fP&_;DZs!(%C3b7;} z!=z@PDV)CcMMY&+MS%3F#Rxz*vgOw~aH$x=vn>WdtWbW)q-}+%zJEnZHMMN2q4dHx z;@V$*!#QU^{SmxnakA1+t>y}ntn?^&Vi#~sOsf;-6C{ZZ`EzjX96P79Bc>?s;U|>E z$6d_79)26$WZ({?K?y#f_K+3JDZRn zB4lZ^HR*CPj!>B2zdo!<_Iw-`AT53UKgAmE*IIV=})!(NOTwsRk)>yxs)c0Z{7|0rn1{OMsV~W@lr|ubyW08 za`Lp*P|Yi@tN4#r`fq}lV@no`WGvxgd^e}}Gom8WjcOj`a?GlrLGK8s03p5Emp4ER zMJZMvf|%eK36!JqEkJwc_=^3vlOAnNX-5WUNJ3@mmlwTOoaZRV8ZH9^ydw38x9neS zvd1fh7_w%e;Y}297iFoOU7Xn?@Lht<92^yl*m6v!Dw{9nag0yIrlL3ed#Xs@m^;tO z8h;%3OX!?fY4flcJO;t(z94bp$bkrs;9ifm^ow7RxE+U|?QFV~L+#=%lIxA{9oCe- zA0{t@W|Lk=-8{IwvZ6i>@YpcnI%#QJ_#I5NwvHA%ZBp!iCeE8A)e)C>)?yybhd6F? zDf#&tq~=QfJ!NFJC~dg^Jt9Dn&_E4qf@(gA?9u(NFOeZR%xW7vAT1W4!_c&V?Z6m% z9+;55VOQWho74(zzMVJrye)LwOUOPO4?vTAuRBW>!<(xkY>4znKIB)B$BqNrY#KA0 z{ABVOti?_Xy(`UHPFZpS2Qf?vv%YR~wGbAff+nBhKxA49#cZZ%d|G$h1yZ$K<{UT~ z|Gl7CrdHQ?QvpktctkiZe@qO?-KG7L!w5>&OH2+Bu+k5y_a{F!2*xkig47WF$jOjD zTs)2&{U6BL3du9}TYFFGCufiN4yDO}BFbcakUcaU!t#8y5v3HYIbr&~@&#|wY0lxW zW1C_4GC#&pE>d?@=!UeMu;wXjAK!f2ein8c-LQ?;D_)}nsAKLzRBU{pP7dVyu&MbL z-`0+{z8d~9uLjd~qir~-KQ-g~v>UpZ&fJ4q5DLQM*=4|h(Vv%hMI%o5ERJ~P)2w#v z*^0OImF%`c9N`^*i*J8?;%>US6tTt=G(6OPj)x&7djwMv z#u!snbpMXtW_tgPCtmgx51Q?FmbD7Y=tkmdi%uTPv#pDB^lvS>$K|v?+W&;Uo#q;% zRONn;yW0ZBG8s)Ux>ALS$>OiC*aVIXE;8{=&FUFt;e*#%{$58m&|xd4NiG%GyPXxi zg~M+(*;udz_*>3vfO>V#t8@EA`E}Pw<-qq^DvVndCb|j$gjOMgZc<~w%Cq8%$Y&?) zh2_>)azTfO*Ap-i@`QxO!(p6oGjFx+XXW#a_BXOb$NrbbY>~^_$tbLM^EO5ywaLMH zOJ@FjihL4f@43WEbxi;~Cx`)bw%pzw!Ark`HjgEiHv5hCcT4dgZy)F8uOVg- zqCM3kahY&c;lx4Ib?0LDH`e;s?rC%P_R(jEc{|6D;65`wwp{sq3D|!<$?;;>WSfmC zkyPzmt3wsxYBRV{ znuz|9lYh9E{aK8N%-qPmz z(fe>XCRlclYo8tIy@XM9UE*xx5a7sw5KNIP<=A*LdB;CE@dfU@Q+z5vzd(lAz7*yg z{;p;532{K16c?6Lh<2L7TTWpsOOaue?2L^OfDXuV)4% zo$s?qvk?Zzyn6lR6?w7{bP7ML=xerM=`)YTr-aWDkN&<4`-DDm^08`7lkag*D^Bbs zKLgE~rB_6{Fj2MA{y9M}!Njw)!8(~sHgZBZWxfHLJVO7F-otBr^z^*Z2~rgUQ*Yuf z$b6il1CFnIf&WQG!nV$L8WmsA7J?K%LLD0QR*_P+=0KO)HG>!nG*W4o_Lm06-|!VBjwQWY5z!@QU!@GK>bbMW@e;&$5`S z=Q)t~mdDo*w1{-f)51;_w`vls#ayVrG`=epK|bjh%7M(7<^Q|nlrP7AbD7}`*hm9w z4DBjvQQ4A3t~~~_e~|@Wky-$1XnOL^vWTJsa}t%U^u8TC{3Mj-xBhqfmmN4%Ts{&$8uF##$&J@aw5~$ z0fGR&YwHcTtEvhn1M+(HlcE0F1dUPlX|Y9et^>A_{KV>)?^=CkYQfup9r>D%5<^WR z4h_PIu8i;6^6Q9++^6JLXsz${-r8HsrUL-tH%pvSO*L(^`1&XP4EcwCFb#jx5%}4| z0MQJ}$o6p+OO@_5gY4>|rj*=zvqOtMw*C`;#6+bj19(4tvES2}5HS&Ul4>vO9hq-H zSSC5=Pq0RD!L$!5Cq$jy0JilQPS|)yTna)&fo*(YQ|2baMa1=y42lniU=rTnZMpAl zQ>wG|QBx~QZ{*0fSgQE~bx+dS&SpVb4@OAFpGh7?ZY{ib+S*ExZv+(RFicLRA=1~d~QB#!@wFP z!%w3&G9xYZ6&9H2I#nNsFMQLrtt@itYx!^W$!5#s1h5t*oPw}&W2>KEP=3l2;l2ny zW3cP@k#Bcs_|@Y!DGPg5*=mUq&e&i3%GzcvBo4}CV3D8_W(*e>V3J>)%>%Wj{J z_;1K#h1o=cvUZkl-4om3(L9E)eH_4BlGDVla=L)6VMqVF;)5;WXGo$C(r+Vfo0w>z zwB6z7z$C=LPF!GbONfq$5Zfvn4xW?H&uAMvG~dqTZbp$Hk<#SnjP!z}M`)&F*hDvB zs!ckDQC5}RO+6LZ58|bhB;G$?gNyYPhDbp)ASZbM0VLyxOMaF1H_y!*K(~@#Pg4cF zpz1<00ksw$-0v;j%vG)N;Q>9af||BwDX)+g7;*yb4!sO!E7Ynkgvw1snCtU$P}=X* z4Gf7>{gzYC)qNRoBin4R#bK6964pS%%XN9K;w@Y*MQmuLk`Yb3hVw`4(liFv@DGIM zr072M;F=DQMri9%^h6wEk9|Gi*xz@7HMmEXl)#k-=_K+(yD-Gl%X#`}k))j^PRnOwhwB2! ziELbC4!ByOCV8|DB?)t8tYT52m7XHf!F!c#ZfH;eg1#^wh(GW1Z#`wvR&U9QwlF@) zCSL2>7hjwyH$dv)WGR-~4B)TCCLIDKH&U(&rC3Ja<0y0QkFV2B9o=7bZA6#Uu+h7< zd|W?1CtnEI9^9qfD9(RLWG6wI`*A=nNHBfLxPL$~lSKi(rg@nXzw2R}hE*V`=hNhW zhRZ{hq&Vo$*^yoQQ-rOoRbXXef18!BI7bF0LuFZQsB&bnXUFmS}j5i$5u$qK@s#t z^;I`@Usiqjo&TaXCtD<6=z<5LVhPsX9$Y(ZWe`zqJk3@R33yJKLk`ENj%@Ca`sL8g za>j5B_A0_XzwDDicc(ZHdaGQD=*mo*Vnu+r;bpHM$~o)pB&TZa$oU{6HLk(i%~Yi! z9y07~2Ccl%yxgmd{BqPGtvA`+AE&l=8~?}ARk$_vzJ2K)C5W&M5RmSW8ZF(TA|)vx z-5rh?C@?@u$89Eb{S29I)3#cQo7WDsfvBaAmbw{8$4%OA}9 zN39ebhB!m#Xl|xC{}kO^{>NlPT8fr%SvFI=PSNW2QNhjCmTxHZRW~iZO>~9t9z5ex zbzv{a9cL)f%J(RxO<(1AJjX)>>)G85`#ZExX!s|#cuS&P*=O2mexyaq;YPOQexh!pnk7# zrR`$bVk5@ELR2VblwD|GcK!E)4L_G`>{wjNVQcI+8kA#7q7DQCGrl6CL^Wb|!_A z0+yd~0s}WkB~FraR2q7$mS1^XeN%@)fhsk1*Yxqf$UP;ZNm<^LT`}U zGDXDa$n*v6)&S=`4C2ImVLL=rT#pBeu(G#hW%Su&rNaji%`ELZ)aR+4&;H}xuYCRc}S4iUg~pazpT9la)* zCSkX~0+kva8#^aV%MV*TW8ph_PMJSX1|wovXRfd5*9IgSr#E6eYqFwzw0e>h63mH*iI8zhCe=V}iYN zVG09Hu9)K_BsMAS_l3cm)!F7vYKkNSiZ5dyni^Gq96XUO{u}^5jvhi*LB$3F)r9%2 z7sRtDl-u4}WgC+7Sc;%S?n#ww!k1eH>846J7W#SU6ruaa%m_t}olH#RnUhS+}r*H%|r z;3zis6P;J1=oDE`U6lROpqJGsU?@F{%WKAt5{jtrDdFF#Tq@Gt7`1r&-UG(uCGcF> z-7wz(x~aT`0AH=-tloT~Q2qyakjvsL4_xi&L>|U}fmHd}Ia5JfcJhqYSQF!elm11@ z>MHu&23Ji?+2mnTFvLfH0_3WLlJ;(%r z#{KdzAGb-*X**nJ5S>T;CihG{W{`ugFo&tz_Qs199yFM7bwJDNj7Y5u6gjiMY?I0} z>vv3J$6f7L2UJYVh0SqcL+7(ychlHxG2M&;WJ~XFd>51TTbATO83tv5Tc*Zi0LBOm z=Lu;A?ioHEePznwHz>`Zrn&$g>h#;r@2FOgn*OccYk>fQ`3F#dGj1~PW5(jx6FMi5 zys<}Jnsfj#91sYc8~OE3uQ8|+^)g8TBc05Wp+s{=$FVwHO_=G%c=R-8p7EC!w$4uY z&qa>Cf{pZ>N3Va-;#FAhM2DznL%Fmn=mLLw3f|J5aBGU75BP$BtEKgmoK$Z>WeN1K zw1!gLuqLCZ!&N=DZNl-lLN?X@u^^&sg{E`6LQJ51nQ(%K_pw!Q)zIL%bW%Zbx?YO%__365 zdf!QaG$2HPI=&v1rGw|RYWZ8a8uYP zD+VZeF`Y86tE$7JSLM}gja@jSCeDk_P62DfZy? z#fx|9L;)w8E4bo~Fj>XXxUq9MxM(jADzO*>U`qNvkhDCWnI=3ah+WFciB^Df9YF?< z2WXmSR!o25!ek6`3(g|c6X;TgeGFu{-3JeR{NbR&8&iV9=mpKD<4WtmN9iHf#TH4Q z_Fllw61rYQ0*v%ifz3L&XOhi_w&8TnlT6?n{nT2puucn&oIcv~jOMtBo^Ee^*8K5p zG9P7#DntW5Q^=pz&PBMM&oLbHnO&!{8WlV!4by1zIdbmp#Gfmq>R2+J*HZZRW=r%>}=iOh#kw~SFmxq+!K-bR_^QK)=-x$ zOt33D?Ev-1bTklabJ(S%Du@!oWS(whp~elb-iSWmgd%eUwuo?I8O>;c?Y&q{HpFFDqwEV_&kL{dc^OsVQPI{n?j zmC#6^ClF6GRNvt&T60uaszKq|UxvXclhk=e;nX0ap-R_I1DF#~)|CRTxjRO6foYK| zz7@`r%96-G*AcwwBILuGMX3K5nWnpE`V%;Ha+NiiTwm-B6Pv){h6f)=}~4{QGZiMwtrI zSlQv9MPTJxn;_)`v%l8mxS^Hy6OF_JvqC)cUUo_HM*a6rK4X2R ze;eS0qLV6g==%WEN6_hH?p8&%q$n<*k+CD5#$G#3KG61>$4QzzSGy}gvE0px?5+sN zw$Wa{CRa*ZDafw{oZLfrV30m>ir&zQ@N+`KTD-X zQj{dKRUZ2A^>WeZDiYV?Y$&ixfHyg1B2Gy$Yq#LE{I2AY1#azQC?3Q%|2ztf|LI;e zaUgp|m`PGuKhxL{J1T1T?_JVP))aC{y9r_}9F4drU zk<(l0Ds;qt_X{bfK(_Dmvo|~`GQC&px8a192_G&QVTsAX%1er zktUIA&;ZeU(&pOkFeD8)+ul7j66LOe2UHKkYeR2s_ zmzX2WBuj6XZ+HXM$Q4+m`{8B#**XL{t%4os@*E!J28n~HtNeTfd=C0-G#6WqK~c!@ z7w^JMi95H(G@t408&XH44tucdyInuwzS4nhqcYwr-ikb$U$h{jEuh>L#9`MZ1Rhlx1&X=?qp2|xYz5Vw{}29$y`LS>qLMC|8m z$FYRCR3EE0>y|4M#kWNOIW7Uj3-=$jnpSSc!Nz=zQ!wcSE8eL#@5vWh9f?hD9@$iysSK z*MPqdRAL6%a;~zBmT?4>%L%f2h8@Nc7g?K|s$f$A5U+MMUej2B22C*8j~c3O*#t$a zX&WX!Iqn89U&G9&yEyOL>9$}X?*;BhR{%hqbridTIP2x$CnS z3xdYjJD^xV*qiPr>M+^ji3e4k;r&7Erd>fh#ywrWf4tz+E>=1h8Kk*qrpWls8d1bs zS>Pnj08-3;T)UGeLM_Yg@~V-I?-_3nR{g6e^(yF~MU8aQf%7N(KFh?_I|gRR6sXk8 zZV;>9#(R)^LCpl`$=F~iBFO0LbpCW!YX0k{e>yv_kSKG{i8Ia_Ez{eyxFXh5CUKk? z4DhR?)Vz>fKh(TXAWKqB97px|%k+)JNrrD9ex_^lpXBa~U!mdFc53ND-be~`Iwsb{ zM;>iH7+b<%@zLh3MtrdIO#PO~77q^Y_<)>8I1dba77&*m;}YWgFo20p`oK?UR|MFekqCD|B7g{9F7=PQ zvpe^IbqKhRYLXQ~CxEh0!K$|!hn&aUfWlQ&9`$Ke5&Rdg<}l@bYr+4?Gs`LfEpOJ{ z9)AtzZEGgXwSHBulTAagO@Bok&VJA)+xvE#CX;EumNJyGp5X_4DCtG4x9{Zu>0fq*a~rZLyOxxa z*hq|(SYea|7Y)?QAjiceq+^e!L!XatHS(y0hR+Nxtv;uiNk$ryAz#CIfnI@WgY^*q~6O!?hs0l3jnEDsKg@w3Y#|_GjlHep|OOKAf<%IQl3U;n_ zx-0@ztJ4q>R@|k-kh%CW;zf;r2iT{lFI1DesO{tRH~CPIL2zrqo%muSM$nIK#khNd zX>x3IZT-rShkKcu+jlQee>2oJsKEdL^LuK{pF&#twwC44U+b@3I}X(UZI{>(V8KY} zKz+N@=l6}}{i0m_7oQ1scS??l6L7b!rN?h(K+o9o%~0=1IBkHb)N4?G<`Vw)5a;Qd zU_f#-R$$97E_#OsWhlbwyPta*>22AqpQhLovFxTaAb*o_7kf<2zIlZsLq9rSE=^|k zci3IB0@IL7PmeqAGVT(hZ2x(r9kBev@Oei3Jo0Pj^qmDnC{b4by||b>i1<%#k-RVT zE{Q;9mmiBN__)B%w}8g!g1y-G+q)LfcMEP2H}J4;Dmp0c{_m`d1#j#tNZPSq=Z-kCO_xV-72qOZ=GJcm)M;^UR zuUq^#`$&1L<9p6UmgCm95-HS^@5&@qEq6OR^Xici!UQKB=&QL}F- zWG56>K^}M@WBiDo8%YBgd;IqV(pZm{`g_)Y^3*(vPbEoyTohGIrMa841PkxjG@Y-2 zo{*8vDT`(9UWzAaxIDIK7fxwQ>h!Au_Fu2KGpujmJDdMs_&+ z;h1Rzoipff!VOf4+G3}*5%wLbZ!>*ORGb~3vA9&!)qdg_gG6-uO=9J$myC$xMNXH9 z+|PneA`-BC}C} zRm#uSF=?<*+~+*pCQFFqPHuVlVsZq)i&*;Vtzg^vHW(8-YOV=x@vG4fKow zdXsy!G+QlXi}M2aM8%c=88gu_Qkl^i>5*(nf+o572{D%+)0P8oWmLX_=8C?;pH^$k z8)p=_5AU?f*jpgelrxK(roSy!CSkhD4S6uQgt5|@E<5(PA9*m${DHLd8#x6787Sntwvh9e{zZ%WuBCGHwuhpvT${5O#2}1@(`7NrAdBH6a)d~ zI}UCKwb7%NCogFF;wXx2xd;T8&<_n~%&(aLr6FY=L08&os}@xsHB>+Eu+H<8c6}Ca z_Dcq)nqBgRVu5*6#7$!2!M_9tYt!12#Ii_@`S$42yc-gD7%$B-YBmh?fh zxmFK5x!_HA^u_ixkX8pwIEJ8gI8JwN#7%4S0~{MsH}~ zh8G+Jc7*agwbD5w8)EfQ5jf2owLl{}juMZ3v%{!k#0YHD(1Xhyu?A8Nocrm86aT10 z`6ij4f1%o9@fucYupNHVR32m4zg)W?EB&dp{cn8eab}JGrX@}132%qQ#&-nLA?7a; z>VVoQ2G!uzX8#$TF>7PzQ1`&3X2yj)>rv{%V*9F1nt3fQx1o$XIkdI;d8c&o$|X0Y zA2TZS{h|jRY}zI4YdMU|x3}Skzvfwtb<6Np4J806`lHwGh9v4(%4M-^_u9nQh$dj@ z-ZYDcC8V#MW{A=CfpQy#uTEeCMO$j0MIqVjD4)NndT7;Ao7|7r0dRl1i8eRLepxJ= z8QSHs7FW#yA;#~^lUqBQ@jHSia>Y9Vg6JG_+?Jgito5{NUEeVu#Jz&Q72IU)BryKL z3B=ud=qR@rChW}no{~$2n&Zl+&ehBGVd!?x(>(RWP1bUx3oV#AN<`eXevy}6`P7PApWq}PT59kDB?aKwD73B756F*EY zeucyq_qc2bM63%7c+Jj4nzQ(j=BmT9ZtVKrD+~XAy6-a1#rDh#LWQqDAw++*MTkcZ<6j^|U%_H$upJiZdR1Bh3-3;<`TJN-4ERC4^BoXT&!?+u{+^~_24-r|N0S<8^ zDP}+ykxclSOrz0y!2*o7%J;-tjc?_T=@!L;YYBg3a;a{Y&<)J|vQWl1 zB8}Z!@3bfZaOHkM+A)#sc)l5WECXBxlk2s9F7d0DF`m=^o-aR#y{sip;=0fH1w)D) zXQA_V)*i8Ht#B|yeLFRD!Lc!cx+fkh&u6b2gLSA)OCK~pJ&jz4R)p;_A6KrFnB&tH zXWQ{mJS(+wNlj!6qfgD)J3LQj(Ibzg;gaj}XEm3m9Qb-cUmPoUl(4sL$DZXOQS;U< z4d(5l^=ho!WH3N;;OmkO`>bJ$g7w#FA|#b5bm(lf(kP#spTh2J?1Fa7QJKX=2+lql zdG*WB9qj+e!m9XNTx3Hb*ei9Zpo{;6cD~2X3RSTz_~qf-+P$xFNbl!N<1^g=RLIt= z58@I)UC3$sLHE7sN;ns(v28wme+RKAJp*E|Ui)}4=lX+NqC@bOiHZMbv_|n_#j-^4 zN%ZU^1E<#;P^REVJ_+hu09aRJdxj6r`C6eWL;hblKf86#^aYcw)>w>P=7ZmOyHmJ$ zGz&4detXsV-H{8&1`H!=YatK$Xy2aB|HU8z3oVAeRou}jsW+2U8 zsb2@rh$?l4zWM+sd;(F9JiNyk8!6IBt3a{0l& zk!$HRT5<v3|6!*Kd=g+FOmxsHj*=}VX6ZbObW@gTS8Xe^ z1>hHo+G^#lTsWrr5oYeV*VSp$(v2pT#ReNjqzqRovug%SR};C5gzXNMKC{#gDHb** z!)X%4`_G*9H~(FoXj;whi>fTyI6YWEP`T>BHX#%n-5gdTzCHMp=gx0O(nsnM5(5>x zzX?jY^UbqepxO;Dy+{P84f3Glast#7n|^{b1xPP=s-I>jQ}95}r98Msp1F?LKhB<8 zno5)OLK@(2xxh>wumJ`jx!{5m?0W`|`(bdW;TJXvw%N^mX7~XcT|TrToPHq|2Pts7 zcvH!Hu!9q;?(VJYOP99lrQ}3 z;g1ZoimlW=ea6be=&GMh4dGD#m5C;40RpmjgNFr^G&v*yXC^<`9y?Rjgb-eO8C3i4 zC|B$mzP^hDgoA58G(6%t=L4`XEe7Z5F2Zj%)!+OWX{sTL0!=#hoB2!^W3Hv4$!VZEywT9p0aXK}fh zU*3JwHWibUac4uwCTdN;S6Ul#2`np(JHXZcR^x7YMDFm1mCv-4h$U-jVi%eO)VS)% z5!4r)K-)H0$AvP^$A$X|)8WG3ZWlw#CNu(b&=t8 z2D8%xX#pfJsb$T=yrHiXhae2|lo)mQt~iwMpHAd*fhoRz6aW?T)4YhSm83z6(Cf!p zw+8S8u(e1A+WG2D9d{Cz@Sxwi(@XSh2rej?y=NF^ziyVy9P@8Uh})?19L7b9px@HN5_%7lws=Sx&LJ}}Ha=%jRHINn4c2oL zUSFk+k0VREwLH#E-;}#aTYMTP+m08tC0T6??m^^o%AC)?rhKayEN=V?hDpeaG_jJ_ z_>;uSUy}JF5xB$sxuy6*^gG8%hG*2Y@>Dp@iKQZ|T?hG0B9oYkYwqtzlY8$Zs|4^3 z^~oQM;Y#)bP_ zL*Vn!?o*ScI|7)(74&Mn?w*8%zyP&qHU&0P28nl>V@eIGTXb(gBy{6%zD9Oq-fFza@2iEXgtyLNf|I{oi`?>`!~+uG+Lf(jP{7`7!)VcEBf@V%4H^DU;- z*5{NQE;124N5{WftGC9O)CcYorG>lCmg3QO_W{K|7Yy@J7xuT^YznW+JhSedzQm+n z<=29NfU}$5K>Fe^uG{-h(@_nB@`ViUsylejq|l}2I{n>FGaAo@wJ9l~#yl+Bvb2sd zYO{%b37K+HYt;s_3wFr_yF2ong6CBkKA(RYZYiDVR=V!*E8&6U_2o`XVr#*&nVwBw zSx zYr0&&<&DgzY9u~xY-Ji(eI3Jj>zEp8_A~;Czc!)?-;1*!>CIxicj@^`@Z{K(5c)y?8Ni?)lu*C_t>zvWq^|>0WU5mxj_WKqX5p* zren_6lCmiw9h)b&P>I3A)@n?xk@lz7bFqSu>)1vb0=mcQ>K`Vf6b1oMpX-*w6N#tYuNzkhum_DM_V z55!DKcy;pVBj#U%&G*WKBEyxt*)qVg~;7o+~0p{Z7vneD9|TniETl8PW701W*Lm) zp<=S+ayD{Tpcqz53aTr@9VTh8DCdx#xX!~kw!a-nt~_JSP>*9nXF=7tq=#Faj_~Rada?qWhW@Z+o$&y@_41ZM?fbN{B z0|){)KBvrJ#WOgTCB|NUwkI4Kw*e!nMHM(_GyF`d>eG`>-gtfCQ5_3l>e{u}GRN1y z{-pVSbJEnAh$=UvPf7>Vm{#WaL-A3gmFzo-MbHe1!;V)m;CvA@+MN*!2uvfh^i)VD zaPkar63=6$#TFwki^3&Ilddg^I-Ayba6*&sqx=e~nx62!mq@AI$McfEY!nb7z-HwY z(eo?mOrKcgqHjBv;gU}7jkl1dz zv!Y~^r~2!(im$fWTI3H~9V&8~-Dn$BlbgcaqMlmIbB0sO+n$yX)5-4iV1E;#iS|QZ z)8Q5|)%UZPyVo+yv<~`YZ&2UT>D_DPxBEj_ecaqBNw*cHGBg%sJ4B1btmSq61qe^b zawnonqIPTcT%>SIoep=Qe%5$afXjc55MNv?hziZKw2DH?79ceQ#ixyqF* zBSfOcX22wHH}L%n0>{BA_75&rsn-=7Tg)_lztWpNuZf`BeKjvc53gm&ayi|Lqz%NY zUL)`MGX}mRy;b(=4w^u%;;ShNKY6pdi~SiqXZ1e_TRP6f*PHYZog~JU7}^|~66Zb; z1lKIfLcTOp!dI%Z-oVvGSabOOyL-ijSbtokl_BqrZv#d`Mnz75<+c4Kd}vmBHPv@X zDV&;QSo%>`@7JWO-sU}_xXfSVflqZVh4Om|@te2aI2Y)E`9C|kVb=Bl>o1R3JT0b| zO$Y-i5#OOsTbW!#j0e(GCh^ig93M`(P&si7=tOE{H|Ns-lT<>bMdK_L=qMfHe=^p0 zbYzK9+!pYa8T>sCov)QN!x3Hvu+!Gi)GM^MmChn`=M#-3rHLtIqjyC@(I8kLgHE=S z8J&z?$sLbioYixY5(wMoN|xCiXDlpvw&Mj_o~ubB%S34I&t(8oINKE7e$O1Kd;Evi zLXoGQ^9;11>?x9@VAH1PA7|C6x;tb%o1Yixym#|g?ro%oz)90f+%91gPg_eU8xPt* zvh(fpdWLO-JXlS1p}we_x%NeLbXZp?C1}tkJCpS9n9aZpJ6AxVs_Qj)sAH-bKiz0M zNcpC*y|tJ(?%KJ0c~)S`%^jyb)_tZ(ET%h&Bg2on(G8@G&;MR`sruAJwxw2`sFJud`xro@M;sL7G(uUX;Zd%~xQPJYG~t1j0kl{=sP`&yCR zJ(OOpI*0v&QDkitbW~>bbizNd&+v>Qwi^cayjgq#*IWh_W(rWD7oWtg3X0Z;8$3PY zGFcJ{%{lQ}3%|fk8GrFu50i=zjP9Qp@>OeYf)-w}o0ID=w9*VO(FDY=%mfIi!Zs_) zZR_lGo@c@@2!uSMa#TZFENN-9=;MaS0Jwyc)1PPce@UOMr(@Zi$6X*V34gNR#=BNV zZO@H!(*@t%bkFFCum-ivxgUNH8s^&cn=`O{buZt^c2}3p!YlmtMT7_{B3LXyGlG)M zK>Hok->FQ9YXdMuZ0l@Nz<@WT;sV}lpJ^pq19^~84sB@bq-XzK&x=|N>2WAPc8oly zesdRj!u)-P0^7E0Q7w<_V);+Nqsm4EYn4WJTYdcEGfTU@W2e2|MOMJrSh^2*>o^%H zwqSh+ACWHZCwI`M8R$SdsMLtc4`vt-cz>PRlKrIoSzw=oEsO`2&0df=jy1~%3_bfq zIDDZCY&vr{Upjr)o9HWu%hgRndX0M%9<eS#g>$KiozdUF@%}){+6Pjpb6~z$7!%GuMrDO3LvebT6ose zDN_C@dD+?Om7d(v8 zU=hFn;%*We6gy-Cl|}ft>Z@}BG?5vZZ^hbU)VoA*|*s6q@zL6I+>vwB^SJ*ap5GRp_V`e#99%jyY! z;ZYI!{o^6Fauy@#agjH5)&=J%N5##c*}}!v8w(={#b++Fr<|M*K8nP5N+QlJQs@pXY@5e}_C)oLDLuZ?QQS)UyG2w@cJ~I#Er~Vk zS!k4rOT4~sOcsZ@Zgsodjp0^Xl$Jro_E<8WWLBA6*#|BK=s+J(-%*bPR2#Wrx%h zn)b+0QTS!+UUY_9ILbAI5_tqTz*TriOK}~9!hCmUIQ=PLO`e^4J`CcACvk^~4GnV4-Nw(U~d9ocg|Y^Ll-r1hd;*QCCtIO4g$z8;4z!o@ibV z*vxu#2-&ZTR^K^phKc)TJ@ws?=|A~B`lc;!Z5*sU+2Il^(Xi2OmIEgsu`X!($f%|M#n(Ozxb4iN&0h`_J!AVa73chhe2xyF zT6g}Z)_j@_axfHG9(DDmhBj|Pe-nUGCUJG&j1SE5sw9s?$~x7i3Hm#ojGl!Kd^P_V zc`SXb(B+xdv!J z{n2*}d(mCdaXy~dHfsgooXP=UC%FVEA2W>*{LzH`7sbaE>mvv(6su9IIx9J@aoE!X zpYe@Wrd|E|$R##U?3Ri9fL)KxyuS8N9D(>}ihe$ivJRPTob3R#t`zofFt=fh*~`0G ztrLqKy0aQI+8A@k9DC&ha}-jaXlm6X*KY=kQOV;vEbFK3en28sm4GqV=IEGRXn(@x;Syr9*ISV@(dy@e_p*d}lI(DnqMPeNS|Gg^Ift~#T>3!%G-do6fV zc%iX>1ekjVBx5sU<#lLkc1tJ#QwX;apC7;f{JUw5H87_H@9*af22c{N2e5r#PVaCd z&$4{mjq?`}=(FN3f$a5Tv@cWahH%V+0Uon-6SdQFE`^j@K77QS-JdyM2bj(^%g+1< zY@|W4ks|x-SsrtSL?abmCLT--Augur#2O*BggcnAOmWc0R{b9*_EQh4po~If9q2b- zwr;ujl|)vQ52tdd#$WXO_+zWrEr!t>SAg(e zVh*+Req*dK)s+?VvDa}>4)`KF8TmX@Z+$w^-N-*9O%v}5j1%|A!(6}>lS)`FF|z`6X94(CxEkNQWRV%o^-mj!r(VdO!a6;DYp}a@A z)W)=00G~8vr#~pO5jigD*>OerEYrsV*$664^h^B*#vE@a$Ev@{x2r{Y!=8{lYk1Fk zH5fGL3xL~PZ|ycP8=ChdHQp_~?;3l)MJvhXe#j|Xys(u_7Yswx3(O|dNS*5rvfm6 zvh0O_dT55OH=!E7gPQ%2%nW{~B5HA^qyKqQsw!>rb|Qe+My^=>V-wb;WLGca5l{#| z&d_{&yU%nY$Tw;MY#atrIo#CEKvpCXBLS$E7)0&X2MSQ_1!f#e&@YQ4j17x zAvhj9^YaXFLP_^h zqLHixb!k5y{w?M|AqH(t&=VV%>->NA5JtZAlFR5cPVXOn5JcDoX1`BXDI2u*{zmqkfE*w%N~d~+D{@B%EBV5?K)hmN@RzTfOUWJ z)ljb5shz5`_&n@QcKZ(*BEfmP%e%{r)84eB#-rf&+S=b+*%YIG6zaTWN&M?*c6GUd zY=q(YyU=Y>$Ol~e?bsaK#HM{}?2X;dR&a;IA(3B9HGQGf5pS}&YqSi5{NSMZe8V)d z=9lVTkm7`0JIa6jDEs(lf+9d)Cdi|NR##h1`EMoB(I` znlG|M?|R)F1k!^sXYV?bS|5QvWQa+O(U(F(V7}CZnUwOA0X_9N=)I-1cYvG3l*Ek# z1RXDfzsbdw!$FAm9ca`HZUIM~=dPKHK5n`5Hk+Hr6?i{6*2$TRr>SSGYsde&t8C)! zMT0#R2oqq_g0j;AzD>G3xk@FYGh#0Gf^qO_vMN^GXche9nGw&f|EhV*;F08tVZOZ` zDN}^&=Mc(%(!7sVr_()LN;ErsR9Ac9QMmY_ChZc+oj<#e7V-&aQtz1v)2PN}oc=~X zjZ6BV%5usKZ;5YIt6{C}8s4L!ijO=QXwV2ETV>**UL!6l0NQ5Wg*c8*g$NJmegX>M zqaO(2e2dT~nw#0+wx$dE(gXHCN4R2`IPhQz@0Jd}L*f>%oIy<2M)B~3&6nN+ziW98 zMM2+A^enN`%dR?LHiosw`qa)=Uuq9=wt%LF~L zc%3%JzTG9)$NE*K>;-*I9)_2RSz!8tGbm|YeASzMJ)hWx%nqBR0`phNXDMBv1H+QS zvwjujz9Z7@^x>n~Ght9~??RpxaQ8_Hk3_uY$#+Qny#k_rg~0axwFx;`uzPGXVf<*A z0FnhuIRSXV6dfwn{R3tJ0Mug>sK3~x|I(A&lG<0&Ig70{l&CdR%!ju1{sqj}Uls^I z)=vr(%9BmrdX{HyN;m9`PniiD*F+cCSw(L20vB=2rz$hvAgWu!(YdF7kIVB04rNPy zrNmq}IXEMmjv#;!LD{-mHTZ&26}npWLQc459*QoAT6hvu`;@pIuyjA#LtSCf^+e9kJ>X0!W6 zFGUqKbmg67x=ngK#CE>_SA_FwY)f^VI`ZoY<}q^fjkEsy)vt0zjf#fw1)<;1?MZXWh@0fcpb2dHuJc=VQNI=Of($-2 zGry9Z<+dOu^z+EwYmTlCvMl+*jPUVvd4&c_Cmh6$ex8Y!d%0w6qEthrynbk^P7IYs zV4)`^4B#o^$PI-2cNJ3($}!EK6gbRsJEL;N>rEfpru_BB@~Fi<0Zz9)PD@G^1S(8g zaeO;4Z?ls1!fA%n%B@(#M8Kd07zj+;th(PfeDz8;UZo@<)z&3!&7K?}YG#W*g2cWm z4|inZUougvKAIcoM7D`>#$^{DC$lDs?(=xm9z!xd$0Z$LA742y>nZPy7#1x4FV{gp z+=Qt1?b$t~DF(G3xJeH49q|=nN+Ap6KGji&HEpJE6rmxF3;mmaU8DO46Fv~;WwK{o z*pZh(*{VYLYJI-2jlIAX28?^q4ES!Xz4WBd&A6u>`l$}R?BE@++-YhQ`-?A;nsnCI zkOSK2Mhr5)#B)eJs2TPtsmsH3Izu*oy+$u#OgVgt!GQC0fZ zaU#3@AYC>s<1?E=g#IdJ7B#M^nYOBVJve7Z$BZ6~3c_+8ht^XSJ;FO8i;ZmI_lGw* zA`em&{G~|1CsdZfE|oRy2{>%oxdjsO6T>eROvz1<2xE3Ws0od?7a~MGzLLth*5Aye zk~8Q7Hp~9XJ8|Oh?bY=)1& z(&CU+kz0757_tO;89d1BsTptSd1W02+CZqS$&UIIfzNAeMN^w~IAp1d5xcl#_gtjd z6LM+yJHIRsr+sp?rTzc_ezIwlj;y2O51PnIr;J`0|)(yAlfifwTeTVn| zol>nguT4BSOs{M4P!XXAWzhelh_w<@0*x-Gre44kQX0`L@xZ4^GoUBBTpLWDy_uK_0sc)c~Z5~TXILl6?|iJ&p)d36P2<%(EwDYMPe7kSx; z|8jgx53m}7h>(sVBH1djlqR*F4=-dB#@?u(Yag0A5e6`I^A2!wyAx@hy7-T>o2B6) zMQ$Ei(L~Vx3hsLr6Aa1n7cesWQQditSIeQZ_b$RKQHKWdS%&fDcUlz>5B-)va;dfz z&o?xb5Pq)S4v$t1Yj~Q{#;-X>nqsRPlX3;?;McdJF5?|b7QR`Ifu2>{(lUMLBo;I6 zI2VKh!zfu{%E*<`6P%;g;#_*Bwabj0`GZ*%?s4voUtO4JUVn*?9nCqli#ny6@8mC0 zwSclr9pL%hhQO#u!*KFE!|)YY=Uv79XzoCR{7>jdh&`IHI5x`uf-ot<-W7gYCS1{X z+C6rhdIKuF@P=Ix$NV2f=NZrD-^Jm-+ACJ6604{^TNQg2rA1XsZBj*J?^q#5Xc5$| zJ!;ghy)`N|YE@Bt2eD(XJbB*bWpaP+{Kh%ob6r+f&<98x1#A}hwY1qVC9+hs@`tF9 zexT@5-HdHMABJI3-SpMt0CBp%f82w91X29|O`E}pPnC?gJZ~sKjkfvfC_#4pw6xBP zqBs8W#Bn-VW#c)q_{kg2L)l(ped@OTP!eXz+o~jF3J(12YUl;uwh&_CS#saIe6L!R z_ucnG1SxXBFj$V{1iD*exbG)u;H$UMt|s>UsookXYCedF(ACofD={KjTd@gd%8Gu- z_0i!b4n1Ug&KoOPD-HFKUPZcr{Ep%JhfSdx9zU(Z(DgKa>dJQtH- zedS7mUvaFjT=QIX&(IfW&#CqQs*=ICo z_XS-}5K|9 zss$VGd~a?9rz6t$N1{(=!3(QG&U#gfBpQ(nHF5mU-0Ljv08<%8%|rD+u$Naew4cVE zte_RuhYOW9!j9ygjt@_485Q!rYW}(2sh%N!a=%0-U4DWC(6hx8-Iun#XkHN>YL5fc zZ~(yTk}n2~TDl%vn0K`Bdz)>vG_}0rMLw{(pFi9B)^pYY?Mo=@<8M{P+E=u*a;zm0+dhrYY5?+@=tlm_f3~GCQtA_eMtl>l zBWQOtp?JzdBDycy=JAPRjh=nrghTl8Yjt#l4Tq7Q5O>s5m3PqQs%Jy|y@b6jBUcbZ zgdWm)vyEd<0XFO_@{hIY9QBk59*aH1Vz?!`A z9!^@2vhnU?qn~I1Y`u~OOwqAbb7DhZGOK-&vK&Bzi5`vdFfvs#i+~hF1-zEdn}BbP z@L|hQ4}`@Za+=tCAunpKNGAT|hjkB6ju`0l=f0#>Q_v-NGAbbI3Ac<>mi)OnupiK# zgM-?fXpJBf1&u%OrcbG~et=!~bbyAk!#cz&+ii-?x69Z&dVk%&$4OOy`*_i5=`GYf zI(||p&u6pd_7zF@rNrrjeB#|;&DAUyyIk@iO~k~XIVin|A1q3nCku;D}@D-&FMWnymiSyvzyTc9y#<5M0i&S7*T9NjuW5XO;z zV-}X>s-A#|l@6Wxd z>d zH)paC*(0zfPufmpudIh!T#MS9>i4GLp%;3r@YaG(84RBS`eKvN0kdD#--oH-W+0YS z+;X5HzgR+@%#iC^(r4`5*+#v3jWcEG-6Lz<%LTwJgZxD)soaHt{v;l;etv6y$)tZZ zSEzm&czbDniE`W0gUv0E8ZN@{4I?EOYnUGFR_vw{AA5U_UmA^4$?!Bgr0Z?i*uU|k zT8?|xl^M`w$Jtp}@$Pmm_fOAUzG9eCYFD@V;H{-^Y_EU$3t7UgUYOxxaU8bHO(*}g z8gv{J0HMKq$gMG-JbRWgiC6iQc6)V;zgNH7=o!a-`hDPr>pM=jraE0^s&BieM5lAf zM$$cpx*$J|sci%Hcxu}p?}x`{9?sxZB5jW{gYS7+_~ggqlWv2aihj|{5E~7=VLtq+ za@7fd{Uo$FX=c98f(N%HRgzI?$J4jMl}M6$^VItHKtM!;#-;gyB|am6kK7sDu)u9u z-MWj-cL9I|X$YEm)HRp>=;>e4*J_s!d716LH6Ky*CO6sj)YcuCmT%1iwL~nH}D~6Yqe>>*4WdruRND+Tp@nh!rdmGDo_(kU7jt2o>>25l1U52q9Cr|!@nKj*>N&>d_&yYKyj&CMFa^@9F z4dot>i1M5Kn;#+Ew+rsO5d7k@i^emH^`yEvs^MZ-CiwWPH)na%H=M!M&He^wfZ~$B z;9KwD7FbpC#Yc@^tr3{oV?MXb{WsPYZ4UbLKYS^MKUupch_Q_n#|2b_enoA2^bfx! zRvo;E@U^%y)n9JF8>m-5_0U%P_TN`YWOKeCIVwwz(3;j!{i0oTwmuW99qfmr>n;AT zr!_U@C-Jxp+b$iJviY_dbxlEDi$1SbZun7neH#jlrJ7cR*Aw!1{Z}JA(U2ub7z<2K zh0IytQ5p&I0+MxnrxJ5aiS0+T0>>TavP$7A({kQ12hoXSk;7l)NSf~wl@Z8}vfsBH zv<%Q|>SzsGwaV}D#oV{iDRD*DsupHOn<}UY0)w6PXsb%=kLUSF~I^KIn>ozkRXBv+i&*-gxaR>P?aLt1g>=B*|FjIy39F?%aW4T?)2rbGxYJCQmPxt zC0t|LB4uyUV=k(|1gM@MOd_veEF~OiO&E=(h7j=V2v%Q9Dj5s!q1(_^)D_E&pDwGj z9${ea-%D&k-SK^_%UUbnbuAu`jfGg?t?i>pu0Lvkg2i3wr_4&)Kbrv8^wRb_moO2h ziQA0352!(NX3!84Fr%5=ZweMEgl(-TG_9kQqwcnk5 z?A!*(Q#o(~d(M0kZNo{*65ExTIhdV^*jG2zOY=_W`pp);tKez;$<Br*fPU2 zCnl_u>yxbh^v+86rLqcnvxeMbG-T4^%2vQ5p$TpiAlbR%uSVbN7;U5ET`F?IJ`^ZN zOpC0&9X(QC22nn=Q80X1y0*tKb!BX|JM3JE)V>gSD@I9K#l(41Tq`v#_xHo*I(<=> z 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μy zVm2)12)sOF#2>p)(Gl7cNb`J+azD=`PK_MDc&QpW65Ow>FD;-$;7s@Ehfn+^+28-# zRJHUJkuesyeB(ZSBv5ej+{}YYy=!o9l>u9tTk>vQq(Ge}dW}u8z7<-*%t`R7uHQC` z%$0aQKcw^!z-2w_UdWD7f0%@k;JmGRomnjvfhxwK*KjGHVWQ4aUnO?ExY4t@7(n|Gf4v~ zWZXo^Q9qBnHz*!Ft14bL7nuxl@uN26`J?C1{PuZHs4p+VG<>vVPrHx+Jsa6zbD2tB z@{8u}buVRV=Kob@SY@N=o#PhzIqGPm zqR=2EEgW*fuc0o}_;8Lz6WuCKNMu<>{bm=8`??fdMJaVSWysvBIJlwZ77l1g&M<8>x z2eZqdJ88-WF*Gi6udoYHsEnJkgx7GEgJZ}*n?p06!DZ|Ya#_!A@^K%ouJl`uq^0bn zo_mJr9|#>N))HY{y`|)s^?y5Ke6@|acXY&_v1ro(=7wUs*{s?$=BWQGx(ctroz0~!3LA8G zojz(LKZ(38u}bQL5Et0?`ce=7m+>|%^T>iqcw92c;TdZH6~O0?9jwA>m+9_ZHUQnf zjx<3y_%iD3nCaq3%7!m2_%3})gRn*llb*6=ZZ&FD(!YQ2XPsG%#*TKXkF_8Kk=!c> z4Fi#Pz8MhDhNx97x!_4A(9b3J#6Hu=70dl}#K?(Vq8$ zVFRlkV9EJ+49sElDeLna4->({qI%*P0(w_paUs`U_sxP*L7n~iJe&K_KK;}k;;3qb zi(03s%!bk*^D5|~SB!7fnHa4-)z@4fhZeql^JLiwx!CI8=Dc|gBWc4NYLE5B5)Dqi zYb5&&AWsLi>*L0X!2^(~ku2U!hcrtAG(Y#S(&?)yuB+%{gzMgSX<&h97S-brjw%}d zr%%W@BmoPVljJcgPJ9N4C#2Tl8uCtE1v}a1qv2Mw<92~ul5_1(*A?!WMWG4dW@a8{ zIp$RDEcaJrKM73br4!5b1tOOlReo^-CUiQD?-Xzt{C5Vx$oA}M0^@3WdFxW1w!4A8jdg zcLE7N3iuu$&aoewJbk7^dkOFWMgz)vZsQr;2?&L5fQQXqjq+EDY+ZXmy(OVrLO7fQ z$kh^KuyT}Vrd-x9TKM?m(MeZZB!pQeHHEiwG`#oxbf%bz$1zT?pLx+#FcjmT9mw68 zp_n&V!+mv~WWRpDJ?M39VYHJBQ)5q8Apr2!9U3qJi!FZUyuakM!gAcCC_Im73;Z0TwR|b+n9(VIG-dUAdA)0)r!^yU| zxuyCq%T=7^2@QpuY)1>czRr5L{OJ$8&AeHF-Y)GZQ9Z|As_d+sUFcSudhRo0 zG0GvL7;j3F-H0k~p?L>;MZ2IgPgUpY*X~Bm+N$jNZGEj*iLG%$zT#s;_wT9ki9fJW z9uqcepOw=h>bR(N_Y;9OMGU`fs$Gw2$UD27OZR(b`kEf?PI;Vj{K49No-ZYE7Z`ZI zC8{q}#<_Hg!>ENwzwQ2Bxs%4x6ez7c?wCOlcoT5Y~}N!pTUO)*ft-tV%{ z?8gGqD}y0d8;$O++cQE28Amq}(2?RP8u*(dvafN}r^~=_doe=;QfCAJ%X&ss+tnED zo5S`Bvda(B^b{z275|Gkxt7jfn;9@Bp9$yo-8QOo{K=ZX$g-U`P_EHRY^q{Ft4!(& z08W~)Jl1h`Ji5Qjm#R@6{6m^zgPjrnc&O@QXC%$(2Agb>ij9@Ee~}8gIWH=Uwe0yc z%=h0aCC=L9l5!XKls=ai*3+Cnwz9lncirMW%+LsNZa0hlG+C!lgmg*i;vN`ctHBPM zYl-Q{%$Qx>H6E7lwb$u^K0#S>knAGCQW64tldQbn1iVM7bxwpaq^JXRG=DLoZDAfx zC6Q7%nRcgxgl1WSi1s1kf`T<^OfPju&Ly|eNB6eA3z?|UxRsBuc=oWWMeeARb5%E5 z>xG!25`vEud)qpbe0BqOne0GsKSBrY8peODhy?suXdxhZsr7MIab7ktQ?6sStzEDH zM|5KnWB&#zHp!F{?m>4>hM+=O&&bl{+t<6`}fE= zA73f)t#~ALh0J5eN{ZusEE`eBkI;)Cold2 z@dm&?4de|m!sD_5Z`FoOUA@HKM(0mm%uKx+yl}w7Dux?@2-{if7to4Tp}gJ#@NI6S z7YzG~x}L^mmT+$z#pjN5m=8DbyMsWFKP1oJ9S-g}_5Z0x?ibCTc6M_Z8s6S<3T=p= ztEmXSSae+FM3!o2`0vBc7P~S=o^-5G8yA;7WknolV|QQF#(BNp4Q;%yEr&^(S?=| zAmk9fn!X@HcOY)@2lyHQ$;+{8qSZG=8-L?p^Sm)25JL=6YNRg;iL9wGa?fr<*A0o@ zi0F5OfkmBCSI73$V%6eAU;9^sCa?yk^5+4B$jLuU32-a4g^SVc!L;9B@<;aaw(1ShlL`!%}2*XihXM zP77^;^`7YA1%2mBc$ zLO4E#u;KdR!{i^DGZde`K-4*8gbxBOavx^=F%A3_Vf6vYZE0td8{F-l@grn-JpoGU z0M`gizr?%k-&FHr62C29W#ewU0(jl!?qK7(-AQ=0xj}dO86H1@C-TzE-ihPg^dOmu z%X8pO_aPZMoA~JW@;{>6hi&G6&Va+E&*(|Q)aT396P?{}i6-^0-^ewdUZ$f0!ZnaT zm!qsHX*ce72V)nX@JUQ_He4LTPptDudary;?-89`RGg&;I?UafM7*dsV-kL}qjH01 zINATH&?{@0L(i+=w*jKu`<~Zl{rEvY&!p)vCiist(LkMtuet-PtxmJzF#87+$#*Qm z=nD`kbCie;yhCIA2|exF?Cc*a8_F>tkt%0$#MVQBf{YxtlveUmPx5&6Xy+<7z`F9= zIYpxv?lb+gXmeT5uclS|kWf0jGCi7MbABG0o+#mxLGJCv$rkH(T1C1;PK{t~IXq8@ zB$HCdeVnEf=)GOCXaI@if6K#ZMX83-fw-E#;)*?ks3GIvjuSUCAG+q{?;3`%SvzaO zG?Ul3=t0DZMy)sK0w_Gcaz*_-fCYPzB_P;_=tynV!|Cu^BgiHddLj zoCB`Zp1x~rhuJ~1H)@9mz`vdpodR+Rz3E+{{&hot(>P>i;y{}FM9ojdns>MHu6BP! z#*ui#e(Tw+yG3X8!uFf79zex{lK3#MJIZt<_UaB?}Y(syUkcJI*q1W|3Z0h zV@baZMolvDh~n9)bv7pAHa~5CY++R5&C%*7tzh2Dq1?CBjJ-+w564?rzW#Oe5L2KoA_68}fKo)fg(BqeKOZCbm zsOG!-7Cr87DeJQu)w=_%TGi1@(d^3XY&+jsM0A*PcS3|WXQ08-JBFvd&j5jJLI5tD zB_@V3X`6dX$e`mi1Cv5vwVYBH2)JsX`P}6dmA@IlzQY<~QJBa)Q7*#7#~AnahGG&J zb!ai!Pm3WFVQ39D4$CLf|M9BW!(cO)n=@@S`w^;R1UK#Z;LihUQ*!yS`rjjj_s&K) zY0FfwMb{Rl8m#PptPKNh<3b#N2TCL-%`|sBc%3dUyA_t2M6bf+pUX3gcRiIV(;GSr zmCncO(ofKKW_9;xU;2gr3U7Sg-);XE5t%1x{zEwAveK3J%1OSq3gzv{tm~c< z&35y2zA~H8Ib&~$a zJ50>scl!Ew&uEBKP4MwbX5NitGGv2(YP@o%({>u?T9Y-3SJsETErB10ANf9TwI@QV zZ57i;5auu|N0e9X03=*z7%R?II#8f>(wYvPB_ab<~L8E2D*vK%z zO@ff8EhT%I%cCiQ&hV=5sE!U62dOA-yEu*R@9q+*C0pJQjLeTz*Jn0fL+A4Hf?Og) z*CRUb16RzwcQk`~JM&gNQ&s~5AHeNNhUlw=m7|70hr>>fY1I+}YRW^Mo~JxvQ|8lD z8d>(VS{mcFWct&X)a(PCbS^>H1yP!SOeFDA^-@!-AUggL#u@7;iZ8|=_9v&FPw&4$ zgDl84esD91rwl9svizi2NfnD05~5YE)qLq!>!!Lo zd@+u}{6++hyTtR~k=!?mm;|(pPvHYPQ0^VNXfQWOWiRj)qF_ypo=m0em}EGS0heW! zTva-s{ni$n&1=&tllBm@wME#j7986pdZ``Q`gb&%cZ;o<-0`V^2fS{wXe6~S`OWL& zh+8BwQQc$#%=d;7H@=PzjsfSppyd>2nYNL&a=kvL-)hnuzM;LIa!2b93u`Ku*U11^ z6k;KK&zI?`!i-FPR3hQ+3b3d+9d z+7PE%T+|WBBbL4B(q_QI`#gd725cuA3A&RuLNU5L$_S92IxSi!_uhRDUg zA+flh&jgpQb(0cm_^z=&&43wP@Q&^yDP%3b-kC{h+^1Yk$>L@sItDgTeG>+@_UpBf zS87W8S~SctT`~NkboEKBbEbB!UkTl}V&9Q&K>hV1QDJLGA&ZHFiC zF_ySc2hJKyQjinu0`qd-1rOvOC?H4Ot-DjyNBK`>m}@m)n}dKK3wfAihoka5kmxH{ zPN9F5P-LpNS3&lyFT%5QQe0^Cpw^N8>USgR6vN3k$R}-e7K#fh_ZF&0DiusAkfjcx zRNty)5;?EmJW{iV{)+Bo2)I9#(X1&s!xs$|dvi~j_l70>q>*&2#g21=5c1U^uF4vv z?5P_yrzP^y``0ja3BNIXpuw@WKmFeBRq5ox+|kZdRxhTzP;V_(m*&L>r7G|h?HFi< zMCd*+kiL!kM*c5v6*1dWA$#l}ZqG=s`Vkk9(h}K9^fJvUd%j=d$iG*%=6~ceK9Y^8 zy>q2Hv2h$U^%STjJpFLygs2Uu;?if;1jZ{P{vb`u|L(N%AjP_io`_VW)&m;@SIt#n z5q31Xn#!r(5cf?s8C$zxPRsBLwGSs$tpv5Dv`nLmK#?9-8pUp55OCq8)zRqHOTx=* zov8PtX}U$@;yMP`Wd`C7n1@&0E-SaKC$fpZoLMxBAFDNR0*Vlc zpLmnpaGtY@1W*FUPwYG1sAkmf1Po=;2hs0atc{Rhl|Vz|PB;TFGIO9$dDj?q0Oc>Qur$9Bf?)RmPPu~euO}F{6X2ub74TKwq1!lp)ls|d>s$1P{;tb zE}SRtxc*cc#`np(RI@QphFhUF<+y3p#7?#yd-T?u_eQw*`;oFbv@AW12d1*@1ik&k z(wlN=eDrN=Zom?eOdZ)2l?O-KKv4PLhG zZFL;edm-nIi_Dl;^+~AcI%CG*0U6lZj!5Hvpjz^3*;tsicbYm$V!htKZQt2J_lp!M z#OMj^q1G0tv)-q@@XGY-o{3zuFT4bh-IlEpU%4>lK@s`;%L}=|j2A;+mjbQ`v$LdK z^dwH{wR{uX%##oADm9haE-KD`8Sr*-r}fw2sqhi&00`)W`y@y3dv&Ch1(&;JXY7T7JffXD5GoS4<;wJmKksYU=)|IsqnER;1z`_2SA_G;im-h`LFK zpe+v$Z7pV;w8i_DMh|99j^Se7hYsagm(B`2A(~P0iZ(Du6F)Q5Om%jkwbR73V5;>=eq$M3iePwN|XD*fo`e_}>JkiVuD!(Vj`s;+5{!dmRoB|Hd<6SU)#p?9dAw@@8Ej$^RbMv;F zmYdwxk-aPPb$M%g>&AD7mGif4o_qXZeW$QxjVk1BXQtIx)FIb-v)f-O$aY0pvj%XV zt$OQL#rSmA%e%t63fpnreP8WqVehDelm7f>{y_H$aVuwvHolM+tPvjwU6WA+x78%& zwdD-ZYy{z=mkXq<{`C5q!{fuafnQCn1|2ZLt5n z=Mo7JkIcK;3%NQIx$L_3+oIPTZ-h+qqau+!>k*YcS>c+b>#`DNp7$(R2yA>!Fv8QV z!woTA4Vc~hY0U^YtW+YJrHIik9|91s6BodDc%7Mdl#BQ11$y}f4Xd7-yP4Fqk0`Y= zDa*E(j!ruWJpWW9i3)hJt~K({R$l+nFfFUWwm=cd?x-c?d+>R@$ErUiXKG`QmX*$S zzLI#f)<=!l|12MrQLmUaE|7QZFgg){(`4BRGD;L*UH6+Y317ltN70Xs?2bLt66q%poiI`P3dc9lv1DJGLE$n*Cn3}c_i za2UaW_%Yx=>P@p7@RC&g#Qov{9-WR|rYfx5E45^mg)S7j!_@u7vE%Uft`SPL8|o0g z-MPVAQF;r`mPb^C&HRx%z1Tmco*G=b1OCpqWPGHy$+Fpq22yEBnny>)@F3b}NlJ`S znk2h)20=9Ty}I(dS%CvtqXwS!&-d(bh1j%0AZP9GDx(de+*du1H`)3*E!9m(ih_F; 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%0At?Qucb^IfYw zR%tHvHmG!KknDN~%!6KIk1(pBOn|B=wv>~lpyG3gea$&hlCd?>pibzF)J*9+HE=!p zod=J)fp^0C#vdbRRPamX`5Iw!ha6(m>K)@qH{X7m^H`T|c8N70CPaJ0x7g`;2~QBG<-qU$v2@5Zz-pbo9`DvUZR2kk_L?ec-pGI{9x9PsFRvlI{udMa!`g=J30 zV+qXk7EA*pA0gXM0^33f-y!v$mnbGq#G&iGV41f*WH`))woT<+<-r;ry3yi)MECKi zOM*i*LhL&FF*_cx4cIp&SzRm9GY5&Jge?f2b%yr$9*=7FLHk;Djz=WD7evwx?J}z`-Ou${vJ1!*|TMI|j2~@DYF(&AjhqVda zqZ?&tkm|y96582 z)0 zuC0C3V4Y~j77)a_r{K~6l{(?DotI8;RVv3RTWgJPDI4d>s>hx8!_88fqs&>vj4<>^0b&j0cqU zss4V(blLQ{@Fyv>6D=`Mxk179NoFN@q!Wo2*XzjhOXO=q^AvhlIbV08@n+iS z%>I(FF-*OMS5<QgbtLW0|&%0p%N-7(m`ctTcvdukT? zdkZDhpx>AcSl5`)vHLb~-1f;5cyzsUMT4kks59owgBl#t?@~;0GRD^5AkJUcQ}%#V z=53_sWa=obeS4%Kc)`5T`y5c$2E=j9^{I~CoN?2-zhOhDH8Z!9sN`yohm6HDqQxcc zKCboLWBoyFkWMtNAAZ3y1avJ)5`eU29MaG8jU^pHxgSX0V)i+7!$ey{Ff9zfRFQe0 z^Ii0Oo3rd7=qhx|c`ZqCY`r9m(}H>)unytm1{LqGMCcCd8b?Hfeh-y~_8K97H*hV* znuK06C{>}`$l%YFuBrXgAof>4J@JcCQZ4hEZMsi6f#K&qXdQZ=dQXxaJ0Nw`_}jO~ z11|Hu`D~|-ksul#c_JIV_^ERF6B{mvI!sr5T-V44tOh-%3W9=rtd!?^vUXg9ZrJ4& z>v=YM4QnN>>CswGJs>5Wccg@OGW%(z>N%WH4#W5C&>h365r;J)=n{KwD0#$5vlRD; zMD&jMsnsE6WTE|~@?4U+uc&*8`FScojj_7dEIADUO zRIcxl<`zAnOy)M4$mF;^JnpezyBRU1Jm|a&C`Yb5#>1KVHUSmH&_s18CsouG9ic*C z1;Yx{p-}#-IetV;o@lUc2sKxVB!jiUwRYW}5ZliC=R`VT+T$9mlLi1MLn-V|ayu71 zy6fvtNY|ldpbkC0#&{21gYC33Ma>f_Hd_yhP3Y~Lmjnb?#syYIi5>#EL@MC@hRIMkQ!H0L7B*Pn!+JE|mIFka9#$=B2RvR6^Vml(W3up*>C~$@ZJh*L<$f;dO>%9nZQ7Ssf8p2ac#q4KJE*3)Rfp<*zgzcDIi*<$I3Z^ z^aTn}NV7Suhi{cYgRZs9edmV9bVHD!Ol)S+BFeKX9D6`2tB>d=yV)?jM}PM6Bf1_^ zX@2Qg+k0jtfMo>pLHV~znNg*CbNw8BvO5<6U0D!Bk5RJr)%tY^N5p#)#E6b$<=FpA zV2OcX-&w*SXw=M+amqx#V+;!-+ zA&B>+e|tnuw9vK&^PBzogqT$N+lY6+-hDvbYUDMW z%5?<&c)_v`aOh4T3VnW^fHYfjC_JR)j!5sv73%$ML|u8kdY+AT1asUfWFla>@?R4w zxB=snbUdN~x7DP-!|+Fk^jL#(w8Rz4bLoiWBkgr;^vN0lyoN_PCm^4j&sc^AUAdr4 z0_C|t1WcFRK6u3bAZ#C4<36Bk^r%j9DCa#0;)_Av+crNUHK2TU&Kk1TpldMQn>OUo z>zyzi2gE+I^WH|lj_4W+C7oo^pg#U2As|L`IDa0HlD9+IfN{92u)83Aa!G&Z`CLTF z0BI2WTKmSEdhC5!Lt6WaMgX0(cl0l7OoFrxW976U0)~~Zo|`Kj*5L=vb%ITx&cv3g$$Wd&WiaTsR=zMyWn2~r2<75njF71|*>u-fR7 zWq2v@h~5ZMQgRAGe4zou-_jnVlE}U0A#0OL(P#T<7`&lN;!gwh3c8Bcqbq#Zf(G$k z1aXa8a6J&jWe*avU^>?HUOdV&q4SpQ8zO8ix7JclDLj2LZJ~m*q;Ai(^HLS&D`H}) zN9?<=NW;<&T^+!EePlNTkFqXtD6h5Ba1o3L`%Je7QoGWk6?TqmImx=Jn}_Vo?(q5WD?%9O{Nv1#G4o?Kav zmU2vkmI$Vd!*m?bH3sQ?SkP<#g886cpfc7?=Ol?cAQ~SehewQuAnJ->_SUa?WF=J&Y9C_B~`}#GL1l&gCH^WDBTVXglAs-#HJcTyk9Xe~+#~`+_*$c}`4e z%h%9r@QBMxf*Xo(=n}ei+P8u87&ha8ydr%ujiCHlK6(vD3}>~M!s!+ds4oG07D88r z60&_Z6gD+HdBX=h$^=3Z*M4;vmKlajU$GAIaeXed!79`#5R_%6K{;ne%g&7~3c7QX zk&h!{SlTM}sj}Rl8_}>~_J{UbLs6ZVo@;B}KHKNe)tQ2n%x#q5SUBJ25KxB1v}Z|V zWGbjfPl!(+*x!UhS?}Zqh(k0Eo)C>2;@Q;y1?k)OSpO^P^DdyCv-8VC(6z+bv3+32 zb25&x#BBLf<(LlS5plo;{cZOse>@>4bdT#JbdP!;a1vfy=>1YagEEI*Pxcr`Y7N#) zW+IW21RT1gAei?8mImF>x}Yp$wf-3kk2r@<=I_TsS;2G&qRx!#!qM@39jMEp zZXA_#MuXJh5p+FqE{}w^{2{C31>NWGgK5uN%Q!<2)Rzdvlw;rKFV!8PhELpn%$ohx*(Mu8!hwgzC+dydg~8`Yf>LMq+|1r z?VS%nm%OQi?cCt~1VWy!A%#Jr2IxFLadmYuu~>nSLL z6Oij=HS0`Jeq?D1sdFL*voB!SNVz0<40}j|sKgv@7>fq=$cJ6C&eyN|z;(biK-s6F z)s2digh-?N3&w*+fzE-xgr^46z5g7X;{@j<<+axTW8lyY2{&e633~hyb!fl%Y#&3< zmUO(ih7GHScHaRp+-xD}hOh&=kF1F~_KNK=#t^al^6|1u8(LoP!|G^PS?q}NoO(o^=*Pmfb$rYA zQ<0Md=aM=Np2zHZeMSh$w{~20MJ^MrP^Wc%UXk|IQ~TSlk6UQDuUVU{W78n@>erH| z5^8O?hR6Z2Uuo0`(kBRfyPux4g&xlh&IeOp&B4+>E^!LyKxrIxf5)o$RpHU~@*30y zO3Pa>Vu*MGQbn>g@pyFa=Y;DCP3uHDO(@R^b~8|i(V$=Pt31CH{vLwEx{;E5qy(%A zSP;Y4ZsHOo5bfsC_(?v5 zLzEqoUC56087Vn|1F4tpkoLz`{KU3XwrvuewEG0z=%}Fk;xr;(LQn*B$3*whnEVZ0 zaKE6AXH@!`VF!m_8zqn2p=_yB$bVwobLNVsJ*UAwXpmZef>eMn8G^1d9D+lfd=59% zAm~^8RBX?f{^1wSp*3ZU>x_1LZ?B;ql`CvIKRx18CAz($`>k!Q=Y;O7cX^E^Ai?Ge z-xB(rx%L#pgi#8Pp&$+Y4#A;*e>oSh|B0qO_kh%!6{Lw}eF#YPEc@jS-LU&J)^|c| z6alCw!BG}oO*<`_YrFDs)3FKWw?o%RdP96XtrRhBFnrH6c8mS(a0^!|I0+@&SMt&w zra=eb5$ixFQ!S)LP~ZrU>mj=a-SxLIprX6Uavcr&t$!M;4)Z*2&X+YHh|4Y>U1DFl zQ6X|Eiv7}HxtGqmEodM)v#&u)@?$_!k*tm*Vn)3is6&aebbmP^1;qOhL?Yz>cj!K@ zHU!F;oufx{-3Hr*-E&XelJtWqcR<%;ZxH3?9x=OJ%z3WR-Xpq?Tx$P&l%tT8`5FZA z{Sh7&eWwHYtA{Hcy50--1zZLk;$#w}mhxRz#tH?M)}=!*9B!(?Cg{B4h8%+7z6prR z*8V*f^ysE|oHaCvhMh-LTn_PVaIa<~83jZS{Q>cDPC-=SIXu$kFe>>z#ae?ycl})3 zRwDVgw(J*-gPxnyb!|nmg zA&3T#wEMoItKS9jJ~{p#-SE5O9^EC>oWKLR-@E_P?$0A79{mQ46z(CQ-~i>Jj$aiN zPG|P%09{Jocti!j&=DsI1+76k!3Ebta(XXI+DQvMpLjQn%iPxfr;>TY^w6_loxT^O zZ5{Gj)_|Qyg88o(rco2x-%51aevhuArU5$E0P-lW{k~Vq4iWniT_U!GazrFo>PG9` z<{9oKIHZpqI>a0#LQoI8J1h^oTO-Z2`wmF^l4wj@*|t-qtiq%FceGL`2TSJmyk{070VL>>Gk${QCM7*mXBfE{8a&1YPp>=o%@P2#@($ zzZO)e=Q6?smlyIEj5F$fnlk$LH%!Oe^DI;jLi@Kz`uG|*otLh#`N9^EzGjtPy&5ef zEzT<{Uyn4jJQgG`XWC!tcQMx+iP{~OXA6_#am zA)pM8E|J^olE4X@G2WmXb{EV??)1vC9%3^OV6D2;!>|1+l&QcZ04MMyu}9 zv8ETs2|U%qTneraUYcRtVAwmS;rfW_332(gmMrghq{@@t(Hh$++m1-zu}-<+Jb%Ho zd9TP5-8{;K?lC=b#`X~;RX1>+AijIxv2ct_cx)HtSIfVc>rfs_p=yQdx&vY#poiwopdLx2SHRS zQf}XhFAeJ`x~f4p?CvlgY(I6PpqwK`SkIkcc_uVIq91}t>e?@M4yX(_h)WIZFNH_hxMP0@ zj06QWU(0YfFZ4#V1I6sqHd^7CV}Xx_C2u<@f?-l`kSd0ss4KU=rG$XG@S)NsG5Zg= z4)46db_shl%*GJf68P*I9^JLLbHHJ|LLhna?{An7yB0qdf>ee*q9V<=8i~K5PW&O; zo={$I*Nt9zXxrk@RrV#26n-Lo-u)-iudDUxgc=0hv1FU{ULG*rDE3Gb=K?;J_Mxw>5&?d4t0Vbf}s1H_E4lHAdPTZgMjU$>>`Jk$Rlz`t_NeI#;g<=;HMg-aN2z}%IW_^0% zI+K|Elo&pyKj?W`9>^ewbZ$VI@NMB=IQUi|7x&jC zqe077L$YVW%9_PMSPFpRTsw!@O0s)zY#3fvr@%C%PGksrxt8 zJs;zIycA}aQP`gfJO7RV zrr}(rhc{88P`EOza%cNvXNy>b{F_}$(4HNEz??f}_g0Agu-M0b&hCD4Nw-P4wCm2B zf$XjD>$MQ2(@$2nF&~y12sD3P9Q9~7ORG_hPg%_61-3)cR)(y9W`s{JM5GAsJi>wT z*BYiQX=?0#L^NF!8~uQ<2v>C#QiCiQZBt6deK*V>NE^s>%2QQ}QSf`FFQCvSd~44t zv$Nr1KsdZ4-{1C{7UO?lGoq5)k3nXm(tGa>bU66nbb?Lp-iD(tYPUM*p1<6;>Y$>F!|H_A(`BCWh!*w0)$}Mtq8TE*@ zkK14tZ(SPhv;HD|E$99keS^D4`z$v0TYH-QZ+z4uM+ui_mFJd-MzS=aZN(ohlv9?d zMtZ~+QsuH=I~>J3X`tmjVI`n3Oy0R&yDJJO3IDb+>TUl#E}D$;S0BdLylD_JP{(tS0U#Y};lnu`+SKJe?7z+0V8N` z=;N7z7Il}`PT|N}y#uwvy4rVS!-Rbb`%ijXEw(-#+6Cdix4(UJ92L)*6@z&>{wR<^ zA|>0z$h{NOg(i$#-B7<5=wy{^YoEI7*ZV0y@u473DW8t8*R>Qg+@55U%jwWuVZ{lZ z(Eovv9Si^3-iSK>i^Rv0F^CcSeQ8q+&!0PZLB~Sn8m8jDy-7}MJd(0J>@ZSAhSO1O zk4NY7r*4?O^KRP%FC?H+tHGBKdZo+0lKP%C=R0USfMT)CS z^)Z-G5}o;}Iz@PXv83^-X@tO*p)}twB*cWLg(h+H@FhN$zmJ;23v5_YF4tY0oKbk# z64@ATeGcZ%p8U1A-yEiALpK)F++R>9X)q z*u|(kUNjr!@iL8NGw~0Bm z#W^m(pO#r!Ip|FK0CN@i7xzeP3wQ#$n74arEDlNk8*n%u6QTWS2y}~%93$iM7JeU5 zS=jETzBoS>ewY%3)Es+*((bt4Rp~lK`vwolrVJ^wc6AZ5HS61+YcZr)X8RT@d2Qik zrf6pK@dUEPHFJ%J?#+THZ)~R`_m_Ydg6VW8wgS6a#f2hNqa`OhT4`h6@p3c1Yttnl zv@m*_D$+U6dH`#l*YJ=hf-GB2#9QiLbPsc+1k zyX~EeS=OMP=hLtK;yqYrSN|5;vwj`MgUj&QniZSgMpo=5e4mAjn z&56DouBPDm`Q9Yl6WDh)4!HCBbh0RkhiWTkk^fWMle=f{f<~CeP?gr3PTHE!!9i6@ zP*i?{y|{aj7AB7tg^xqapAX9cXdUWT#K`ZUZ6+td$g1wB@CvmA}ae!emH=qoRC zhk$wuSAj^~&B~F4$Jd_e;cXuVG=v9iMBxY5|FDhz_q+XcUVcn*PrUP{!haiFacv$t zX8WPSOX`4U!p7hL`W4`s*e`z6gCZYtRuFqK`+R!mBQjXXcWYLEA;N>y(u5Pz&6i)@nxY|OAV=?}O@L3;wYe})&AA{@Z=qGn`;~D(U570v`OqOQ*;zk>q zah+COiXy8vkg7k`CKaaRm7|J}?|fsXpE&_#ds(?>{&EoFc89kWV&4y%&)%1sH zV+Ub*o=e=p5CzI;xdZq$5wLzD!k;QXeK+eaZ>nzf-gM8*bz4+ zb)owNq2^U_q%lc zAmG8EpY(l>ao7o9#o(soU`Rh}E3&z^UZ5s8EyG4vdl&U=Wbep<8rj#!P1jn`gNZpJ z531D1&=QISbl3g@&!4srL*5=Lyqdqlm9b)tABq*Xm@4Po?#-&Fyg;sKr-n?2Farqe`?-I>g|!f!_fMOUzah}H@GX#5 zY-!Uis9DtqHj`gk%2!#|Eq}T|EVd(2WMd0nXPs)r+kaB)Z}QZn zo&rXteh42x9&T0&wOD~1lv+Yf9rf6H`DhUCRWlvj1ZGykdp@^>n3k{KoX zhg8UIW(>MqmU60q0ij$HE~&t!;xv+9 z&2fZjO_gche(~OLxI61T99t?7CZS&7>YJF~7xFR_S0n!5 zWsH-m!b%#96?vX+5t+v87H>Lyai+ibP{PEm>i(bNuhtiv!))@eSy$hzfE0b0GjV`9 z9aOlhVgG`&X8r4E>)oT(LKC?DW*e1(+`A*y?6<0~Rb|Nnk=p{hO{FiFQ{!Se6WyEj z&N(jJ;B1thrn7hWS>24~8FgQi!k4FQtO`Bxv_oS4vNGyF_9&1Ds!fGqlI6r(d{^fa zLzGIIyTJtGJ#e|MdfAu*LGaq}{rmTg<%Vlr%w9~bR#sEMGv>=fI`mP#tfk%$*@s4A z%Db`~IRFZ9RP=cd4wH3C{ zt0>@Zy;WFE%V$OS%lNIR#z%X(F57H-ZzF%6<~X$_I?_`qkc81_A=%6XP#ISL@nW$S zmjg;0!8ax+hp^^a z#ojke%i@13=^KyvyG5eh-bPuyUDBu6clFw9)_NZfaR2^oCm)|$^Qeb~W7Bn5Pmph{ zzproN;axQ<#D<7WW}Qfyf*W|Hmu*7kCCoJpZDpgQy`DKQOl(H7E{=NVRWa#?e+#?M z&(ykg!koXa`{8^njTVIE_vG6>t$v%eQfhk7$dwD^ z-1Z+D7@qH1%}rIvqF(WZ@&1i}JiiHbjSmjis^l}5=uZR{suv|4eu(MPqMEu zTmZ&}(`ucj=bmeXEl*F!8$?fEMNMF~DEGGbMrFGX8xCoqV3Nr{iVR-QHlOXzhR&9( zE7(>HIgwLQ-4N0nI(hIo4Z0Sj13vtnQeQ++QQc%#!2Yr~nfn1xOwV>;!_FA;^mmbM zPMRj0rV(412XO21gQmfO320?w6JkQ+O>Ob1(NMHLnJTN4`V-ktRGA)5=P_9iFSYq{ zWH&-4F}6{S(}fTDMfaq*vD|CkE9sn+@ zU?tn9GZ<_iU|itYHhV{9n7Zk08B^imy(BK?W|dAU&gA!lim$LDa4Zgd1DL$Uizl8#2Gi#Pj}?kLOur11eX8`OwR z4BF^R$4o4EMfO%v5Jia3lS7Zwh3@6_nF?5bYtWbMKbbF%0F*s=jaG{5KDs7LIU6Y8 zL6@1^qi z7|%yD1eItfsld=mzH(^rc3Ngu<2_K^kGfK+sfg4fc84uURJP^jR8I>Ig ze-yb&WxDrBx`t*9_^JXvXn_$t_r$eEhR?+@;XvaW)6<&Jt-&KYAvvXBZRtiE;YT zhlEp;5M%!?)nj1&jyY|5ooBvjd(*wGH4_~_zO9Bl4%qrz^=-JqV?lzCG|w?F0G1K- zs@LXAV4`!kkL3eE2(&%wLmf1pCaY1^sX3{!>iR(K2!GtxSmR0TmV4Xu8{^3nzMVp# ztajBFIb+xKF7MAL=4@)+)+|rtI@9yHlW7X#{SPjo9u{x~)>5;qVZ?`Wa7-xlULGcL zw}Y)W&?yfU{=ulvCR6iWHm?eW8|JQgvZ>`SS{I@J>bHHXl_HJ6f_GAS zvpdyX5^+EI@MW=_|K(KF1LchEoU5{Bo##_^qR*-c4g=X09Z#oftY!q8Eynr%oSWp5= ztIZXdf3H(A5I++ksi#q3op;|%M2@HB_=PsmV{~pZ_yKOKsi%yv!_$hyi5{?D({imW zeFz?l7_Upq9L0=){nNKk+B7dxA?aDcMtoe|eJB8AV^UhC#>5?Gt5^6u0T7q1E}hWn ztd?OWdQ+Z>sq7{&H0qv~%d)&zUL4A_ZI|iDM~5+-UW-xu(T8JskDR#1HY1RA2$CsA zUwOaOuTA$tHk?Oi0{Q%oO4;jN8LO*$mR$wk-}jzZWv^fMuAoewn)wr3TyP}G=g zXRkB=V)ewnBKB(QfzhZ^G4KnGV!{|-k26k;PQVu=@&qR8x07Q6;G&O9fVr&&1(4C^ zOE))WXIvhFCo#G72>Z{?g0C|Ulo^&ceAx;nRf8O84@Y2L$r$)tL$o1%4Non`>t z~mGwV}c*VXl2votp1>)I07sbqY2uy z?rwuI5Vhd!CByaXXd2%?2^O_cyk6Wax*`EQ@dFx={HNfN;>+7wHX0iwCw}A5VnH%f zw1ybzO{W#VQaDT6OV!diZ$dZioz=!&#SH!;o$_%=BOUigwN3U_hiFIIOMm}GoRT8D zgI7=EjxZWppDdXz3?rSMRSbQFksv=8P_d_@>_k7aOP#Qi0{zR~mX(p6gU)&qNjy)k z(>qdUwVF`1OX}%QH*T-{K~ww{$2-eF^O`|dWGB*4#QV>H@0c?AZFjd(CUNy7#Gh*< z$2^uipU5ugzI}Hqxs-C{e2N`-JEt9kjwFEYpPSaoA7xf^k2$fje(=uxsy+(xM~LSF{|A zU7usB)4MP(tQ{^lcTq&^b#1p!6Zd^z#(4j3liEVE`UKxZ(IM#wupQCTiV{K&@Xjicf%G( ztJzj(B1|Xf;~fWElyDI@Ds))B{SE0gdb1|v6kG@xGg2@!b_~)9>Q%Myt;*fFIjeYD z;4g@c@+nIO4#@rUFwJiT7ZYFw9AgH0YnDFk#~Ne!nmNJ}519b`doDLJ%uF6~KWCe@M9KEZi zCYCoQl6ku%UcugPhdOebMvskLPQgNP{r@N1E==HUAk|)xI+yPjrN*!^+D#<1ON&^L zzV`ZzdTD97ODSfbtM>q7{w7TYXCk_hBV?;88`w<>F47UKT5L+ z2p(k;KaVD8_3X>wid;nd@lkxAypwX^?jHc31r+V2pef z4ZohqeqWL0jNAb=9!E@V%H@kh4xfU05w>&}OzMw%C@LwOiU(2+hS2ZGcah^?-z+xB zWlj9#RUyNPl?SfiKey>z7fr3eTuhv^8dOkX+}B)xk5{X&7U530!c$d1D$GG}nbID` zM?qU?$S#Vs8`!glGv~~LkQISZ^G4!+36b1A+=)5jri3AU32&!gq7R%id;zcDy$x-mP(e`l=dyKSjBZ# zHb*IMrIT>NBZ6yT?TwFuE=)F zf=i^bnY7}4t0DkrDbY=hTKwanUQNzfuQj&texu!f7Dyt#AB~<>ROS(6?F>1kRG2-P z+U6mV0iB7_5_lu~Cj8BP-A$7HObvv57+1W(e(%O+ryI^_=lf-yay754# ztZHsD#T7;}y}5}vpPH83>ym9sl(18jrBaw5c(4yTkg6`;$_Xu%`;B^#R2Fr1nAk!* ze7!k0JIw`!=+RY|9Cg&o7+Ga`w!MO?^)@muG!@N7)-+dv6dTdti>|wTc19j`eq&`WGJnRGOIo8H#?48`n?wX z`!v0Za*WVw)P{rW<82v*dTNE?J!K zjr?MDAjPg8JBH8jAa4*Oun{u4+@GDLLTX*ZKrb(JL8cwL1zLPLh21I@)xfb49cRW4 zAz5_w9X1BQGUyJtn=Zl2F?1mOml}92b>IPj)~ZkT--27D(g#1_34q+D`kX$v>+Ipq zsN|M@^kAsm8M}|=MS&tyRjLnK{?ww_V7_WmIZ@ zG$M1$H|ZHcfAi55P(PA6dB^|Sr^V}ev|{6NJkDg$m)s5rem|UPzz}96au@{#tcZ;T z+D~t3t;9+4S+d(uxJ=^MurG)Fixye$In=2~-qkDLkJymVmvfM3p-|Q9yiV@#3lvXR zn~J}w$HL75U&fXz;A)7j*V?b^v6#~n&sFUi++#eyWAF?}IlMsWcA9!OoNVV0mL^q=u@8(A6xBP$t zGZ@#zy~U72z6vdKA*w>kZQ3cTI3k$KdHGzm3hsFu3Rh3CDz^}$Id+_@oPoIOvAOw{90Vh=~fadQpTR6_-mMY z##FDTh*x*RBlrOw$H@2AKaJi=S~sBD-zC>?|C*^|>T`bGqO}@F$+32tCWjDbm=%OU z8S`drHuc$6Bh#mkPH_oQEU}II39y%?p19N5jDE+oiSiJPiB1}evExau_ud*e?d}J1 z*YhM7{ikImuHyE-2K>~^uFo8;`FK(Gas_R}tQ<0J?4T%>pjemGl3Yv38VHTHJ|DMZ zd;;oLR9R42PUlLY?T z@QjEAgy-0`sq6Bc(za9PH%rP-uGH~zy6Rj!E;EVENkY`G>Sae84%^4DO*K0UW@x5B zkis4DCCZ)6L*$`qrZTZsekq(<7_0Li-lk!iJ)n~o)iXa2^V=(drub%bE#G}ub!{OV zXLrE9aXXqORh(1goJTiXz7!`8cT`}8)v2O|cy1N)%pT-PtDD0HVWPot+a@C3`ln$H zt03VDIk{u9ux*t7n||y*V7%}4|D!0Fi4at`lgkWt9g<8gqC?e8@!a_!qohUs&-oPC zmYvkJLB7@1o?az#?2`XDL7%YAhN*R(N!!m<=f0Pt*%WBHM^8J00t2k#^j>+v9{iz?C#U_&iz7Diu>qRt}_zCA0KB_R* zF{zcWu1Ae;iZN$Y$gSUg<(zZ6E?Cu!_C3%EUoE2*W6QHqA<_4qaYEIDU)d|zFn|LK z_1ghe2{hy244&69Fuc_vj~~@M9nrFuwwU48+w9c>S1x&n+k9&ru3c*95OLnsL~c`I z>bRGV^88Ged-El{^fwIj*Q3aSgZxVEYq}|pRCu=Xgt=(toj0vO}cNy$a3HI zF)Z7CprKjz_MR_f)`;>JTtCwInLNwzgc3EZIxxauiqg}(Ffi|jPq%TzD;l`R{ zEw|P~d|=DxrO90yeSbkRN3gRy>O@k`8*kv2`mMhMjvtK+=hVwnnDqD1wX!{ljjv;) znlBY^s6X!T8)`cFcCEYS?j|VCIO3h9-B=`TsVC`jPLfMfW}~tnAr3)m+1_6_9Uf@+ z7NtTQxK!axAJsA+0bmB^ia8D1WpNYzPG-~jRIj#vn)RY#6>hgJiBM)?(xsP9$597I=hcS;(_zNHkdOo2flk|3v-39-4 z1VWKJVy1fpnn6~>tntv=xLKu1e4@9w%c~xTH=rpOV7Sa#!@XxI9b(hY>TB$+-Xp}c z9q$zSp(Iodg9%-}3s}Y40oLDE@gRDcE>rT(Kh74_jsW9u#)e-mSZfo zL0ZyG{aw?1Mw@GxDiDIV*pZ(6Taypizjnreo@@oq1T!CXM0Rj#_TkU%9?M=I9&b_i ze=sXMt`Jf@#q-s%zKy*_-}H9do&?%;idXT>+g5NWn7-MZZtULHe((}2_`OPe9_s{v z$hi?EXd!UvH2VuT@-1x?t)H98{QoU@!wu{eB%*C`BM-o}ECrd7E z>m5dap@m2+?9C}9){i=mcLo+5OsgZ}|L64KpNJ-(iqJ^%e(%TtJ1N%OJWw#Z=tL@u zN3ORK;y9h|EyTfUm>2`STVjOP*~t>qga`BJ@_LhZc*FInSWwKO)5ik{aPyywWasCU ziyMd!Z{9}vvL$OqYl}f|YXT~(Z!BgrIGW=Eg*mDPJGvPSR#ztb7I zd2Z)MVo8i%f-Et+-MtOO6Uiq^(x=48p5rYunIkTHnydM%ns-}2XC8WA-rQ)fxFp)x zosv!R=mUlRd7YN9`BnT*CwXo^cA%rX1czUG!41>zlc!(4k?ROeTdA)ebpc^*XKcdNo`?auXs&sH(K~L z(QXf`{heR$v{R1>h(PEvHk%rs{xoQ5@+18uiYZgW>c7K|=YD9jemf&|W1q%r?>p~M zg)wG5y~ncCA!sW|Avj<~dsl2`>NLbI9YnqKy*#wwurEA=-n24Av?Ai5R)l!#>dB~z< z%rMRR+U$WX51k4U@j z3zJiVQ9y*5pXk`f`!TBIah($uTQ1myhK+KwgSS2IX8yZ9W2`Md1AG}DF{d>dLF$~@ z6Fkc?^3=tB-pp@F?cR$oOn$she1f=i^aZgMk3LInA=5_#JL(O#R*88o&8?=M~RKDkRk!_G&I zDthHLQd5CmK?dbrxkM3%v^{VfARlLr-skfkm=_-2C=c*t&E8sr6*M}jJFp(*z-A)H z8F27{0c-gC7+EW`TTj&T1Yyn08IdSq{0i9$VVB-!R;x+|Mpnj{c}L^F@)Al{ix=pK zM?x&TTg_jpLWh(XA$+C_6xmGqk&2)An2P#)6eJCI`e~2@nN(i5++k!J8e!ZHjqQhb z1C!HTMi*EHnK*3pOTcA|$n zT#^kNPacKAPDY(>R+5v&)&q+r)y@7wj*`~B}vQ0hi72~4niqI=1))1Eb8_SVxdrSPcPbmtdXeXKnXKQoq)^Ybbg9$e?@_-nxl-Ec(P`~6eFVf-N5q;P0|O+)n_${V`o zZjMmPHG0X;}NCq zq!CfO9$@BQdkHHxvxdH36Ty|j54&q`jW>=nSRXclWW!hQ{r_Yer!+G~;Z~DyQB=PR zE^Q;oPjRD8GZ_Z-q`l;R!%%&9tN;uFgh(!hj}~W)Jy|x2(4AasFN{BohvEg zZqqkN{6CjP&0Dz)r_n|8BxVfVQ@0M?z>a57I#9I!7Y2kl`sbomwE7-7Ln{{TWJ_U@ zD;rCnk#+}+v(%$i4LPE~6j%kWOXjJTt`->GJlwKM*bk}p$>%8JRWtF?QKukJ`$7QK z9M(t9KgsGHf)0nK>AADhiqWpm-yw|=nQ%d;6sbq)r0P-OJz zaIEu2wMAO`PrVu83at;Ad_f<9k>ofsvaRYz=^LIBmgDCBlNgNu>wlo3lLB7fYN6Yq zf^48)C-z%kgr^ZGliI~g?oTxm=~3#%8sy`)f2WbDIN%L$y_|qW9Osu7C$G218RTf} z>2raoSR>UcXcC<Dj z!~8xv?V(6z;Z|9A2hFvCbY;4@v-^G81&~*9V>YbXI6g}J_w@_S(ydxP6@-`cdgg3G z`TgJ32SKH-GT;;H(i`eW98iowr0)4=y|A{sK3cWfRhQHT*kL!em8kRZLZt8x!Ui(r z!UOtoi3-Z+y>lI8a9_Y8b@u2R-@%OiS19$7&U4=#?m$= zRGmoH%kfDtXQ$DtX-Tv7c1?KD4q>Gyh^xJds2%i;G@2h#C@c|PmS9J&$}tiuf>k$7IzAT1a!2KujAvz7RW_D{)+;s&whP@?AID(d-VE_aD+MySXAd z@yXnV((DrtPuTntPiZqJj{&mx>A9VKbdRhpO*j0%JMkQkn-n-|9t)Q6P#kbJD*Bj3 zM_@Z>jqg+w-vDniE0q51rIhX#=FuG9e%XAk{3*GHV_=ser1VS9{azE;mzxln?~^X( z4KAUn{{WZnr%V#Ih-0mjd846pj(@(&5w_W1Gs1OD=f@!t&v~PVi?{O;sZBJaqu=AQ zCskGtHi_-Ub2ZtC4N$UwMJl_VN`ZbBpdFeF(F^a!-eRe#@pz`NeA_0`swW_unSHZG z$QZ0gs0Q5=km^E}K75cT*u!^9xM^{^ zdspDOKxSaUPKXMDhjGLcaZ#6cnk4z+J4Mf@;Gyi;dIJ1=p z_`4^(kn>3p6+4N_Fm*KmGYjH>i9LZH#qYJ}JU0a~!ZEy6M%S1u)7TRO#p}cM`(m9O z*z>>U1Y_1iii?UStUxevMSngCd!%boNw6TseDvxDZoq6psq5ul8(NM&kWy zAWPH>DbPY2U|H3kgb{Mtb2$e|Tl|Ew$H5WL61+S`Z?fqfk9P-xLRk}@4X*?JK6R@b zrWSn-1os8wK11LGp;a8of{?{oZcIKy1e<^-3Vn0v?3vY*MV}`qg|)P6s*j!v%-t2s zsPJ?9#@Y+GpvJ0Z<)^S~iEV!94M6w>-BHzgYg9jz1{EhpU_0~Nql&&}Kjg+UY9?90H}=4 zzx`|wG{k7R_;=fJBY+UWh6kK~K6u^}!0t~`j;W}}89X}e0KPcrycI6u!Ql5(X{WaD z@3iNE)_i>39o=thu?!Ka z;*Zb@kursTBz_Ncog>@_5$t@~VxBL*w!yVHRW1gV*W8i+BM5y7n*}bHRpnPI~N_p3>Mp$GM7rolB*t3-SfF!<@gD^dNy%# zuPRZ_-jBPF^7(L*6F3O!uXu8t;wx-xXfL3k-gmLh!6ULROgE;0smomoLj{B(#f)^U zS5>B8!o1J&=;C8O=$n(A`mBR8z!topTyhE9O-_!=#+h@rrlL^Ettj3LA@NSr+j7V} z+DvR-?YE%~g|zkpCBw#sA&OC3A6r4?Aep|91%W}R3Zd$8;NJ?KSLrH^r}X`}ijAg+ z)FCfB%7;7*a(Sx-nKqr zjhnJYF5ARDh^b#*($brBA&)t}4mcC~B$HsjY*7#`Rw`IqS&T@53vuHXAP%O&{*!2@ zPM@%3M;Hnm$2meyU^Dr&Us!_-K|a$0jH42o!}{bBhNzCHH!}6}8}Tm(t^*75Ow0@N zKhvtyddINBx?#sBFMsZQzixRr%t>KkW{;i!ywz)!w&4yP5jO4)F7Uwl4V1_A`!w&Z z>0YWkoi!;>GGmNieG5PV0XzP98qU>+eN;5FKYD`>#XH6C`yi#& zj_sbFe*f_K@!rcG3PSML(4JyPfs2BVi=X&I_)pS?Po_mOlO7#gpWgpZz~4^De~@H;=lk`I>UBND{5`&~eM ztq-Nw!vS77R3E!aL_WjFHaDA3|1^I25w?YLBOkk&x>;B8haDrOlo|Q@^hdzYdH5!eP@X5M z&1?kepwbaHzbHyAl3k@cb~aRw?WZVY=_q8~GVDyPEASrvVmRh<5<3 z#h(7t0`zWZdGDS4hyPV2)fgw4DfC~v$glo;K%$&Cx15Ex@)`d}e%-rkW>Br?1p6PM CHP}}G literal 0 HcmV?d00001 diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/it/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/it/strings.xml index 310a021ff2..ba11e0e29b 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/it/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/it/strings.xml @@ -847,7 +847,6 @@ Proibisci l\'invio di messaggi vocali. ricevuto, vietato Ripristina i colori - Salva colore Imposta 1 giorno Imposta le preferenze del gruppo Tema diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/iw/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/iw/strings.xml index 7899c374b2..e335c199d0 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/iw/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/iw/strings.xml @@ -898,7 +898,6 @@ שמור סיסמה ופתח את הצ׳אט שמור ארכיון בחירת אנשי קשר - שמור צבע קוד גישה להשמדה עצמית שניות אישור diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/ja/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/ja/strings.xml index 83d59b3705..eebb40a1c5 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/ja/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/ja/strings.xml @@ -792,7 +792,6 @@ 保存 ネットワーク設定を更新しますか? 設定を更新すると、全サーバにクライントの再接続が行われます。 - 色を保存 あなたが次を許可しています: オン グループ設定を行う diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/ko/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/ko/strings.xml index af3972035f..3caa99bc59 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/ko/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/ko/strings.xml @@ -757,7 +757,6 @@ 저장하고 대화 상대에게 알리기 지우기 아카이브 저장하기 - 색상 저장하기 암호 저장소에 비밀번호 저장하기 데이터베이스 백업 복원하기 데이터베이스 백업을 복원한 후 이전 비밀번호를 입력해 주세요. 이 작업은 되돌릴 수 없어요. diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/lt/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/lt/strings.xml index 43237fa2a9..b5191f342d 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/lt/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/lt/strings.xml @@ -189,7 +189,6 @@ Daugiau neberodyti Tamsus Atstatyti spalvas - Įrašyti spalvą Grupės parinktys Ištrinti visiems Tiesioginės žinutės diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/ml/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/ml/strings.xml index 92bd3e381a..455f9d53bd 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/ml/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/ml/strings.xml @@ -323,7 +323,6 @@ പഴയപടിയാക്കുക സംവിധാനം സംവിധാനം - നിറം സംരക്ഷിക്കുക ശീർഷകം രണ്ടാംതരമായ അതെ diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/nl/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/nl/strings.xml index ab10a01a66..8c803bdeea 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/nl/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/nl/strings.xml @@ -814,7 +814,6 @@ Wanneer je een incognito profiel met iemand deelt, wordt dit profiel gebruikt voor de groepen waarvoor ze je uitnodigen. Thema Kleuren resetten - Kleur opslaan Systeem ja gekregen, verboden diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/pl/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/pl/strings.xml index d667126730..825b5200c4 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/pl/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/pl/strings.xml @@ -799,7 +799,6 @@ Zabroń wysyłania znikających wiadomości. otrzymane, zabronione Resetuj kolory - Zapisz kolor Ustaw 1 dzień System System diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/pt-rBR/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/pt-rBR/strings.xml index cc0bd49454..7d4570e561 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/pt-rBR/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/pt-rBR/strings.xml @@ -485,7 +485,6 @@ Reverter Salvar Redefinir cores - Salvar cor interface italiana Notificações periódicas Câmera diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/pt/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/pt/strings.xml index 7889ef396e..4bb442faf8 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/pt/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/pt/strings.xml @@ -370,7 +370,6 @@ Você está a tentar convidar um contato com quem partilhou um perfil anónimo para o grupo no qual voçê está a usar o seu perfil principal Conexão O modo anónimo protege a privacidade do nome e da imagem do seu perfil principal — para cada novo contato um novo perfil aleatório é criado. - Salvar cor você partilhou ligação de utilização única você partilhou ligação anónima de utilização única Ligação de conexão inválida diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/ru/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/ru/strings.xml index a71638eae0..33b511c1e5 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/ru/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/ru/strings.xml @@ -848,7 +848,6 @@ Темная Тема - Сохранить цвет Сбросить цвета Акцент diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/th/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/th/strings.xml index 5701c0ca78..f6988ca367 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/th/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/th/strings.xml @@ -855,7 +855,6 @@ เปลี่ยนกลับ บันทึก รีเซ็ตสี - บันทึกสี ได้รับ, ห้าม ผู้รับจะเห็นการอัปเดตเมื่อคุณพิมพ์ ลดการใช้แบตเตอรี่ diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/tr/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/tr/strings.xml index 9ae8707c11..f659db0e2a 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/tr/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/tr/strings.xml @@ -122,7 +122,6 @@ SimpleX Koyu tema Tema - Rengi kaydet Temayı içe aktar Temayı içe aktarırken hata oluştu Dosyanın doğru YAML sözdizimine sahip olduğundan emin olun. Tema dosyası yapısının bir örneğine sahip olmak için temayı dışa aktarın. diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/uk/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/uk/strings.xml index 948f91b89a..2d52051098 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/uk/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/uk/strings.xml @@ -450,7 +450,6 @@ Змінити роль у групі\? Помилка при вилученні учасника Ваш профіль чату буде відправлений учасникам групи - Зберегти колір Видалення для всіх Голосові повідомлення Голосові повідомлення заборонені в цьому чаті. diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/zh-rCN/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/zh-rCN/strings.xml index 536207892d..1002e458f5 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/zh-rCN/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/zh-rCN/strings.xml @@ -831,7 +831,6 @@ 恢复 重置颜色 - 保存颜色 减少电池使用量 为了保护时区,图像/语音文件使用 UTC。 使用聊天 diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/zh-rTW/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/zh-rTW/strings.xml index c9d4298bc7..b6434c39db 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/zh-rTW/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/zh-rTW/strings.xml @@ -827,7 +827,6 @@ 儲存群組檔案時出錯 恢復 主題 - 儲存顏色 你允許 修改群組內的設定 私訊 diff --git a/apps/multiplatform/common/src/commonTest/kotlin/chat/simplex/app/ThemesTest.kt b/apps/multiplatform/common/src/commonTest/kotlin/chat/simplex/app/ThemesTest.kt new file mode 100644 index 0000000000..ae838dcff5 --- /dev/null +++ b/apps/multiplatform/common/src/commonTest/kotlin/chat/simplex/app/ThemesTest.kt @@ -0,0 +1,38 @@ +package chat.simplex.app + +import chat.simplex.common.ui.theme.* +import kotlin.test.Test +import kotlin.test.assertEquals + +// use this command for testing: +// ./gradlew desktopTest +class ThemesTest { + @Test + fun testSkipDuplicates() { + val r = ArrayList() + r.add(ThemeOverrides("UUID", DefaultTheme.DARK)) + r.add(ThemeOverrides("UUID", DefaultTheme.DARK)) + r.add(ThemeOverrides("UUID", DefaultTheme.LIGHT)) + r.add(ThemeOverrides("UUID2", DefaultTheme.DARK)) + r.add(ThemeOverrides("UUID3", DefaultTheme.LIGHT, wallpaper = ThemeWallpaper())) + r.add(ThemeOverrides("UUID4", DefaultTheme.LIGHT, wallpaper = null)) + r.add(ThemeOverrides("UUID5", DefaultTheme.LIGHT, wallpaper = ThemeWallpaper(preset = "something"))) + r.add(ThemeOverrides("UUID5", DefaultTheme.LIGHT, wallpaper = ThemeWallpaper(preset = "something2"))) + r.add(ThemeOverrides("UUID6", DefaultTheme.LIGHT, wallpaper = ThemeWallpaper(preset = "something2"))) + r.add(ThemeOverrides("UUID7", DefaultTheme.DARK, wallpaper = ThemeWallpaper(preset = "something2"))) + r.add(ThemeOverrides("UUID8", DefaultTheme.DARK, wallpaper = ThemeWallpaper(imageFile = "image"))) + r.add(ThemeOverrides("UUID9", DefaultTheme.DARK, wallpaper = ThemeWallpaper(imageFile = "image2"))) + r.add(ThemeOverrides("UUID10", DefaultTheme.LIGHT, wallpaper = ThemeWallpaper(imageFile = "image"))) + assertEquals( + r.skipDuplicates(), listOf( + ThemeOverrides("UUID", DefaultTheme.DARK), + ThemeOverrides("UUID3", DefaultTheme.LIGHT, wallpaper = ThemeWallpaper()), + ThemeOverrides("UUID5", DefaultTheme.LIGHT, wallpaper = ThemeWallpaper(preset = "something")), + ThemeOverrides("UUID6", DefaultTheme.LIGHT, wallpaper = ThemeWallpaper(preset = "something2")), + ThemeOverrides("UUID7", DefaultTheme.DARK, wallpaper = ThemeWallpaper(preset = "something2")), + ThemeOverrides("UUID8", DefaultTheme.DARK, wallpaper = ThemeWallpaper(imageFile = "image")), + ThemeOverrides("UUID10", DefaultTheme.LIGHT, wallpaper = ThemeWallpaper(imageFile = "image")) + ) + ) + } +} diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/DesktopApp.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/DesktopApp.kt index 7b7762eefc..eba22603d8 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/DesktopApp.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/DesktopApp.kt @@ -4,8 +4,7 @@ import androidx.compose.desktop.ui.tooling.preview.Preview import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text +import androidx.compose.material.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/AppCommon.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/AppCommon.desktop.kt index 71f862b30a..33a3ae2578 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/AppCommon.desktop.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/AppCommon.desktop.kt @@ -26,7 +26,7 @@ fun initApp() { } applyAppLocale() if (DatabaseUtils.ksSelfDestructPassword.get() == null) { - initChatControllerAndRunMigrations() + initChatControllerOnStart() } // LALAL //testCrypto() diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/Files.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/Files.desktop.kt index 9b2368fcd3..5f33e2a943 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/Files.desktop.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/Files.desktop.kt @@ -13,8 +13,10 @@ actual val dataDir: File = File(desktopPlatform.dataPath) actual val tmpDir: File = File(System.getProperty("java.io.tmpdir") + File.separator + "simplex").also { it.deleteOnExit() } actual val filesDir: File = File(dataDir.absolutePath + File.separator + "simplex_v1_files") actual val appFilesDir: File = filesDir +actual val wallpapersDir: File = File(dataDir.absolutePath + File.separator + "simplex_v1_assets" + File.separator + "wallpapers").also { it.mkdirs() } actual val coreTmpDir: File = File(dataDir.absolutePath + File.separator + "tmp") actual val dbAbsolutePrefixPath: String = dataDir.absolutePath + File.separator + "simplex_v1" +actual val preferencesDir = File(desktopPlatform.configPath).also { it.parentFile.mkdirs() } actual val chatDatabaseFileName: String = "simplex_v1_chat.db" actual val agentDatabaseFileName: String = "simplex_v1_agent.db" diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/Resources.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/Resources.desktop.kt index b758988227..f8c123eea1 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/Resources.desktop.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/Resources.desktop.kt @@ -1,12 +1,17 @@ package chat.simplex.common.platform import androidx.compose.runtime.* +import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.graphics.toComposeImageBitmap import androidx.compose.ui.text.font.Font import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.* import chat.simplex.common.simplexWindowState +import chat.simplex.common.ui.theme.reactOnDarkThemeChanges +import com.jthemedetecor.OsThemeDetector import com.russhwolf.settings.* +import dev.icerock.moko.resources.ImageResource import dev.icerock.moko.resources.StringResource import dev.icerock.moko.resources.desc.desc import java.io.File @@ -18,7 +23,15 @@ actual fun font(name: String, res: String, weight: FontWeight, style: FontStyle) actual fun StringResource.localized(): String = desc().toString() -actual fun isInNightMode() = false +private val detector: OsThemeDetector = OsThemeDetector.getDetector() +actual fun isInNightMode() = try { + detector.isDark +} +catch (e: Exception) { + Log.e(TAG, e.stackTraceToString()) + /* On Mac this code can produce exception */ + false +} private val settingsFile = File(desktopPlatform.configPath + File.separator + "settings.properties") @@ -58,3 +71,6 @@ actual fun isRtl(text: CharSequence): Boolean { dir == Character.DIRECTIONALITY_RIGHT_TO_LEFT || dir == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC } } + +actual fun ImageResource.toComposeImageBitmap(): ImageBitmap? = + image.toComposeImageBitmap() diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/ui/theme/Theme.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/ui/theme/Theme.desktop.kt index 358c20d769..d7dc1ca859 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/ui/theme/Theme.desktop.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/ui/theme/Theme.desktop.kt @@ -10,6 +10,10 @@ private val detector: OsThemeDetector = OsThemeDetector.getDetector() registerListener(::reactOnDarkThemeChanges) } +// TODO: explore possibility to use +//@Composable +//actual fun isSystemInDarkTheme(): Boolean = androidx.compose.foundation.isSystemInDarkTheme() + @Composable actual fun isSystemInDarkTheme(): Boolean = try { detector.isDark diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/call/CallView.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/call/CallView.desktop.kt index d3bf1bf01e..d6331616cc 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/call/CallView.desktop.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/call/CallView.desktop.kt @@ -25,11 +25,6 @@ val connections = ArrayList() @Composable actual fun ActiveCallView() { - val endCall = { - val call = chatModel.activeCall.value - if (call != null) withBGApi { chatModel.callManager.endCall(call) } - } - BackHandler(onBack = endCall) val scope = rememberCoroutineScope() WebRTCController(chatModel.callCommand) { apiMsg -> Log.d(TAG, "received from WebRTCController: $apiMsg") diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/usersettings/Appearance.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/usersettings/Appearance.desktop.kt index 4e4846bc9f..669dd1949d 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/usersettings/Appearance.desktop.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/usersettings/Appearance.desktop.kt @@ -4,34 +4,23 @@ import SectionBottomSpacer import SectionDividerSpaced import SectionView import androidx.compose.foundation.layout.* -import androidx.compose.runtime.Composable -import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.* import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import chat.simplex.common.model.ChatModel import chat.simplex.common.model.SharedPreference -import chat.simplex.common.platform.ColumnWithScrollBar -import chat.simplex.common.platform.defaultLocale -import chat.simplex.common.ui.theme.ThemeColor +import chat.simplex.common.platform.* import chat.simplex.common.views.helpers.* -import chat.simplex.common.views.usersettings.AppearanceScope.ColorEditor import chat.simplex.res.MR import dev.icerock.moko.resources.compose.stringResource import kotlinx.coroutines.delay import java.util.Locale @Composable -actual fun AppearanceView(m: ChatModel, showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit)) { +actual fun AppearanceView(m: ChatModel) { AppearanceScope.AppearanceLayout( m.controller.appPrefs.appLanguage, m.controller.appPrefs.systemDarkTheme, - showSettingsModal = showSettingsModal, - editColor = { name, initialColor -> - ModalManager.start.showModalCloseable { close -> - ColorEditor(name, initialColor, close) - } - }, ) } @@ -39,8 +28,6 @@ actual fun AppearanceView(m: ChatModel, showSettingsModal: (@Composable (ChatMod fun AppearanceScope.AppearanceLayout( languagePref: SharedPreference, systemDarkTheme: SharedPreference, - showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit), - editColor: (ThemeColor, Color) -> Unit, ) { ColumnWithScrollBar( Modifier.fillMaxWidth(), @@ -63,10 +50,11 @@ fun AppearanceScope.AppearanceLayout( } } SectionDividerSpaced(maxTopPadding = true) - ProfileImageSection() + ThemesSection(systemDarkTheme) SectionDividerSpaced(maxTopPadding = true) - ThemesSection(systemDarkTheme, showSettingsModal, editColor) + ProfileImageSection() + SectionBottomSpacer() } } diff --git a/apps/multiplatform/desktop/src/jvmMain/kotlin/chat/simplex/desktop/Main.kt b/apps/multiplatform/desktop/src/jvmMain/kotlin/chat/simplex/desktop/Main.kt index 7171f17991..9925a6346b 100644 --- a/apps/multiplatform/desktop/src/jvmMain/kotlin/chat/simplex/desktop/Main.kt +++ b/apps/multiplatform/desktop/src/jvmMain/kotlin/chat/simplex/desktop/Main.kt @@ -18,6 +18,7 @@ import java.io.File fun main() { initHaskell() + runMigrations() initApp() tmpDir.deleteRecursively() tmpDir.mkdir() From b0516b64408b8b41350ef04450a1b15a5f1d8c7a Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Sat, 25 May 2024 11:18:49 +0100 Subject: [PATCH 12/18] core: 5.7.4.1 --- cabal.project | 2 +- package.yaml | 2 +- scripts/nix/sha256map.nix | 2 +- simplex-chat.cabal | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cabal.project b/cabal.project index 62764bb139..9efbb332ff 100644 --- a/cabal.project +++ b/cabal.project @@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd source-repository-package type: git location: https://github.com/simplex-chat/simplexmq.git - tag: 6309f92c6860fce39d6675eb92fc460bdc3db01d + tag: df35c50b99a1291aac3ff86ed71387bb4f03c984 source-repository-package type: git diff --git a/package.yaml b/package.yaml index fa4d066c6b..606cd16b4e 100644 --- a/package.yaml +++ b/package.yaml @@ -1,5 +1,5 @@ name: simplex-chat -version: 5.7.4.0 +version: 5.7.4.1 #synopsis: #description: homepage: https://github.com/simplex-chat/simplex-chat#readme diff --git a/scripts/nix/sha256map.nix b/scripts/nix/sha256map.nix index 74286532bd..7c11ea0e9f 100644 --- a/scripts/nix/sha256map.nix +++ b/scripts/nix/sha256map.nix @@ -1,5 +1,5 @@ { - "https://github.com/simplex-chat/simplexmq.git"."6309f92c6860fce39d6675eb92fc460bdc3db01d" = "0aiyjcjraispkripv1viry6357nxvydv2sb6k5ali0hr8cnsskg3"; + "https://github.com/simplex-chat/simplexmq.git"."df35c50b99a1291aac3ff86ed71387bb4f03c984" = "0a3vvay14a0f7ypl94fag23g0z7b1kpq3l36kw6jgb0fjhr84m83"; "https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38"; "https://github.com/simplex-chat/direct-sqlcipher.git"."f814ee68b16a9447fbb467ccc8f29bdd3546bfd9" = "1ql13f4kfwkbaq7nygkxgw84213i0zm7c1a8hwvramayxl38dq5d"; "https://github.com/simplex-chat/sqlcipher-simple.git"."a46bd361a19376c5211f1058908fc0ae6bf42446" = "1z0r78d8f0812kxbgsm735qf6xx8lvaz27k1a0b4a2m0sshpd5gl"; diff --git a/simplex-chat.cabal b/simplex-chat.cabal index 86b2b9668e..681bcc9e57 100644 --- a/simplex-chat.cabal +++ b/simplex-chat.cabal @@ -5,7 +5,7 @@ cabal-version: 1.12 -- see: https://github.com/sol/hpack name: simplex-chat -version: 5.7.4.0 +version: 5.7.4.1 category: Web, System, Services, Cryptography homepage: https://github.com/simplex-chat/simplex-chat#readme author: simplex.chat From dccd6631afbac678fb774e3e18f2ba242dcdb362 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Sat, 25 May 2024 17:06:11 +0100 Subject: [PATCH 13/18] 5.7.4: ios 219, android 212, desktop 48 --- apps/ios/SimpleX.xcodeproj/project.pbxproj | 64 +++++++++++----------- apps/multiplatform/gradle.properties | 8 +-- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/apps/ios/SimpleX.xcodeproj/project.pbxproj b/apps/ios/SimpleX.xcodeproj/project.pbxproj index 30345d6895..be1ca4c444 100644 --- a/apps/ios/SimpleX.xcodeproj/project.pbxproj +++ b/apps/ios/SimpleX.xcodeproj/project.pbxproj @@ -53,6 +53,11 @@ 5C5E5D3B2824468B00B0488A /* ActiveCallView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C5E5D3A2824468B00B0488A /* ActiveCallView.swift */; }; 5C5F2B6D27EBC3FE006A9D5F /* ImagePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C5F2B6C27EBC3FE006A9D5F /* ImagePicker.swift */; }; 5C5F2B7027EBC704006A9D5F /* ProfileImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C5F2B6F27EBC704006A9D5F /* ProfileImage.swift */; }; + 5C614CFB2C021C1C000E7758 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C614CF62C021C1C000E7758 /* libffi.a */; }; + 5C614CFC2C021C1C000E7758 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C614CF72C021C1C000E7758 /* libgmpxx.a */; }; + 5C614CFD2C021C1C000E7758 /* libHSsimplex-chat-5.7.4.1-FMTNcSSNT86KdfUI39X2r7-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C614CF82C021C1C000E7758 /* libHSsimplex-chat-5.7.4.1-FMTNcSSNT86KdfUI39X2r7-ghc9.6.3.a */; }; + 5C614CFE2C021C1C000E7758 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C614CF92C021C1C000E7758 /* libgmp.a */; }; + 5C614CFF2C021C1C000E7758 /* libHSsimplex-chat-5.7.4.1-FMTNcSSNT86KdfUI39X2r7.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C614CFA2C021C1C000E7758 /* libHSsimplex-chat-5.7.4.1-FMTNcSSNT86KdfUI39X2r7.a */; }; 5C65DAF929D0CC20003CEE45 /* DeveloperView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C65DAF829D0CC20003CEE45 /* DeveloperView.swift */; }; 5C65F343297D45E100B67AF3 /* VersionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C65F341297D3F3600B67AF3 /* VersionView.swift */; }; 5C6BA667289BD954009B8ECC /* DismissSheets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C6BA666289BD954009B8ECC /* DismissSheets.swift */; }; @@ -115,11 +120,6 @@ 5CD67B8F2B0E858A00C510B1 /* hs_init.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CD67B8D2B0E858A00C510B1 /* hs_init.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5CD67B902B0E858A00C510B1 /* hs_init.c in Sources */ = {isa = PBXBuildFile; fileRef = 5CD67B8E2B0E858A00C510B1 /* hs_init.c */; }; 5CDCAD482818589900503DA2 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD472818589900503DA2 /* NotificationService.swift */; }; - 5CE0E8AB2BF0C1B5008D6E06 /* libHSsimplex-chat-5.7.3.0-BQ0iWJUV1AuAQdR2Nu1hMg-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CE0E8A62BF0C1B5008D6E06 /* libHSsimplex-chat-5.7.3.0-BQ0iWJUV1AuAQdR2Nu1hMg-ghc9.6.3.a */; }; - 5CE0E8AC2BF0C1B5008D6E06 /* libHSsimplex-chat-5.7.3.0-BQ0iWJUV1AuAQdR2Nu1hMg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CE0E8A72BF0C1B5008D6E06 /* libHSsimplex-chat-5.7.3.0-BQ0iWJUV1AuAQdR2Nu1hMg.a */; }; - 5CE0E8AD2BF0C1B5008D6E06 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CE0E8A82BF0C1B5008D6E06 /* libgmp.a */; }; - 5CE0E8AE2BF0C1B5008D6E06 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CE0E8A92BF0C1B5008D6E06 /* libffi.a */; }; - 5CE0E8AF2BF0C1B5008D6E06 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CE0E8AA2BF0C1B5008D6E06 /* libgmpxx.a */; }; 5CE2BA702845308900EC33A6 /* SimpleXChat.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */; }; 5CE2BA712845308900EC33A6 /* SimpleXChat.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 5CE2BA77284530BF00EC33A6 /* SimpleXChat.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CE2BA76284530BF00EC33A6 /* SimpleXChat.h */; }; @@ -316,6 +316,11 @@ 5C5E5D3C282447AB00B0488A /* CallTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallTypes.swift; sourceTree = ""; }; 5C5F2B6C27EBC3FE006A9D5F /* ImagePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagePicker.swift; sourceTree = ""; }; 5C5F2B6F27EBC704006A9D5F /* ProfileImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileImage.swift; sourceTree = ""; }; + 5C614CF62C021C1C000E7758 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = ""; }; + 5C614CF72C021C1C000E7758 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = ""; }; + 5C614CF82C021C1C000E7758 /* libHSsimplex-chat-5.7.4.1-FMTNcSSNT86KdfUI39X2r7-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.7.4.1-FMTNcSSNT86KdfUI39X2r7-ghc9.6.3.a"; sourceTree = ""; }; + 5C614CF92C021C1C000E7758 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = ""; }; + 5C614CFA2C021C1C000E7758 /* libHSsimplex-chat-5.7.4.1-FMTNcSSNT86KdfUI39X2r7.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.7.4.1-FMTNcSSNT86KdfUI39X2r7.a"; sourceTree = ""; }; 5C636F662AAB3D2400751C84 /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = "uk.lproj/SimpleX--iOS--InfoPlist.strings"; sourceTree = ""; }; 5C636F672AAB3D2400751C84 /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/InfoPlist.strings; sourceTree = ""; }; 5C65DAE429C77136003CEE45 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; @@ -420,11 +425,6 @@ 5CDCAD7428188D2900503DA2 /* APITypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APITypes.swift; sourceTree = ""; }; 5CDCAD7D2818941F00503DA2 /* API.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = API.swift; sourceTree = ""; }; 5CDCAD80281A7E2700503DA2 /* Notifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = ""; }; - 5CE0E8A62BF0C1B5008D6E06 /* libHSsimplex-chat-5.7.3.0-BQ0iWJUV1AuAQdR2Nu1hMg-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.7.3.0-BQ0iWJUV1AuAQdR2Nu1hMg-ghc9.6.3.a"; sourceTree = ""; }; - 5CE0E8A72BF0C1B5008D6E06 /* libHSsimplex-chat-5.7.3.0-BQ0iWJUV1AuAQdR2Nu1hMg.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.7.3.0-BQ0iWJUV1AuAQdR2Nu1hMg.a"; sourceTree = ""; }; - 5CE0E8A82BF0C1B5008D6E06 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = ""; }; - 5CE0E8A92BF0C1B5008D6E06 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = ""; }; - 5CE0E8AA2BF0C1B5008D6E06 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = ""; }; 5CE1330328E118CC00FFFD8C /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = "de.lproj/SimpleX--iOS--InfoPlist.strings"; sourceTree = ""; }; 5CE1330428E118CC00FFFD8C /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SimpleXChat.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -529,13 +529,13 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 5C614CFD2C021C1C000E7758 /* libHSsimplex-chat-5.7.4.1-FMTNcSSNT86KdfUI39X2r7-ghc9.6.3.a in Frameworks */, + 5C614CFF2C021C1C000E7758 /* libHSsimplex-chat-5.7.4.1-FMTNcSSNT86KdfUI39X2r7.a in Frameworks */, + 5C614CFC2C021C1C000E7758 /* libgmpxx.a in Frameworks */, 5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */, - 5CE0E8AE2BF0C1B5008D6E06 /* libffi.a in Frameworks */, - 5CE0E8AD2BF0C1B5008D6E06 /* libgmp.a in Frameworks */, + 5C614CFB2C021C1C000E7758 /* libffi.a in Frameworks */, + 5C614CFE2C021C1C000E7758 /* libgmp.a in Frameworks */, 5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */, - 5CE0E8AC2BF0C1B5008D6E06 /* libHSsimplex-chat-5.7.3.0-BQ0iWJUV1AuAQdR2Nu1hMg.a in Frameworks */, - 5CE0E8AB2BF0C1B5008D6E06 /* libHSsimplex-chat-5.7.3.0-BQ0iWJUV1AuAQdR2Nu1hMg-ghc9.6.3.a in Frameworks */, - 5CE0E8AF2BF0C1B5008D6E06 /* libgmpxx.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -601,11 +601,11 @@ 5C764E5C279C70B7000C6508 /* Libraries */ = { isa = PBXGroup; children = ( - 5CE0E8A92BF0C1B5008D6E06 /* libffi.a */, - 5CE0E8A82BF0C1B5008D6E06 /* libgmp.a */, - 5CE0E8AA2BF0C1B5008D6E06 /* libgmpxx.a */, - 5CE0E8A62BF0C1B5008D6E06 /* libHSsimplex-chat-5.7.3.0-BQ0iWJUV1AuAQdR2Nu1hMg-ghc9.6.3.a */, - 5CE0E8A72BF0C1B5008D6E06 /* libHSsimplex-chat-5.7.3.0-BQ0iWJUV1AuAQdR2Nu1hMg.a */, + 5C614CF62C021C1C000E7758 /* libffi.a */, + 5C614CF92C021C1C000E7758 /* libgmp.a */, + 5C614CF72C021C1C000E7758 /* libgmpxx.a */, + 5C614CF82C021C1C000E7758 /* libHSsimplex-chat-5.7.4.1-FMTNcSSNT86KdfUI39X2r7-ghc9.6.3.a */, + 5C614CFA2C021C1C000E7758 /* libHSsimplex-chat-5.7.4.1-FMTNcSSNT86KdfUI39X2r7.a */, ); path = Libraries; sourceTree = ""; @@ -1552,7 +1552,7 @@ CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 215; + CURRENT_PROJECT_VERSION = 219; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; @@ -1577,7 +1577,7 @@ "@executable_path/Frameworks", ); LLVM_LTO = YES_THIN; - MARKETING_VERSION = 5.7.3; + MARKETING_VERSION = 5.7.4; PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app; PRODUCT_NAME = SimpleX; SDKROOT = iphoneos; @@ -1601,7 +1601,7 @@ CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 215; + CURRENT_PROJECT_VERSION = 219; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; @@ -1626,7 +1626,7 @@ "@executable_path/Frameworks", ); LLVM_LTO = YES; - MARKETING_VERSION = 5.7.3; + MARKETING_VERSION = 5.7.4; PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app; PRODUCT_NAME = SimpleX; SDKROOT = iphoneos; @@ -1687,7 +1687,7 @@ CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 215; + CURRENT_PROJECT_VERSION = 219; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; GCC_OPTIMIZATION_LEVEL = s; @@ -1702,7 +1702,7 @@ "@executable_path/../../Frameworks", ); LLVM_LTO = YES; - MARKETING_VERSION = 5.7.3; + MARKETING_VERSION = 5.7.4; PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1724,7 +1724,7 @@ CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 215; + CURRENT_PROJECT_VERSION = 219; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; ENABLE_CODE_COVERAGE = NO; @@ -1739,7 +1739,7 @@ "@executable_path/../../Frameworks", ); LLVM_LTO = YES; - MARKETING_VERSION = 5.7.3; + MARKETING_VERSION = 5.7.4; PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1761,7 +1761,7 @@ CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES; CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 215; + CURRENT_PROJECT_VERSION = 219; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; DYLIB_COMPATIBILITY_VERSION = 1; @@ -1787,7 +1787,7 @@ "$(PROJECT_DIR)/Libraries/sim", ); LLVM_LTO = YES; - MARKETING_VERSION = 5.7.3; + MARKETING_VERSION = 5.7.4; PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SDKROOT = iphoneos; @@ -1812,7 +1812,7 @@ CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES; CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 215; + CURRENT_PROJECT_VERSION = 219; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; DYLIB_COMPATIBILITY_VERSION = 1; @@ -1838,7 +1838,7 @@ "$(PROJECT_DIR)/Libraries/sim", ); LLVM_LTO = YES; - MARKETING_VERSION = 5.7.3; + MARKETING_VERSION = 5.7.4; PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SDKROOT = iphoneos; diff --git a/apps/multiplatform/gradle.properties b/apps/multiplatform/gradle.properties index fcbf8b9d9e..2c44f841f9 100644 --- a/apps/multiplatform/gradle.properties +++ b/apps/multiplatform/gradle.properties @@ -26,11 +26,11 @@ android.enableJetifier=true kotlin.mpp.androidSourceSetLayoutVersion=2 kotlin.jvm.target=11 -android.version_name=5.7.3 -android.version_code=206 +android.version_name=5.7.4 +android.version_code=212 -desktop.version_name=5.7.3 -desktop.version_code=44 +desktop.version_name=5.7.4 +desktop.version_code=48 kotlin.version=1.9.23 gradle.plugin.version=8.2.0 From a03ccd0ba606b24296060d7df06de46413df6d81 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Sat, 25 May 2024 18:55:15 +0100 Subject: [PATCH 14/18] ios: update core library 5.8.0.3 --- apps/ios/SimpleX.xcodeproj/project.pbxproj | 40 +++++++++++----------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/apps/ios/SimpleX.xcodeproj/project.pbxproj b/apps/ios/SimpleX.xcodeproj/project.pbxproj index 3ea66b6087..70c5df74ae 100644 --- a/apps/ios/SimpleX.xcodeproj/project.pbxproj +++ b/apps/ios/SimpleX.xcodeproj/project.pbxproj @@ -76,11 +76,6 @@ 5C9CC7AD28C55D7800BEF955 /* DatabaseEncryptionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C9CC7AC28C55D7800BEF955 /* DatabaseEncryptionView.swift */; }; 5C9D13A3282187BB00AB8B43 /* WebRTC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C9D13A2282187BB00AB8B43 /* WebRTC.swift */; }; 5C9D811A2AA8727A001D49FD /* CryptoFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C9D81182AA7A4F1001D49FD /* CryptoFile.swift */; }; - 5C9F3DD62BFBCDD90003B86B /* libHSsimplex-chat-5.8.0.2-8RkLdmy05dJBsgWrGV50Uf-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C9F3DD12BFBCDD80003B86B /* libHSsimplex-chat-5.8.0.2-8RkLdmy05dJBsgWrGV50Uf-ghc9.6.3.a */; }; - 5C9F3DD72BFBCDD90003B86B /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C9F3DD22BFBCDD80003B86B /* libffi.a */; }; - 5C9F3DD82BFBCDD90003B86B /* libHSsimplex-chat-5.8.0.2-8RkLdmy05dJBsgWrGV50Uf.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C9F3DD32BFBCDD80003B86B /* libHSsimplex-chat-5.8.0.2-8RkLdmy05dJBsgWrGV50Uf.a */; }; - 5C9F3DD92BFBCDD90003B86B /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C9F3DD42BFBCDD90003B86B /* libgmpxx.a */; }; - 5C9F3DDA2BFBCDD90003B86B /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C9F3DD52BFBCDD90003B86B /* libgmp.a */; }; 5C9FD96E27A5D6ED0075386C /* SendMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C9FD96D27A5D6ED0075386C /* SendMessageView.swift */; }; 5CA059DC279559F40002BEB4 /* Tests_iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CA059DB279559F40002BEB4 /* Tests_iOS.swift */; }; 5CA059DE279559F40002BEB4 /* Tests_iOSLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CA059DD279559F40002BEB4 /* Tests_iOSLaunchTests.swift */; }; @@ -144,6 +139,11 @@ 5CEACCED27DEA495000BD591 /* MsgContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CEACCEC27DEA495000BD591 /* MsgContentView.swift */; }; 5CEBD7462A5C0A8F00665FE2 /* KeyboardPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CEBD7452A5C0A8F00665FE2 /* KeyboardPadding.swift */; }; 5CEBD7482A5F115D00665FE2 /* SetDeliveryReceiptsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CEBD7472A5F115D00665FE2 /* SetDeliveryReceiptsView.swift */; }; + 5CEE87942C024F4F00583B8A /* libHSsimplex-chat-5.8.0.3-3OkzEeUKATkEGDdUZR1g6G-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CEE878F2C024F4F00583B8A /* libHSsimplex-chat-5.8.0.3-3OkzEeUKATkEGDdUZR1g6G-ghc9.6.3.a */; }; + 5CEE87952C024F4F00583B8A /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CEE87902C024F4F00583B8A /* libgmp.a */; }; + 5CEE87962C024F4F00583B8A /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CEE87912C024F4F00583B8A /* libgmpxx.a */; }; + 5CEE87972C024F4F00583B8A /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CEE87922C024F4F00583B8A /* libffi.a */; }; + 5CEE87982C024F4F00583B8A /* libHSsimplex-chat-5.8.0.3-3OkzEeUKATkEGDdUZR1g6G.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CEE87932C024F4F00583B8A /* libHSsimplex-chat-5.8.0.3-3OkzEeUKATkEGDdUZR1g6G.a */; }; 5CF937202B24DE8C00E1D781 /* SharedFileSubscriber.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CF9371F2B24DE8C00E1D781 /* SharedFileSubscriber.swift */; }; 5CF937232B2503D000E1D781 /* NSESubscriber.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CF937212B25034A00E1D781 /* NSESubscriber.swift */; }; 5CFA59C42860BC6200863A68 /* MigrateToAppGroupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CFA59C32860BC6200863A68 /* MigrateToAppGroupView.swift */; }; @@ -354,11 +354,6 @@ 5C9CC7AC28C55D7800BEF955 /* DatabaseEncryptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatabaseEncryptionView.swift; sourceTree = ""; }; 5C9D13A2282187BB00AB8B43 /* WebRTC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebRTC.swift; sourceTree = ""; }; 5C9D81182AA7A4F1001D49FD /* CryptoFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CryptoFile.swift; sourceTree = ""; }; - 5C9F3DD12BFBCDD80003B86B /* libHSsimplex-chat-5.8.0.2-8RkLdmy05dJBsgWrGV50Uf-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.8.0.2-8RkLdmy05dJBsgWrGV50Uf-ghc9.6.3.a"; sourceTree = ""; }; - 5C9F3DD22BFBCDD80003B86B /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = ""; }; - 5C9F3DD32BFBCDD80003B86B /* libHSsimplex-chat-5.8.0.2-8RkLdmy05dJBsgWrGV50Uf.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.8.0.2-8RkLdmy05dJBsgWrGV50Uf.a"; sourceTree = ""; }; - 5C9F3DD42BFBCDD90003B86B /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = ""; }; - 5C9F3DD52BFBCDD90003B86B /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = ""; }; 5C9FD96A27A56D4D0075386C /* JSON.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSON.swift; sourceTree = ""; }; 5C9FD96D27A5D6ED0075386C /* SendMessageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendMessageView.swift; sourceTree = ""; }; 5CA059C3279559F40002BEB4 /* SimpleXApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimpleXApp.swift; sourceTree = ""; }; @@ -440,6 +435,11 @@ 5CEACCEC27DEA495000BD591 /* MsgContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MsgContentView.swift; sourceTree = ""; }; 5CEBD7452A5C0A8F00665FE2 /* KeyboardPadding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardPadding.swift; sourceTree = ""; }; 5CEBD7472A5F115D00665FE2 /* SetDeliveryReceiptsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetDeliveryReceiptsView.swift; sourceTree = ""; }; + 5CEE878F2C024F4F00583B8A /* libHSsimplex-chat-5.8.0.3-3OkzEeUKATkEGDdUZR1g6G-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.8.0.3-3OkzEeUKATkEGDdUZR1g6G-ghc9.6.3.a"; sourceTree = ""; }; + 5CEE87902C024F4F00583B8A /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = ""; }; + 5CEE87912C024F4F00583B8A /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = ""; }; + 5CEE87922C024F4F00583B8A /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = ""; }; + 5CEE87932C024F4F00583B8A /* libHSsimplex-chat-5.8.0.3-3OkzEeUKATkEGDdUZR1g6G.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.8.0.3-3OkzEeUKATkEGDdUZR1g6G.a"; sourceTree = ""; }; 5CF9371F2B24DE8C00E1D781 /* SharedFileSubscriber.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharedFileSubscriber.swift; sourceTree = ""; }; 5CF937212B25034A00E1D781 /* NSESubscriber.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSESubscriber.swift; sourceTree = ""; }; 5CFA59C32860BC6200863A68 /* MigrateToAppGroupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrateToAppGroupView.swift; sourceTree = ""; }; @@ -529,13 +529,13 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 5C9F3DD92BFBCDD90003B86B /* libgmpxx.a in Frameworks */, - 5C9F3DDA2BFBCDD90003B86B /* libgmp.a in Frameworks */, - 5C9F3DD82BFBCDD90003B86B /* libHSsimplex-chat-5.8.0.2-8RkLdmy05dJBsgWrGV50Uf.a in Frameworks */, + 5CEE87942C024F4F00583B8A /* libHSsimplex-chat-5.8.0.3-3OkzEeUKATkEGDdUZR1g6G-ghc9.6.3.a in Frameworks */, + 5CEE87972C024F4F00583B8A /* libffi.a in Frameworks */, + 5CEE87962C024F4F00583B8A /* libgmpxx.a in Frameworks */, 5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */, - 5C9F3DD62BFBCDD90003B86B /* libHSsimplex-chat-5.8.0.2-8RkLdmy05dJBsgWrGV50Uf-ghc9.6.3.a in Frameworks */, + 5CEE87952C024F4F00583B8A /* libgmp.a in Frameworks */, 5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */, - 5C9F3DD72BFBCDD90003B86B /* libffi.a in Frameworks */, + 5CEE87982C024F4F00583B8A /* libHSsimplex-chat-5.8.0.3-3OkzEeUKATkEGDdUZR1g6G.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -601,11 +601,11 @@ 5C764E5C279C70B7000C6508 /* Libraries */ = { isa = PBXGroup; children = ( - 5C9F3DD22BFBCDD80003B86B /* libffi.a */, - 5C9F3DD52BFBCDD90003B86B /* libgmp.a */, - 5C9F3DD42BFBCDD90003B86B /* libgmpxx.a */, - 5C9F3DD12BFBCDD80003B86B /* libHSsimplex-chat-5.8.0.2-8RkLdmy05dJBsgWrGV50Uf-ghc9.6.3.a */, - 5C9F3DD32BFBCDD80003B86B /* libHSsimplex-chat-5.8.0.2-8RkLdmy05dJBsgWrGV50Uf.a */, + 5CEE87922C024F4F00583B8A /* libffi.a */, + 5CEE87902C024F4F00583B8A /* libgmp.a */, + 5CEE87912C024F4F00583B8A /* libgmpxx.a */, + 5CEE878F2C024F4F00583B8A /* libHSsimplex-chat-5.8.0.3-3OkzEeUKATkEGDdUZR1g6G-ghc9.6.3.a */, + 5CEE87932C024F4F00583B8A /* libHSsimplex-chat-5.8.0.3-3OkzEeUKATkEGDdUZR1g6G.a */, ); path = Libraries; sourceTree = ""; From 373070f388302aec985d0dec82c7432f80587f36 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Sat, 25 May 2024 19:54:05 +0100 Subject: [PATCH 15/18] ui: show UI for additional group preferences (SimpleX links and per-role permissions) --- .../Views/Chat/Group/GroupPreferencesView.swift | 5 +---- .../common/views/chat/group/GroupPreferences.kt | 15 ++++++--------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/apps/ios/Shared/Views/Chat/Group/GroupPreferencesView.swift b/apps/ios/Shared/Views/Chat/Group/GroupPreferencesView.swift index b4e1992848..6ae5032be5 100644 --- a/apps/ios/Shared/Views/Chat/Group/GroupPreferencesView.swift +++ b/apps/ios/Shared/Views/Chat/Group/GroupPreferencesView.swift @@ -34,8 +34,7 @@ struct GroupPreferencesView: View { featureSection(.reactions, $preferences.reactions.enable) featureSection(.voice, $preferences.voice.enable, $preferences.voice.role) featureSection(.files, $preferences.files.enable, $preferences.files.role) - // TODO enable simplexLinks preference in 5.8 - // featureSection(.simplexLinks, $preferences.simplexLinks.enable, $preferences.simplexLinks.role) + featureSection(.simplexLinks, $preferences.simplexLinks.enable, $preferences.simplexLinks.role) featureSection(.history, $preferences.history.enable) if groupInfo.canEdit { @@ -102,8 +101,6 @@ struct GroupPreferencesView: View { } } .frame(height: 36) - // remove in v5.8 - .disabled(true) } } else { settingsRow(icon, color: color) { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupPreferences.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupPreferences.kt index 265d0cdeae..82646a99c5 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupPreferences.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupPreferences.kt @@ -123,13 +123,12 @@ private fun GroupPreferencesLayout( applyPrefs(preferences.copy(files = RoleGroupPreference(enable = enable, role))) } - // TODO enable simplexLinks preference in 5.8 -// SectionDividerSpaced(true, maxBottomPadding = false) -// val allowSimplexLinks = remember(preferences) { mutableStateOf(preferences.simplexLinks.enable) } -// val simplexLinksRole = remember(preferences) { mutableStateOf(preferences.simplexLinks.role) } -// FeatureSection(GroupFeature.SimplexLinks, allowSimplexLinks, simplexLinksRole, groupInfo, preferences, onTTLUpdated) { enable, role -> -// applyPrefs(preferences.copy(simplexLinks = RoleGroupPreference(enable = enable, role))) -// } + SectionDividerSpaced(true, maxBottomPadding = false) + val allowSimplexLinks = remember(preferences) { mutableStateOf(preferences.simplexLinks.enable) } + val simplexLinksRole = remember(preferences) { mutableStateOf(preferences.simplexLinks.role) } + FeatureSection(GroupFeature.SimplexLinks, allowSimplexLinks, simplexLinksRole, groupInfo, preferences, onTTLUpdated) { enable, role -> + applyPrefs(preferences.copy(simplexLinks = RoleGroupPreference(enable = enable, role))) + } SectionDividerSpaced(true, maxBottomPadding = false) val enableHistory = remember(preferences) { mutableStateOf(preferences.history.enable) } @@ -189,8 +188,6 @@ private fun FeatureSection( generalGetString(MR.strings.feature_enabled_for), featureRoles, enableForRole, - // remove in v5.8 - enabled = remember { mutableStateOf(false) }, onSelected = { value -> onSelected(enableFeature.value, value) } From a1d4f52185b9efab9eeec2f83e023fa83fac0904 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Sat, 25 May 2024 20:57:07 +0100 Subject: [PATCH 16/18] 5.8-beta.3: ios 220, android 214, desktop 49 --- apps/ios/SimpleX.xcodeproj/project.pbxproj | 12 ++++++------ apps/multiplatform/gradle.properties | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/ios/SimpleX.xcodeproj/project.pbxproj b/apps/ios/SimpleX.xcodeproj/project.pbxproj index 70c5df74ae..523f099226 100644 --- a/apps/ios/SimpleX.xcodeproj/project.pbxproj +++ b/apps/ios/SimpleX.xcodeproj/project.pbxproj @@ -1552,7 +1552,7 @@ CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 218; + CURRENT_PROJECT_VERSION = 220; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; @@ -1601,7 +1601,7 @@ CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 218; + CURRENT_PROJECT_VERSION = 220; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; @@ -1687,7 +1687,7 @@ CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 218; + CURRENT_PROJECT_VERSION = 220; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; GCC_OPTIMIZATION_LEVEL = s; @@ -1724,7 +1724,7 @@ CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 218; + CURRENT_PROJECT_VERSION = 220; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; ENABLE_CODE_COVERAGE = NO; @@ -1761,7 +1761,7 @@ CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES; CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 218; + CURRENT_PROJECT_VERSION = 220; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; DYLIB_COMPATIBILITY_VERSION = 1; @@ -1812,7 +1812,7 @@ CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES; CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 218; + CURRENT_PROJECT_VERSION = 220; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; DYLIB_COMPATIBILITY_VERSION = 1; diff --git a/apps/multiplatform/gradle.properties b/apps/multiplatform/gradle.properties index 01e3b17296..c90510566a 100644 --- a/apps/multiplatform/gradle.properties +++ b/apps/multiplatform/gradle.properties @@ -26,11 +26,11 @@ android.enableJetifier=true kotlin.mpp.androidSourceSetLayoutVersion=2 kotlin.jvm.target=11 -android.version_name=5.8-beta.2 -android.version_code=210 +android.version_name=5.8-beta.3 +android.version_code=214 -desktop.version_name=5.8-beta.2 -desktop.version_code=47 +desktop.version_name=5.8-beta.3 +desktop.version_code=49 kotlin.version=1.9.23 gradle.plugin.version=8.2.0 From c70e7223d9a3d07eb17a03e13aacac8f8246c1b3 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Mon, 27 May 2024 15:32:09 +0100 Subject: [PATCH 17/18] core: delete connection records when connecting (JOIN) fails (#4233) * core: delete connection records when connecting (JOIN) fails * show errors in commands --- src/Simplex/Chat.hs | 41 ++++++++++++++++++--------- src/Simplex/Chat/Store/Connections.hs | 5 ++++ src/Simplex/Chat/Store/Direct.hs | 4 +-- src/Simplex/Chat/Store/Groups.hs | 4 +-- src/Simplex/Chat/View.hs | 22 +++++++------- 5 files changed, 48 insertions(+), 28 deletions(-) diff --git a/src/Simplex/Chat.hs b/src/Simplex/Chat.hs index e259629d2b..77fac9ddc2 100644 --- a/src/Simplex/Chat.hs +++ b/src/Simplex/Chat.hs @@ -1550,8 +1550,8 @@ processChatCommand' vr = \case let chatV = agentToChatVersion agentV dm <- encodeConnInfoPQ pqSup' chatV $ XInfo profileToSend connId <- withAgent $ \a -> prepareConnectionToJoin a (aUserId user) True cReq pqSup' - conn <- withStore' $ \db -> createDirectConnection db user connId cReq ConnJoined (incognitoProfile $> profileToSend) subMode chatV pqSup' - void . withAgent $ \a -> joinConnection a (aUserId user) (Just connId) True cReq dm pqSup' subMode + conn@PendingContactConnection {pccConnId} <- withStore' $ \db -> createDirectConnection db user connId cReq ConnJoined (incognitoProfile $> profileToSend) subMode chatV pqSup' + joinPreparedAgentConnection user pccConnId connId cReq dm pqSup' subMode pure $ CRSentConfirmation user conn APIConnect userId incognito (Just (ACR SCMContact cReq)) -> withUserId userId $ \user -> connectViaContact user incognito cReq APIConnect _ _ Nothing -> throwChatError CEInvalidConnReq @@ -1806,12 +1806,20 @@ processChatCommand' vr = \case dm <- encodeConnInfo $ XGrpAcpt membershipMemId agentConnId <- withAgent $ \a -> prepareConnectionToJoin a (aUserId user) True connRequest PQSupportOff let chatV = vr `peerConnChatVersion` peerChatVRange - withStore' $ \db -> do - createMemberConnection db userId fromMember agentConnId chatV peerChatVRange subMode + cId <- withStore' $ \db -> do + Connection {connId = cId} <- createMemberConnection db userId fromMember agentConnId chatV peerChatVRange subMode updateGroupMemberStatus db userId fromMember GSMemAccepted updateGroupMemberStatus db userId membership GSMemAccepted - void . withAgent $ \a -> joinConnection a (aUserId user) (Just agentConnId) True connRequest dm PQSupportOff subMode - updateCIGroupInvitationStatus user g CIGISAccepted `catchChatError` \_ -> pure () + pure cId + void (withAgent $ \a -> joinConnection a (aUserId user) (Just agentConnId) True connRequest dm PQSupportOff subMode) + `catchChatError` \e -> do + withStore' $ \db -> do + deleteConnectionRecord db user cId + updateGroupMemberStatus db userId fromMember GSMemInvited + updateGroupMemberStatus db userId membership GSMemInvited + withAgent $ \a -> deleteConnectionAsync a False agentConnId + throwError e + updateCIGroupInvitationStatus user g CIGISAccepted `catchChatError` (toView . CRChatError (Just user)) pure $ CRUserAcceptedGroupSent user g {membership = membership {memberStatus = GSMemAccepted}} Nothing Nothing -> throwChatError $ CEContactNotActive ct APIMemberRole groupId memberId memRole -> withUser $ \user -> do @@ -2338,8 +2346,8 @@ processChatCommand' vr = \case -- [incognito] generate profile to send incognitoProfile <- if incognito then Just <$> liftIO generateRandomProfile else pure Nothing subMode <- chatReadVar subscriptionMode - conn <- withStore' $ \db -> createConnReqConnection db userId connId cReqHash xContactId incognitoProfile groupLinkId subMode chatV pqSup - joinContact user connId cReq incognitoProfile xContactId inGroup pqSup chatV + conn@PendingContactConnection {pccConnId} <- withStore' $ \db -> createConnReqConnection db userId connId cReqHash xContactId incognitoProfile groupLinkId subMode chatV pqSup + joinContact user pccConnId connId cReq incognitoProfile xContactId inGroup pqSup chatV pure $ CRSentInvitation user conn incognitoProfile connectContactViaAddress :: User -> IncognitoEnabled -> Contact -> ConnectionRequestUri 'CMContact -> CM ChatResponse connectContactViaAddress user incognito ct cReq = @@ -2351,8 +2359,8 @@ processChatCommand' vr = \case -- [incognito] generate profile to send incognitoProfile <- if incognito then Just <$> liftIO generateRandomProfile else pure Nothing subMode <- chatReadVar subscriptionMode - ct' <- withStore $ \db -> createAddressContactConnection db vr user ct connId cReqHash newXContactId incognitoProfile subMode chatV pqSup - joinContact user connId cReq incognitoProfile newXContactId False pqSup chatV + (pccConnId, ct') <- withStore $ \db -> createAddressContactConnection db vr user ct connId cReqHash newXContactId incognitoProfile subMode chatV pqSup + joinContact user pccConnId connId cReq incognitoProfile newXContactId False pqSup chatV pure $ CRSentInvitationToContact user ct' incognitoProfile prepareContact :: User -> ConnectionRequestUri 'CMContact -> PQSupport -> CM (ConnId, VersionChat) prepareContact user cReq pqSup = do @@ -2365,12 +2373,19 @@ processChatCommand' vr = \case let chatV = agentToChatVersion agentV connId <- withAgent $ \a -> prepareConnectionToJoin a (aUserId user) True cReq pqSup pure (connId, chatV) - joinContact :: User -> ConnId -> ConnectionRequestUri 'CMContact -> Maybe Profile -> XContactId -> Bool -> PQSupport -> VersionChat -> CM () - joinContact user connId cReq incognitoProfile xContactId inGroup pqSup chatV = do + joinContact :: User -> Int64 -> ConnId -> ConnectionRequestUri 'CMContact -> Maybe Profile -> XContactId -> Bool -> PQSupport -> VersionChat -> CM () + joinContact user pccConnId connId cReq incognitoProfile xContactId inGroup pqSup chatV = do let profileToSend = userProfileToSend user incognitoProfile Nothing inGroup dm <- encodeConnInfoPQ pqSup chatV (XContact profileToSend $ Just xContactId) subMode <- chatReadVar subscriptionMode - void . withAgent $ \a -> joinConnection a (aUserId user) (Just connId) True cReq dm pqSup subMode + joinPreparedAgentConnection user pccConnId connId cReq dm pqSup subMode + joinPreparedAgentConnection :: User -> Int64 -> ConnId -> ConnectionRequestUri m -> ByteString -> PQSupport -> SubscriptionMode -> CM () + joinPreparedAgentConnection user pccConnId connId cReq connInfo pqSup subMode = do + void (withAgent $ \a -> joinConnection a (aUserId user) (Just connId) True cReq connInfo pqSup subMode) + `catchChatError` \e -> do + withStore' $ \db -> deleteConnectionRecord db user pccConnId + withAgent $ \a -> deleteConnectionAsync a False connId + throwError e contactMember :: Contact -> [GroupMember] -> Maybe GroupMember contactMember Contact {contactId} = find $ \GroupMember {memberContactId = cId, memberStatus = s} -> diff --git a/src/Simplex/Chat/Store/Connections.hs b/src/Simplex/Chat/Store/Connections.hs index 1c3e949562..0d085d216c 100644 --- a/src/Simplex/Chat/Store/Connections.hs +++ b/src/Simplex/Chat/Store/Connections.hs @@ -14,6 +14,7 @@ module Simplex.Chat.Store.Connections getContactConnEntityByConnReqHash, getConnectionsToSubscribe, unsetConnectionToSubscribe, + deleteConnectionRecord, ) where @@ -225,3 +226,7 @@ getConnectionsToSubscribe db vr = do unsetConnectionToSubscribe :: DB.Connection -> IO () unsetConnectionToSubscribe db = DB.execute_ db "UPDATE connections SET to_subscribe = 0 WHERE to_subscribe = 1" + +deleteConnectionRecord :: DB.Connection -> User -> Int64 -> IO () +deleteConnectionRecord db User {userId} cId = do + DB.execute db "DELETE FROM connections WHERE user_id = ? AND connection_id = ?" (userId, cId) diff --git a/src/Simplex/Chat/Store/Direct.hs b/src/Simplex/Chat/Store/Direct.hs index ecba9be7fa..afbd3f7960 100644 --- a/src/Simplex/Chat/Store/Direct.hs +++ b/src/Simplex/Chat/Store/Direct.hs @@ -130,11 +130,11 @@ deletePendingContactConnection db userId connId = |] (userId, connId, ConnContact) -createAddressContactConnection :: DB.Connection -> VersionRangeChat -> User -> Contact -> ConnId -> ConnReqUriHash -> XContactId -> Maybe Profile -> SubscriptionMode -> VersionChat -> PQSupport -> ExceptT StoreError IO Contact +createAddressContactConnection :: DB.Connection -> VersionRangeChat -> User -> Contact -> ConnId -> ConnReqUriHash -> XContactId -> Maybe Profile -> SubscriptionMode -> VersionChat -> PQSupport -> ExceptT StoreError IO (Int64, Contact) createAddressContactConnection db vr user@User {userId} Contact {contactId} acId cReqHash xContactId incognitoProfile subMode chatV pqSup = do PendingContactConnection {pccConnId} <- liftIO $ createConnReqConnection db userId acId cReqHash xContactId incognitoProfile Nothing subMode chatV pqSup liftIO $ DB.execute db "UPDATE connections SET contact_id = ? WHERE connection_id = ?" (contactId, pccConnId) - getContact db vr user contactId + (pccConnId,) <$> getContact db vr user contactId createConnReqConnection :: DB.Connection -> UserId -> ConnId -> ConnReqUriHash -> XContactId -> Maybe Profile -> Maybe GroupLinkId -> SubscriptionMode -> VersionChat -> PQSupport -> IO PendingContactConnection createConnReqConnection db userId acId cReqHash xContactId incognitoProfile groupLinkId subMode chatV pqSup = do diff --git a/src/Simplex/Chat/Store/Groups.hs b/src/Simplex/Chat/Store/Groups.hs index 5e603a40c9..5efc915066 100644 --- a/src/Simplex/Chat/Store/Groups.hs +++ b/src/Simplex/Chat/Store/Groups.hs @@ -944,10 +944,10 @@ getMemberInvitation db User {userId} groupMemberId = fmap join . maybeFirstRow fromOnly $ DB.query db "SELECT sent_inv_queue_info FROM group_members WHERE group_member_id = ? AND user_id = ?" (groupMemberId, userId) -createMemberConnection :: DB.Connection -> UserId -> GroupMember -> ConnId -> VersionChat -> VersionRangeChat -> SubscriptionMode -> IO () +createMemberConnection :: DB.Connection -> UserId -> GroupMember -> ConnId -> VersionChat -> VersionRangeChat -> SubscriptionMode -> IO Connection createMemberConnection db userId GroupMember {groupMemberId} agentConnId chatV peerChatVRange subMode = do currentTs <- getCurrentTime - void $ createMemberConnection_ db userId groupMemberId agentConnId chatV peerChatVRange Nothing 0 currentTs subMode + createMemberConnection_ db userId groupMemberId agentConnId chatV peerChatVRange Nothing 0 currentTs subMode createMemberConnectionAsync :: DB.Connection -> User -> GroupMemberId -> (CommandId, ConnId) -> VersionChat -> VersionRangeChat -> SubscriptionMode -> IO () createMemberConnectionAsync db user@User {userId} groupMemberId (cmdId, agentConnId) chatV peerChatVRange subMode = do diff --git a/src/Simplex/Chat/View.hs b/src/Simplex/Chat/View.hs index 08980f21d2..671706c5f2 100644 --- a/src/Simplex/Chat/View.hs +++ b/src/Simplex/Chat/View.hs @@ -388,9 +388,9 @@ responseToView hu@(currentRH, user_) ChatConfig {logLevel, showReactions, showRe CRAgentConnDeleted acId -> ["completed deleting connection, agent connection id: " <> sShow acId | logLevel <= CLLInfo] CRAgentUserDeleted auId -> ["completed deleting user" <> if logLevel <= CLLInfo then ", agent user id: " <> sShow auId else ""] CRMessageError u prefix err -> ttyUser u [plain prefix <> ": " <> plain err | prefix == "error" || logLevel <= CLLWarning] - CRChatCmdError u e -> ttyUserPrefix' u $ viewChatError logLevel testView e - CRChatError u e -> ttyUser' u $ viewChatError logLevel testView e - CRChatErrors u errs -> ttyUser' u $ concatMap (viewChatError logLevel testView) errs + CRChatCmdError u e -> ttyUserPrefix' u $ viewChatError True logLevel testView e + CRChatError u e -> ttyUser' u $ viewChatError False logLevel testView e + CRChatErrors u errs -> ttyUser' u $ concatMap (viewChatError False logLevel testView) errs CRArchiveImported archiveErrs -> if null archiveErrs then ["ok"] else ["archive import errors: " <> plain (show archiveErrs)] CRAppSettings as -> ["app settings: " <> plain (LB.unpack $ J.encode as)] CRTimedAction _ _ -> [] @@ -1894,8 +1894,8 @@ viewRemoteCtrl CtrlAppInfo {deviceName, appVersionRange = AppVersionRange _ (App | otherwise = "" showCompatible = if compatible then "" else ", " <> bold' "not compatible" -viewChatError :: ChatLogLevel -> Bool -> ChatError -> [StyledString] -viewChatError logLevel testView = \case +viewChatError :: Bool -> ChatLogLevel -> Bool -> ChatError -> [StyledString] +viewChatError isCmd logLevel testView = \case ChatError err -> case err of CENoActiveUser -> ["error: active user is required"] CENoConnectionUser agentConnId -> ["error: message user not found, conn id: " <> sShow agentConnId | logLevel <= CLLError] @@ -2034,14 +2034,14 @@ viewChatError logLevel testView = \case <> "error: connection authorization failed - this could happen if connection was deleted,\ \ secured with different credentials, or due to a bug - please re-create the connection" ] - BROKER _ NETWORK -> [] - BROKER _ TIMEOUT -> [] - AGENT A_DUPLICATE -> [withConnEntity <> "error: AGENT A_DUPLICATE" | logLevel == CLLDebug] - AGENT (A_PROHIBITED e) -> [withConnEntity <> "error: AGENT A_PROHIBITED, " <> plain e | logLevel <= CLLWarning] - CONN NOT_FOUND -> [withConnEntity <> "error: CONN NOT_FOUND" | logLevel <= CLLWarning] + BROKER _ NETWORK | not isCmd -> [] + BROKER _ TIMEOUT | not isCmd -> [] + AGENT A_DUPLICATE -> [withConnEntity <> "error: AGENT A_DUPLICATE" | logLevel == CLLDebug || isCmd] + AGENT (A_PROHIBITED e) -> [withConnEntity <> "error: AGENT A_PROHIBITED, " <> plain e | logLevel <= CLLWarning || isCmd] + CONN NOT_FOUND -> [withConnEntity <> "error: CONN NOT_FOUND" | logLevel <= CLLWarning || isCmd] CRITICAL restart e -> [plain $ "critical error: " <> e] <> ["please restart the app" | restart] INTERNAL e -> [plain $ "internal error: " <> e] - e -> [withConnEntity <> "smp agent error: " <> sShow e | logLevel <= CLLWarning] + e -> [withConnEntity <> "smp agent error: " <> sShow e | logLevel <= CLLWarning || isCmd] where withConnEntity = case entity_ of Just entity@(RcvDirectMsgConnection conn contact_) -> case contact_ of From 01cadefde707d948a33150ca75565412c1dfd10a Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Mon, 27 May 2024 18:42:39 +0400 Subject: [PATCH 18/18] core: avoid creating duplicate introductions between group members connecting concurrently (#4235) --- src/Simplex/Chat/Store/Groups.hs | 39 +++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/src/Simplex/Chat/Store/Groups.hs b/src/Simplex/Chat/Store/Groups.hs index 5efc915066..21b50113b0 100644 --- a/src/Simplex/Chat/Store/Groups.hs +++ b/src/Simplex/Chat/Store/Groups.hs @@ -1090,20 +1090,33 @@ createIntroductions db chatV members toMember = do then pure [] else do currentTs <- getCurrentTime - mapM (insertIntro_ currentTs) reMembers + catMaybes <$> mapM (createIntro_ currentTs) reMembers where - insertIntro_ :: UTCTime -> GroupMember -> IO GroupMemberIntro - insertIntro_ ts reMember = do - DB.execute - db - [sql| - INSERT INTO group_member_intros - (re_group_member_id, to_group_member_id, intro_status, intro_chat_protocol_version, created_at, updated_at) - VALUES (?,?,?,?,?,?) - |] - (groupMemberId' reMember, groupMemberId' toMember, GMIntroPending, chatV, ts, ts) - introId <- insertedRowId db - pure GroupMemberIntro {introId, reMember, toMember, introStatus = GMIntroPending, introInvitation = Nothing} + createIntro_ :: UTCTime -> GroupMember -> IO (Maybe GroupMemberIntro) + createIntro_ ts reMember = + -- when members connect concurrently, host would try to create introductions between them in both directions; + -- this check avoids creating second (redundant) introduction + checkInverseIntro >>= \case + Just _ -> pure Nothing + Nothing -> do + DB.execute + db + [sql| + INSERT INTO group_member_intros + (re_group_member_id, to_group_member_id, intro_status, intro_chat_protocol_version, created_at, updated_at) + VALUES (?,?,?,?,?,?) + |] + (groupMemberId' reMember, groupMemberId' toMember, GMIntroPending, chatV, ts, ts) + introId <- insertedRowId db + pure $ Just GroupMemberIntro {introId, reMember, toMember, introStatus = GMIntroPending, introInvitation = Nothing} + where + checkInverseIntro :: IO (Maybe Int64) + checkInverseIntro = + maybeFirstRow fromOnly $ + DB.query + db + "SELECT 1 FROM group_member_intros WHERE re_group_member_id = ? AND to_group_member_id = ? LIMIT 1" + (groupMemberId' toMember, groupMemberId' reMember) updateIntroStatus :: DB.Connection -> Int64 -> GroupMemberIntroStatus -> IO () updateIntroStatus db introId introStatus = do